diff --git a/get.go b/get.go index 99333e5..792e04c 100644 --- a/get.go +++ b/get.go @@ -806,7 +806,8 @@ func install(ctx context.Context, logger *log.Logger, r *runner.Runner, modDir s } // go install does not define -modfile flag, so we mimic go install with go build -o instead. - binPath := filepath.Join(gobin, fmt.Sprintf("%s-%s", name, pkg.Module.Version)) + binName := fmt.Sprintf("%s-%s", name, pkg.Module.Version) + binPath := filepath.Join(gobin, binName) // New context with new environment files. modCtx = r.With(ctx, modFile.Filepath(), modDir, pkg.BuildEnvs) @@ -825,12 +826,19 @@ func install(ctx context.Context, logger *log.Logger, r *runner.Runner, modDir s return nil } - if err := os.RemoveAll(filepath.Join(gobin, name)); err != nil { + return installSymlink(gobin, binName, name) +} + +func installSymlink(dir, oldName, newName string) error { + newPath := filepath.Join(dir, newName) + if err := os.RemoveAll(newPath); err != nil { return errors.Wrap(err, "rm") } - if err := os.Symlink(binPath, filepath.Join(gobin, name)); err != nil { + + if err := os.Symlink(oldName, newPath); err != nil { return errors.Wrap(err, "symlink") } + return nil } diff --git a/get_test.go b/get_test.go index 3a8514a..fcb6c4c 100644 --- a/get_test.go +++ b/get_test.go @@ -4,6 +4,8 @@ package main import ( + "os" + "path/filepath" "testing" "github.com/efficientgo/core/errors" @@ -89,3 +91,38 @@ func TestParseTarget(t *testing.T) { } } + +func TestInstallSymlink(t *testing.T) { + dir := t.TempDir() + oldName := "some-binary-1.2.3" + newName := "some-binary" + oldPath := filepath.Join(dir, oldName) + newPath := filepath.Join(dir, newName) + testData := "#!/bin/true" + + // simulate an existing symlink to test the removal logic + f, err := os.Create(newPath) + testutil.Ok(t, err) + testutil.Ok(t, f.Close()) + + // create a dummy target ... + f, err = os.Create(oldPath) + testutil.Ok(t, err) + // ... and write some data for verification later + _, err = f.Write([]byte(testData)) + testutil.Ok(t, err) + testutil.Ok(t, f.Close()) + + err = installSymlink(dir, oldName, newName) + testutil.Ok(t, err) + + gotPath, err := os.Readlink(newPath) + testutil.Ok(t, err) + testutil.Equals(t, oldName, gotPath) + + gotData, err := os.ReadFile(newPath) + testutil.Ok(t, err) + + // ensure the symlink leads to the desired target + testutil.Equals(t, testData, string(gotData)) +}