func updatePlugins(t string) { updated := false 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 { lockfile := updateLockPath + "." + name LogIfError(golock.Lock(lockfile)) b, _ := gode.UpdatePackage(name) LogIfError(golock.Unlock(lockfile)) if len(b) > 0 { updated = true } } } Errln("done") if updated { Err("rebuilding plugins cache... ") ClearPluginCache() WritePluginCache(GetPlugins()) Errln("done") } }
func updateCLI(channel string) { manifest, err := getUpdateManifest(channel) if err != nil { Warn("Error updating CLI") PrintError(err) return } if manifest.Version == Version && manifest.Channel == Channel { return } LogIfError(golock.Lock(updateLockPath)) defer golock.Unlock(updateLockPath) Errf("Updating Heroku v4 CLI to %s (%s)... ", manifest.Version, manifest.Channel) build := manifest.Builds[runtime.GOOS][runtime.GOARCH] // on windows we can't remove an existing file or remove the running binary // so we download the file to binName.new // move the running binary to binName.old (deleting any existing file first) // rename the downloaded file to binName if err := downloadBin(binPath+".new", build.URL); err != nil { panic(err) } if fileSha1(binPath+".new") != build.Sha1 { panic("SHA mismatch") } os.Remove(binPath + ".old") os.Rename(binPath, binPath+".old") if err := os.Rename(binPath+".new", binPath); err != nil { panic(err) } os.Remove(binPath + ".old") Errln("done") }
func installPlugins(plugins ...string) error { for _, plugin := range plugins { lockfile := updateLockPath + "." + plugin LogIfError(golock.Lock(lockfile)) } err := node.InstallPackage(plugins...) for _, plugin := range plugins { lockfile := updateLockPath + "." + plugin LogIfError(golock.Unlock(lockfile)) } return err }
// SetupNode sets up node and npm in ~/.heroku func SetupNode() { if !node.IsSetup() { LogIfError(golock.Lock(updateLockPath)) defer golock.Unlock(updateLockPath) if node.IsSetup() { return } Errf("Setting up iojs-v%s...", node.NodeVersion) ExitIfError(node.Setup()) clearOldNodeInstalls() Errln(" done") } }
// Setup downloads and sets up node in the RootPath directory func Setup() error { golock.Lock(lockPath) defer golock.Unlock(lockPath) t := findTarget() if t == nil { return errors.New(`node does not offer a prebuilt binary for your OS. You'll need to compile the tarball from nodejs.org and place it in ~/.heroku/node-v` + Version) } if t.isSetup() { return nil } if err := t.setup(); err != nil { return err } SetRootPath(rootPath) // essentially sets this node as the current one return t.clearOldNodeInstalls() }
func installPlugins(names ...string) error { for _, name := range names { lockfile := updateLockPath + "." + name LogIfError(golock.Lock(lockfile)) } err := gode.InstallPackage(names...) plugins := make([]*Plugin, 0, len(names)) for _, name := range names { plugins = append(plugins, getPlugin(name, true)) } AddPluginsToCache(plugins...) for _, name := range names { lockfile := updateLockPath + "." + name LogIfError(golock.Unlock(lockfile)) } return err }
func runFn(plugin *Plugin, module, topic, command string) func(ctx *Context) { return func(ctx *Context) { lockfile := updateLockPath + "." + module if exists, _ := fileExists(lockfile); exists { golock.Lock(lockfile) golock.Unlock(lockfile) } ctx.Dev = isPluginSymlinked(module) ctx.Version = ctx.Version + " " + module + "/" + plugin.Version + " iojs-v" + node.NodeVersion ctxJSON, err := json.Marshal(ctx) if err != nil { panic(err) } script := fmt.Sprintf(` 'use strict'; var moduleName = '%s'; var topic = '%s'; var command = '%s'; var ctx = %s; var logPath = %s; process.chdir(ctx.cwd); function repair (name) { console.error('Attempting to repair ' + name + '...'); require('child_process') .spawnSync('heroku', ['plugins:install', name], {stdio: [0,1,2]}); console.error('Repair complete. Try running your command again.'); } if (!ctx.dev) { process.on('uncaughtException', function (err) { console.error(' ! Error in ' + moduleName + ':') if (err.message) { console.error(' ! ' + err.message); if (err.message.indexOf('Cannot find module') != -1) { repair(moduleName); process.exit(1); } } else { console.error(' ! ' + err); } if (err.stack) { var fs = require('fs'); var log = function (line) { var d = new Date().toISOString() .replace(/T/, ' ') .replace(/-/g, '/') .replace(/\..+/, ''); fs.appendFileSync(logPath, d + ' ' + line + '\n'); } log('Error during ' + topic + ':' + command); log(err.stack); console.error(' ! See ' + logPath + ' for more info.'); } process.exit(1); }); } if (command === '') { command = null } var module = require(moduleName); var cmd = module.commands.filter(function (c) { return c.topic === topic && c.command == command; })[0]; cmd.run(ctx);`, module, topic, command, ctxJSON, strconv.Quote(ErrLogPath)) // swallow sigint since the plugin will handle it swallowSignal(os.Interrupt) cmd := node.RunScript(script) if ctx.Flags["debugger"] == true { cmd = node.DebugScript(script) } os.Chdir(cmd.Dir) execBin(cmd.Path, cmd.Args) } }