From 054c6659ddcd0d8631c1b656be80a254fb6c7919 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Sun, 22 Jul 2018 23:42:40 -0400 Subject: [PATCH] status: Accommodate new verify systems The implementation of status could probably be considerably trimmed down now, as a number of the things it was doing can be done by new logic in gps/verify. This does the bare minimum necessary to get templated output working. --- cmd/dep/status.go | 109 +++++++++++++++++++++++++++++++---------- cmd/dep/status_test.go | 58 +++++++++++++--------- 2 files changed, 120 insertions(+), 47 deletions(-) diff --git a/cmd/dep/status.go b/cmd/dep/status.go index 56897dc9db..be9ae59d56 100644 --- a/cmd/dep/status.go +++ b/cmd/dep/status.go @@ -30,10 +30,11 @@ import ( const availableTemplateVariables = "ProjectRoot, Constraint, Version, Revision, Latest, and PackageCount." const availableDefaultTemplateVariables = `.Projects[]{ .ProjectRoot,.Source,.Constraint,.PackageCount,.Packages[], - .Locked{.Branch,.Revision,.Version},.Latest{.Revision,.Version} + .PruneOpts,.Digest,.Locked{.Branch,.Revision,.Version}, + .Latest{.Revision,.Version} }, .Metadata{ - .AnalyzerName,.AnalyzerVersion,.InputsDigest,.SolverName, + .AnalyzerName,.AnalyzerVersion,.InputImports,.SolverName, .SolverVersion }` @@ -405,6 +406,8 @@ func (out *templateOutput) DetailLine(ds *DetailStatus) error { Constraint: ds.getConsolidatedConstraint(), Locked: formatDetailVersion(ds.Version, ds.Revision), Latest: formatDetailLatestVersion(ds.Latest, ds.hasError), + PruneOpts: ds.getPruneOpts(), + Digest: ds.Digest.String(), PackageCount: ds.PackageCount, Source: ds.Source, Packages: ds.Packages, @@ -757,6 +760,8 @@ type rawDetailProject struct { Packages []string Locked rawDetailVersion Latest rawDetailVersion + PruneOpts string + Digest string Source string `json:"Source,omitempty"` Constraint string PackageCount int @@ -765,7 +770,8 @@ type rawDetailProject struct { type rawDetailMetadata struct { AnalyzerName string AnalyzerVersion int - InputsDigest string + InputsDigest string // deprecated + InputImports []string SolverName string SolverVersion int } @@ -778,6 +784,7 @@ func newRawMetadata(metadata *dep.SolveMeta) rawDetailMetadata { return rawDetailMetadata{ AnalyzerName: metadata.AnalyzerName, AnalyzerVersion: metadata.AnalyzerVersion, + InputImports: metadata.InputImports, SolverName: metadata.SolverName, SolverVersion: metadata.SolverVersion, } @@ -802,8 +809,10 @@ type BasicStatus struct { // information included about a a project in a lock file. type DetailStatus struct { BasicStatus - Packages []string - Source string + Packages []string + Source string + PruneOpts gps.PruneOptions + Digest verify.VersionedDigest } func (bs *BasicStatus) getConsolidatedConstraint() string { @@ -849,6 +858,10 @@ func (bs *BasicStatus) getConsolidatedLatest(revSize uint8) string { return latest } +func (ds *DetailStatus) getPruneOpts() string { + return (ds.PruneOpts & ^gps.PruneNestedVendorDirs).String() +} + func (bs *BasicStatus) marshalJSON() *rawStatus { return &rawStatus{ ProjectRoot: bs.ProjectRoot, @@ -868,6 +881,8 @@ func (ds *DetailStatus) marshalJSON() *rawDetailProject { Constraint: rawStatus.Constraint, Locked: formatDetailVersion(ds.Version, ds.Revision), Latest: formatDetailLatestVersion(ds.Latest, ds.hasError), + PruneOpts: ds.getPruneOpts(), + Digest: ds.Digest.String(), Source: ds.Source, Packages: ds.Packages, PackageCount: ds.PackageCount, @@ -926,9 +941,10 @@ func (cmd *statusCommand) runStatusAll(ctx *dep.Ctx, out outputter, p *dep.Proje lsat := verify.LockSatisfiesInputs(p.Lock, p.Manifest, params.RootPackageTree) if lsat.Satisfied() { - // If these are equal, we're guaranteed that the lock is a transitively - // complete picture of all deps. That eliminates the need for at least - // some checks. + // If the lock satisfies the inputs, we're guaranteed (barring manual + // meddling, about which we can do nothing) that the lock is a + // transitively complete picture of all deps. That eliminates the need + // for some checks. logger.Println("Checking upstream projects:") @@ -945,7 +961,7 @@ func (cmd *statusCommand) runStatusAll(ctx *dep.Ctx, out outputter, p *dep.Proje wg.Add(1) logger.Printf("(%d/%d) %s\n", i+1, len(slp), proj.Ident().ProjectRoot) - go func(proj gps.LockedProject) { + go func(proj verify.VerifiableProject) { bs := BasicStatus{ ProjectRoot: string(proj.Ident().ProjectRoot), PackageCount: len(proj.Packages()), @@ -1043,12 +1059,14 @@ func (cmd *statusCommand) runStatusAll(ctx *dep.Ctx, out outputter, p *dep.Proje if cmd.detail { ds.Source = proj.Ident().Source ds.Packages = proj.Packages() + ds.PruneOpts = proj.PruneOpts + ds.Digest = proj.Digest } dsCh <- &ds wg.Done() - }(proj) + }(proj.(verify.VerifiableProject)) } wg.Wait() @@ -1118,12 +1136,6 @@ func (cmd *statusCommand) runStatusAll(ctx *dep.Ctx, out outputter, p *dep.Proje return false, errCount, err } - // Hash digest mismatch may indicate that some deps are no longer - // needed, some are missing, or that some constraints or source - // locations have changed. - // - // It's possible for digests to not match, but still have a correct - // lock. rm, _ := ptree.ToReachMap(true, true, false, p.Manifest.IgnoredPackages()) external := rm.FlattenFn(paths.IsStandardImportPath) @@ -1406,28 +1418,75 @@ func parseStatusTemplate(format string) (*template.Template, error) { "dec": func(i int) int { return i - 1 }, + "tomlStrSplit": tomlStrSplit, + "tomlStrSplit2": func(strlist []string, level int) string { + // Hardcode to two spaces. + inbracket, inp := strings.Repeat(" ", level), strings.Repeat(" ", level+1) + switch len(strlist) { + case 0: + return "[]" + case 1: + return fmt.Sprintf("[\"%s\"]", strlist[0]) + default: + var buf bytes.Buffer + + fmt.Fprintf(&buf, "[\n") + for _, str := range strlist { + fmt.Fprintf(&buf, "%s\"%s\",\n", inp, str) + } + fmt.Fprintf(&buf, "%s]", inbracket) + + return buf.String() + } + }, }).Parse(format) return tmpl, err } +func tomlStrSplit(strlist []string) string { + switch len(strlist) { + case 0: + return "[]" + case 1: + return fmt.Sprintf("[\"%s\"]", strlist[0]) + default: + var buf bytes.Buffer + + // Hardcode to two spaces. + fmt.Fprintf(&buf, "[\n") + for _, str := range strlist { + fmt.Fprintf(&buf, " \"%s\",\n", str) + } + fmt.Fprintf(&buf, " ]") + + return buf.String() + } +} + const statusLockTemplate = `# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. -{{range $p := .Projects}}[[projects]]{{if $p.Locked.Branch}} - branch = "{{$p.Locked.Branch}}"{{end}} +{{range $p := .Projects}}[[projects]] + {{- if $p.Locked.Branch}} + branch = "{{$p.Locked.Branch}}" + {{- end}} + digest = "{{$p.Digest}}" name = "{{$p.ProjectRoot}}" - packages = [{{if eq 0 (len $p.Packages)}}"."]{{else}}{{range $i, $pkg := $p.Packages}} - "{{$pkg}}"{{if lt $i (dec (len $p.Packages))}},{{end}}{{end}} - ]{{end}} - revision = "{{$p.Locked.Revision}}"{{if $p.Source}} - source = "{{$p.Source}}"{{end}}{{if $p.Locked.Version}} - version = "{{$p.Locked.Version}}"{{end}} + packages = {{(tomlStrSplit $p.Packages)}} + pruneopts = "{{$p.PruneOpts}}" + revision = "{{$p.Locked.Revision}}" + {{- if $p.Source}} + source = "{{$p.Source}}" + {{- end}} + {{- if $p.Locked.Version}} + version = "{{$p.Locked.Version}}" + {{- end}} {{end}}[solve-meta] analyzer-name = "{{.Metadata.AnalyzerName}}" analyzer-version = {{.Metadata.AnalyzerVersion}} - inputs-digest = "{{.Metadata.InputsDigest}}" + input-imports = {{(tomlStrSplit .Metadata.InputImports)}} solver-name = "{{.Metadata.SolverName}}" solver-version = {{.Metadata.SolverVersion}} ` diff --git a/cmd/dep/status_test.go b/cmd/dep/status_test.go index 28923ecad6..80df0cc7be 100644 --- a/cmd/dep/status_test.go +++ b/cmd/dep/status_test.go @@ -871,56 +871,71 @@ const expectedStatusDetail = `# This file is autogenerated, do not edit; changes %s[solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "900e50172c505781bfed67991919eccea483d78173f8e5c74404a5f6d05858bb" + input-imports = %s solver-name = "gps-cdcl" solver-version = 1 ` -var expectedStatusMetadata = rawDetailMetadata{ - AnalyzerName: "dep", - AnalyzerVersion: 1, - InputsDigest: "900e50172c505781bfed67991919eccea483d78173f8e5c74404a5f6d05858bb", - SolverName: "gps-cdcl", - SolverVersion: 1, -} - func TestStatusDetailTemplates(t *testing.T) { + expectedStatusMetadata := rawDetailMetadata{ + AnalyzerName: "dep", + AnalyzerVersion: 1, + SolverName: "gps-cdcl", + SolverVersion: 1, + } + expectWithInputs := expectedStatusMetadata + expectWithInputs.InputImports = []string{"github.com/akutz/one", "github.com/akutz/three/a"} + testCases := []struct { name string tpl string exp string data rawDetail }{ + { + name: "Lock Template No Projects", + tpl: statusLockTemplate, + exp: fmt.Sprintf(expectedStatusDetail, "", tomlStrSplit(nil)), + data: rawDetail{ + Metadata: expectedStatusMetadata, + }, + }, { name: "Lock Template", tpl: statusLockTemplate, exp: fmt.Sprintf(expectedStatusDetail, `[[projects]] branch = "master" + digest = "1:cbcdef1234" name = "github.com/akutz/one" packages = ["."] + pruneopts = "UT" revision = "b78744579491c1ceeaaa3b40205e56b0591b93a3" [[projects]] + digest = "1:dbcdef1234" name = "github.com/akutz/two" packages = [ ".", - "helloworld" + "helloworld", ] + pruneopts = "NUT" revision = "12bd96e66386c1960ab0f74ced1362f66f552f7b" version = "v1.0.0" [[projects]] branch = "feature/morning" + digest = "1:abcdef1234" name = "github.com/akutz/three" packages = [ "a", "b", - "c" + "c", ] + pruneopts = "NUT" revision = "890a5c3458b43e6104ff5da8dfa139d013d77544" source = "https://github.com/mandy/three" -`), +`, tomlStrSplit([]string{"github.com/akutz/one", "github.com/akutz/three/a"})), data: rawDetail{ Projects: []rawDetailProject{ rawDetailProject{ @@ -928,7 +943,10 @@ func TestStatusDetailTemplates(t *testing.T) { Branch: "master", Revision: "b78744579491c1ceeaaa3b40205e56b0591b93a3", }, + Packages: []string{"."}, ProjectRoot: "github.com/akutz/one", + PruneOpts: "UT", + Digest: "1:cbcdef1234", }, rawDetailProject{ Locked: rawDetailVersion{ @@ -940,6 +958,8 @@ func TestStatusDetailTemplates(t *testing.T) { ".", "helloworld", }, + PruneOpts: "NUT", + Digest: "1:dbcdef1234", }, rawDetailProject{ Locked: rawDetailVersion{ @@ -952,18 +972,12 @@ func TestStatusDetailTemplates(t *testing.T) { "b", "c", }, - Source: "https://github.com/mandy/three", + Source: "https://github.com/mandy/three", + PruneOpts: "NUT", + Digest: "1:abcdef1234", }, }, - Metadata: expectedStatusMetadata, - }, - }, - { - name: "Lock Template No Projects", - tpl: statusLockTemplate, - exp: fmt.Sprintf(expectedStatusDetail, ""), - data: rawDetail{ - Metadata: expectedStatusMetadata, + Metadata: expectWithInputs, }, }, }