Skip to content

Commit

Permalink
update Head (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
JunNishimura committed Jun 4, 2023
1 parent acb3317 commit 2d635c4
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 14 deletions.
61 changes: 55 additions & 6 deletions internal/store/head.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,80 @@ import (
"path/filepath"
"regexp"
"strings"

"github.com/JunNishimura/Goit/internal/object"
"github.com/JunNishimura/Goit/internal/sha"
)

type Head string
type Head struct {
Reference string
Commit *object.Commit
}

var (
headRegexp = regexp.MustCompile("ref: refs/heads/.+")
ErrInvalidHead = errors.New("error: invalid HEAD format")
ErrIOHandling = errors.New("IO handling error")
)

func NewHead(rootGoitPath string) (Head, error) {
func getHeadCommit(branch, rootGoitPath string) (*object.Commit, error) {
branchPath := filepath.Join(rootGoitPath, "refs", "heads", branch)
hashBytes, err := os.ReadFile(branchPath)
if err != nil {
return nil, fmt.Errorf("%w: %s", ErrIOHandling, branchPath)
}
hashString := string(hashBytes)
hash, err := sha.ReadHash(hashString)
if err != nil {
return nil, fmt.Errorf("fail to decode hash string: %w", err)
}
commitObject, err := object.GetObject(rootGoitPath, hash)
if err != nil {
return nil, fmt.Errorf("fail to get last commit object: %w", err)
}
commit, err := object.NewCommit(commitObject)
if err != nil {
return nil, fmt.Errorf("fail to get last commit: %w", err)
}
return commit, nil
}

func NewHead(rootGoitPath string) (*Head, error) {
head := newHead()

headPath := filepath.Join(rootGoitPath, "HEAD")
if _, err := os.Stat(headPath); !os.IsNotExist(err) {
// get branch
headByte, err := os.ReadFile(headPath)
if err != nil {
return "", fmt.Errorf("fail to read file: %s", headPath)
return nil, fmt.Errorf("fail to read file: %s", headPath)
}
headString := string(headByte)
if ok := headRegexp.MatchString(headString); !ok {
return "", ErrInvalidHead
return nil, ErrInvalidHead
}
headSplit := strings.Split(headString, ": ")
slashSplit := strings.Split(headSplit[1], "/")
branch := slashSplit[len(slashSplit)-1]
return Head(branch), nil
head.Reference = branch

// get commit from branch
branchPath := filepath.Join(rootGoitPath, "refs", "heads", branch)
if _, err := os.Stat(branchPath); os.IsNotExist(err) {
return head, nil
}
commit, err := getHeadCommit(rootGoitPath, branch)
if err != nil {
return nil, ErrInvalidHead
}
head.Commit = commit

return head, nil
}

return "", nil
return head, nil
}

func newHead() *Head {
return &Head{}
}
23 changes: 15 additions & 8 deletions internal/store/head_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"os"
"path/filepath"
"reflect"
"testing"
)

Expand All @@ -12,27 +13,33 @@ func TestNewHead(t *testing.T) {
name string
content string
isCreated bool
want Head
want *Head
wantErr error
}{
{
name: "success",
content: "ref: refs/heads/main",
isCreated: true,
want: "main",
wantErr: nil,
want: &Head{
Reference: "main",
Commit: nil,
},
wantErr: nil,
}, {
name: "invalid HEAD format",
content: "ref: ***",
isCreated: true,
want: "",
want: nil,
wantErr: ErrInvalidHead,
}, {
name: "no HEAD file",
content: "ref: refs/heads/main",
isCreated: false,
want: "",
wantErr: nil,
want: &Head{
Reference: "",
Commit: nil,
},
wantErr: nil,
},
}
for _, tt := range tests {
Expand Down Expand Up @@ -88,8 +95,8 @@ func TestNewHead(t *testing.T) {
if !errors.Is(err, tt.wantErr) {
t.Errorf("got = %v, want = %v", err, tt.wantErr)
}
if head != tt.want {
t.Errorf("got = %s, want = %s", head, tt.want)
if !reflect.DeepEqual(head, tt.want) {
t.Errorf("got = %v, want = %v", head, tt.want)
}
})
}
Expand Down

0 comments on commit 2d635c4

Please sign in to comment.