Resolve LFS objects from git common dir
This commit is contained in:
@@ -733,10 +733,14 @@ func chunksFromManifest(assets []assetResource, entries []BuildManifestHAK) ([]h
|
|||||||
|
|
||||||
func collectLFSAssetInfo(p *project.Project) (map[string]lfsAssetInfo, error) {
|
func collectLFSAssetInfo(p *project.Project) (map[string]lfsAssetInfo, error) {
|
||||||
result := make(map[string]lfsAssetInfo)
|
result := make(map[string]lfsAssetInfo)
|
||||||
|
lfsObjectRoot, err := resolveLFSObjectRoot(p.Root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
for _, rel := range p.Inventory.AssetFiles {
|
for _, rel := range p.Inventory.AssetFiles {
|
||||||
rel = filepath.ToSlash(rel)
|
rel = filepath.ToSlash(rel)
|
||||||
abs := filepath.Join(p.AssetsDir(), filepath.FromSlash(rel))
|
abs := filepath.Join(p.AssetsDir(), filepath.FromSlash(rel))
|
||||||
info, ok, err := parseLFSPointerFile(abs, p.Root)
|
info, ok, err := parseLFSPointerFile(abs, lfsObjectRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -748,7 +752,22 @@ func collectLFSAssetInfo(p *project.Project) (map[string]lfsAssetInfo, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseLFSPointerFile(path, repoRoot string) (lfsAssetInfo, bool, error) {
|
func resolveLFSObjectRoot(repoRoot string) (string, error) {
|
||||||
|
output, err := gitOutput(repoRoot, "rev-parse", "--git-common-dir")
|
||||||
|
if err != nil {
|
||||||
|
return filepath.Join(repoRoot, ".git", "lfs", "objects"), nil
|
||||||
|
}
|
||||||
|
commonDir := strings.TrimSpace(output)
|
||||||
|
if commonDir == "" {
|
||||||
|
return filepath.Join(repoRoot, ".git", "lfs", "objects"), nil
|
||||||
|
}
|
||||||
|
if !filepath.IsAbs(commonDir) {
|
||||||
|
commonDir = filepath.Join(repoRoot, commonDir)
|
||||||
|
}
|
||||||
|
return filepath.Join(filepath.Clean(commonDir), "lfs", "objects"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseLFSPointerFile(path, lfsObjectRoot string) (lfsAssetInfo, bool, error) {
|
||||||
entry, err := os.Lstat(path)
|
entry, err := os.Lstat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return lfsAssetInfo{}, false, fmt.Errorf("stat %s: %w", path, err)
|
return lfsAssetInfo{}, false, fmt.Errorf("stat %s: %w", path, err)
|
||||||
@@ -784,7 +803,7 @@ func parseLFSPointerFile(path, repoRoot string) (lfsAssetInfo, bool, error) {
|
|||||||
return lfsAssetInfo{}, false, nil
|
return lfsAssetInfo{}, false, nil
|
||||||
}
|
}
|
||||||
if len(info.OID) >= 4 {
|
if len(info.OID) >= 4 {
|
||||||
info.ObjectPath = filepath.Join(repoRoot, ".git", "lfs", "objects", info.OID[:2], info.OID[2:4], info.OID)
|
info.ObjectPath = filepath.Join(lfsObjectRoot, info.OID[:2], info.OID[2:4], info.OID)
|
||||||
}
|
}
|
||||||
return info, true, nil
|
return info, true, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1874,6 +1874,59 @@ func TestPlanHAKChunksPutsNewestAssetsInLastChunk(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCollectLFSAssetInfoUsesGitCommonDirForWorktree(t *testing.T) {
|
||||||
|
if _, err := exec.LookPath("git"); err != nil {
|
||||||
|
t.Skip("git not available")
|
||||||
|
}
|
||||||
|
|
||||||
|
parent := t.TempDir()
|
||||||
|
repoRoot := filepath.Join(parent, "repo")
|
||||||
|
worktreeRoot := filepath.Join(parent, "worktree")
|
||||||
|
mustMkdir(t, repoRoot)
|
||||||
|
runGitTest(t, repoRoot, "init")
|
||||||
|
mustWriteFile(t, filepath.Join(repoRoot, "README.md"), "test\n")
|
||||||
|
runGitTest(t, repoRoot, "add", ".")
|
||||||
|
runGitTest(t, repoRoot, "config", "user.name", "Test User")
|
||||||
|
runGitTest(t, repoRoot, "config", "user.email", "test@example.com")
|
||||||
|
runGitTest(t, repoRoot, "commit", "-m", "initial")
|
||||||
|
runGitTest(t, repoRoot, "worktree", "add", worktreeRoot, "HEAD")
|
||||||
|
|
||||||
|
oid := strings.Repeat("a", 64)
|
||||||
|
assetRel := filepath.Join("core", "foo.mdl")
|
||||||
|
assetPath := filepath.Join(worktreeRoot, "assets", assetRel)
|
||||||
|
mustMkdir(t, filepath.Dir(assetPath))
|
||||||
|
mustWriteFile(t, assetPath, "version https://git-lfs.github.com/spec/v1\n"+"oid sha256:"+oid+"\n"+"size 5\n")
|
||||||
|
|
||||||
|
lfsObjectPath := filepath.Join(repoRoot, ".git", "lfs", "objects", oid[:2], oid[2:4], oid)
|
||||||
|
mustMkdir(t, filepath.Dir(lfsObjectPath))
|
||||||
|
mustWriteFile(t, lfsObjectPath, "model")
|
||||||
|
|
||||||
|
proj := &project.Project{
|
||||||
|
Root: worktreeRoot,
|
||||||
|
Config: project.Config{
|
||||||
|
Paths: project.PathConfig{Source: "src", Assets: "assets", Build: "build"},
|
||||||
|
},
|
||||||
|
Inventory: project.Inventory{
|
||||||
|
AssetFiles: []string{filepath.ToSlash(assetRel)},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
infos, err := collectLFSAssetInfo(proj)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("collect lfs asset info: %v", err)
|
||||||
|
}
|
||||||
|
info, ok := infos[filepath.ToSlash(assetRel)]
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("expected LFS asset info")
|
||||||
|
}
|
||||||
|
if got, want := info.ObjectPath, lfsObjectPath; got != want {
|
||||||
|
t.Fatalf("unexpected LFS object path:\ngot %s\nwant %s", got, want)
|
||||||
|
}
|
||||||
|
if _, err := lfsPathResource(assetPath, info, true); err != nil {
|
||||||
|
t.Fatalf("expected worktree LFS object to resolve: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func runGitCommitTest(t *testing.T, dir, timestamp, message string) {
|
func runGitCommitTest(t *testing.T, dir, timestamp, message string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
runGitTest(t, dir, "add", ".")
|
runGitTest(t, dir, "add", ".")
|
||||||
|
|||||||
Reference in New Issue
Block a user