diff --git a/hell/cmd/hell/main.go b/hell/cmd/hell/main.go index c6837b008a2fbe35fb3e8ff2222c4b99e0fbba0f..249e7797c1c7fa1222685f1136a869ae42f51c45 100644 --- a/hell/cmd/hell/main.go +++ b/hell/cmd/hell/main.go @@ -1,12 +1,20 @@ package main import ( - "io/ioutil" - - "github.com/spf13/cobra" - "gopkg.in/yaml.v2" "fmt" "os" + + "path/filepath" + + "github.com/Masterminds/glide/cache" + "github.com/Masterminds/glide/cfg" + "github.com/Masterminds/glide/msg" + "github.com/Masterminds/glide/path" + "github.com/Masterminds/glide/util" + "github.com/eris-ltd/eris-db/hell" + "github.com/spf13/cobra" + "github.com/Masterminds/glide/action" + "github.com/Masterminds/glide/repo" ) func main() { @@ -17,28 +25,93 @@ func main() { Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, } + // Lock merge command var baseGlideLockFile, depGlideLockFile string - dependCmd := &cobra.Command{ + lockMergeCmd := &cobra.Command{ Use: "lock-merge", Short: "Merge glide.lock files together", - Long: "", + Long: "This command merges two glide.lock files into a single one by copying all dependencies " + + "from a base glide.lock and an override glide.lock to an output glide.lock with dependencies " + + "from override taking precedence over those from base.", Run: func(cmd *cobra.Command, args []string) { - bytes, err := ioutil.ReadFile(baseGlideLockFile) + baseLockFile, err := cfg.ReadLockFile(baseGlideLockFile) if err != nil { fmt.Printf("Could not read file: %s\n", err) os.Exit(1) } - err = yaml.Unmarshal(bytes, &m) - bytes, err = ioutil.ReadFile(depGlideLockFile) + overrideLockFile, err := cfg.ReadLockFile(depGlideLockFile) if err != nil { fmt.Printf("Could not read file: %s\n", err) os.Exit(1) } - m := make(map[interface{}]interface{}) + mergedLockFile, err := hell.MergeGlideLockFiles(baseLockFile, overrideLockFile) + if err != nil { + fmt.Printf("Could not merge lock files: %s\n", err) + os.Exit(1) + } + mergedBytes, err := mergedLockFile.Marshal() + if err != nil { + fmt.Printf("Could not marshal lock file: %s\n", err) + os.Exit(1) + } + os.Stdout.Write(mergedBytes) }, } - dependCmd.PersistentFlags().StringVarP(&baseGlideLockFile, "base", "b", "", "") - dependCmd.PersistentFlags().StringVarP(&depGlideLockFile, "dep", "d", "", "") - hellCmd.AddCommand(dependCmd) - dependCmd.Execute() + lockMergeCmd.PersistentFlags().StringVarP(&baseGlideLockFile, "base", "b", "", "base lock file") + lockMergeCmd.PersistentFlags().StringVarP(&depGlideLockFile, "override", "o", "", "override lock file") + + // Lock update + interactive := false + getTransitiveCmd := &cobra.Command{ + Use: "get", + Short: "gets a remote dependency to this project along with its transtive dependencies.", + Long: "Gets a remote dependency and its transitive dependencies by adding the remote " + + "depednency to this project's glide.yaml and merging the remote dependency's " + + "glide.lock into this project's glide.lock", + Run: func(cmd *cobra.Command, args []string) { + if len(args) != 1 { + msg.Die("%s requires a single argument of the remote dependency\n", cmd.Name()) + } + rootPackage, _ := util.NormalizeName(args[0]) + // Add dependency to glide + action.Get(args, repo.NewInstaller() , false, true, false, !interactive, false) + // Now hunt down the repo cache + dep := action.EnsureConfig().Imports.Get(rootPackage) + key, err := cache.Key(dep.Remote()) + if err != nil { + msg.Die("%s requires a single argument of the remote dependency\n", cmd.Name()) + } + cacheDir := filepath.Join(cache.Location(), "src", key) + + if path.HasLock(cacheDir) { + msg.Info("Found dependency lock file, merging into project lock file") + lockPath := filepath.Join(".", path.LockFile) + baseLockFile, err := cfg.ReadLockFile(lockPath) + if err != nil { + msg.Die("Could not read base lock file: %s", err) + } + overrideLockFile, err := cfg.ReadLockFile(filepath.Join(cacheDir, path.LockFile)) + if err != nil { + msg.Die("Could not read dependency lock file: %s", err) + } + mergedLockFile, err := hell.MergeGlideLockFiles(baseLockFile, overrideLockFile) + if err != nil { + msg.Die("Could not merge lock files: %s\n", err) + } + err = mergedLockFile.WriteFile(lockPath) + if err != nil { + msg.Die("Could not write merged lock file: %s", err) + } + } else { + msg.Info("Did not find dependency lock file, so nothing merged intoo project lock file") + } + }, + } + + getTransitiveCmd.PersistentFlags().BoolVarP(&interactive, "interactive", "i", false, + "set dependency verion interactively") + + hellCmd.AddCommand(lockMergeCmd) + hellCmd.AddCommand(getTransitiveCmd) + lockMergeCmd.Execute() } diff --git a/hell/merge.go b/hell/merge.go index 89137da5c5c566583017acdac386f7bf8e0ebed2..242d22af176eb084b0b41ae061e5b9b397883c47 100644 --- a/hell/merge.go +++ b/hell/merge.go @@ -1,4 +1,4 @@ -package main +package hell import ( "crypto/sha256" @@ -11,16 +11,7 @@ import ( // Merges two glide lock files together, letting dependencies from 'base' be overwritten // by those from 'override'. Returns the resultant glide lock file bytes -func MergeGlideLockFiles(baseGlideLockFileBytes, overrideGlideLockFileBytes []byte) ([]byte, error) { - baseLockFile, err := cfg.LockfileFromYaml(baseGlideLockFileBytes) - if err != nil { - return nil, err - } - overrideLockFile, err := cfg.LockfileFromYaml(overrideGlideLockFileBytes) - if err != nil { - return nil, err - } - +func MergeGlideLockFiles(baseLockFile, overrideLockFile *cfg.Lockfile) (*cfg.Lockfile, error) { imports := make(map[string]*cfg.Lock, len(baseLockFile.Imports)) devImports := make(map[string]*cfg.Lock, len(baseLockFile.DevImports)) // Copy the base dependencies into a map @@ -51,15 +42,10 @@ func MergeGlideLockFiles(baseGlideLockFileBytes, overrideGlideLockFileBytes []by } hasher := sha256.New() - hasher.Write(baseGlideLockFileBytes) - hasher.Write(overrideGlideLockFileBytes) - - lockFile, err := cfg.NewLockfile(deps, devDeps, fmt.Sprintf("%x", hasher.Sum(nil))) - if err != nil { - return nil, err - } + hasher.Write(([]byte)(baseLockFile.Hash)) + hasher.Write(([]byte)(overrideLockFile.Hash)) - return lockFile.Marshal() + return cfg.NewLockfile(deps, devDeps, fmt.Sprintf("%x", hasher.Sum(nil))) } func mergeLocks(baseLock, overrideLock *cfg.Lock) *cfg.Lock { diff --git a/hell/merge_test.go b/hell/merge_test.go index 7194f01bf2ec7a72bc270b6c2651c6c7b4b46cf4..f62849d3fb487c9d72a10ea48b9e28783f769af1 100644 --- a/hell/merge_test.go +++ b/hell/merge_test.go @@ -1,14 +1,14 @@ -package main +package hell import ( + "fmt" "testing" + "github.com/stretchr/testify/assert" - "fmt" + "strings" ) - -const baseLockYml =` -imports: +const baseLockYml = `imports: - name: github.com/gogo/protobuf version: 82d16f734d6d871204a3feb1a73cb220cc92574c - name: github.com/tendermint/tendermint @@ -25,8 +25,7 @@ imports: - rpc/core - state ` -const overrideLockYml =` -imports: +const overrideLockYml = `imports: - name: github.com/tendermint/tendermint version: 764091dfbb035f1b28da4b067526e04c6a849966 subpackages: @@ -35,31 +34,29 @@ imports: - types - version ` -const expectedLockYml =` -imports: +const expectedLockYml = `imports: - name: github.com/gogo/protobuf version: 82d16f734d6d871204a3feb1a73cb220cc92574c - name: github.com/tendermint/tendermint version: 764091dfbb035f1b28da4b067526e04c6a849966 subpackages: - benchmarks - - node - - proxy - - types - - version - - consensus - - rpc/core/types - blockchain + - consensus - mempool + - node + - proxy - rpc/core - - state + - rpc/core/types +testImports: [] ` - func TestMergeGlideLockFiles(t *testing.T) { lockYml, err := MergeGlideLockFiles(([]byte)(baseLockYml), ([]byte)(overrideLockYml)) assert.NoError(t, err, "Lockfiles should merge") - fmt.Println(string(lockYml)) - assert.Equal(t, expectedLockYml, string(lockYml)) - + ymlLines := strings.Split(string(lockYml), "\n") + // Drop the updated and hash lines + actualYml := strings.Join(ymlLines[2:], "\n") + fmt.Println(actualYml) + assert.Equal(t, expectedLockYml, actualYml) }