1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
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)
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
|