Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions app/command_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package app

import (
"encoding/json"
"os"
"path/filepath"
"testing"

"github.com/alecthomas/assert/v2"
Expand Down Expand Up @@ -41,6 +43,48 @@ func TestCommandInfoJson(t *testing.T) {
assert.Equal(t, stringValue(t, js["Reference"], "Name"), "test-version")
assert.Equal(t, stringValue(t, js["Reference"], "Version"), "1.1")
assert.Equal(t, stringValue(t, js["Root"]), f.State.PkgDir()+"/test-version-1.1")
// The package isn't installed, so its binaries can't be resolved and are left as-is.
assert.Equal(t, []string{"bin"}, stringsValue(t, js["Binaries"]))
}

func TestCommandInfoJsonExpandsBinaryGlobs(t *testing.T) {
l, buf := ui.NewForTesting()
f := hermittest.NewEnvTestFixture(t, nil).WithManifests(map[string]string{
"test-globs.hcl": `
description = "test package"
binaries = ["bin/*"]
version "1.0" {
source = "www.example.com"
}
`,
})
defer f.Clean()

binDir := filepath.Join(f.State.PkgDir(), "test-globs-1.0", "bin")
assert.NoError(t, os.MkdirAll(binDir, 0700))
for _, name := range []string{"foo", "bar"} {
assert.NoError(t, os.WriteFile(filepath.Join(binDir, name), nil, 0600))
}

cmd := infoCmd{
Packages: []manifest.GlobSelector{manifest.MustParseGlobSelector("test-globs-1.0")},
JSONFormattable: JSONFormattable{
JSON: true,
},
}
assert.NoError(t, cmd.Run(l, f.Env, f.State))

var jss []map[string]json.RawMessage
assert.NoError(t, json.Unmarshal(buf.Bytes(), &jss))
assert.Equal(t, 1, len(jss))
assert.Equal(t, []string{"bin/bar", "bin/foo"}, stringsValue(t, jss[0]["Binaries"]))
}

func stringsValue(t *testing.T, from json.RawMessage) []string {
t.Helper()
var res []string
assert.NoError(t, json.Unmarshal(from, &res))
return res
}

func stringValue(t *testing.T, from json.RawMessage, path ...string) string {
Expand Down
26 changes: 25 additions & 1 deletion app/info_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (i *infoCmd) Run(l *ui.UI, env *hermit.Env, sta *state.State) error {
}

if i.JSON {
js, err := json.Marshal(packages) //nolint:musttag // default JSON behavior is fine
js, err := json.Marshal(expandBinaryGlobs(packages)) //nolint:musttag // default JSON behavior is fine
if err != nil {
return errors.WithStack(err)
}
Expand Down Expand Up @@ -105,6 +105,30 @@ func (i *infoCmd) Run(l *ui.UI, env *hermit.Env, sta *state.State) error {
return nil
}

// expandBinaryGlobs returns the packages with their binary globs expanded to the matching files,
// relative to the package root. Globs that can't be resolved, eg. because the package isn't
// installed, are left as they are in the manifest.
func expandBinaryGlobs(packages []*manifest.Package) []*manifest.Package {
out := make([]*manifest.Package, 0, len(packages))
for _, pkg := range packages {
bins, err := pkg.ResolveBinaries()
if err != nil {
out = append(out, pkg)
continue
}
expanded := *pkg
expanded.Binaries = make([]string, 0, len(bins))
for _, bin := range bins {
if rel, err := filepath.Rel(pkg.Root, bin); err == nil {
bin = rel
}
expanded.Binaries = append(expanded.Binaries, bin)
}
out = append(out, &expanded)
}
return out
}

func getInstalledPackageMap(l *ui.UI, env *hermit.Env) (map[string]*manifest.Package, error) {
installedPkgs, err := env.ListInstalled(l)
if err != nil {
Expand Down