137 lines
3.6 KiB
Ruby
137 lines
3.6 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,
|
|
"branch",
|
|
)
|
|
|
|
# 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)
|
|
result = Vagrant::Util::Subprocess.execute(*cmd)
|
|
|
|
if result.exit_code != 0
|
|
raise Errors::CommandFailed,
|
|
cmd: cmd.join(" "),
|
|
stdout: result.stdout,
|
|
stderr: result.stderr
|
|
end
|
|
|
|
result
|
|
end
|
|
end
|
|
end
|
|
end
|