fix: keep the access path of archives discovered through a link

`discoverArchives` collects MIME hits first, and those are bare real paths. When the glob pass then found the same file through a symlink, it was dropped as a duplicate along with its access path. Java decides whether to describe an archive by its name, so a content-addressed jar (`store/3f9a1c`, linked from `lib/json-simple-1.1.1.jar`) was extracted but produced no package. This is the pnpm / nix / bazel layout.

When deduping, the candidate now takes the first location that carries an access path.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Alex Goodman
2026-09-24 11:25:40 -04:00
parent eec86cf88d
commit 5fc384dddb
2 changed files with 34 additions and 4 deletions
+9 -4
View File
@@ -263,9 +263,9 @@ func (c *archiveCataloger) discoverArchives(resolver file.Resolver) []archiveCan
}
var candidates []archiveCandidate
seen := map[file.Coordinates]struct{}{}
seen := map[file.Coordinates]int{}
for _, loc := range archives {
seen[loc.Coordinates] = struct{}{}
seen[loc.Coordinates] = len(candidates)
candidates = append(candidates, archiveCandidate{location: loc, sniffedAsArchive: true})
}
@@ -275,10 +275,15 @@ func (c *archiveCataloger) discoverArchives(resolver file.Resolver) []archiveCan
return candidates
}
for _, loc := range namedLikeZips {
if _, dup := seen[loc.Coordinates]; dup {
if i, dup := seen[loc.Coordinates]; dup {
// a MIME hit is the bare real path; the name it is reached by (a link such as
// lib/dep.jar -> ../store/3f9a1c) is what name-based catalogers like java key off
if prev := candidates[i].location; prev.AccessPath == "" || prev.AccessPath == prev.RealPath {
candidates[i].location = loc
}
continue
}
seen[loc.Coordinates] = struct{}{}
seen[loc.Coordinates] = len(candidates)
candidates = append(candidates, archiveCandidate{location: loc})
}
return candidates