From 45162e5572ca98ea3d89252afa677f0075b4cf43 Mon Sep 17 00:00:00 2001 From: Sunny Date: Thu, 11 May 2017 22:26:14 +0530 Subject: [PATCH 1/2] Backup vendor at init - Creates backup of vendor directory, if exists with content, at init. - Adds tests for BackupVendor() function. - Adds RemoveFile() function to test helper. --- cmd/dep/init.go | 15 +++++++++-- internal/test/test.go | 7 +++++ project.go | 26 +++++++++++++++++++ project_test.go | 59 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 2 deletions(-) diff --git a/cmd/dep/init.go b/cmd/dep/init.go index 7f89ea0687..5ccfd8637c 100644 --- a/cmd/dep/init.go +++ b/cmd/dep/init.go @@ -10,6 +10,7 @@ import ( "path/filepath" "strings" "sync" + "time" "github.com/golang/dep" "github.com/golang/dep/internal" @@ -72,6 +73,7 @@ func (cmd *initCommand) Run(ctx *dep.Ctx, args []string) error { mf := filepath.Join(root, dep.ManifestName) lf := filepath.Join(root, dep.LockName) + vpath := filepath.Join(root, "vendor") mok, err := dep.IsRegular(mf) if err != nil { @@ -190,8 +192,17 @@ func (cmd *initCommand) Run(ctx *dep.Ctx, args []string) error { l.Memo = s.HashInputs() - if ctx.Loggers.Verbose { - ctx.Loggers.Err.Println("dep: Writing manifest and lock files.") + // Pass timestamp (yyyyMMddHHmmss format) as suffix to backup name. + vendorbak, err := dep.BackupVendor(vpath, time.Now().Format("20060102150405")) + if err != nil { + return err + } + if vendorbak != "" { + ctx.loggers.Err.Printf("Old vendor backed up to %v", vendorbak) + } + + if ctx.loggers.Verbose { + loggers.Err.Println("dep: Writing manifest and lock files.") } sw, err := dep.NewSafeWriter(m, nil, l, dep.VendorAlways) diff --git a/internal/test/test.go b/internal/test/test.go index 66a399b4e0..19500adde3 100644 --- a/internal/test/test.go +++ b/internal/test/test.go @@ -617,3 +617,10 @@ func (h *Helper) GetCommit(repo string) string { } return strings.TrimSpace(string(out)) } + +func (h *Helper) RemoveFile(path string) { + err := os.RemoveAll(path) + if err != nil { + h.t.Fatalf("%+v", errors.Wrap(err, "could not remove file")) + } +} diff --git a/project.go b/project.go index 21ec738f49..feae10ff40 100644 --- a/project.go +++ b/project.go @@ -13,6 +13,7 @@ import ( ) var errProjectNotFound = fmt.Errorf("could not find project %s, use dep init to initiate a manifest", ManifestName) +var errVendorBackupFailed = fmt.Errorf("Failed to create vendor backup") // findProjectRoot searches from the starting directory upwards looking for a // manifest file until we get to the root of the filesystem. @@ -64,3 +65,28 @@ func (p *Project) MakeParams() gps.SolveParameters { return params } + +// BackupVendor looks for existing vendor directory and if it's not empty, +// creates a backup of it to a new directory with the provided suffix. +func BackupVendor(vpath, suffix string) (string, error) { + // Check if there's a non-empty vendor directory + vendorExists, err := IsNonEmptyDir(vpath) + if err != nil { + return "", err + } + if vendorExists { + vendorbak := vpath + "-" + suffix + // Check if a directory with same name exists + if _, err = os.Stat(vendorbak); os.IsNotExist(err) { + // Copy existing vendor to vendor-{suffix} + if err := CopyDir(vpath, vendorbak); err != nil { + return "", err + } + return vendorbak, nil + } else { + return "", errVendorBackupFailed + } + } + + return "", nil +} diff --git a/project_test.go b/project_test.go index d466309dc9..7db638f10c 100644 --- a/project_test.go +++ b/project_test.go @@ -103,3 +103,62 @@ func TestSlashedGOPATH(t *testing.T) { t.Fatal(err) } } + +func TestBackupVendor(t *testing.T) { + h := test.NewHelper(t) + defer h.Cleanup() + + pc := NewTestProjectContext(h, "vendorbackupproject") + defer pc.Release() + + dummyFile := filepath.Join("vendor", "badinput_fileroot") + pc.CopyFile(dummyFile, "txn_writer/badinput_fileroot") + pc.Load() + + if err := pc.VendorShouldExist(); err != nil { + t.Fatal(err) + } + + // Create a backup + wantName := "vendor-sfx" + vendorbak, err := BackupVendor("vendor", "sfx") + if err != nil { + t.Fatal(err) + } + + if vendorbak != wantName { + t.Fatalf("Vendor backup name is not as expected: \n\t(GOT) %v\n\t(WNT) %v", vendorbak, wantName) + } + + if err = pc.h.ShouldExist(vendorbak); err != nil { + t.Fatal(err) + } + + if err = pc.h.ShouldExist(vendorbak + string(filepath.Separator) + "badinput_fileroot"); err != nil { + t.Fatal(err) + } + + // Should return error on creating backup with existing filename + vendorbak, err = BackupVendor("vendor", "sfx") + + if err != errVendorBackupFailed { + t.Fatalf("Vendor backup error is not as expected: \n\t(GOT) %v\n\t(WNT) %v", err, errVendorBackupFailed) + } + + if vendorbak != "" { + t.Fatalf("Vendor backup name is not as expected: \n\t(GOT) %v\n\t(WNT) %v", vendorbak, "") + } + + // Delete vendor + pc.h.RemoveFile("vendor") + + // Should return empty backup file name when no vendor exists + vendorbak, err = BackupVendor("vendor", "sfx") + if err != nil { + t.Fatal(err) + } + + if vendorbak != "" { + t.Fatalf("Vendor backup name is not as expected: \n\t(GOT) %v\n\t(WNT) %v", vendorbak, "") + } +} From 47302cf1edae1e4794830feae1377bffd601cfe9 Mon Sep 17 00:00:00 2001 From: Sunny Date: Fri, 12 May 2017 18:44:50 +0530 Subject: [PATCH 2/2] Rename existing vendor instead of copying - Renames existing vendor instead of copying. - Remove removeFile() from test helpers. No longer required. --- cmd/dep/init.go | 6 +++--- internal/test/test.go | 7 ------- project.go | 6 +++--- project_test.go | 8 +++++++- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/cmd/dep/init.go b/cmd/dep/init.go index 5ccfd8637c..95eb01f026 100644 --- a/cmd/dep/init.go +++ b/cmd/dep/init.go @@ -198,11 +198,11 @@ func (cmd *initCommand) Run(ctx *dep.Ctx, args []string) error { return err } if vendorbak != "" { - ctx.loggers.Err.Printf("Old vendor backed up to %v", vendorbak) + ctx.Loggers.Err.Printf("Old vendor backed up to %v", vendorbak) } - if ctx.loggers.Verbose { - loggers.Err.Println("dep: Writing manifest and lock files.") + if ctx.Loggers.Verbose { + ctx.Loggers.Err.Println("dep: Writing manifest and lock files.") } sw, err := dep.NewSafeWriter(m, nil, l, dep.VendorAlways) diff --git a/internal/test/test.go b/internal/test/test.go index 19500adde3..66a399b4e0 100644 --- a/internal/test/test.go +++ b/internal/test/test.go @@ -617,10 +617,3 @@ func (h *Helper) GetCommit(repo string) string { } return strings.TrimSpace(string(out)) } - -func (h *Helper) RemoveFile(path string) { - err := os.RemoveAll(path) - if err != nil { - h.t.Fatalf("%+v", errors.Wrap(err, "could not remove file")) - } -} diff --git a/project.go b/project.go index feae10ff40..26d965fb16 100644 --- a/project.go +++ b/project.go @@ -13,7 +13,7 @@ import ( ) var errProjectNotFound = fmt.Errorf("could not find project %s, use dep init to initiate a manifest", ManifestName) -var errVendorBackupFailed = fmt.Errorf("Failed to create vendor backup") +var errVendorBackupFailed = fmt.Errorf("Failed to create vendor backup. File with same name exists.") // findProjectRoot searches from the starting directory upwards looking for a // manifest file until we get to the root of the filesystem. @@ -78,8 +78,8 @@ func BackupVendor(vpath, suffix string) (string, error) { vendorbak := vpath + "-" + suffix // Check if a directory with same name exists if _, err = os.Stat(vendorbak); os.IsNotExist(err) { - // Copy existing vendor to vendor-{suffix} - if err := CopyDir(vpath, vendorbak); err != nil { + // Rename existing vendor to vendor-{suffix} + if err := renameWithFallback(vpath, vendorbak); err != nil { return "", err } return vendorbak, nil diff --git a/project_test.go b/project_test.go index 7db638f10c..6a93a6b453 100644 --- a/project_test.go +++ b/project_test.go @@ -138,6 +138,10 @@ func TestBackupVendor(t *testing.T) { t.Fatal(err) } + // Create another vendor directory. Previous vendor moved as backup. + os.MkdirAll("vendor", 0777) + pc.CopyFile(dummyFile, "txn_writer/badinput_fileroot") + // Should return error on creating backup with existing filename vendorbak, err = BackupVendor("vendor", "sfx") @@ -150,7 +154,9 @@ func TestBackupVendor(t *testing.T) { } // Delete vendor - pc.h.RemoveFile("vendor") + if err = os.RemoveAll("vendor"); err != nil { + t.Fatal(err) + } // Should return empty backup file name when no vendor exists vendorbak, err = BackupVendor("vendor", "sfx")