This is just a convenience enhancement - rather than swallowing all the output from the Heroku push command, print stdout and stderr like we do elsewhere with subprocesses. Heoku pushes are pretty involved and dump lots of useful output, so it should be useful for users to see this.
145 lines
3.9 KiB
Ruby
145 lines
3.9 KiB
Ruby
require "vagrant/util/subprocess"
|
|
require "vagrant/util/which"
|
|
|
|
require_relative "errors"
|
|
|
|
module VagrantPlugins
|
|
module HerokuPush
|
|
class Push < Vagrant.plugin("2", :push)
|
|
def push
|
|
# Expand any paths relative to the root
|
|
dir = File.expand_path(config.dir, env.root_path)
|
|
|
|
# Verify git is installed
|
|
verify_git_bin!(config.git_bin)
|
|
|
|
# Verify we are operating in a git repo
|
|
verify_git_repo!(dir)
|
|
|
|
# Get the current branch
|
|
branch = git_branch(dir)
|
|
|
|
# Get the name of the app
|
|
app = config.app || interpret_app(dir)
|
|
|
|
# Check if we need to add the git remote
|
|
if !has_git_remote?(config.remote, dir)
|
|
add_heroku_git_remote(config.remote, app, dir)
|
|
end
|
|
|
|
# Push to Heroku
|
|
git_push_heroku(config.remote, branch, dir)
|
|
end
|
|
|
|
# Verify that git is installed.
|
|
# @raise [Errors::GitNotFound]
|
|
def verify_git_bin!(path)
|
|
if Vagrant::Util::Which.which(path).nil?
|
|
raise Errors::GitNotFound, bin: path
|
|
end
|
|
end
|
|
|
|
# Verify that the given path is a git directory.
|
|
# @raise [Errors::NotAGitRepo]
|
|
# @param [String]
|
|
def verify_git_repo!(path)
|
|
if !File.directory?(git_dir(path))
|
|
raise Errors::NotAGitRepo, path: path
|
|
end
|
|
end
|
|
|
|
# Interpret the name of the Heroku application from the given path.
|
|
# @param [String] path
|
|
# @return [String]
|
|
def interpret_app(path)
|
|
File.basename(path)
|
|
end
|
|
|
|
# The git directory for the given path.
|
|
# @param [String] path
|
|
# @return [String]
|
|
def git_dir(path)
|
|
"#{path}/.git"
|
|
end
|
|
|
|
# The name of the current git branch.
|
|
# @param [String] path
|
|
# @return [String]
|
|
def git_branch(path)
|
|
result = execute!("git",
|
|
"--git-dir", git_dir(path),
|
|
"--work-tree", path,
|
|
"symbolic-ref",
|
|
"HEAD",
|
|
)
|
|
|
|
# Returns something like "* master"
|
|
result.stdout.sub("*", "").strip
|
|
end
|
|
|
|
# Push to the Heroku remote.
|
|
# @param [String] remote
|
|
# @param [String] branch
|
|
def git_push_heroku(remote, branch, path)
|
|
execute!("git",
|
|
"--git-dir", git_dir(path),
|
|
"--work-tree", path,
|
|
"push", remote, "#{branch}:master",
|
|
)
|
|
end
|
|
|
|
# Check if the git remote has the given remote.
|
|
# @param [String] remote
|
|
# @return [true, false]
|
|
def has_git_remote?(remote, path)
|
|
result = execute!("git",
|
|
"--git-dir", git_dir(path),
|
|
"--work-tree", path,
|
|
"remote",
|
|
)
|
|
remotes = result.stdout.split(/\r?\n/).map(&:strip)
|
|
remotes.include?(remote.to_s)
|
|
end
|
|
|
|
# Add the Heroku to the current repository.
|
|
# @param [String] remote
|
|
# @param [String] app
|
|
def add_heroku_git_remote(remote, app, path)
|
|
execute!("git",
|
|
"--git-dir", git_dir(path),
|
|
"--work-tree", path,
|
|
"remote", "add", remote, heroku_git_url(app),
|
|
)
|
|
end
|
|
|
|
# The URL for this project on Heroku.
|
|
# @return [String]
|
|
def heroku_git_url(app)
|
|
"git@heroku.com:#{app}.git"
|
|
end
|
|
|
|
# Execute the command, raising an exception if it fails.
|
|
# @return [Vagrant::Util::Subprocess::Result]
|
|
def execute!(*cmd)
|
|
subproccmd = cmd.dup << { notify: [:stdout, :stderr] }
|
|
result = Vagrant::Util::Subprocess.execute(*subproccmd) do |type, data|
|
|
if type == :stdout
|
|
@env.ui.info(data, new_line: false)
|
|
elsif type == :stderr
|
|
@env.ui.warn(data, new_line: false)
|
|
end
|
|
end
|
|
|
|
if result.exit_code != 0
|
|
raise Errors::CommandFailed,
|
|
cmd: cmd.join(" "),
|
|
stdout: result.stdout,
|
|
stderr: result.stderr
|
|
end
|
|
|
|
result
|
|
end
|
|
end
|
|
end
|
|
end
|