diff --git a/cmd/dep/ensure.go b/cmd/dep/ensure.go index 93bdac23e7..c23776c0a6 100644 --- a/cmd/dep/ensure.go +++ b/cmd/dep/ensure.go @@ -8,6 +8,8 @@ import ( "bytes" "flag" "go/build" + "io/ioutil" + "log" "os" "path/filepath" "sort" @@ -252,7 +254,11 @@ func (cmd *ensureCommand) runDefault(ctx *dep.Ctx, args []string, p *dep.Project return nil } - return errors.WithMessage(sw.Write(p.AbsRoot, sm, true), "grouped write of manifest, lock and vendor") + logger := ctx.Err + if !ctx.Verbose { + logger = log.New(ioutil.Discard, "", 0) + } + return errors.WithMessage(sw.Write(p.AbsRoot, sm, true, logger), "grouped write of manifest, lock and vendor") } solution, err := solver.Solve() @@ -269,7 +275,11 @@ func (cmd *ensureCommand) runDefault(ctx *dep.Ctx, args []string, p *dep.Project return sw.PrintPreparedActions(ctx.Out) } - return errors.Wrap(sw.Write(p.AbsRoot, sm, false), "grouped write of manifest, lock and vendor") + logger := ctx.Err + if !ctx.Verbose { + logger = log.New(ioutil.Discard, "", 0) + } + return errors.Wrap(sw.Write(p.AbsRoot, sm, false, logger), "grouped write of manifest, lock and vendor") } func (cmd *ensureCommand) runVendorOnly(ctx *dep.Ctx, args []string, p *dep.Project, sm gps.SourceManager, params gps.SolveParameters) error { @@ -289,10 +299,20 @@ func (cmd *ensureCommand) runVendorOnly(ctx *dep.Ctx, args []string, p *dep.Proj if cmd.dryRun { ctx.Out.Printf("Would have populated vendor/ directory from %s", dep.LockName) + if ctx.Verbose { + err := sw.PrintPreparedActions(ctx.Err) + if err != nil { + return errors.WithMessage(err, "prepared actions") + } + } return nil } - return errors.WithMessage(sw.Write(p.AbsRoot, sm, true), "grouped write of manifest, lock and vendor") + logger := ctx.Err + if !ctx.Verbose { + logger = log.New(ioutil.Discard, "", 0) + } + return errors.WithMessage(sw.Write(p.AbsRoot, sm, true, logger), "grouped write of manifest, lock and vendor") } func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project, sm gps.SourceManager, params gps.SolveParameters) error { @@ -379,7 +399,11 @@ func (cmd *ensureCommand) runUpdate(ctx *dep.Ctx, args []string, p *dep.Project, return sw.PrintPreparedActions(ctx.Out) } - return errors.Wrap(sw.Write(p.AbsRoot, sm, false), "grouped write of manifest, lock and vendor") + logger := ctx.Err + if !ctx.Verbose { + logger = log.New(ioutil.Discard, "", 0) + } + return errors.Wrap(sw.Write(p.AbsRoot, sm, false, logger), "grouped write of manifest, lock and vendor") } func (cmd *ensureCommand) runAdd(ctx *dep.Ctx, args []string, p *dep.Project, sm gps.SourceManager, params gps.SolveParameters) error { @@ -610,7 +634,11 @@ func (cmd *ensureCommand) runAdd(ctx *dep.Ctx, args []string, p *dep.Project, sm return sw.PrintPreparedActions(ctx.Out) } - if err := errors.Wrap(sw.Write(p.AbsRoot, sm, true), "grouped write of manifest, lock and vendor"); err != nil { + logger := ctx.Err + if !ctx.Verbose { + logger = log.New(ioutil.Discard, "", 0) + } + if err := errors.Wrap(sw.Write(p.AbsRoot, sm, true, logger), "grouped write of manifest, lock and vendor"); err != nil { return err } diff --git a/cmd/dep/init.go b/cmd/dep/init.go index 1afab53d66..65547733c3 100644 --- a/cmd/dep/init.go +++ b/cmd/dep/init.go @@ -6,6 +6,8 @@ package main import ( "flag" + "io/ioutil" + "log" "os" "path/filepath" "time" @@ -201,7 +203,11 @@ func (cmd *initCommand) Run(ctx *dep.Ctx, args []string) error { return err } - if err := sw.Write(root, sm, !cmd.noExamples); err != nil { + logger := ctx.Err + if !ctx.Verbose { + logger = log.New(ioutil.Discard, "", 0) + } + if err := sw.Write(root, sm, !cmd.noExamples, logger); err != nil { return errors.Wrap(err, "safe write of manifest and lock") } diff --git a/cmd/dep/prune.go b/cmd/dep/prune.go index 5690dc4aae..94f057028e 100644 --- a/cmd/dep/prune.go +++ b/cmd/dep/prune.go @@ -97,7 +97,7 @@ func pruneProject(p *dep.Project, sm gps.SourceManager, logger *log.Logger) erro } defer os.RemoveAll(td) - if err := gps.WriteDepTree(td, p.Lock, sm, true); err != nil { + if err := gps.WriteDepTree(td, p.Lock, sm, true, logger); err != nil { return err } diff --git a/internal/gps/lock.go b/internal/gps/lock.go index f221ad997b..661bf63dd2 100644 --- a/internal/gps/lock.go +++ b/internal/gps/lock.go @@ -6,6 +6,7 @@ package gps import ( "bytes" + "fmt" "sort" ) @@ -195,6 +196,11 @@ func (lp LockedProject) Packages() []string { return lp.pkgs } +func (lp LockedProject) String() string { + return fmt.Sprintf("%s@%s with packages: %v", + lp.Ident().errString(), lp.Version(), lp.pkgs) +} + type safeLock struct { h []byte p []LockedProject diff --git a/internal/gps/lock_test.go b/internal/gps/lock_test.go index 8b6ef6f99e..a985b40b01 100644 --- a/internal/gps/lock_test.go +++ b/internal/gps/lock_test.go @@ -128,3 +128,54 @@ func TestLocksAreEq(t *testing.T) { t.Error("should fail when individual lp were not eq") } } + +func TestLockedProjectsString(t *testing.T) { + tt := []struct { + name string + lp LockedProject + want string + }{ + { + name: "full info", + lp: NewLockedProject(mkPI("github.com/sdboyer/gps"), NewVersion("v0.10.0"), []string{"gps"}), + want: "github.com/sdboyer/gps@v0.10.0 with packages: [gps]", + }, + { + name: "empty package list", + lp: NewLockedProject(mkPI("github.com/sdboyer/gps"), NewVersion("v0.10.0"), []string{}), + want: "github.com/sdboyer/gps@v0.10.0 with packages: []", + }, + { + name: "nil package", + lp: NewLockedProject(mkPI("github.com/sdboyer/gps"), NewVersion("v0.10.0"), nil), + want: "github.com/sdboyer/gps@v0.10.0 with packages: []", + }, + { + name: "with source", + lp: NewLockedProject( + ProjectIdentifier{ProjectRoot: "github.com/sdboyer/gps", Source: "github.com/another/repo"}, + NewVersion("v0.10.0"), []string{"."}), + want: "github.com/sdboyer/gps (from github.com/another/repo)@v0.10.0 with packages: [.]", + }, + { + name: "version pair", + lp: NewLockedProject(mkPI("github.com/sdboyer/gps"), NewVersion("v0.10.0").Pair("278a227dfc3d595a33a77ff3f841fd8ca1bc8cd0"), []string{"gps"}), + want: "github.com/sdboyer/gps@v0.10.0 with packages: [gps]", + }, + { + name: "revision only", + lp: NewLockedProject(mkPI("github.com/sdboyer/gps"), Revision("278a227dfc3d595a33a77ff3f841fd8ca1bc8cd0"), []string{"gps"}), + want: "github.com/sdboyer/gps@278a227dfc3d595a33a77ff3f841fd8ca1bc8cd0 with packages: [gps]", + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + s := tc.lp.String() + if tc.want != s { + t.Fatalf("want %s, got %s", tc.want, s) + } + }) + } + +} diff --git a/internal/gps/result.go b/internal/gps/result.go index 504b02368b..3e3f982947 100644 --- a/internal/gps/result.go +++ b/internal/gps/result.go @@ -6,6 +6,7 @@ package gps import ( "fmt" + "log" "os" "path/filepath" ) @@ -51,7 +52,7 @@ type solution struct { // It requires a SourceManager to do the work, and takes a flag indicating // whether or not to strip vendor directories contained in the exported // dependencies. -func WriteDepTree(basedir string, l Lock, sm SourceManager, sv bool) error { +func WriteDepTree(basedir string, l Lock, sm SourceManager, sv bool, logger *log.Logger) error { if l == nil { return fmt.Errorf("must provide non-nil Lock to WriteDepTree") } @@ -65,10 +66,11 @@ func WriteDepTree(basedir string, l Lock, sm SourceManager, sv bool) error { for _, p := range l.Projects() { to := filepath.FromSlash(filepath.Join(basedir, string(p.Ident().ProjectRoot))) + logger.Printf("Writing out %s@%s", p.Ident().errString(), p.Version()) err = sm.ExportProject(p.Ident(), p.Version(), to) if err != nil { removeAll(basedir) - return fmt.Errorf("error while exporting %s: %s", p.Ident().ProjectRoot, err) + return fmt.Errorf("error while exporting %s@%s: %s", p.Ident().errString(), p.Version(), err) } if sv { filepath.Walk(to, stripVendor) diff --git a/internal/gps/result_test.go b/internal/gps/result_test.go index cc96a8e2cb..0385d48270 100644 --- a/internal/gps/result_test.go +++ b/internal/gps/result_test.go @@ -6,12 +6,15 @@ package gps import ( "io/ioutil" + "log" "os" "path" "path/filepath" "testing" ) +var discardLogger = log.New(ioutil.Discard, "", 0) + var basicResult solution func pi(n string) ProjectIdentifier { @@ -90,12 +93,12 @@ func testWriteDepTree(t *testing.T) { } // nil lock/result should err immediately - err = WriteDepTree(tmp, nil, sm, true) + err = WriteDepTree(tmp, nil, sm, true, discardLogger) if err == nil { t.Errorf("Should error if nil lock is passed to WriteDepTree") } - err = WriteDepTree(tmp, r, sm, true) + err = WriteDepTree(tmp, r, sm, true, discardLogger) if err != nil { t.Errorf("Unexpected error while creating vendor tree: %s", err) } @@ -143,7 +146,7 @@ func BenchmarkCreateVendorTree(b *testing.B) { // ease manual inspection os.RemoveAll(exp) b.StartTimer() - err = WriteDepTree(exp, r, sm, true) + err = WriteDepTree(exp, r, sm, true, discardLogger) b.StopTimer() if err != nil { b.Errorf("unexpected error after %v iterations: %s", i, err) diff --git a/txn_writer.go b/txn_writer.go index aeb8134168..8327c9d7db 100644 --- a/txn_writer.go +++ b/txn_writer.go @@ -261,7 +261,7 @@ func (sw SafeWriter) validate(root string, sm gps.SourceManager) error { // operations succeeded. It also does its best to roll back if any moves fail. // This mostly guarantees that dep cannot exit with a partial write that would // leave an undefined state on disk. -func (sw *SafeWriter) Write(root string, sm gps.SourceManager, examples bool) error { +func (sw *SafeWriter) Write(root string, sm gps.SourceManager, examples bool, logger *log.Logger) error { err := sw.validate(root, sm) if err != nil { return err @@ -313,7 +313,7 @@ func (sw *SafeWriter) Write(root string, sm gps.SourceManager, examples bool) er } if sw.writeVendor { - err = gps.WriteDepTree(filepath.Join(td, "vendor"), sw.lock, sm, true) + err = gps.WriteDepTree(filepath.Join(td, "vendor"), sw.lock, sm, true, logger) if err != nil { return errors.Wrap(err, "error while writing out vendor tree") } @@ -449,13 +449,7 @@ func (sw *SafeWriter) PrintPreparedActions(output *log.Logger) error { if sw.writeVendor { output.Println("Would have written the following projects to the vendor directory:") for _, project := range sw.lock.Projects() { - prj := project.Ident() - rev, _, _ := gps.VersionComponentStrings(project.Version()) - if prj.Source == "" { - output.Printf("%s@%s\n", prj.ProjectRoot, rev) - } else { - output.Printf("%s -> %s@%s\n", prj.ProjectRoot, prj.Source, rev) - } + output.Println(project) } } diff --git a/txn_writer_test.go b/txn_writer_test.go index ad550cd92d..2178954704 100644 --- a/txn_writer_test.go +++ b/txn_writer_test.go @@ -26,7 +26,7 @@ func TestSafeWriter_BadInput_MissingRoot(t *testing.T) { defer pc.Release() sw, _ := NewSafeWriter(nil, nil, nil, VendorOnChanged) - err := sw.Write("", pc.SourceManager, true) + err := sw.Write("", pc.SourceManager, true, discardLogger) if err == nil { t.Fatal("should have errored without a root path, but did not") @@ -44,7 +44,7 @@ func TestSafeWriter_BadInput_MissingSourceManager(t *testing.T) { pc.Load() sw, _ := NewSafeWriter(nil, nil, pc.Project.Lock, VendorAlways) - err := sw.Write(pc.Project.AbsRoot, nil, true) + err := sw.Write(pc.Project.AbsRoot, nil, true, discardLogger) if err == nil { t.Fatal("should have errored without a source manager when forceVendor is true, but did not") @@ -92,7 +92,7 @@ func TestSafeWriter_BadInput_NonexistentRoot(t *testing.T) { sw, _ := NewSafeWriter(nil, nil, nil, VendorOnChanged) missingroot := filepath.Join(pc.Project.AbsRoot, "nonexistent") - err := sw.Write(missingroot, pc.SourceManager, true) + err := sw.Write(missingroot, pc.SourceManager, true, discardLogger) if err == nil { t.Fatal("should have errored with nonexistent dir for root path, but did not") @@ -110,7 +110,7 @@ func TestSafeWriter_BadInput_RootIsFile(t *testing.T) { sw, _ := NewSafeWriter(nil, nil, nil, VendorOnChanged) fileroot := pc.CopyFile("fileroot", "txn_writer/badinput_fileroot") - err := sw.Write(fileroot, pc.SourceManager, true) + err := sw.Write(fileroot, pc.SourceManager, true, discardLogger) if err == nil { t.Fatal("should have errored when root path is a file, but did not") @@ -145,7 +145,7 @@ func TestSafeWriter_Manifest(t *testing.T) { } // Write changes - err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true) + err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true, discardLogger) h.Must(errors.Wrap(err, "SafeWriter.Write failed")) // Verify file system changes @@ -190,7 +190,7 @@ func TestSafeWriter_ManifestAndUnmodifiedLock(t *testing.T) { } // Write changes - err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true) + err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true, discardLogger) h.Must(errors.Wrap(err, "SafeWriter.Write failed")) // Verify file system changes @@ -235,7 +235,7 @@ func TestSafeWriter_ManifestAndUnmodifiedLockWithForceVendor(t *testing.T) { } // Write changes - err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true) + err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true, discardLogger) h.Must(errors.Wrap(err, "SafeWriter.Write failed")) // Verify file system changes @@ -285,7 +285,7 @@ func TestSafeWriter_ModifiedLock(t *testing.T) { } // Write changes - err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true) + err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true, discardLogger) h.Must(errors.Wrap(err, "SafeWriter.Write failed")) // Verify file system changes @@ -335,7 +335,7 @@ func TestSafeWriter_ModifiedLockSkipVendor(t *testing.T) { } // Write changes - err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true) + err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true, discardLogger) h.Must(errors.Wrap(err, "SafeWriter.Write failed")) // Verify file system changes @@ -363,7 +363,7 @@ func TestSafeWriter_ForceVendorWhenVendorAlreadyExists(t *testing.T) { pc.Load() sw, _ := NewSafeWriter(nil, pc.Project.Lock, pc.Project.Lock, VendorAlways) - err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true) + err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true, discardLogger) h.Must(errors.Wrap(err, "SafeWriter.Write failed")) // Verify prepared actions @@ -381,7 +381,7 @@ func TestSafeWriter_ForceVendorWhenVendorAlreadyExists(t *testing.T) { t.Fatal("Expected the payload to contain the vendor directory ") } - err = sw.Write(pc.Project.AbsRoot, pc.SourceManager, true) + err = sw.Write(pc.Project.AbsRoot, pc.SourceManager, true, discardLogger) h.Must(errors.Wrap(err, "SafeWriter.Write failed")) // Verify file system changes @@ -431,7 +431,7 @@ func TestSafeWriter_NewLock(t *testing.T) { } // Write changes - err = sw.Write(pc.Project.AbsRoot, pc.SourceManager, true) + err = sw.Write(pc.Project.AbsRoot, pc.SourceManager, true, discardLogger) h.Must(errors.Wrap(err, "SafeWriter.Write failed")) // Verify file system changes @@ -478,7 +478,7 @@ func TestSafeWriter_NewLockSkipVendor(t *testing.T) { } // Write changes - err = sw.Write(pc.Project.AbsRoot, pc.SourceManager, true) + err = sw.Write(pc.Project.AbsRoot, pc.SourceManager, true, discardLogger) h.Must(errors.Wrap(err, "SafeWriter.Write failed")) // Verify file system changes @@ -571,7 +571,7 @@ func TestSafeWriter_VendorDotGitPreservedWithForceVendor(t *testing.T) { t.Fatal("Expected the payload to contain the vendor directory") } - err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true) + err := sw.Write(pc.Project.AbsRoot, pc.SourceManager, true, discardLogger) h.Must(errors.Wrap(err, "SafeWriter.Write failed")) // Verify file system changes