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



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

def ci branch=Git.current_branch
  ci = CI.new(project_name, branch, local: options["local-ci"])
  if ci.exists?
    return puts ci.status if options["status"]

    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 ci.jenkins? && 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

#dataObject



18
19
20
21
22
23
# File 'lib/bard.rb', line 18

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

#deploy(to = nil) ⇒ Object



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

def deploy to=nil
  branch = Git.current_branch

  if branch == "master"
    run_crucial "git push origin #{branch}:#{branch}" if !Git.up_to_date_with_remote?(branch)
    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



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

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

#hurt(*args) ⇒ Object



142
143
144
145
146
147
148
149
150
151
# File 'lib/bard.rb', line 142

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



167
168
169
170
171
172
# File 'lib/bard.rb', line 167

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



194
195
196
197
198
199
200
201
# File 'lib/bard.rb', line 194

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



135
136
137
138
139
# File 'lib/bard.rb', line 135

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



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/bard.rb', line 175

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



155
156
157
158
159
160
161
162
163
164
# File 'lib/bard.rb', line 155

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



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/bard.rb', line 27

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}", verbose: 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



209
210
211
# File 'lib/bard.rb', line 209

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