bard 0.41.2 → 0.42.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b56dfecf167ffd69e2e99c558c0392fc6265f374
4
- data.tar.gz: 3e05c1a6fb673e9bd03e4ac4960ad91ed558aa22
2
+ SHA256:
3
+ metadata.gz: 8ede698ef957275736c6d373ab637f83e9a676bf3a7214a789d4314ee69f3532
4
+ data.tar.gz: c0ac00d558f50fa633858358d2387f68095810e8741b13b4227a08cfd3f9c5c4
5
5
  SHA512:
6
- metadata.gz: 3649d61bdf34b2340a1720c7b76ded57c6a0d3a015919f69d45210ed28556fe0d4efb3bed58b0cb1f34ecb4fc8c81543979cf8359afb0a00782e9a2f040cd975
7
- data.tar.gz: e6b78253e0841ddc31e503cd515d1a56202483ba5fd29320343d78d6a1df24ff572f2fe0e80b2f6dd338caa820b29ec1d14a7d90e55b4f685a681942fc9cec58
6
+ metadata.gz: a237a2cc3ddc4611486f1dfe6b14a8c282daa7656330bc0748c960f668c4e5ec213ebd7cb9b7cd0671de95476a4a61b0e6763bb5588cda63dc08ab2d0809f9f0
7
+ data.tar.gz: 6861a6cf67056c5762144eb4fafc809c3a7a1040a8213a5bcac5860bc4f33aec9d44dccd7567e761f96465b20e0f14e5fa4a45aadcd96217a47b92ac7c8ce008
data/.gitignore CHANGED
@@ -7,6 +7,7 @@ rdoc
7
7
  tmp
8
8
  .bundle
9
9
  .rvmrc
10
+ .ruby-version
10
11
  Gemfile.lock
