Class: Bard::CLI
- Inherits:
-
Thor
- Object
- Thor
- Bard::CLI
- Defined in:
- lib/bard/cli.rb,
lib/bard/plugins/run.rb,
lib/bard/plugins/ssh.rb,
lib/bard/plugins/vim.rb,
lib/bard/plugins/data.rb,
lib/bard/plugins/hurt.rb,
lib/bard/plugins/open.rb,
lib/bard/plugins/ping.rb,
lib/bard/plugins/setup.rb,
lib/bard/plugins/deploy.rb,
lib/bard/plugins/install.rb
Class Method Summary collapse
Instance Method Summary collapse
- #ci(branch = Bard::Git.current_branch) ⇒ Object
- #data ⇒ Object
- #deploy(branch = nil) ⇒ Object
- #hurt(*args) ⇒ Object
- #install ⇒ Object
- #master_key ⇒ Object
- #open(target = :production) ⇒ Object
- #ping(target = :production) ⇒ Object
- #run(*args) ⇒ Object
- #setup ⇒ Object
- #ssh(to = :production) ⇒ Object
- #stage(branch = Bard::Git.current_branch) ⇒ Object
- #version ⇒ Object
- #vim(branch = "master") ⇒ Object
Class Method Details
.exit_on_failure? ⇒ Boolean
18 |
# File 'lib/bard/cli.rb', line 18 def self.exit_on_failure? = true |
Instance Method Details
#ci(branch = Bard::Git.current_branch) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/bard/plugins/deploy.rb', line 139 def ci(branch = Bard::Git.current_branch) runner_name = if ["local-ci"] :local elsif ["ci"] ["ci"].to_sym else config.ci end ci = Bard::CI.new(project_name, branch, runner_name: runner_name) unless ci.exists? puts red("No CI found for #{project_name}!") puts "Re-run with --skip-ci to bypass CI, if you absolutely must, and know what you're doing." exit 1 end return puts ci.status if ["status"] if ["resume"] puts "Continuous integration: resuming build..." success = ci.resume do |elapsed_time, last_time| if last_time percentage = (elapsed_time.to_f / last_time.to_f * 100).to_i output = " Estimated completion: #{percentage}%" else output = " No estimated completion time. Elapsed time: #{elapsed_time} sec" end print "\x08" * output.length print output $stdout.flush end else puts "Continuous integration: starting build on #{branch}..." success = ci.run do |elapsed_time, last_time| if last_time percentage = (elapsed_time.to_f / last_time.to_f * 100).to_i output = " Estimated completion: #{percentage}%" else output = " No estimated completion time. Elapsed time: #{elapsed_time} sec" end print "\x08" * output.length print output $stdout.flush end end if success puts puts "Continuous integration: success!" else puts puts ci.console puts red("Automated tests failed!") exit 1 end end |
#data ⇒ Object
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 |
# File 'lib/bard/plugins/data.rb', line 10 def data from = config[[:from]] to = config[[:to]] from.require_capability!(:ssh) unless from.key == :local to.require_capability!(:ssh) unless to.key == :local if to.key == :production url = to.url puts yellow "WARNING: You are about to push data to production, overwriting everything that is there!" answer = ask("If you really want to do this, please type in the full HTTPS url of the production server:") if answer != url puts red("!!! ") + "Failed! We expected #{url}. Is this really where you want to overwrite all the data?" exit 1 end end puts "Dumping #{from.key} database to file..." from.run! "bin/rake db:dump" puts "Transfering file from #{from.key} to #{to.key}..." Bard::Copy.file "db/data.sql.gz", from: from, to: to, verbose: true puts "Loading file into #{to.key} database..." to.run! "bin/rake db:load" config.data.each do |path| puts "Synchronizing files in #{path}..." Bard::Copy.dir path, from: from, to: to, verbose: true end rescue Bard::Command::Error => e puts red("!!! ") + "Running command failed: #{yellow(e.)}" exit 1 end |
#deploy(branch = nil) ⇒ Object
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 |
# File 'lib/bard/plugins/deploy.rb', line 19 def deploy(branch = nil) branch ||= Bard::Git.current_branch if branch == "master" if !Bard::Git.up_to_date_with_remote?(branch) run! "git push origin #{branch}:#{branch}" end invoke :ci, [branch], .slice("local-ci", "ci") unless ["skip-ci"] || config.ci == false else run! "git fetch origin" if Bard::Git.current_branch != "master" && !Bard::Git.in_linked_worktree? run! "git fetch origin master:master" end unless Bard::Git.fast_forward_merge?("origin/master", branch) puts "The master branch has advanced. Attempting rebase..." if branch == Bard::Git.current_branch run! "git rebase origin/master" else tmpdir = Dir.mktmpdir("bard-rebase") begin run! "git worktree add --detach #{tmpdir} #{branch}" success = Dir.chdir(tmpdir) { system("git rebase origin/master") } rebased_sha = Dir.chdir(tmpdir) { `git rev-parse HEAD`.strip } if success run! "git worktree remove #{tmpdir} --force" unless success puts red("!!! ") + "Rebase failed due to conflicts." puts "Please rebase #{branch} manually:" puts " git checkout #{branch}" puts " git rebase origin/master" exit 1 end run! "git branch -f #{branch} #{rebased_sha}" ensure FileUtils.rm_rf(tmpdir) if Dir.exist?(tmpdir) end end end run! "git push -f origin #{branch}:#{branch}" invoke :ci, [branch], .slice("local-ci", "ci") unless ["skip-ci"] || config.ci == false run! "git push origin #{branch}:master" if Bard::Git.current_branch == "master" run! "git pull --ff-only origin master" elsif Bard::Git.in_linked_worktree? run! "git fetch origin master" else run! "git fetch origin master:master" end end if `git remote` =~ /\bgithub\b/ run! "git push github" end to = [:target].to_sym target = config[to] strategy = target.deploy_strategy_instance if [:clone] strategy.deploy(clone: project_name) else strategy.deploy end puts green("Deploy Succeeded") if branch != "master" puts "Deleting branch: #{branch}" run! "git push --delete origin #{branch}" if branch == Bard::Git.current_branch && Bard::Git.in_linked_worktree? worktree_path = Dir.pwd main_checkout = File.dirname(File.(`git rev-parse --git-common-dir`.chomp)) Dir.chdir(main_checkout) run! "git worktree remove #{worktree_path}" run! "git branch -D #{branch}" puts "Worktree removed. Run: cd #{main_checkout}" else if branch == Bard::Git.current_branch run! "git checkout master" end run! "git branch -D #{branch}" end end ping to rescue Bard::Command::Error => e puts red("!!! ") + "Running command failed: #{yellow(e.)}" exit 1 end |
#hurt(*args) ⇒ Object
3 4 5 6 7 8 9 10 11 12 |
# File 'lib/bard/plugins/hurt.rb', line 3 def hurt(*args) (1..).each do |count| puts "Running attempt #{count}" system *args unless $?.success? puts "Ran #{count-1} times before failing" break end end end |
#install ⇒ Object
3 4 5 6 7 8 |
# File 'lib/bard/plugins/install.rb', line 3 def install install_files_path = File.("install", __dir__) system "cp -R #{install_files_path}/* bin/" system "cp -R #{install_files_path}/.github ./" end |
#master_key ⇒ Object
199 200 201 202 203 |
# File 'lib/bard/plugins/deploy.rb', line 199 def master_key from = config[[:from]] to = config[[:to]] Bard::Copy.file "config/master.key", from: from, to: to end |
#open(target = :production) ⇒ Object
5 6 7 |
# File 'lib/bard/plugins/open.rb', line 5 def open(target = :production) exec "xdg-open #{open_url target}" end |
#ping(target = :production) ⇒ Object
5 6 7 8 9 |
# File 'lib/bard/plugins/ping.rb', line 5 def ping(target = :production) down_urls = Bard::Ping.call(config[target]) down_urls.each { |url| puts "#{url} is down!" } exit 1 if down_urls.any? end |
#run(*args) ⇒ Object
12 13 14 15 16 17 18 |
# File 'lib/bard/plugins/run.rb', line 12 def run(*args) target = config[[:target].to_sym] target.run!(*args.join(" "), verbose: true, home: [:home]) rescue Bard::Command::Error => e puts red("!!! ") + "Running command failed: #{yellow(e.)}" exit 1 end |
#setup ⇒ Object
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 |
# File 'lib/bard/plugins/setup.rb', line 6 def setup path = "/etc/nginx/sites-available/#{project_name}" system "sudo tee #{path} >/dev/null <<-'EOF' upstream puma { server 127.0.0.1:3000 fail_timeout=5; } server { listen 80; server_name #{nginx_server_name}; root #{Dir.pwd}/public; try_files $uri @app; location @app { proxy_pass http://puma; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location ~* \\-[0-9a-f]\\{64\\}\\.(ico|css|js|gif|jpe?g|png|webp)$ { access_log off; expires max; add_header Cache-Control public; } gzip_static on; } EOF" dest_path = path.sub("sites-available", "sites-enabled") system "sudo ln -sf #{path} #{dest_path}" if !File.exist?(dest_path) system "sudo service nginx restart" end |
#ssh(to = :production) ⇒ Object
7 8 9 |
# File 'lib/bard/plugins/ssh.rb', line 7 def ssh(to = :production) config[to].exec! "exec $SHELL -l", home: [:home] end |
#stage(branch = Bard::Git.current_branch) ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/bard/plugins/deploy.rb', line 115 def stage(branch = Bard::Git.current_branch) if config[:production] == config[:staging] raise Thor::Error.new("`bard stage` is disabled until a production target is defined. Until then, please use `bard deploy` to deploy to the staging target.") end run! "git push -u origin #{branch}", verbose: true target = config[:staging] strategy = target.deploy_strategy_instance strategy.deploy(branch: branch, force: true) puts green("Stage Succeeded") ping :staging rescue Bard::Command::Error => e puts red("!!! ") + "Running command failed: #{yellow(e.)}" exit 1 end |
#vim(branch = "master") ⇒ Object
3 4 5 |
# File 'lib/bard/plugins/vim.rb', line 3 def vim(branch = "master") exec "vim -p `(git diff #{branch} --name-only; git ls-files --others --exclude-standard) | grep -v '^app/assets/images/' | grep -v '^app/assets/stylesheets/' | while read f; do [ -f \"$f\" ] && ! file -b \"$f\" | grep -q \"binary\" && echo \"$f\"; done | tac`" end |