Skip to content

Commit

Permalink
Added support for replacements.
Browse files Browse the repository at this point in the history
  • Loading branch information
nomad-software committed Aug 1, 2020
1 parent efd9020 commit dc54ecb
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 45 deletions.
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,3 @@ Run the following command for help.
```
$ vend -help
```

## Caveats

* [Go mod replace directives](https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive) are intentionally not supported because there is no consensus how to support them.
130 changes: 93 additions & 37 deletions file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,102 @@ import (
"github.com/nomad-software/vend/output"
)

// CopyModuleDependencies copies module level dependencies transitively.
func CopyModuleDependencies(mod GoMod, deps []Dep) {
modFile := cli.ReadModFile(vendorDir())
deleteVendorDir()
// VendorDir represents a vendor directory.
type VendorDir struct {
basePath string
modFileContent []byte
mod GoMod
deps []Dep
}

for _, d := range deps {
fmt.Fprintf(output.Stdout, "vend: copying %s (%s)\n", d.Path, d.Version)
dest := path.Join(vendorDir(), d.Path)
copy(d.Dir, dest)
// InitVendorDir creates a new vendor directory.
func InitVendorDir() VendorDir {
wd, err := os.Getwd()
output.OnError(err, "Error getting the current directory")

v := VendorDir{
basePath: path.Join(wd, "vendor"),
mod: ParseModJSON(cli.ReadModJSON()),
deps: ParseDownloadJSON(cli.ReadDownloadJSON()),
}

if !v.exists(v.basePath) {
output.Error("No dependencies vendored")
}

SaveReport(modFile)
return v
}

// SaveReport saves the report into the vendor directory.
func SaveReport(report string) {
if _, err := os.Stat(vendorDir()); os.IsNotExist(err) {
output.Info("No dependencies vended")
} else {
file := path.Join(vendorDir(), "modules.txt")
err := ioutil.WriteFile(file, []byte(report), 0644)
output.OnError(err, "Error saving report")
// CopyDependencies copies remote module level dependencies transitively.
func (v *VendorDir) CopyDependencies() {
v.clear()

for _, d := range v.deps {
fmt.Fprintf(output.Stdout, "vend: copying %s (%s)\n", d.Path, d.Version)
v.copy(d.Dir, v.vendPath(d.Path))
}

for _, r := range v.mod.Replace {
if r.Old.Path != r.New.Path {
fmt.Fprintf(output.Stdout, "vend: replacing %s with %s\n", r.Old.Path, r.New.Path)
newPath := v.vendPath(r.New.Path)
oldPath := v.vendPath(r.Old.Path)
// If the directory is in the vendor folder it was copied from the
// module cache so we can just rename it. Otherwise it's a local
// directory located somewhere else that needs copying in.
if v.exists(newPath) {
v.copy(newPath, oldPath)
v.remove(newPath)
} else {
v.copy(r.New.Path, oldPath)
}
}
}
}

// VendorDir returns the vendor directory in the current directory.
func vendorDir() string {
wd, err := os.Getwd()
output.OnError(err, "Error getting the current directory")
return path.Join(wd, "vendor")
// exists checks if a file exists.
func (v *VendorDir) exists(file string) bool {
_, err := os.Stat(file)
return !os.IsNotExist(err)
}

// remove removes a path.
func (v *VendorDir) remove(p string) {
err := os.RemoveAll(p)
output.OnError(err, "Error removing path")
}

// vendPath creates a vendor directory path.
func (v *VendorDir) vendPath(p string) string {
return path.Join(v.basePath, p)
}

// deleteVendorDir deletes the vendor directory.
func deleteVendorDir() {
err := os.RemoveAll(vendorDir())
output.OnError(err, "Error removing vendor directory")
// copyModFile internally copies and saves the modules.txt file.
func (v *VendorDir) copyModFile() {
var err error
v.modFileContent, err = ioutil.ReadFile(v.vendPath("modules.txt"))
output.OnError(err, "Error reading modules.txt")
}

// writeModFile writes the modules.txt file into the vendor directory.
func (v *VendorDir) writeModFile() {
err := ioutil.WriteFile(v.vendPath("modules.txt"), v.modFileContent, 0644)
output.OnError(err, "Error saving modules.txt")
}

// clear removes all dependencies from the vendor directory.
func (v *VendorDir) clear() {
v.copyModFile()
v.remove(v.basePath)

err := os.MkdirAll(v.basePath, 0755)
output.OnError(err, "Error creating vendor directory")

v.writeModFile()
}

// Copy will copy files to the vendor directory.
func copy(src string, dest string) {
// copy will copy files and directories.
func (v *VendorDir) copy(src string, dest string) {
info, err := os.Lstat(src)
output.OnError(err, "Error getting information about source")

Expand All @@ -60,15 +116,15 @@ func copy(src string, dest string) {
}

if info.IsDir() {
copyDirectory(src, dest)
v.copyDirectory(src, dest)
} else {
copyFile(src, dest)
v.copyFile(src, dest)
}
}

// CopyDirectory will copy directories.
func copyDirectory(src string, dest string) {
err := os.MkdirAll(dest, os.ModePerm)
// copyDirectory will copy directories.
func (v *VendorDir) copyDirectory(src string, dest string) {
err := os.MkdirAll(dest, 0755)
output.OnError(err, "Error creating directories")

contents, err := ioutil.ReadDir(src)
Expand All @@ -77,13 +133,13 @@ func copyDirectory(src string, dest string) {
for _, content := range contents {
s := filepath.Join(src, content.Name())
d := filepath.Join(dest, content.Name())
copy(s, d)
v.copy(s, d)
}
}

// CopyFile will copy files.
func copyFile(src string, dest string) {
err := os.MkdirAll(filepath.Dir(dest), os.ModePerm)
// copyFile will copy files.
func (v *VendorDir) copyFile(src string, dest string) {
err := os.MkdirAll(filepath.Dir(dest), 0755)
output.OnError(err, "Error creating directories")

d, err := os.Create(dest)
Expand Down
6 changes: 2 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ func main() {
} else {
cli.UpdateModule()

deps := file.ParseDownloadJSON(cli.ReadDownloadJSON())
mod := file.ParseModJSON(cli.ReadModJSON())

file.CopyModuleDependencies(mod, deps)
dir := file.InitVendorDir()
dir.CopyDependencies()
}
}

0 comments on commit dc54ecb

Please sign in to comment.