11
12
  pkg/*
12
13
 
@@ -19,11 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency "thor", ">= 0.19.0"
22
- spec.add_dependency "capistrano", "= 2.5.10"
23
- spec.add_dependency "net-ssh", "~> 4.0"
24
22
  spec.add_dependency "rvm"
25
- spec.add_dependency "rvm-capistrano"
26
- spec.add_dependency "systemu", ">= 1.2.0"
27
23
  spec.add_dependency "term-ansicolor", ">= 1.0.3"
28
24
  spec.add_dependency "bard-rake", ">= 0.1.1"
29
25
 
@@ -2,7 +2,6 @@ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
2
  require 'ruby-debug'
3
3
  require 'grit'
4
4
  require 'spec/expectations'
5
- require 'systemu'
6
5
  gem 'sqlite3-ruby'
7
6
 
8
7
  ENV["PATH"] += ":#{File.dirname(File.expand_path(__FILE__))}/../../bin"
@@ -1,5 +1,6 @@
1
+ require "open3"
1
2
  def type(command)
2
- @status, @stdout, @stderr = systemu command, :env => @env
3
+ @stdout, @stderr, @status = Open3.capture3(@env, command)
3
4
  if ENV['DEBUG']
4
5
  puts '-' * 20
5
6
  puts "Executing command: #{command}"
@@ -1,60 +1,71 @@
1
- $:.unshift File.expand_path(File.dirname(__FILE__))
2
-
3
1
  module Bard; end
4
2
 
5
3
  require "bard/base"
6
4
  require "bard/git"
7
5
  require "bard/ci"
6
+ require "bard/data"
7
+
8
+ require "bard/config"
8
9
 
9
10
  class Bard::CLI < Thor
11
+ def initialize(*args, **kwargs, &block)
12
+ super
13
+ @config = Config.new(project_name, "bard.rb")
14
+ end
15
+
10
16
  desc "data [FROM=production, TO=local]", "copy database and assets from FROM to TO"
11
- def data(from = "production", to = "local")
12
- exec "cap _2.5.10_ data:pull ROLES=#{from}" if to == "local"
13
- exec "cap _2.5.10_ data:push ROLES=#{to}" if from == "local"
17
+ def data(from="production", to="local")
18
+ Data.new(self, from, to).call
14
19
  end
15
20
 
16
21
  method_options %w( verbose -v ) => :boolean
17
- desc "stage", "pushes current branch, and stages it"
18
- def stage
19
- unless File.read("Capfile").include?("role :production")
22
+ desc "stage [BRANCH=HEAD]", "pushes current branch, and stages it"
23
+ def stage branch=Git.current_branch
24
+ unless @config.servers.key?(:production)
20
25
  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.")
21
26
  end
22
27
 
23
- branch = Git.current_branch
24
-
25
28
  run_crucial "git push -u origin #{branch}", true
26
- run_crucial "cap _2.5.10_ stage BRANCH=#{branch}", options.verbose?
29
+ command = "git fetch && git checkout -f origin/#{branch} && bin/setup"
30
+ run_crucial ssh_command(:staging, command)
27
31
  puts green("Stage Succeeded")
28
32
 
29
- unless system("cap _2.5.10_ ping ROLES=staging >/dev/null 2>&1")
30
- puts red("Staging is now down!")
31
- end
33
+ ping :staging
32
34
  end
33
35
 
34
- method_options %w( verbose -v ) => :boolean, %w( skip-ci ) => :boolean
35
- desc "deploy [BRANCH=HEAD]", "checks that branch is a ff with master, checks with ci, and then merges into master and deploys to production, and deletes branch."
36
- def deploy branch=Git.current_branch
36
+ method_options %w[verbose -v] => :boolean, %w[skip-ci] => :boolean, %w[local-ci -l] => :boolean
37
+ 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."
38
+ def deploy to=nil
39
+ branch = Git.current_branch
40
+
37
41
  if branch == "master"
38
42
  run_crucial "git push origin master:master"
39
- invoke :ci unless options["skip-ci"]
43
+ invoke :ci, [branch], options.slice("local-ci") unless options["skip-ci"]
40
44
 
41
45
  else
42
46
  run_crucial "git fetch origin master:master"
43
47
 
44
- if not Git.fast_forward_merge? "origin/master", branch
48
+ unless Git.fast_forward_merge?("origin/master", branch)
45
49
  puts "The master branch has advanced. Attempting rebase..."
46
50
  run_crucial "git rebase origin/master"
47
51
  end
48
52
 
49
53
  run_crucial "git push -f origin #{branch}:#{branch}"
50
54
 
51
- invoke :ci unless options["skip-ci"]
55
+ invoke :ci, [branch], options.slice("local-ci") unless options["skip-ci"]
52
56
 
53
57
  run_crucial "git push origin #{branch}:master"
54
58
  run_crucial "git fetch origin master:master"
55
59
  end
56
60
 
57
- run_crucial "cap _2.5.10_ deploy", options.verbose?
61
+ if `git remote` =~ /\bgithub\b/
62
+ run_crucial "git push github"
63
+ end
64
+
65
+ to ||= @config.servers.key?(:production) ? :production : :staging
66
+
67
+ command = "git pull origin master && bin/setup"
68
+ run_crucial ssh_command(to, command)
58
69
 
59
70
  puts green("Deploy Succeeded")
60
71
 
@@ -62,26 +73,20 @@ class Bard::CLI < Thor
62
73
  puts "Deleting branch: #{branch}"
63
74
  run_crucial "git push --delete origin #{branch}"
64
75
 
65
- case Git.current_branch
66
- when branch
76
+ if branch == Git.current_branch
67
77
  run_crucial "git checkout master"
68
- run_crucial "git branch -d #{branch}"
69
- when "master"
70
- run_crucial "git branch -d #{branch}"
71
- else
72
- run_crucial "git branch -D #{branch}"
73
78
  end
74
- end
75
79
 
76
- unless system("cap _2.5.10_ ping ROLES=production >/dev/null 2>&1")
77
- puts red("Production is now down!")
80
+ run_crucial "git branch -D #{branch}"
78
81
  end
82
+
83
+ ping to
79
84
  end
80
85
 
81
- method_options %w( verbose -v ) => :boolean
86
+ method_options %w[verbose -v] => :boolean, %w[local-ci -l] => :boolean
82
87
  desc "ci [BRANCH=HEAD]", "runs ci against BRANCH"
83
88
  def ci branch=Git.current_branch
84
- ci = CI.new(project_name, `git rev-parse #{branch}`.chomp)
89
+ ci = CI.new(project_name, `git rev-parse #{branch}`.chomp, local: options["local-ci"])
85
90
  if ci.exists?
86
91
  puts "Continuous integration: starting build on #{branch}..."
87
92
 
@@ -100,9 +105,9 @@ class Bard::CLI < Thor
100
105
  if success
101
106
  puts
102
107
  puts "Continuous integration: success!"
103
- if File.exist?("coverage")
108
+ if !options["local-ci"] && File.exist?("coverage")
104
109
  puts "Downloading test coverage from CI..."
105
- run_crucial "cap _2.5.10_ download_ci_test_coverage"
110
+ download_ci_test_coverage
106
111
  end
107
112
  puts "Deploying..."
108
113
  else
@@ -132,16 +137,16 @@ class Bard::CLI < Thor
132
137
  end
133
138
  end
134
139
 
135
- method_options %w( home ) => :boolean
140
+ method_options %w[home] => :boolean
136
141
  desc "ssh [TO=production]", "logs into the specified server via SSH"
137
- def ssh to="production"
138
- if to == "gubs"
139
- command = "exec $SHELL"
140
- command = "cd Sites/#{project_name} && #{command}" unless options["home"]
141
- command = %(ssh -t gubito@gubs.pagekite.me 'bash -l -c "exec ./vagrant \\"#{command}\\""')
142
- exec command
142
+ def ssh to=:production
143
+ command = "exec $SHELL -l"
144
+ if to == "gubs" && !options["home"]
145
+ server = @config.servers[:gubs]
146
+ command = %(bash -lic "exec ./vagrant \\"cd #{server.path} && #{command}\\"")
147
+ exec ssh_command(to, command, home: true)
143
148
  else
144
- exec "cap _2.5.10_ ssh ROLES=#{to}#{" NOCD=1" if options["home"]}"
149
+ exec ssh_command(to, command, home: options["home"])
145
150
  end
146
151
  end
147
152
 
@@ -150,5 +155,39 @@ class Bard::CLI < Thor
150
155
  install_files_path = File.expand_path(File.join(__dir__, "../install_files/*"))
151
156
  system "cp #{install_files_path} bin/"
152
157
  end
158
+
159
+ desc "ping [SERVER=production]", "hits the server over http to verify that its up."
160
+ def ping server=:production
161
+ server = @config.servers[server.to_sym]
162
+ return false if server.ping == false
163
+
164
+ url = server.default_ping
165
+ if server.ping =~ %r{^/}
166
+ url += server.ping
167
+ elsif server.ping.to_s.length > 0
168
+ url = server.ping
169
+ end
170
+
171
+ command = "curl -sfL #{url} 2>&1 1>/dev/null"
172
+ unless system command
173
+ puts "#{server.to_s.capitalize} is down!"
174
+ exit 1
175
+ end
176
+ end
177
+
178
+ desc "master_key [FROM=production, TO=local]", "copy master key from FROM to TO"
179
+ def master_key from="production", to="local"
180
+ if to == "local"
181
+ copy :from, from, "config/master.key"
182
+ end
183
+ if from == "local"
184
+ copy :to, to, "config/master.key"
185
+ end
186
+ end
187
+
188
+ desc "download_ci_test_coverage", "download latest test coverage information from CI"
189
+ def download_ci_test_coverage
190
+ rsync :from, :ci, "coverage"
191
+ end
153
192
  end
154
193
 
@@ -1,28 +1,79 @@
1
1
  require "thor"
2
2
  require "term/ansicolor"
3
- require "systemu"
3
+ require "open3"
4
4
 
5
5
  class Bard::CLI < Thor
6
6
  include Term::ANSIColor
7
7
 
8
8
  private
9
9
 
10
- def fatal(message)
11
- raise red("!!! ") + message
12
- end
13
-
14
10
  def run_crucial(command, verbose = false)
15
- status, stdout, stderr = systemu command
16
- fatal "Running command: #{yellow(command)}: #{stderr}" if status.to_i.nonzero?
17
- if verbose
11
+ stdout, stderr, status = Open3.capture3(command)
12
+ failed = status.to_i.nonzero?
13
+ if verbose || failed
18
14
  $stdout.puts stdout
19
15
  $stderr.puts stderr
20
16
  end
17
+ if failed
18
+ puts red("!!! ") + "Running command failed: #{yellow(command)}"
19
+ exit 1
20
+ end
21
21
  stdout.chomp
22
22
  end
23
23
 
24
24
  def project_name
25
25
  @project_name ||= File.expand_path(".").split("/").last
26
26
  end
27
+
28
+ def ssh_command server, command, home: false
29
+ server = @config.servers[server.to_sym]
30
+ uri = URI.parse("ssh://#{server.ssh}")
31
+ command = "cd #{server.path} && #{command}" unless home
32
+ command = "ssh -tt #{"-p#{uri.port} " if uri.port}#{uri.user}@#{uri.host} '#{command}'"
33
+ if server.gateway
34
+ uri = URI.parse("ssh://#{server.gateway}")
35
+ command = "ssh -tt #{" -p#{uri.port} " if uri.port}#{uri.user}@#{uri.host} \"#{command}\""
36
+ end
37
+ command
38
+ end
39
+
40
+ def copy direction, server, path
41
+ server = @config.servers[server.to_sym]
42
+
43
+ uri = URI.parse("ssh://#{server.gateway}")
44
+ port = uri.port ? "-p#{uri.port}" : ""
45
+ gateway = server.gateway ? "-oProxyCommand='ssh #{port} #{uri.user}@#{uri.host} -W %h:%p'" : ""
46
+
47
+ uri = URI.parse("ssh://#{server.ssh}")
48
+ port = uri.port ? "-P#{uri.port}" : ""
49
+ from_and_to = [path, "#{uri.user}@#{uri.host}:#{server.path}/#{path}"]
50
+
51
+ from_and_to.reverse! if direction == :from
52
+ command = "scp #{gateway} #{port} #{from_and_to.join(" ")}"
53
+
54
+ run_crucial command
55
+ end
56
+
57
+ def rsync direction, server, path
58
+ server = @config.servers[server.to_sym]
59
+
60
+ uri = URI.parse("ssh://#{server.gateway}")
61
+ port = uri.port ? "-p#{uri.port}" : ""
62
+ gateway = server.gateway ? "-oProxyCommand=\"ssh #{port} #{uri.user}@#{uri.host} -W %h:%p\"" : ""
63
+
64
+ uri = URI.parse("ssh://#{server.ssh}")
65
+ port = uri.port ? "-p#{uri.port}" : ""
66
+ ssh = "-e'ssh #{port} #{gateway}'"
67
+
68
+ dest_path = path.dup
69
+ dest_path = "./#{dest_path}"
70
+ from_and_to = [dest_path, "#{uri.user}@#{uri.host}:#{server.path}/#{path}"]
71
+ from_and_to.reverse! if direction == :from
72
+ from_and_to[-1].sub! %r(/[^/]+$), '/'
73
+
74
+ command = "rsync #{ssh} --delete -avz #{from_and_to.join(" ")}"
75
+
76
+ run_crucial command
77
+ end
27
78
  end
28
79
 
@@ -1,69 +1,142 @@
1
+ require "json"
2
+ require "forwardable"
3
+ require "open3"
4
+
1
5
  class Bard::CLI < Thor
2
- class CI < Struct.new(:project_name, :sha)
3
- def run
4
- last_time_elapsed = get_last_time_elapsed
5
- start
6
- sleep(2) until started?
6
+ class CI
7
+ def initialize project_name, sha, local: false
8
+ @project_name = project_name
9
+ @sha = sha
10
+ @local = !!local
11
+ @runner = @local ? Local.new(project_name, sha) : Remote.new(project_name, sha)
12
+ end
7
13
 
8
- start_time = Time.new.to_i
9
- while building?
10
- elapsed_time = Time.new.to_i - start_time
11
- yield elapsed_time, last_time_elapsed
12
- sleep(2)
13
- end
14
+ attr_reader :project_name, :sha, :runner
14
15
 
15
- success?
16
+ def local?
17
+ @local
16
18
  end
17
19
 
18
- def exists?
19
- `curl -s -I #{ci_host}/?token=botandrose` =~ /\b200 OK\b/
20
- end
20
+ extend Forwardable
21
21
 
22
- def console
23
- raw = `curl -s #{ci_host}/lastBuild/console?token=botandrose`
24
- raw[%r{<pre.*?>(.+)</pre>}m, 1]
25
- end
22
+ delegate [:run, :exists?, :console, :last_response] => :runner
26
23
 
27
- attr_accessor :last_response
24
+ class Remote < Struct.new(:project_name, :sha)
25
+ def run
26
+ last_time_elapsed = get_last_time_elapsed
27
+ start
28
+ sleep(2) until started?
28
29
 
29
- private
30
+ start_time = Time.new.to_i
31
+ while building?
32
+ elapsed_time = Time.new.to_i - start_time
33
+ yield elapsed_time, last_time_elapsed
34
+ sleep(2)
35
+ end
30
36
 
31
- def get_last_time_elapsed
32
- response = `curl -s #{ci_host}/lastStableBuild/api/xml?token=botandrose`
33
- response.match(/<duration>(\d+)<\/duration>/)
34
- $1 ? $1.to_i / 1000 : nil
35
- end
37
+ success?
38
+ end
36
39
 
37
- def ci_host
38
- "http://botandrose:thecakeisalie!@ci.botandrose.com/job/#{project_name}"
39
- end
40
+ def exists?
41
+ `curl -s -I #{ci_host}/?token=botandrose` =~ /\b200 OK\b/
42
+ end
40
43
 
41
- def start
42
- command = "curl -s -I -X POST '#{ci_host}/buildWithParameters?token=botandrose&GIT_REF=#{sha}'"
43
- output = `#{command}`
44
- @queueId = output[%r{Location: .+/queue/item/(\d+)/}, 1].to_i
45
- end
44
+ def console
45
+ raw = `curl -s #{ci_host}/lastBuild/console?token=botandrose`
46
+ raw[%r{<pre.*?>(.+)</pre>}m, 1]
47
+ end
46
48
 
47
- def started?
48
- command = "curl -s -g '#{ci_host}/api/json?depth=1&tree=builds[queueId,number]'"
49
- output = `#{command}`
50
- output =~ /"queueId":#{@queueId}\b/
51
- end
49
+ attr_accessor :last_response
50
+
51
+ private
52
52
 
53
- def job_id
54
- @job_id ||= begin
55
- output = `curl -s -g '#{ci_host}/api/json?depth=1&tree=builds[queueId,number]'`
56
- output[/"number":(\d+),"queueId":#{@queueId}\b/, 1].to_i
53
+ def get_last_time_elapsed
54
+ response = `curl -s #{ci_host}/lastStableBuild/api/xml?token=botandrose`
55
+ response.match(/<duration>(\d+)<\/duration>/)
56
+ $1 ? $1.to_i / 1000 : nil
57
+ end
58
+
59
+ def ci_host
60
+ "http://botandrose:thecakeisalie!@ci.botandrose.com/job/#{project_name}"
57
61
  end
58
- end
59
62
 
60
- def building?
61
- self.last_response = `curl -s #{ci_host}/#{job_id}/api/json?tree=building,result`
62
- last_response.include? '"building":true'
63
+ def start
64
+ command = "curl -s -I -X POST '#{ci_host}/buildWithParameters?token=botandrose&GIT_REF=#{sha}'"
65
+ output = `#{command}`
66
+ @queueId = output[%r{Location: .+/queue/item/(\d+)/}, 1].to_i
67
+ end
68
+
69
+ def started?
70
+ command = "curl -s -g '#{ci_host}/api/json?depth=1&tree=builds[queueId,number]'"
71
+ output = `#{command}`
72
+ JSON.parse(output)["builds"][0]["queueId"] == @queueId
73
+ end
74
+
75
+ def job_id
76
+ @job_id ||= begin
77
+ output = `curl -s -g '#{ci_host}/api/json?depth=1&tree=builds[queueId,number]'`
78
+ output[/"number":(\d+),"queueId":#{@queueId}\b/, 1].to_i
79
+ end
80
+ end
81
+
82
+ def building?
83
+ self.last_response = `curl -s #{ci_host}/#{job_id}/api/json?tree=building,result`
84
+ if last_response.blank?
85
+ sleep(2) # retry
86
+ self.last_response = `curl -s #{ci_host}/#{job_id}/api/json?tree=building,result`
87
+ if last_response.blank?
88
+ raise "Blank response from CI twice in a row. Aborting!"
89
+ end
90
+ end
91
+ last_response.include? '"building":true'
92
+ end
93
+
94
+ def success?
95
+ last_response.include? '"result":"SUCCESS"'
96
+ end
63
97
  end
64
98
 
65
- def success?
66
- last_response.include? '"result":"SUCCESS"'
99
+ class Local < Struct.new(:project_name, :sha)
100
+ def run
101
+ start
102
+
103
+ start_time = Time.new.to_i
104
+ while building?
105
+ elapsed_time = Time.new.to_i - start_time
106
+ yield elapsed_time, nil
107
+ sleep(2)
108
+ end
109
+
110
+ @stdin.close
111
+ @console = @stdout_and_stderr.read
112
+ @stdout_and_stderr.close
113
+
114
+ success?
115
+ end
116
+
117
+ def exists?
118
+ true
119
+ end
120
+
121
+ def console
122
+ @console
123
+ end
124
+
125
+ attr_accessor :last_response
126
+
127
+ private
128
+
129
+ def start
130
+ @stdin, @stdout_and_stderr, @wait_thread = Open3.popen2e("bin/rake ci")
131
+ end
132
+
133
+ def building?
134
+ ![nil, false].include?(@wait_thread.status)
135
+ end
136
+
137
+ def success?
138
+ @wait_thread.value.success?
139
+ end
67
140
  end
68
141
  end
69
142
  end
@@ -0,0 +1,85 @@
1
+ class Bard::CLI < Thor
2
+ class Config
3
+ def initialize project_name, path
4
+ @project_name = project_name
5
+ @servers = {
6
+ local: Server.new(
7
+ project_name,
8
+ :local,
9
+ false,
10
+ "./",
11
+ false,
12
+ ),
13
+ gubs: Server.new(
14
+ project_name,
15
+ :gubs,
16
+ "gubito@gubs.pagekite.me",
17
+ "Sites/#{project_name}",
18
+ false,
19
+ ),
20
+ ci: Server.new(
21
+ project_name,
22
+ :ci,
23
+ "jenkins@ci.botandrose.com:22022",
24
+ "jobs/#{project_name}/workspace",
25
+ false,
26
+ ),
27
+ staging: Server.new(
28
+ project_name,
29
+ :staging,
30
+ "www@#{project_name}.botandrose.com:22022",
31
+ ),
32
+ }
33
+ load_local_config! path
34
+ end
35
+
36
+ attr_reader :servers
37
+
38
+ def server key, &block
39
+ @servers[key] ||= Server.new(@project_name, key)
40
+ @servers[key].instance_eval &block if block_given?
41
+ @servers[key]
42
+ end
43
+
44
+ def data *paths
45
+ if paths.length == 0
46
+ Array(@data)
47
+ else
48
+ @data = paths
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def load_local_config! path
55
+ instance_eval File.read(File.expand_path(path)) if File.exist?(path)
56
+ end
57
+
58
+ class Server < Struct.new(:project_name, :key, :ssh, :path, :ping, :gateway)
59
+ def self.setting *fields
60
+ fields.each do |field|
61
+ define_method field do |*args|
62
+ if args.length == 1
63
+ send :"#{field}=", args.first
64
+ elsif args.length == 0
65
+ super()
66
+ else
67
+ raise ArgumentError
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ setting :ssh, :path, :ping, :gateway
74
+
75
+ def default_ping
76
+ uri = URI.parse("ssh://#{ssh}")
77
+ "http://#{uri.host}"
78
+ end
79
+
80
+ def path
81
+ super || project_name
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,49 @@
1
+ class Bard::CLI < Thor
2
+ class Data < Struct.new(:bard, :from, :to)
3
+ def call
4
+ if to == "local"
5
+ data_pull_db from.to_sym
6
+ data_pull_assets from.to_sym
7
+ end
8
+ if from == "local"
9
+ data_push_db to.to_sym
10
+ data_push_assets to.to_sym
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def data_pull_db server
17
+ bard.instance_eval do
18
+ run_crucial ssh_command(server, "bin/rake db:dump && gzip -9f db/data.sql")
19
+ copy :from, server, "db/data.sql.gz"
20
+ run_crucial "gunzip -f db/data.sql.gz && bin/rake db:load"
21
+ end
22
+ end
23
+
24
+ def data_push_db server
25
+ bard.instance_eval do
26
+ run_crucial "bin/rake db:dump && gzip -9f db/data.sql"
27
+ copy :to, server, "db/data.sql.gz"
28
+ run_crucial ssh_command(server, "gunzip -f db/data.sql.gz && bin/rake db:load")
29
+ end
30
+ end
31
+
32
+ def data_pull_assets server
33
+ bard.instance_eval do
34
+ @config.data.each do |path|
35
+ rsync :from, server, path
36
+ end
37
+ end
38
+ end
39
+
40
+ def data_push_assets server
41
+ bard.instance_eval do
42
+ @config.data.each do |path|
43
+ rsync :to, server, path
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+
@@ -1,4 +1,4 @@
1
1
  module Bard
2
- VERSION = "0.41.2"
2
+ VERSION = "0.42.0"
3
3
  end
4
4
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.41.2
4
+ version: 0.42.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Micah Geisel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-26 00:00:00.000000000 Z
11
+ date: 2020-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -24,34 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.19.0
27
- - !ruby/object:Gem::Dependency
28
- name: capistrano
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '='
32
- - !ruby/object:Gem::Version
33
- version: 2.5.10
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '='
39
- - !ruby/object:Gem::Version
40
- version: 2.5.10
41
- - !ruby/object:Gem::Dependency
42
- name: net-ssh
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '4.0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '4.0'
55
27
  - !ruby/object:Gem::Dependency
56
28
  name: rvm
57
29
  requirement: !ruby/object:Gem::Requirement
@@ -66,34 +38,6 @@ dependencies:
66
38
  - - ">="
67
39
  - !ruby/object:Gem::Version
68
40
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rvm-capistrano
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: systemu
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: 1.2.0
90
- type: :runtime
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: 1.2.0
97
41
  - !ruby/object:Gem::Dependency
98
42
  name: term-ansicolor
99
43
  requirement: !ruby/object:Gem::Requirement
@@ -174,8 +118,6 @@ extra_rdoc_files: []
174
118
  files:
175
119
  - ".gitignore"
176
120
  - ".gitmodules"
177
- - ".ruby-gemset"
178
- - ".ruby-version"
179
121
  - Gemfile
180
122
  - LICENSE
181
123
  - README.rdoc
@@ -203,8 +145,9 @@ files:
203
145
  - install_files/specified_yarn.rb
204
146
  - lib/bard.rb
205
147
  - lib/bard/base.rb
206
- - lib/bard/capistrano.rb
207
148
  - lib/bard/ci.rb
149
+ - lib/bard/config.rb
150
+ - lib/bard/data.rb
208
151
  - lib/bard/git.rb
209
152
  - lib/bard/version.rb
210
153
  - spec/bard_spec.rb
@@ -228,8 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
228
171
  - !ruby/object:Gem::Version
229
172
  version: '0'
230
173
  requirements: []
231
- rubyforge_project:
232
- rubygems_version: 2.6.14
174
+ rubygems_version: 3.0.3
233
175
  signing_key:
234
176
  specification_version: 4
235
177
  summary: CLI to automate common development tasks.
@@ -1 +0,0 @@
1
- bard
@@ -1 +0,0 @@
1
- ruby-2.4.3
@@ -1,131 +0,0 @@
1
- require 'uri'
2
-
3
- Capistrano::Configuration.instance(:must_exist).load do
4
- require "rvm/capistrano"
5
- set :rvm_type, :user
6
- ruby_version = File.read(".ruby-version").chomp
7
- ruby_gemset = File.read(".ruby-gemset").chomp
8
- set :rvm_ruby_string, [ruby_version, ruby_gemset].join("@")
9
-
10
- set :application, File.basename(Dir.pwd)
11
-
12
- role :staging, "www@staging.botandrose.com:22022"
13
- role :ci, "jenkins@ci.botandrose.com:22022"
14
-
15
- set :asset_paths, []
16
-
17
- namespace "data" do
18
- namespace "pull" do
19
- desc "pull data"
20
- task "default" do
21
- run "cd #{application} && bundle exec rake db:dump && gzip -9f db/data.sql"
22
- transfer :down, "#{application}/db/data.sql.gz", "db/data.sql.gz"
23
- system "gunzip -f db/data.sql.gz && bundle exec rake db:load"
24
- end
25
-
26
- desc "sync the static assets"
27
- task "assets" do
28
- uri = URI.parse("ssh://#{roles[ENV['ROLES'].to_sym].first.to_s}")
29
- portopt = "-e'ssh -p#{uri.port}'" if uri.port
30
-
31
- [asset_paths].flatten.each do |path|
32
- dest_path = path.dup
33
- dest_path.sub! %r(/[^/]+$), '/'
34
- system "rsync #{portopt} --delete -avz #{uri.user}@#{uri.host}:#{application}/#{path} #{dest_path}"
35
- end
36
- end
37
- end
38
-
39
- namespace "push" do
40
- desc "push data"
41
- task "default" do
42
- system "bundle exec rake db:dump && gzip -9f db/data.sql"
43
- transfer :up, "db/data.sql.gz", "#{application}/db/data.sql.gz"
44
- run "cd #{application} && gunzip -f db/data.sql.gz && bundle exec rake db:load"
45
- end
46
-
47
- desc "sync the static assets"
48
- task "assets" do
49
- uri = URI.parse("ssh://#{roles[ENV['ROLES'].to_sym].first.to_s}")
50
- portopt = "-e'ssh -p#{uri.port}'" if uri.port
51
-
52
- [asset_paths].flatten.each do |path|
53
- dest_path = path.dup
54
- dest_path.sub! %r(/[^/]+$), '/'
55
- system "rsync #{portopt} --delete -avz #{path} #{uri.user}@#{uri.host}:#{application}/#{dest_path}"
56
- end
57
- end
58
- end
59
- end
60
-
61
- after 'data:pull', 'data:pull:assets'
62
- after 'data:push', 'data:push:assets'
63
-
64
- desc "push app to production"
65
- task :deploy do
66
- deploy_roles = roles.keys.include?(:production) ? :production : :staging
67
- ENV["ROLES"] = deploy_roles.to_s
68
- find_and_execute_task "rvm:install_ruby"
69
- system "git push github" if `git remote` =~ /\bgithub\b/
70
- run "cd #{application} && git pull origin master && bin/setup", roles: deploy_roles
71
- end
72
-
73
- desc "push app to staging"
74
- task :stage do
75
- ENV["ROLES"] = "staging"
76
- find_and_execute_task "rvm:install_ruby"
77
- branch = ENV.fetch("BRANCH")
78
- run "cd #{application} && git fetch && git checkout -f origin/#{branch} && bin/setup", :roles => :staging
79
- end
80
-
81
- desc "test app for downtime"
82
- task :ping do
83
- deploy_roles = roles.keys.include?(:production) ? :production : :staging
84
- ENV["ROLES"] = deploy_roles.to_s
85
- role_name = ENV.fetch("ROLES", "production").to_sym
86
- server_definition = roles[role_name].first
87
-
88
- url = server_definition.host
89
- if role_name == :staging && server_definition.host == "staging.botandrose.com"
90
- url = "#{application}.botandrose.com"
91
- end
92
-
93
- ping_option = server_definition.options.fetch(:ping, "")
94
- if ping_option =~ %r{^/}
95
- url += ping_option
96
- elsif ping_option.to_s.length > 0
97
- url = ping_option
98
- end
99
-
100
- command = "curl -sfL #{url} 2>&1 1>/dev/null"
101
- unless system command
102
- puts "#{role_name.to_s.capitalize} is down!"
103
- exit 1
104
- end
105
- end
106
-
107
- desc "push master key"
108
- task :push_master_key do
109
- transfer :up, "config/master.key", "#{application}/config/master.key"
110
- end
111
-
112
- desc "pull master key"
113
- task :pull_master_key do
114
- transfer :down, "#{application}/config/master.key", "config/master.key"
115
- end
116
-
117
- desc "log in via ssh"
118
- task :ssh do
119
- role = ENV['ROLES'].to_sym
120
- path = role == :ci ? "jobs/#{application}/workspace" : application
121
- uri = URI.parse("ssh://#{roles[role].first.to_s}")
122
- exec "ssh -t #{"-p#{uri.port} " if uri.port}#{uri.user}@#{uri.host} '#{"cd #{path} && " unless ENV['NOCD']}exec $SHELL -l'"
123
- end
124
-
125
- desc "download latest test coverage information from CI"
126
- task :download_ci_test_coverage do
127
- uri = URI.parse("ssh://#{roles[:staging].first}")
128
- portopt = "-e'ssh -p#{uri.port}'" if uri.port
129
- system "rsync #{portopt} --delete -avz #{uri.user}@#{uri.host}:~jenkins/jobs/#{application}/workspace/coverage ./"
130
- end
131
- end