class Deploku::Remote
Attributes
force[R]
maintenance[R]
remote[R]
Public Class Methods
new(remote)
click to toggle source
# File lib/deploku/remote.rb, line 8 def initialize(remote) @remote = remote end
Public Instance Methods
add_migration(hash)
click to toggle source
# File lib/deploku/remote.rb, line 168 def add_migration(hash) @migrations ||= [] migration = @migrations.detect {|m| m.version == hash[:version] } || Deploku::Migration.new(version: hash[:version]) if hash[:location] == :local migration.local_status = hash[:status] else migration.remote_status = hash[:status] end @migrations << migration end
ahead()
click to toggle source
# File lib/deploku/remote.rb, line 37 def ahead @ahead ||= count_rev_list("..#{remote_commit}") end
app_name()
click to toggle source
# File lib/deploku/remote.rb, line 12 def app_name @app_name ||= begin output = run_command("git remote -v | grep #{remote} | grep push") if output =~ /git@/ output.match(/heroku[^:]*:(.*)\.git/)[1] else output.match(/\/\/[^\/]+\/(.*)\.git/)[1] end end end
behind()
click to toggle source
# File lib/deploku/remote.rb, line 33 def behind @behind ||= count_rev_list("#{remote_commit}..") end
count_rev_list(range)
click to toggle source
# File lib/deploku/remote.rb, line 41 def count_rev_list(range) run_command("git rev-list #{range}").split("\n").size end
database_configured?()
click to toggle source
# File lib/deploku/remote.rb, line 28 def database_configured? return @database_configured if defined? @database_configured @database_configured = test_command("bundle exec rake db:migrate:status") end
deploy(args)
click to toggle source
# File lib/deploku/remote.rb, line 84 def deploy(args) status(args) @force = !!args.delete("force") if args.delete("maintenance") @maintenance = :use elsif args.delete("maintenance:skip") @maintenance = :skip end if args.any? puts "Unknown argument(s): #{args.join(", ")}" exit 1 end puts "The following command#{'s' if deploy_commands.size > 1} will be run:" puts deploy_commands.each_with_index do |command, index| puts " #{index + 1}. #{command}" end repeat = true while repeat repeat = false print "\nChoose:\nD = deploy, or\nL = list commits to deploy, or\nanything else to abort: " proceed = STDIN.getch.upcase puts proceed if proceed == "D" puts "" deploy_commands.each_with_index do |command, index| puts " #{index + 1}. #{command} ..." run_command command end puts elsif proceed == "L" puts "\nList of commits between #{remote_commit.slice(0, 7)} and local branch\n" run_command "git log --oneline #{remote_commit}..", :echo repeat = true else puts "Abort" end end end
deploy_commands()
click to toggle source
# File lib/deploku/remote.rb, line 124 def deploy_commands return @deploy_commands if @deploy_commands maintenance_mode = false list = [] if migration_required? case maintenance when :use maintenance_mode = true when :skip # OK, nothing to do else puts "There are migrations to run. Please either choose maintenance or maintenance:skip" exit 1 end end list << "heroku maintenance:on --app #{app_name}" if maintenance_mode list << "git push#{force ? " --force" : ""} #{remote} #{local_branch}:master" list << "heroku run rake db:migrate --app #{app_name}" if migration_required? list << "heroku restart --app #{app_name}" if migration_required? list << "heroku maintenance:off --app #{app_name}" if maintenance_mode @deploy_commands = list end
extract_migrations(output, location)
click to toggle source
# File lib/deploku/remote.rb, line 187 def extract_migrations(output, location) output.split("\n"). select {|line| line =~ /^\s*(up|down)/ }.map {|line| values = line.split(" ") add_migration( location: location, version: values[1], status: values[0], ) } end
local_branch()
click to toggle source
# File lib/deploku/remote.rb, line 151 def local_branch @local_branch ||= run_command("git symbolic-ref HEAD").chomp.sub(/^\/?refs\/heads\//, '') end
local_migrations()
click to toggle source
# File lib/deploku/remote.rb, line 179 def local_migrations @local_migrations ||= extract_migrations(run_command("bundle exec rake db:migrate:status"), :local) end
migration_required?()
click to toggle source
# File lib/deploku/remote.rb, line 147 def migration_required? database_configured? && pending_migration_count > 0 end
migrations()
click to toggle source
# File lib/deploku/remote.rb, line 159 def migrations local_migrations && remote_migrations # Triggers building of @migrations @migrations.sort_by(&:version) end
pending_migration_count()
click to toggle source
# File lib/deploku/remote.rb, line 155 def pending_migration_count pending_migrations.size end
pending_migrations()
click to toggle source
# File lib/deploku/remote.rb, line 164 def pending_migrations migrations.select(&:pending?) end
remote_commit()
click to toggle source
# File lib/deploku/remote.rb, line 45 def remote_commit @remote_commit ||= run_command("git ls-remote #{remote} 2> /dev/null").chomp.split(' ').first end
remote_commit_exists_locally?()
click to toggle source
# File lib/deploku/remote.rb, line 23 def remote_commit_exists_locally? return @remote_commit_exists_locally if defined? @remote_commit_exists_locally @remote_commit_exists_locally = test_command("git show #{remote_commit}") end
remote_migrations()
click to toggle source
# File lib/deploku/remote.rb, line 183 def remote_migrations @remote_migrations ||= extract_migrations(run_command("heroku run rake db:migrate:status --app #{app_name}"), :remote) end
status(args)
click to toggle source
# File lib/deploku/remote.rb, line 49 def status(args) puts "Looking up current status for #{remote}" puts "Heroku app #{app_name} is running commit #{remote_commit.slice(0, 7)}" if remote_commit_exists_locally? if behind == 0 && ahead == 0 puts "It is up to date" else if ahead == 0 puts "It is #{behind} commit#{"s" if behind > 1} behind your local #{local_branch} branch" elsif behind == 0 puts "It is #{ahead} commit#{"s" if ahead > 1} ahead of your local #{local_branch} branch" else puts "It is #{behind} commit#{"s" if behind > 1} behind and #{ahead} commit#{"s" if ahead > 1} ahead of your local #{local_branch} branch" end end else puts "Warning! The commit #{remote_commit.slice(0, 7)} is not present in the local repo. Why?" end if database_configured? case pending_migration_count when 0 puts "There are no pending migrations" when 1 puts "There is 1 pending migration" else puts "There are #{pending_migration_count} pending migrations" end if pending_migration_count > 0 pending_migrations.each do |migration| puts migration end end end end