Class: Bard::CLI

Inherits:
Thor
  • Object
show all
Includes:
Term::ANSIColor
Defined in:
lib/bard.rb,
lib/bard/ci.rb,
lib/bard/base.rb,
lib/bard/data.rb,
lib/bard/config.rb,
lib/bard/ci/local.rb,
lib/bard/ci/jenkins.rb,
lib/bard/ci/github_actions.rb

Defined Under Namespace

Modules: Git Classes: CI, Config, Data

Instance Method Summary collapse

Constructor Details

#initialize(*args, **kwargs, &block) ⇒ CLI

Returns a new instance of CLI.



11
12
13
14
# File 'lib/bard.rb', line 11

def initialize(*args, **kwargs, &block)
  super
  @config = Config.new(project_name, "bard.rb")
end

Instance Method Details

#ci(branch = Git.current_branch) ⇒ Object



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
# File 'lib/bard.rb', line 89

def ci branch=Git.current_branch
  ci = CI.new(project_name, branch, local: options["local-ci"])
  if ci.exists?
    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

    if success
      puts
      puts "Continuous integration: success!"
      if !options["local-ci"] && File.exist?("coverage")
        puts "Downloading test coverage from CI..."
        download_ci_test_coverage
      end
      puts "Deploying..."
    else
      puts
      puts ci.last_response
      puts ci.console
      puts red("Automated tests failed!")
      exit 1
    end

  else
    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
end

#data(from = nil, to = "local") ⇒ Object



17
18
19
20
# File 'lib/bard.rb', line 17

def data(from=nil, to="local")
  from ||= @config.servers.key?(:production) ? "production" : "staging"
  Data.new(self, from, to).call
end

#deploy(to = nil) ⇒ Object



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
# File 'lib/bard.rb', line 39

def deploy to=nil
  branch = Git.current_branch

  if branch == "master"
    run_crucial "git push origin master:master"
    invoke :ci, [branch], options.slice("local-ci") unless options["skip-ci"]

  else
    run_crucial "git fetch origin master:master"

    unless Git.fast_forward_merge?("origin/master", branch)
      puts "The master branch has advanced. Attempting rebase..."
      run_crucial "git rebase origin/master"
    end

    run_crucial "git push -f origin #{branch}:#{branch}"

    invoke :ci, [branch], options.slice("local-ci") unless options["skip-ci"]

    run_crucial "git push origin #{branch}:master"
    run_crucial "git fetch origin master:master"
  end

  if `git remote` =~ /\bgithub\b/
    run_crucial "git push github"
  end

  to ||= @config.servers.key?(:production) ? :production : :staging

  command = "git pull origin master && bin/setup"
  run_crucial ssh_command(to, command)

  puts green("Deploy Succeeded")

  if branch != "master"
    puts "Deleting branch: #{branch}"
    run_crucial "git push --delete origin #{branch}"

    if branch == Git.current_branch
      run_crucial "git checkout master"
    end

    run_crucial "git branch -D #{branch}"
  end

  ping to
end

#download_ci_test_coverageObject



199
200
201
# File 'lib/bard.rb', line 199

def download_ci_test_coverage
  rsync :from, :ci, "coverage"
end

#hurt(*args) ⇒ Object



137
138
139
140
141
142
143
144
145
146
# File 'lib/bard.rb', line 137

def hurt *args
  1.upto(Float::INFINITY) do |count|
    puts "Running attempt #{count}"
    system *args
    unless $?.success?
      puts "Ran #{count-1} times before failing"
      break
    end
  end
end

#installObject



162
163
164
165
166
167
# File 'lib/bard.rb', line 162

def install
  install_files_path = File.expand_path(File.join(__dir__, "../install_files/*"))
  system "cp -R #{install_files_path} bin/"
  github_files_path = File.expand_path(File.join(__dir__, "../install_files/.github"))
  system "cp -R #{github_files_path} ./"
end

#master_key(from = "production", to = "local") ⇒ Object



189
190
191
192
193
194
195
196
# File 'lib/bard.rb', line 189

def master_key from="production", to="local"
  if to == "local"
    copy :from, from, "config/master.key"
  end
  if from == "local"
    copy :to, to, "config/master.key"
  end
end

#open(server = nil) ⇒ Object



130
131
132
133
134
# File 'lib/bard.rb', line 130

def open server=nil
  server ||= @config.servers.key?(:production) ? :production : :staging
  server = @config.servers[server.to_sym]
  exec "xdg-open #{server.default_ping}"
end

#ping(server = :production) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/bard.rb', line 170

def ping server=:production
  server = @config.servers[server.to_sym]
  return false if server.ping == false

  url = server.default_ping
  if server.ping =~ %r{^/}
    url += server.ping
  elsif server.ping.to_s.length > 0
    url = server.ping
  end

  command = "curl -sfL #{url} 2>&1 1>/dev/null"
  unless system command
    puts "#{server.key.to_s.capitalize} is down!"
    exit 1
  end
end

#ssh(to = :production) ⇒ Object



150
151
152
153
154
155
156
157
158
159
# File 'lib/bard.rb', line 150

def ssh to=:production
  command = "exec $SHELL -l"
  if to == "theia" && !options["home"]
    server = @config.servers[:theia]
    command = %(bash -lic "exec ./vagrant \\"cd #{server.path} && #{command}\\"")
    exec ssh_command(to, command, home: true)
  else
    exec ssh_command(to, command, home: options["home"])
  end
end

#stage(branch = Git.current_branch) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/bard.rb', line 24

def stage branch=Git.current_branch
  unless @config.servers.key?(:production)
    raise Thor::Error.new("`bard stage` is disabled until a production server is defined. Until then, please use `bard deploy` to deploy to the staging server.")
  end

  run_crucial "git push -u origin #{branch}", true
  command = "git fetch && git checkout -f origin/#{branch} && bin/setup"
  run_crucial ssh_command(:staging, command)
  puts green("Stage Succeeded")

  ping :staging
end

#vim(branch = "master") ⇒ Object



204
205
206
# File 'lib/bard.rb', line 204

def vim branch="master"
  exec "vim -p `git diff #{branch} --name-only | grep -v sass$ | tac`"
end