Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 11 additions & 13 deletions gode/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,20 @@ func RemovePackage(name string) error {
return nil
}

// UpdatePackages updates all packages.
func UpdatePackages() (string, error) {
stdout, stderr, err := execNpm("update")
// OutdatedPackages returns a map of packages and their latest version
func OutdatedPackages(names ...string) (map[string]string, error) {
args := append([]string{"outdated", "--json"}, names...)
stdout, stderr, err := execNpm(args...)
if err != nil {
return stdout, errors.New(stderr)
return nil, errors.New(stderr)
}
return stdout, nil
}

// UpdatePackage updates a package.
func UpdatePackage(name string) (string, error) {
stdout, stderr, err := execNpm("update", name)
if err != nil {
return stdout, errors.New(stderr)
var outdated map[string]struct{ Latest string }
json.Unmarshal([]byte(stdout), &outdated)
packages := make(map[string]string, len(outdated))
for name, versions := range outdated {
packages[name] = versions.Latest
}
return stdout, nil
return packages, nil
}

func npmCmd(args ...string) (*exec.Cmd, error) {
Expand Down
9 changes: 6 additions & 3 deletions gode/packages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,14 @@ func TestRemovePackage(t *testing.T) {
}
}

func TestUpdatePackages(t *testing.T) {
func TestOutdatedPackages(t *testing.T) {
setup()
must(InstallPackage("request"))
_, err := UpdatePackages()
must(InstallPackage("heroku-cli-util@1.0.0"))
packages, err := OutdatedPackages("heroku-cli-util")
must(err)
if packages["heroku-cli-util"] == "" {
t.Fatal("heroku-cli-util not found")
}
}

func TestPackagesGithubPackage(t *testing.T) {
Expand Down
7 changes: 7 additions & 0 deletions io.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,10 @@ func supportsColor() bool {
}
return os.Getenv("COLOR") != "false"
}

func plural(word string, count int) string {
if count == 1 {
return word
}
return word + "s"
}
9 changes: 0 additions & 9 deletions plugin_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,6 @@ import (

var pluginCachePath = filepath.Join(AppDir(), "plugin-cache.json")

// UpdatePluginCache updates all the plugins in ~/.heroku/plugin-cache.json
func UpdatePluginCache() {
cache := FetchPluginCache()
for name := range cache {
cache[name] = getPlugin(name, true)
}
savePluginCache(cache)
}

// AddPluginsToCache adds/updates a set of plugins to ~/.heroku/plugin-cache.json
func AddPluginsToCache(plugins ...*Plugin) {
cache := FetchPluginCache()
Expand Down
39 changes: 16 additions & 23 deletions update.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func Update(channel string, t string) {
touchAutoupdateFile()
updateCLI(channel)
updateNode()
updatePlugins(t)
updatePlugins()
done <- true
}()
select {
Expand All @@ -70,38 +70,34 @@ func Update(channel string, t string) {
}
}

func updatePlugins(t string) {
updated := false
func updatePlugins() {
plugins := PluginNamesNotSymlinked()
if len(plugins) == 0 {
return
}
Err("Updating plugins... ")
if t == "foreground" || t == "block" {
b, _ := gode.UpdatePackages()
if len(b) > 0 {
updated = true
}
} else {
for _, name := range plugins {
packages, err := gode.OutdatedPackages(plugins...)
PrintError(err)
if len(packages) > 0 {
for name, version := range packages {
lockfile := updateLockPath + "." + name
LogIfError(golock.Lock(lockfile))
b, _ := gode.UpdatePackage(name)
err := gode.InstallPackage(name + "@" + version)
PrintError(err)
AddPluginsToCache(getPlugin(name, true))
LogIfError(golock.Unlock(lockfile))
if len(b) > 0 {
updated = true
}
}
}
Errln("done")
if updated {
Err("rebuilding plugins cache... ")
UpdatePluginCache()
Errln("done")
Errf("done. Updated %d %s.\n", len(packages), plural("package", len(packages)))
} else {
Errln("no plugins to update.")
}
}

func updateCLI(channel string) {
if channel == "?" {
// do not update dev version
return
}
manifest, err := getUpdateManifest(channel)
if err != nil {
Warn("Error updating CLI")
Expand Down Expand Up @@ -136,9 +132,6 @@ func updateCLI(channel string) {

// IsUpdateNeeded checks if an update is available
func IsUpdateNeeded(t string) bool {
if Channel == "?" {
return false
}
f, err := os.Stat(autoupdateFile)
if err != nil {
return true
Expand Down