bard 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +76 -0
  3. data/PLUGINS.md +114 -0
  4. data/README.md +14 -6
  5. data/features/ci.feature +62 -0
  6. data/features/deploy_git_workflow.feature +88 -0
  7. data/features/step_definitions/bard_steps.rb +96 -0
  8. data/features/support/bard-coverage +16 -0
  9. data/features/support/env.rb +10 -1
  10. data/features/support/test_server.rb +2 -1
  11. data/lib/bard/ci/github_actions.rb +1 -2
  12. data/lib/bard/ci/jenkins.rb +82 -11
  13. data/lib/bard/ci/local.rb +6 -6
  14. data/lib/bard/ci/runner.rb +35 -1
  15. data/lib/bard/ci.rb +11 -23
  16. data/lib/bard/cli/ci.rb +45 -38
  17. data/lib/bard/cli/deploy.rb +40 -8
  18. data/lib/bard/cli/hurt.rb +10 -15
  19. data/lib/bard/cli/install.rb +7 -12
  20. data/lib/bard/cli/open.rb +12 -16
  21. data/lib/bard/cli/ping.rb +8 -14
  22. data/lib/bard/cli/run.rb +5 -3
  23. data/lib/bard/cli/vim.rb +5 -10
  24. data/lib/bard/cli.rb +7 -12
  25. data/lib/bard/config.rb +1 -13
  26. data/lib/bard/github.rb +2 -4
  27. data/lib/bard/plugin.rb +99 -0
  28. data/lib/bard/plugins/backup.rb +19 -0
  29. data/lib/bard/plugins/github_pages.rb +34 -0
  30. data/lib/bard/plugins/hurt.rb +5 -0
  31. data/lib/bard/plugins/install.rb +5 -0
  32. data/lib/bard/plugins/jenkins.rb +6 -0
  33. data/lib/bard/plugins/new.rb +5 -0
  34. data/lib/bard/plugins/ping.rb +6 -0
  35. data/lib/bard/plugins/provision.rb +5 -0
  36. data/lib/bard/plugins/vim.rb +5 -0
  37. data/lib/bard/secrets.rb +10 -0
  38. data/lib/bard/version.rb +1 -1
  39. data/spec/bard/ci/github_actions_spec.rb +116 -13
  40. data/spec/bard/ci/jenkins_spec.rb +139 -0
  41. data/spec/bard/ci/runner_spec.rb +61 -0
  42. data/spec/bard/cli/ci_spec.rb +34 -8
  43. data/spec/bard/cli/deploy_spec.rb +20 -8
  44. data/spec/bard/cli/hurt_spec.rb +2 -2
  45. data/spec/bard/cli/install_spec.rb +4 -4
  46. data/spec/bard/cli/open_spec.rb +10 -8
  47. data/spec/bard/cli/ping_spec.rb +5 -5
  48. data/spec/bard/cli/run_spec.rb +20 -1
  49. data/spec/bard/cli/vim_spec.rb +5 -5
  50. data/spec/bard/github_spec.rb +1 -1
  51. data/spec/bard/plugin_spec.rb +79 -0
  52. data/spec/spec_helper.rb +6 -1
  53. metadata +27 -3
  54. data/README.rdoc +0 -15
@@ -1,12 +1,28 @@
1
1
  require "json"
2
2
  require "bard/ci/runner"
3
+ require "bard/secrets"
3
4
 
4
5
  module Bard
5
6
  class CI
6
7
  class Jenkins < Runner
7
-
8
8
  def exists?
