Skip to content

Commit 659b780

Browse files
committed
First pass at new Install and Update
1 parent 2224d42 commit 659b780

File tree

5 files changed

+116
-113
lines changed

5 files changed

+116
-113
lines changed

action/install.go

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
package action
22

33
import (
4+
"bytes"
5+
"fmt"
46
"io/ioutil"
7+
"os"
58
"path/filepath"
69

710
"github.com/Masterminds/glide/cfg"
811
"github.com/Masterminds/glide/dependency"
912
"github.com/Masterminds/glide/msg"
1013
gpath "github.com/Masterminds/glide/path"
1114
"github.com/Masterminds/glide/repo"
15+
"github.com/Sirupsen/logrus"
16+
"github.com/sdboyer/vsolver"
1217
)
1318

1419
// Install installs a vendor directory based on an existing Glide configuration.
@@ -19,58 +24,66 @@ func Install(installer *repo.Installer, strip, stripVendor bool) {
1924
EnsureVendorDir()
2025
conf := EnsureConfig()
2126

22-
// Lockfile exists
23-
if !gpath.HasLock(base) {
24-
msg.Info("Lock file (glide.lock) does not exist. Performing update.")
25-
Update(installer, false, strip, stripVendor)
26-
return
27-
}
28-
// Load lockfile
29-
lock, err := LoadLockfile(base, conf)
27+
// Create the SourceManager for this run
28+
sm, err := vsolver.NewSourceManager(filepath.Join(installer.Home, "cache"), base, true, false, dependency.Analyzer{})
3029
if err != nil {
31-
msg.Die("Could not load lockfile.")
30+
msg.Die(err.Error())
3231
}
3332

34-
// Delete unused packages
35-
if installer.DeleteUnused {
36-
// It's unclear whether this should operate off of the lock, or off
37-
// of the glide.yaml file. I'd think that doing this based on the
38-
// lock would be much more reliable.
39-
dependency.DeleteUnused(conf)
33+
opts := vsolver.SolveOpts{
34+
N: vsolver.ProjectName(filepath.Dir(installer.Vendor)),
35+
Root: filepath.Dir(installer.Vendor),
36+
M: conf,
4037
}
4138

42-
// Install
43-
newConf, err := installer.Install(lock, conf)
44-
if err != nil {
45-
msg.Die("Failed to install: %s", err)
46-
}
47-
48-
msg.Info("Setting references.")
39+
if gpath.HasLock(base) {
40+
opts.L, err = LoadLockfile(base, conf)
41+
if err != nil {
42+
msg.Die("Could not load lockfile.")
43+
}
44+
// Check if digests match, and warn if they don't
45+
if bytes.Equal(opts.L.InputHash(), opts.HashInputs()) {
46+
msg.Warn("glide.yaml is out of sync with glide.lock!")
47+
}
48+
err = writeVendor(installer.Vendor, opts.L, sm)
49+
if err != nil {
50+
msg.Die(err.Error())
51+
}
52+
} else {
53+
// There is no lock, so we solve first
54+
s := vsolver.NewSolver(sm, logrus.New())
55+
r, err := s.Solve(opts)
56+
if err != nil {
57+
// TODO better error handling
58+
msg.Die(err.Error())
59+
}
4960

50-
// Set reference
51-
if err := repo.SetReference(newConf); err != nil {
52-
msg.Err("Failed to set references: %s (Skip to cleanup)", err)
61+
err = writeVendor(installer.Vendor, r, sm)
62+
if err != nil {
63+
msg.Die(err.Error())
64+
}
5365
}
66+
}
5467

55-
// VendoredCleanup. This should ONLY be run if UpdateVendored was specified.
56-
// When stripping VCS happens this will happen as well. No need for double
57-
// effort.
58-
if installer.UpdateVendored && !strip {
59-
repo.VendoredCleanup(newConf)
68+
// TODO This will almost certainly need to be renamed and move somewhere else
69+
func writeVendor(vendor string, l vsolver.Lock, sm vsolver.SourceManager) error {
70+
td, err := ioutil.TempDir(os.TempDir(), "glide")
71+
if err != nil {
72+
return fmt.Errorf("Error while creating temp dir for vendor directory: %s", err)
6073
}
74+
defer os.RemoveAll(td)
6175

62-
if strip {
63-
msg.Info("Removing version control data from vendor directory...")
64-
gpath.StripVcs()
76+
err = vsolver.CreateVendorTree(td, l, sm)
77+
if err != nil {
78+
return fmt.Errorf("Error while generating vendor tree: %s", err)
6579
}
6680

67-
if stripVendor {
68-
msg.Info("Removing nested vendor and Godeps/_workspace directories...")
69-
err := gpath.StripVendor()
70-
if err != nil {
71-
msg.Err("Unable to strip vendor directories: %s", err)
72-
}
81+
err = os.Rename(td, vendor)
82+
if err != nil {
83+
return fmt.Errorf("Error while moving generated vendor directory into place: %s", err)
7384
}
85+
86+
return nil
7487
}
7588

7689
// LoadLockfile loads the contents of a glide.lock file.

action/update.go

Lines changed: 50 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
package action
22

33
import (
4+
"encoding/hex"
45
"path/filepath"
6+
"time"
57

68
"github.com/Masterminds/glide/cfg"
79
"github.com/Masterminds/glide/dependency"
8-
"github.com/Masterminds/glide/godep"
910
"github.com/Masterminds/glide/msg"
1011
gpath "github.com/Masterminds/glide/path"
1112
"github.com/Masterminds/glide/repo"
13+
"github.com/Sirupsen/logrus"
14+
"github.com/sdboyer/vsolver"
1215
)
1316

1417
// Update updates repos and the lock file from the main glide yaml.
@@ -18,93 +21,71 @@ func Update(installer *repo.Installer, skipRecursive, strip, stripVendor bool) {
1821
EnsureVendorDir()
1922
conf := EnsureConfig()
2023

21-
// Delete unused packages
22-
if installer.DeleteUnused {
23-
dependency.DeleteUnused(conf)
24-
}
24+
// TODO(mattfarina): Detect when a new dependency has been added or removed
25+
// from the project. A removed dependency should warn and an added dependency
26+
// should be added to the glide.yaml file. See issue #193.
2527

26-
// Try to check out the initial dependencies.
27-
if err := installer.Checkout(conf, false); err != nil {
28-
msg.Die("Failed to do initial checkout of config: %s", err)
28+
// Create the SourceManager for this run
29+
sm, err := vsolver.NewSourceManager(filepath.Join(installer.Home, "cache"), base, true, false, dependency.Analyzer{})
30+
if err != nil {
31+
msg.Die(err.Error())
2932
}
3033

31-
// Set the versions for the initial dependencies so that resolved dependencies
32-
// are rooted in the correct version of the base.
33-
if err := repo.SetReference(conf); err != nil {
34-
msg.Die("Failed to set initial config references: %s", err)
34+
opts := vsolver.SolveOpts{
35+
N: vsolver.ProjectName(filepath.Dir(installer.Vendor)),
36+
Root: filepath.Dir(installer.Vendor),
37+
M: conf,
3538
}
3639

37-
// Prior to resolving dependencies we need to start working with a clone
38-
// of the conf because we'll be making real changes to it.
39-
confcopy := conf.Clone()
40-
41-
if !skipRecursive {
42-
// Get all repos and update them.
43-
err := installer.Update(confcopy)
40+
if gpath.HasLock(base) {
41+
opts.L, err = LoadLockfile(base, conf)
4442
if err != nil {
45-
msg.Die("Could not update packages: %s", err)
43+
msg.Warn("Could not load lockfile; all projects will be updated.")
4644
}
45+
}
4746

48-
// TODO: There is no support here for importing Godeps, GPM, and GB files.
49-
// I think that all we really need to do now is hunt for these files, and then
50-
// roll their version numbers into the config file.
51-
52-
// Set references. There may be no remaining references to set since the
53-
// installer set them as it went to make sure it parsed the right imports
54-
// from the right version of the package.
55-
msg.Info("Setting references for remaining imports")
56-
if err := repo.SetReference(confcopy); err != nil {
57-
msg.Err("Failed to set references: %s (Skip to cleanup)", err)
58-
}
47+
s := vsolver.NewSolver(sm, logrus.New())
48+
r, err := s.Solve(opts)
49+
if err != nil {
50+
// TODO better error handling
51+
msg.Die(err.Error())
5952
}
60-
// Vendored cleanup
61-
// VendoredCleanup. This should ONLY be run if UpdateVendored was specified.
62-
// When stripping VCS happens this will happen as well. No need for double
63-
// effort.
64-
if installer.UpdateVendored && !strip {
65-
repo.VendoredCleanup(confcopy)
53+
54+
err = writeVendor(installer.Vendor, r, sm)
55+
if err != nil {
56+
msg.Die(err.Error())
6657
}
6758

68-
// Write glide.yaml (Why? Godeps/GPM/GB?)
69-
// I think we don't need to write a new Glide file because update should not
70-
// change anything important. It will just generate information about
71-
// transative dependencies, all of which belongs exclusively in the lock
72-
// file, not the glide.yaml file.
73-
// TODO(mattfarina): Detect when a new dependency has been added or removed
74-
// from the project. A removed dependency should warn and an added dependency
75-
// should be added to the glide.yaml file. See issue #193.
59+
// TODO compare old and new lock, and only change if contents differ
7660

77-
if stripVendor {
78-
confcopy = godep.RemoveGodepSubpackages(confcopy)
61+
// Create and write out a new lock file from the result
62+
lf := &cfg.Lockfile{
63+
Hash: hex.EncodeToString(r.InputHash()),
64+
Updated: time.Now(),
7965
}
8066

81-
if !skipRecursive {
82-
// Write lock
83-
hash, err := conf.Hash()
84-
if err != nil {
85-
msg.Die("Failed to generate config hash. Unable to generate lock file.")
86-
}
87-
lock := cfg.NewLockfile(confcopy.Imports, hash)
88-
if err := lock.WriteFile(filepath.Join(base, gpath.LockFile)); err != nil {
89-
msg.Err("Could not write lock file to %s: %s", base, err)
90-
return
67+
for _, p := range r.Projects() {
68+
l := &cfg.Lock{
69+
Name: string(p.Name()),
70+
Repository: p.URI(), // TODO this is wrong
71+
VcsType: "", // TODO allow this to be extracted from sm
9172
}
9273

93-
msg.Info("Project relies on %d dependencies.", len(confcopy.Imports))
94-
} else {
95-
msg.Warn("Skipping lockfile generation because full dependency tree is not being calculated")
74+
v := p.Version()
75+
if pv, ok := v.(vsolver.PairedVersion); ok {
76+
l.Version = pv.Underlying().String()
77+
} else {
78+
l.Version = pv.String()
79+
}
9680
}
9781

98-
if strip {
99-
msg.Info("Removing version control data from vendor directory...")
100-
gpath.StripVcs()
82+
err = lf.WriteFile(filepath.Join(base, gpath.LockFile))
83+
if err != nil {
84+
msg.Die("Error on writing new lock file: %s", err)
10185
}
10286

103-
if stripVendor {
104-
msg.Info("Removing nested vendor and Godeps/_workspace directories...")
105-
err := gpath.StripVendor()
106-
if err != nil {
107-
msg.Err("Unable to strip vendor directories: %s", err)
108-
}
87+
err = writeVendor(installer.Vendor, r, sm)
88+
if err != nil {
89+
msg.Die(err.Error())
10990
}
11091
}

cfg/lock.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cfg
22

33
import (
4+
"encoding/hex"
45
"io/ioutil"
56
"sort"
67
"strings"
@@ -50,8 +51,12 @@ func (lf *Lockfile) WriteFile(lockpath string) error {
5051

5152
// InputHash returns the hash of the input arguments that resulted in this lock
5253
// file.
53-
func (lf *Lockfile) InputHash() string {
54-
return lf.Hash
54+
func (lf *Lockfile) InputHash() []byte {
55+
b, err := hex.DecodeString(lf.Hash)
56+
if err != nil {
57+
return nil
58+
}
59+
return b
5560
}
5661

5762
// Projects returns the list of projects enumerated in the lock file.

glide.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/sdboyer/vsolver/types.go

Lines changed: 6 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)