package packagemanager import ( "testing" packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestGoPackageManagerParseCommand(t *testing.T) { type target struct { name string version string explicit bool } cases := []struct { name string args []string nonDownload bool manifestInstall bool targets []target }{ { name: "go version is non-download", args: []string{"go", "version"}, nonDownload: true, }, { name: "go env is non-download", args: []string{"go", "env", "GOPROXY"}, nonDownload: true, }, { name: "go vet is not non-download (can fetch on cold cache)", args: []string{"go", "vet", "./..."}, }, { name: "go fmt is not non-download (runs go list, can fetch on cold cache)", args: []string{"go", "fmt", "./..."}, }, { name: "go clean is not non-download (loads packages, can fetch on cold cache)", args: []string{"go", "clean", "./..."}, }, { name: "go build runs with proxy", args: []string{"go", "build", "./..."}, }, { name: "go get with canonical version", args: []string{"go", "get", "github.com/x/y@v1.2.3"}, targets: []target{{name: "github.com/x/y", version: "v1.2.3", explicit: true}}, }, { name: "go get with pseudo-version is explicit", args: []string{"go", "get", "github.com/x/y@v0.0.0-20191109021931-daa7c04131f5"}, targets: []target{{name: "github.com/x/y", version: "v0.0.0-20191109021931-daa7c04131f5", explicit: true}}, }, { name: "go install with latest query is not explicit", args: []string{"go", "install", "github.com/x/y/cmd/y@latest"}, targets: []target{{name: "github.com/x/y/cmd/y", version: "latest", explicit: false}}, }, { name: "go get with branch query is not explicit", args: []string{"go", "get", "github.com/x/y@master"}, targets: []target{{name: "github.com/x/y", version: "master", explicit: false}}, }, { name: "go install local path yields no target", args: []string{"go", "install", "./cmd/foo"}, }, { name: "go run current dir yields no target", args: []string{"go", "run", "."}, }, { name: "go get without version", args: []string{"go", "get", "example.com/m"}, targets: []target{{name: "example.com/m", version: "", explicit: false}}, }, { name: "flags before target are skipped", args: []string{"go", "get", "-u", "example.com/m@v2.0.0"}, targets: []target{{name: "example.com/m", version: "v2.0.0", explicit: true}}, }, { name: "go mod tidy is manifest install", args: []string{"go", "mod", "tidy"}, manifestInstall: true, }, { name: "go mod download without args is manifest install", args: []string{"go", "mod", "download"}, manifestInstall: true, }, { name: "go mod download with module", args: []string{"go", "mod", "download", "example.com/m@v1.0.0"}, targets: []target{{name: "example.com/m", version: "v1.0.0", explicit: true}}, }, { name: "no subcommand", args: []string{"go"}, }, } pm, err := NewGoPackageManager(DefaultGoPackageManagerConfig()) require.NoError(t, err) assert.Equal(t, "go", pm.Name()) assert.Equal(t, packagev1.Ecosystem_ECOSYSTEM_GO, pm.Ecosystem()) for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { parsed, err := pm.ParseCommand(tc.args) require.NoError(t, err) assert.Equal(t, tc.nonDownload, parsed.IsKnownNonDownloadCommand) assert.Equal(t, tc.manifestInstall, parsed.IsManifestInstall) require.Len(t, parsed.InstallTargets, len(tc.targets)) for i, want := range tc.targets { got := parsed.InstallTargets[i] assert.Equal(t, want.name, got.PackageVersion.GetPackage().GetName()) assert.Equal(t, want.version, got.PackageVersion.GetVersion()) assert.Equal(t, want.explicit, got.IsExplicitVersion) assert.Equal(t, packagev1.Ecosystem_ECOSYSTEM_GO, got.PackageVersion.GetPackage().GetEcosystem()) } }) } } func TestIsGoRemoteModuleTarget(t *testing.T) { cases := []struct { target string want bool }{ {"github.com/x/y", true}, {"example.com/m@v1.0.0", true}, {"gopkg.in/yaml.v3", true}, {".", false}, {"..", false}, {"./cmd/foo", false}, {"../pkg", false}, {"/abs/path", false}, {"./...", false}, {"...", false}, {`a\b`, false}, {"", false}, {"fmt", false}, {"cmd/foo", false}, } for _, tc := range cases { assert.Equal(t, tc.want, isGoRemoteModuleTarget(tc.target), "target %q", tc.target) } }