9
- `curl -s -I #{ci_host}/` =~ /\b200 OK\b/
9
+ `curl -s -I #{ci_host}/` =~ /\b200 OK\b/ or create!
10
+ end
11
+
12
+ private def create!
13
+ git_url = `git remote get-url origin`.strip
14
+ config = JOB_CONFIG_XML.sub("GIT_URL", git_url)
15
+ if File.exist?("config/master.key")
16
+ master_key = File.read("config/master.key").strip
17
+ master_key_step = <<~XML.chomp
18
+ <hudson.tasks.Shell>
19
+ <command>echo #{master_key} > config/master.key</command>
20
+ </hudson.tasks.Shell>
21
+
22
+ XML
23
+ config = config.sub("<builders>\n", "<builders>\n #{master_key_step}")
24
+ end
25
+ `curl -s -X POST "http://#{auth}@ci.botandrose.com/createItem?name=#{project_name}" -H "Content-Type: application/xml" -d '#{config}'`
10
26
  end
11
27
 
12
28
  def console
@@ -23,7 +39,7 @@ module Bard
23
39
  end
24
40
 
25
41
  def start
26
- command = "curl -s -I -X POST -L '#{ci_host}/buildWithParameters?GIT_REF=#{sha}'"
42
+ command = "curl -s -I -X POST -L '#{ci_host}/buildWithParameters?GIT_REF=#{branch}'"
27
43
  output = `#{command}`
28
44
  @queueId = output[%r{Location: .+/queue/item/(\d+)/}, 1].to_i
29
45
  end
@@ -31,7 +47,7 @@ module Bard
31
47
  def building?
32
48
  retry_with_backoff do
33
49
  self.last_response = `curl -s #{ci_host}/#{job_id}/api/json?tree=building,result`
34
- raise "Blank response from CI" if last_response.blank?
50
+ raise "Blank response from CI" if last_response.empty?
35
51
  end
36
52
  last_response.include? '"building":true'
37
53
  end
@@ -61,9 +77,9 @@ module Bard
61
77
  private
62
78
 
63
79
  def get_last_time_elapsed
64
- retry_with_backoff do
80
+ response = retry_with_backoff do
65
81
  response = `curl -s #{ci_host}/lastStableBuild/api/xml`
66
- raise "Blank response from CI" if response.blank?
82
+ raise "Blank response from CI" if response.empty?
67
83
  response
68
84
  end
69
85
  response.match(/<duration>(\d+)<\/duration>/)
@@ -74,7 +90,7 @@ module Bard
74
90
  end
75
91
 
76
92
  def auth
77
- "botandrose:11cc2ba6ef2e43fbfbedc1f466724f6290"
93
+ @auth ||= "#{Bard::Secrets.fetch("jenkins-user")}:#{Bard::Secrets.fetch("jenkins-token")}"
78
94
  end
79
95
 
80
96
  def ci_host
@@ -85,8 +101,10 @@ module Bard
85
101
  retry_with_backoff do
86
102
  command = "curl -s -g '#{ci_host}/api/json?depth=1&tree=builds[queueId,number]'"
87
103
  output = `#{command}`
88
- raise "Blank response from CI" if output.blank?
89
- JSON.parse(output)["builds"][0]["queueId"] == @queueId
104
+ raise "Blank response from CI" if output.empty?
105
+ builds = JSON.parse(output)["builds"]
106
+ raise "Build not found in builds list" if builds.empty?
107
+ builds.first["queueId"] == @queueId
90
108
  end
91
109
  end
92
110
 
@@ -94,11 +112,64 @@ module Bard
94
112
  @job_id ||= begin
95
113
  retry_with_backoff do
96
114
  output = `curl -s -g '#{ci_host}/api/json?depth=1&tree=builds[queueId,number]'`
97
- raise "Blank response from CI" if output.blank?
98
- output[/"number":(\d+),"queueId":#{@queueId}\b/, 1].to_i
115
+ raise "Blank response from CI" if output.empty?
116
+ builds = JSON.parse(output)["builds"]
117
+ build = builds.find { |b| b["queueId"] == @queueId }
118
+ build["number"]
99
119
  end
100
120
  end
101
121
  end
122
+ JOB_CONFIG_XML = <<~XML
123
+ <?xml version="1.0" encoding="UTF-8"?>
124
+ <project>
125
+ <actions/>
126
+ <description></description>
127
+ <keepDependencies>false</keepDependencies>
128
+ <properties>
129
+ <hudson.model.ParametersDefinitionProperty>
130
+ <parameterDefinitions>
131
+ <hudson.model.StringParameterDefinition>
132
+ <name>GIT_REF</name>
133
+ <description></description>
134
+ <defaultValue>master</defaultValue>
135
+ </hudson.model.StringParameterDefinition>
136
+ </parameterDefinitions>
137
+ </hudson.model.ParametersDefinitionProperty>
138
+ </properties>
139
+ <scm class="hudson.plugins.git.GitSCM" plugin="git@3.3.0">
140
+ <configVersion>2</configVersion>
141
+ <userRemoteConfigs>
142
+ <hudson.plugins.git.UserRemoteConfig>
143
+ <url>GIT_URL</url>
144
+ </hudson.plugins.git.UserRemoteConfig>
145
+ </userRemoteConfigs>
146
+ <branches>
147
+ <hudson.plugins.git.BranchSpec>
148
+ <name>$GIT_REF</name>
149
+ </hudson.plugins.git.BranchSpec>
150
+ </branches>
151
+ <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
152
+ <submoduleCfg class="list"/>
153
+ <extensions/>
154
+ </scm>
155
+ <canRoam>true</canRoam>
156
+ <disabled>false</disabled>
157
+ <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
158
+ <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
159
+ <triggers/>
160
+ <concurrentBuild>false</concurrentBuild>
161
+ <builders>
162
+ <hudson.tasks.Shell>
163
+ <command>bash -l -c bin/setup</command>
164
+ </hudson.tasks.Shell>
165
+ <hudson.tasks.Shell>
166
+ <command>bash -l -c bin/ci</command>
167
+ </hudson.tasks.Shell>
168
+ </builders>
169
+ <publishers/>
170
+ <buildWrappers/>
171
+ </project>
172
+ XML
102
173
  end
103
174
  end
104
175
  end
data/lib/bard/ci/local.rb CHANGED
@@ -1,10 +1,9 @@
1
- require "open3"
1
+ require "tempfile"
2
2
  require "bard/ci/runner"
3
3
 
4
4
  module Bard
5
5
  class CI
6
6
  class Local < Runner
7
-
8
7
  def exists?
9
8
  true
10
9
  end
@@ -16,7 +15,8 @@ module Bard
16
15
  protected
17
16
 
18
17
  def start
19
- @stdin, @stdout_and_stderr, @wait_thread = Open3.popen2e("CLEAN=true bin/rake ci")
18
+ @output_file = Tempfile.new("bard-ci")
19
+ @wait_thread = Process.detach(spawn("CLEAN=true bin/rake ci", [:out, :err] => @output_file))
20
20
  end
21
21
 
22
22
  def building?
@@ -47,9 +47,9 @@ module Bard
47
47
  sleep(2)
48
48
  end
49
49
 
50
- @stdin.close
51
- @console = @stdout_and_stderr.read
52
- @stdout_and_stderr.close
50
+ @output_file.rewind
51
+ @console = @output_file.read
52
+ @output_file.close!
53
53
  end
54
54
  end
55
55
  end
@@ -6,12 +6,43 @@ module Bard
6
6
  class Runner < Struct.new(:project_name, :branch, :sha)
7
7
  include Retryable
8
8
 
9
+ @runners = {}
10
+
11
+ class << self
12
+ attr_reader :runners
13
+
14
+ def inherited(subclass)
15
+ super
16
+ name = extract_runner_name(subclass)
17
+ runners[name] = subclass if name
18
+ end
19
+
20
+ def [](name)
21
+ runners[name.to_sym]
22
+ end
23
+
24
+ # Returns the last registered runner (most recently loaded wins)
25
+ def default
26
+ runners.values.last
27
+ end
28
+
29
+ private
30
+
31
+ def extract_runner_name(klass)
32
+ klass.name&.split("::")&.last
33
+ &.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
34
+ &.gsub(/([a-z\d])([A-Z])/, '\1_\2')
35
+ &.downcase
36
+ &.to_sym
37
+ end
38
+ end
39
+
9
40
  def run
10
41
  start
11
42
  @start_time = Time.new.to_i
12
43
  @last_time_elapsed = get_last_time_elapsed
13
44
  save_state
14
- wait_until_started if respond_to?(:wait_until_started)
45
+ wait_until_started
15
46
 
16
47
  poll_until_complete { |elapsed, last_time| yield elapsed, last_time }
17
48
 
@@ -62,6 +93,9 @@ module Bard
62
93
  raise NotImplementedError, "#{self.class}#success? not implemented"
63
94
  end
64
95
 
96
+ def wait_until_started
97
+ end
98
+
65
99
  def get_last_time_elapsed
66
100
  nil
67
101
  end
data/lib/bard/ci.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  require "forwardable"
2
+ require "bard/ci/runner"
2
3
 
3
4
  module Bard
4
5
  class CI
5
- def initialize project_name, branch, local: false
6
+ def initialize(project_name, branch, runner_name: nil)
6
7
  @project_name = project_name
7
8
  @branch = branch
8
- @local = !!local
9
+ @runner_name = runner_name
9
10
  end
10
11
 
11
12
  extend Forwardable
@@ -13,18 +14,6 @@ module Bard
13
14
 
14
15
  private
15
16
 
16
- def local?
17
- @local
18
- end
19
-
20
- def github_actions?
21
- File.exist?(".github/workflows/ci.yml")
22
- end
23
-
24
- def jenkins?
25
- !local? && !github_actions?
26
- end
27
-
28
17
  def runner
29
18
  @runner ||= choose_runner_class.new(@project_name, @branch, sha)
30
19
  end
@@ -34,15 +23,14 @@ module Bard
34
23
  end
35
24
 
36
25
  def choose_runner_class
37
- if local?
38
- require_relative "./ci/local"
39
- Local
40
- elsif github_actions?
41
- require_relative "./ci/github_actions"
42
- GithubActions
43
- elsif jenkins?
44
- require_relative "./ci/jenkins"
45
- Jenkins
26
+ if @runner_name
27
+ runner_class = Runner[@runner_name]
28
+ raise "Unknown CI runner: #{@runner_name}" unless runner_class
29
+ runner_class
30
+ else
31
+ runner_class = Runner.default
32
+ raise "No CI runner available" unless runner_class
33
+ runner_class
46
34
  end
47
35
  end
48
36
  end
data/lib/bard/cli/ci.rb CHANGED
@@ -6,56 +6,63 @@ module Bard::CLI::CI
6
6
  mod.class_eval do
7
7
 
8
8
  option :"local-ci", type: :boolean
9
+ option :ci, type: :string
9
10
  option :status, type: :boolean
10
11
  option :resume, type: :boolean
11
12
  desc "ci [branch=HEAD]", "runs ci against BRANCH"
12
13
  def ci branch=Bard::Git.current_branch
13
- ci = Bard::CI.new(project_name, branch, local: options["local-ci"])
14
- if ci.exists?
15
- return puts ci.status if options["status"]
14
+ runner_name = if options["local-ci"]
15
+ :local
16
+ elsif options["ci"]
17
+ options["ci"].to_sym
18
+ else
19
+ config.ci
20
+ end
21
+ ci = Bard::CI.new(project_name, branch, runner_name: runner_name)
22
+ unless ci.exists?
23
+ puts red("No CI found for #{project_name}!")
24
+ puts "Re-run with --skip-ci to bypass CI, if you absolutely must, and know what you're doing."
25
+ exit 1
26
+ end
16
27
 
17
- if options["resume"]
18
- puts "Continuous integration: resuming build..."
19
- success = ci.resume do |elapsed_time, last_time|
20
- if last_time
21
- percentage = (elapsed_time.to_f / last_time.to_f * 100).to_i
22
- output = " Estimated completion: #{percentage}%"
23
- else
24
- output = " No estimated completion time. Elapsed time: #{elapsed_time} sec"
25
- end
26
- print "\x08" * output.length
27
- print output
28
- $stdout.flush
29
- end
30
- else
31
- puts "Continuous integration: starting build on #{branch}..."
28
+ return puts ci.status if options["status"]
32
29
 
33
- success = ci.run do |elapsed_time, last_time|
34
- if last_time
35
- percentage = (elapsed_time.to_f / last_time.to_f * 100).to_i
36
- output = " Estimated completion: #{percentage}%"
37
- else
38
- output = " No estimated completion time. Elapsed time: #{elapsed_time} sec"
39
- end
40
- print "\x08" * output.length
41
- print output
42
- $stdout.flush
30
+ if options["resume"]
31
+ puts "Continuous integration: resuming build..."
32
+ success = ci.resume do |elapsed_time, last_time|
33
+ if last_time
34
+ percentage = (elapsed_time.to_f / last_time.to_f * 100).to_i
35
+ output = " Estimated completion: #{percentage}%"
36
+ else
37
+ output = " No estimated completion time. Elapsed time: #{elapsed_time} sec"
43
38
  end
39
+ print "\x08" * output.length
40
+ print output
41
+ $stdout.flush
44
42
  end
43
+ else
44
+ puts "Continuous integration: starting build on #{branch}..."
45
45
 
46
- if success
47
- puts
48
- puts "Continuous integration: success!"
49
- else
50
- puts
51
- puts ci.console
52
- puts red("Automated tests failed!")
53
- exit 1
46
+ success = ci.run do |elapsed_time, last_time|
47
+ if last_time
48
+ percentage = (elapsed_time.to_f / last_time.to_f * 100).to_i
49
+ output = " Estimated completion: #{percentage}%"
50
+ else
51
+ output = " No estimated completion time. Elapsed time: #{elapsed_time} sec"
52
+ end
53
+ print "\x08" * output.length
54
+ print output
55
+ $stdout.flush
54
56
  end
57
+ end
55
58
 
59
+ if success
60
+ puts
61
+ puts "Continuous integration: success!"
56
62
  else
57
- puts red("No CI found for #{project_name}!")
58
- puts "Re-run with --skip-ci to bypass CI, if you absolutely must, and know what you're doing."
63
+ puts
64
+ puts ci.console
65
+ puts red("Automated tests failed!")
59
66
  exit 1
60
67
  end
61
68
  end
@@ -1,6 +1,7 @@
1
1
  require "bard/git"
2
2
  require "bard/command"
3
3
  require "bard/github_pages"
4
+ require "tmpdir"
4
5
 
5
6
  module Bard::CLI::Deploy
6
7
  def self.included mod
@@ -8,37 +9,68 @@ module Bard::CLI::Deploy
8
9
 
9
10
  option :"skip-ci", type: :boolean
10
11
  option :"local-ci", type: :boolean
12
+ option :ci, type: :string
11
13
  option :clone, type: :boolean
12
- desc "deploy [TO=production]", "checks that current branch is a ff with master, checks with ci, merges into master, deploys to target, and then deletes branch."
13
- def deploy to=:production
14
- branch = Bard::Git.current_branch
14
+ option :target, type: :string, default: "production"
15
+ desc "deploy [BRANCH]", "deploys branch to target (default: current branch to production)"
16
+ def deploy branch=nil
17
+ branch ||= Bard::Git.current_branch
15
18
 
16
19
  if branch == "master"
17
20
  if !Bard::Git.up_to_date_with_remote?(branch)
18
21
  run! "git push origin #{branch}:#{branch}"
19
22
  end
20
- invoke :ci, [branch], options.slice("local-ci") unless options["skip-ci"]
23
+ invoke :ci, [branch], options.slice("local-ci", "ci") unless options["skip-ci"]
21
24
 
22
25
  else
23
- run! "git fetch origin master:master"
26
+ run! "git fetch origin"
27
+ if Bard::Git.current_branch != "master"
28
+ run! "git fetch origin master:master"
29
+ end
24
30
 
25
31
  unless Bard::Git.fast_forward_merge?("origin/master", branch)
26
32
  puts "The master branch has advanced. Attempting rebase..."
27
- run! "git rebase origin/master"
33
+ if branch == Bard::Git.current_branch
34
+ run! "git rebase origin/master"
35
+ else
36
+ tmpdir = Dir.mktmpdir("bard-rebase")
37
+ begin
38
+ run! "git worktree add --detach #{tmpdir} #{branch}"
39
+ success = Dir.chdir(tmpdir) { system("git rebase origin/master") }
40
+ rebased_sha = Dir.chdir(tmpdir) { `git rev-parse HEAD`.strip } if success
41
+ run! "git worktree remove #{tmpdir} --force"
42
+ unless success
43
+ puts red("!!! ") + "Rebase failed due to conflicts."
44
+ puts "Please rebase #{branch} manually:"
45
+ puts " git checkout #{branch}"
46
+ puts " git rebase origin/master"
47
+ exit 1
48
+ end
49
+ run! "git branch -f #{branch} #{rebased_sha}"
50
+ ensure
51
+ FileUtils.rm_rf(tmpdir) if Dir.exist?(tmpdir)
52
+ end
53
+ end
28
54
  end
29
55
 
30
56
  run! "git push -f origin #{branch}:#{branch}"
31
57
 
32
- invoke :ci, [branch], options.slice("local-ci") unless options["skip-ci"]
58
+ invoke :ci, [branch], options.slice("local-ci", "ci") unless options["skip-ci"]
33
59
 
34
60
  run! "git push origin #{branch}:master"
35
- run! "git fetch origin master:master"
61
+ if Bard::Git.current_branch != "master"
62
+ run! "git fetch origin master:master"
63
+ else
64
+ run! "git pull origin master"
65
+ end
36
66
  end
37
67
 
38
68
  if `git remote` =~ /\bgithub\b/
39
69
  run! "git push github"
40
70
  end
41
71
 
72
+ to = options[:target].to_sym
73
+
42
74
  if options[:clone]
43
75
  config[to].run! "git clone git@github.com:botandrosedesign/#{project_name} #{config[to].path}", home: true
44
76
  invoke :master_key, [], from: "local", to: to
data/lib/bard/cli/hurt.rb CHANGED
@@ -1,20 +1,15 @@
1
- module Bard::CLI::Hurt
2
- def self.included mod
3
- mod.class_eval do
1
+ require "bard/cli/command"
4
2
 
5
- desc "hurt <command>", "reruns a command until it fails"
6
- def hurt *args
7
- (1..).each do |count|
8
- puts "Running attempt #{count}"
9
- system *args
10
- unless $?.success?
11
- puts "Ran #{count-1} times before failing"
12
- break
13
- end
14
- end
3
+ class Bard::CLI::Hurt < Bard::CLI::Command
4
+ desc "hurt <command>", "reruns a command until it fails"
5
+ def hurt *args
6
+ (1..).each do |count|
7
+ puts "Running attempt #{count}"
8
+ system *args
9
+ unless $?.success?
10
+ puts "Ran #{count-1} times before failing"
11
+ break
15
12
  end
16
-
17
13
  end
18
14
  end
19
15
  end
20
-
@@ -1,16 +1,11 @@
1
- module Bard::CLI::Install
2
- def self.included mod
3
- mod.class_eval do
1
+ require "bard/cli/command"
4
2
 
5
- desc "install", "copies bin/setup and bin/ci scripts into current project."
6
- def install
7
- install_files_path = File.expand_path(File.join(__dir__, "../../../install_files"))
3
+ class Bard::CLI::Install < Bard::CLI::Command
4
+ desc "install", "copies bin/setup and bin/ci scripts into current project."
5
+ def install
6
+ install_files_path = File.expand_path(File.join(__dir__, "../../../install_files"))
8
7
 
9
- system "cp -R #{install_files_path}/* bin/"
10
- system "cp -R #{install_files_path}/.github ./"
11
- end
12
-
13
- end
8
+ system "cp -R #{install_files_path}/* bin/"
9
+ system "cp -R #{install_files_path}/.github ./"
14
10
  end
15
11
  end
16
-
data/lib/bard/cli/open.rb CHANGED
@@ -1,22 +1,18 @@
1
- module Bard::CLI::Open
2
- def self.included mod
3
- mod.class_eval do
1
+ require "bard/cli/command"
4
2
 
5
- desc "open [server=production]", "opens the url in the web browser."
6
- def open server=:production
7
- exec "xdg-open #{open_url server}"
8
- end
3
+ class Bard::CLI::Open < Bard::CLI::Command
4
+ desc "open [server=production]", "opens the url in the web browser."
5
+ def open server=:production
6
+ exec "xdg-open #{open_url server}"
7
+ end
9
8
 
10
- private
9
+ private
11
10
 
12
- def open_url server
13
- if server.to_sym == :ci
14
- "https://github.com/botandrosedesign/#{project_name}/actions/workflows/ci.yml"
15
- else
16
- config[server].ping.first
17
- end
18
- end
11
+ def open_url server
12
+ if server.to_sym == :ci
13
+ "https://github.com/botandrosedesign/#{project_name}/actions/workflows/ci.yml"
14
+ else
15
+ config[server].ping.first
19
16
  end
20
17
  end
21
18
  end
22
-
data/lib/bard/cli/ping.rb CHANGED
@@ -1,18 +1,12 @@
1
+ require "bard/cli/command"
1
2
  require "bard/ping"
2
3
 
3
- module Bard::CLI::Ping
4
- def self.included mod
5
- mod.class_eval do
6
-
7
- desc "ping [server=production]", "hits the server over http to verify that its up."
8
- def ping server=:production
9
- server = config[server]
10
- down_urls = Bard::Ping.call(config[server])
11
- down_urls.each { |url| puts "#{url} is down!" }
12
- exit 1 if down_urls.any?
13
- end
14
-
15
- end
4
+ class Bard::CLI::Ping < Bard::CLI::Command
5
+ desc "ping [server=production]", "hits the server over http to verify that its up."
6
+ def ping server=:production
7
+ server = config[server]
8
+ down_urls = Bard::Ping.call(config[server])
9
+ down_urls.each { |url| puts "#{url} is down!" }
10
+ exit 1 if down_urls.any?
16
11
  end
17
12
  end
18
-
data/lib/bard/cli/run.rb CHANGED
@@ -9,10 +9,12 @@ module Bard::CLI::Run
9
9
  Thor::THOR_RESERVED_WORDS -= ["run"]
10
10
  $VERBOSE = original_verbose
11
11
 
12
- desc "run <command>", "run the given command on production"
12
+ option :target, type: :string, default: "production"
13
+ option :home, type: :boolean
14
+ desc "run <command>", "run the given command on the specified target"
13
15
  def run *args
14
- server = config[:production]
15
- server.run! *args.join(" "), verbose: true
16
+ target = config[options[:target].to_sym]
17
+ target.run! *args.join(" "), verbose: true, home: options[:home]
16
18
  rescue Bard::Command::Error => e
17
19
  puts red("!!! ") + "Running command failed: #{yellow(e.message)}"
18
20
  exit 1
data/lib/bard/cli/vim.rb CHANGED
@@ -1,13 +1,8 @@
1
- module Bard::CLI::Vim
2
- def self.included mod
3
- mod.class_eval do
1
+ require "bard/cli/command"
4
2
 
5
- desc "vim [branch=master]", "open all files that have changed since master"
6
- def vim branch="master"
7
- 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`"
8
- end
9
-
10
- end
3
+ class Bard::CLI::Vim < Bard::CLI::Command
4
+ desc "vim [branch=master]", "open all files that have changed since master"
5
+ def vim branch="master"
6
+ 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`"
11
7
  end
12
8
  end
13
-