bard 1.0.1 → 1.0.3
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.
- checksums.yaml +4 -4
- data/Rakefile +5 -0
- data/features/bard_check.feature +1 -1
- data/features/bard_push.feature +1 -1
- data/features/step_definitions/global_steps.rb +4 -4
- data/features/support/env.rb +1 -1
- data/features/support/io.rb +1 -1
- data/lib/bard/ci/github_actions.rb +3 -6
- data/lib/bard/ci/local.rb +0 -2
- data/lib/bard/ci.rb +10 -12
- data/lib/bard/cli/ci.rb +51 -0
- data/lib/bard/cli/data.rb +45 -0
- data/lib/bard/cli/deploy.rb +64 -0
- data/lib/bard/cli/hurt.rb +20 -0
- data/lib/bard/cli/install.rb +16 -0
- data/lib/bard/cli/master_key.rb +17 -0
- data/lib/bard/cli/open.rb +13 -0
- data/lib/bard/cli/ping.rb +18 -0
- data/lib/bard/cli/provision.rb +15 -0
- data/lib/bard/cli/run.rb +24 -0
- data/lib/bard/cli/setup.rb +45 -0
- data/lib/bard/cli/ssh.rb +14 -0
- data/lib/bard/cli/stage.rb +27 -0
- data/lib/bard/cli/vim.rb +13 -0
- data/lib/bard/cli.rb +21 -246
- data/lib/bard/command.rb +8 -6
- data/lib/bard/config.rb +2 -11
- data/lib/bard/copy.rb +15 -40
- data/lib/bard/git.rb +0 -4
- data/lib/bard/ping.rb +0 -1
- data/lib/bard/provision/ssh.rb +1 -1
- data/lib/bard/provision.rb +4 -23
- data/lib/bard/server.rb +29 -7
- data/lib/bard/version.rb +1 -1
- data/spec/bard/ci_spec.rb +10 -0
- data/spec/bard/config_spec.rb +83 -0
- data/spec/bard/server_spec.rb +127 -0
- metadata +23 -3
- /data/lib/bard/provision/{master_key.rb → masterkey.rb} +0 -0
data/lib/bard/cli.rb
CHANGED
@@ -1,17 +1,9 @@
|
|
1
1
|
# this file gets loaded in the CLI context, not the Rails boot context
|
2
2
|
|
3
3
|
require "thor"
|
4
|
-
require "bard/git"
|
5
|
-
require "bard/ci"
|
6
|
-
require "bard/copy"
|
7
|
-
require "bard/github"
|
8
|
-
require "bard/ping"
|
9
4
|
require "bard/config"
|
10
5
|
require "bard/command"
|
11
|
-
require "bard/provision"
|
12
6
|
require "term/ansicolor"
|
13
|
-
require "open3"
|
14
|
-
require "uri"
|
15
7
|
|
16
8
|
module Bard
|
17
9
|
class CLI < Thor
|
@@ -19,244 +11,24 @@ module Bard
|
|
19
11
|
|
20
12
|
class_option :verbose, type: :boolean, aliases: :v
|
21
13
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
from.run! "bin/rake db:dump"
|
41
|
-
|
42
|
-
puts "Transfering file from #{from.key} to #{to.key}..."
|
43
|
-
from.copy_file "db/data.sql.gz", to: to, verbose: true
|
44
|
-
|
45
|
-
puts "Loading file into #{to.key} database..."
|
46
|
-
to.run! "bin/rake db:load"
|
47
|
-
|
48
|
-
config.data.each do |path|
|
49
|
-
puts "Synchronizing files in #{path}..."
|
50
|
-
from.copy_dir path, to: to, verbose: true
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
desc "master_key --from=production --to=local", "copy master key from from to to"
|
55
|
-
option :from, default: "production"
|
56
|
-
option :to, default: "local"
|
57
|
-
def master_key
|
58
|
-
from = config[options[:from]]
|
59
|
-
to = config[options[:to]]
|
60
|
-
from.copy_file "config/master.key", to:
|
61
|
-
end
|
62
|
-
|
63
|
-
desc "stage [branch=HEAD]", "pushes current branch, and stages it"
|
64
|
-
def stage branch=Git.current_branch
|
65
|
-
unless config.servers.key?(:production)
|
66
|
-
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.")
|
67
|
-
end
|
68
|
-
|
69
|
-
run! "git push -u origin #{branch}", verbose: true
|
70
|
-
config[:staging].run! "git fetch && git checkout -f origin/#{branch} && bin/setup"
|
71
|
-
puts green("Stage Succeeded")
|
72
|
-
|
73
|
-
ping :staging
|
74
|
-
end
|
75
|
-
|
76
|
-
option :"skip-ci", type: :boolean
|
77
|
-
option :"local-ci", type: :boolean
|
78
|
-
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."
|
79
|
-
def deploy to=:production
|
80
|
-
branch = Git.current_branch
|
81
|
-
|
82
|
-
if branch == "master"
|
83
|
-
if !Git.up_to_date_with_remote?(branch)
|
84
|
-
run! "git push origin #{branch}:#{branch}"
|
85
|
-
end
|
86
|
-
invoke :ci, [branch], options.slice("local-ci") unless options["skip-ci"]
|
87
|
-
|
88
|
-
else
|
89
|
-
run! "git fetch origin master:master"
|
90
|
-
|
91
|
-
unless Git.fast_forward_merge?("origin/master", branch)
|
92
|
-
puts "The master branch has advanced. Attempting rebase..."
|
93
|
-
run! "git rebase origin/master"
|
94
|
-
end
|
95
|
-
|
96
|
-
run! "git push -f origin #{branch}:#{branch}"
|
97
|
-
|
98
|
-
invoke :ci, [branch], options.slice("local-ci") unless options["skip-ci"]
|
99
|
-
|
100
|
-
run! "git push origin #{branch}:master"
|
101
|
-
run! "git fetch origin master:master"
|
102
|
-
end
|
103
|
-
|
104
|
-
if `git remote` =~ /\bgithub\b/
|
105
|
-
run! "git push github"
|
106
|
-
end
|
107
|
-
|
108
|
-
config[to].run! "git pull origin master && bin/setup"
|
109
|
-
|
110
|
-
puts green("Deploy Succeeded")
|
111
|
-
|
112
|
-
if branch != "master"
|
113
|
-
puts "Deleting branch: #{branch}"
|
114
|
-
run! "git push --delete origin #{branch}"
|
115
|
-
|
116
|
-
if branch == Git.current_branch
|
117
|
-
run! "git checkout master"
|
118
|
-
end
|
119
|
-
|
120
|
-
run! "git branch -D #{branch}"
|
121
|
-
end
|
122
|
-
|
123
|
-
ping to
|
124
|
-
end
|
125
|
-
|
126
|
-
option :"local-ci", type: :boolean
|
127
|
-
option :status, type: :boolean
|
128
|
-
desc "ci [branch=HEAD]", "runs ci against BRANCH"
|
129
|
-
def ci branch=Git.current_branch
|
130
|
-
ci = CI.new(project_name, branch, local: options["local-ci"])
|
131
|
-
if ci.exists?
|
132
|
-
return puts ci.status if options["status"]
|
133
|
-
|
134
|
-
puts "Continuous integration: starting build on #{branch}..."
|
135
|
-
|
136
|
-
success = ci.run do |elapsed_time, last_time|
|
137
|
-
if last_time
|
138
|
-
percentage = (elapsed_time.to_f / last_time.to_f * 100).to_i
|
139
|
-
output = " Estimated completion: #{percentage}%"
|
140
|
-
else
|
141
|
-
output = " No estimated completion time. Elapsed time: #{elapsed_time} sec"
|
142
|
-
end
|
143
|
-
print "\x08" * output.length
|
144
|
-
print output
|
145
|
-
$stdout.flush
|
146
|
-
end
|
147
|
-
|
148
|
-
if success
|
149
|
-
puts
|
150
|
-
puts "Continuous integration: success!"
|
151
|
-
puts "Deploying..."
|
152
|
-
else
|
153
|
-
puts
|
154
|
-
puts ci.last_response
|
155
|
-
puts ci.console
|
156
|
-
puts red("Automated tests failed!")
|
157
|
-
exit 1
|
158
|
-
end
|
159
|
-
|
160
|
-
else
|
161
|
-
puts red("No CI found for #{project_name}!")
|
162
|
-
puts "Re-run with --skip-ci to bypass CI, if you absolutely must, and know what you're doing."
|
163
|
-
exit 1
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
desc "open [server=production]", "opens the url in the web browser."
|
168
|
-
def open server=:production
|
169
|
-
exec "xdg-open #{config[server].ping.first}"
|
170
|
-
end
|
171
|
-
|
172
|
-
option :home, type: :boolean
|
173
|
-
desc "ssh [to=production]", "logs into the specified server via SSH"
|
174
|
-
def ssh to=:production
|
175
|
-
config[to].exec! "exec $SHELL -l", home: options[:home]
|
176
|
-
end
|
177
|
-
|
178
|
-
desc "install", "copies bin/setup and bin/ci scripts into current project."
|
179
|
-
def install
|
180
|
-
install_files_path = File.expand_path(File.join(__dir__, "../../install_files/*"))
|
181
|
-
system "cp -R #{install_files_path} bin/"
|
182
|
-
github_files_path = File.expand_path(File.join(__dir__, "../../install_files/.github"))
|
183
|
-
system "cp -R #{github_files_path} ./"
|
184
|
-
end
|
185
|
-
|
186
|
-
desc "provision [ssh_url]", "takes an ssh url to a raw ubuntu 22.04 install, and readies it in the shape of :production"
|
187
|
-
def provision ssh_url
|
188
|
-
Provision.call(config, ssh_url.dup) # dup unfreezes the string for later mutation
|
189
|
-
end
|
190
|
-
|
191
|
-
desc "setup", "installs app in nginx"
|
192
|
-
def setup
|
193
|
-
path = "/etc/nginx/sites-available/#{project_name}"
|
194
|
-
dest_path = path.sub("sites-available", "sites-enabled")
|
195
|
-
server_name = case ENV["RAILS_ENV"]
|
196
|
-
when "production"
|
197
|
-
(config[:production].ping.map do |str|
|
198
|
-
"*.#{URI.parse(str).host}"
|
199
|
-
end + ["_"]).join(" ")
|
200
|
-
when "staging" then "#{project_name}.botandrose.com"
|
201
|
-
else "#{project_name}.localhost"
|
202
|
-
end
|
203
|
-
|
204
|
-
system "sudo tee #{path} >/dev/null <<-EOF
|
205
|
-
server {
|
206
|
-
listen 80;
|
207
|
-
server_name #{server_name};
|
208
|
-
|
209
|
-
root #{Dir.pwd}/public;
|
210
|
-
passenger_enabled on;
|
211
|
-
|
212
|
-
location ~* \\.(ico|css|js|gif|jp?g|png|webp) {
|
213
|
-
access_log off;
|
214
|
-
if (\\$request_filename ~ \"-[0-9a-f]{32}\\.\") {
|
215
|
-
expires max;
|
216
|
-
add_header Cache-Control public;
|
217
|
-
}
|
218
|
-
}
|
219
|
-
gzip_static on;
|
220
|
-
}
|
221
|
-
EOF"
|
222
|
-
system "sudo ln -sf #{path} #{dest_path}" if !File.exist?(dest_path)
|
223
|
-
system "sudo service nginx restart"
|
224
|
-
end
|
225
|
-
|
226
|
-
desc "ping [server=production]", "hits the server over http to verify that its up."
|
227
|
-
def ping server=:production
|
228
|
-
server = config[server]
|
229
|
-
down_urls = Bard::Ping.call(config[server])
|
230
|
-
down_urls.each { |url| puts "#{url} is down!" }
|
231
|
-
exit 1 if down_urls.any?
|
232
|
-
end
|
233
|
-
|
234
|
-
# HACK: we don't use Thor::Base#run, so its okay to stomp on it here
|
235
|
-
original_verbose, $VERBOSE = $VERBOSE, nil
|
236
|
-
Thor::THOR_RESERVED_WORDS -= ["run"]
|
237
|
-
$VERBOSE = original_verbose
|
238
|
-
|
239
|
-
desc "run <command>", "run the given command on production"
|
240
|
-
def run *args
|
241
|
-
server = config[:production]
|
242
|
-
server.run! *args, verbose: true
|
243
|
-
end
|
244
|
-
|
245
|
-
desc "hurt <command>", "reruns a command until it fails"
|
246
|
-
def hurt *args
|
247
|
-
1.upto(Float::INFINITY) do |count|
|
248
|
-
puts "Running attempt #{count}"
|
249
|
-
system *args
|
250
|
-
unless $?.success?
|
251
|
-
puts "Ran #{count-1} times before failing"
|
252
|
-
break
|
253
|
-
end
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
desc "vim [branch=master]", "open all files that have changed since master"
|
258
|
-
def vim branch="master"
|
259
|
-
exec "vim -p `git diff #{branch} --name-only | grep -v sass$ | tac`"
|
14
|
+
{
|
15
|
+
data: "Data",
|
16
|
+
stage: "Stage",
|
17
|
+
deploy: "Deploy",
|
18
|
+
ci: "CI",
|
19
|
+
master_key: "MasterKey",
|
20
|
+
setup: "Setup",
|
21
|
+
run: "Run",
|
22
|
+
open: "Open",
|
23
|
+
ssh: "SSH",
|
24
|
+
install: "Install",
|
25
|
+
provision: "Provision",
|
26
|
+
ping: "Ping",
|
27
|
+
hurt: "Hurt",
|
28
|
+
vim: "Vim",
|
29
|
+
}.each do |command, klass|
|
30
|
+
require "bard/cli/#{command}"
|
31
|
+
include const_get(klass)
|
260
32
|
end
|
261
33
|
|
262
34
|
def self.exit_on_failure? = true
|
@@ -273,6 +45,9 @@ EOF"
|
|
273
45
|
|
274
46
|
def run!(...)
|
275
47
|
Bard::Command.run!(...)
|
48
|
+
rescue Bard::Command::Error => e
|
49
|
+
puts red("!!! ") + "Running command failed: #{yellow(e.message)}"
|
50
|
+
exit 1
|
276
51
|
end
|
277
52
|
end
|
278
53
|
end
|
data/lib/bard/command.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
+
require "open3"
|
2
|
+
|
1
3
|
module Bard
|
2
4
|
class Command < Struct.new(:command, :on, :home)
|
5
|
+
class Error < RuntimeError; end
|
6
|
+
|
3
7
|
def self.run! command, on: :local, home: false, verbose: false, quiet: false
|
4
8
|
new(command, on, home).run! verbose:, quiet:
|
5
9
|
end
|
@@ -14,9 +18,7 @@ module Bard
|
|
14
18
|
|
15
19
|
def run! verbose: false, quiet: false
|
16
20
|
if !run(verbose:, quiet:)
|
17
|
-
raise
|
18
|
-
# puts red("!!! ") + "Running command failed: #{yellow(command)}"
|
19
|
-
# exit 1
|
21
|
+
raise Error.new(full_command)
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
@@ -49,7 +51,6 @@ module Bard
|
|
49
51
|
end
|
50
52
|
|
51
53
|
def remote_command quiet: false
|
52
|
-
uri = on.ssh_uri
|
53
54
|
ssh_key = on.ssh_key ? "-i #{on.ssh_key} " : ""
|
54
55
|
cmd = command
|
55
56
|
if on.env
|
@@ -58,10 +59,11 @@ module Bard
|
|
58
59
|
unless home
|
59
60
|
cmd = "cd #{on.path} && #{cmd}"
|
60
61
|
end
|
61
|
-
|
62
|
+
uri = on.ssh_uri
|
63
|
+
cmd = "ssh -tt #{ssh_key} -p#{uri.port} #{uri.user}@#{uri.host} '#{cmd}'"
|
62
64
|
if on.gateway
|
63
65
|
uri = on.ssh_uri(:gateway)
|
64
|
-
cmd = "ssh -tt
|
66
|
+
cmd = "ssh -tt -p#{uri.port} #{uri.user}@#{uri.host} \"#{cmd}\""
|
65
67
|
end
|
66
68
|
cmd += " 2>&1" if quiet
|
67
69
|
cmd
|
data/lib/bard/config.rb
CHANGED
@@ -12,13 +12,6 @@ module Bard
|
|
12
12
|
"./",
|
13
13
|
false,
|
14
14
|
),
|
15
|
-
theia: Server.new(
|
16
|
-
project_name,
|
17
|
-
:theia,
|
18
|
-
"gubito@gubs.pagekite.me",
|
19
|
-
"Sites/#{project_name}",
|
20
|
-
false,
|
21
|
-
),
|
22
15
|
gubs: Server.new(
|
23
16
|
project_name,
|
24
17
|
:gubs,
|
@@ -40,7 +33,7 @@ module Bard
|
|
40
33
|
),
|
41
34
|
}
|
42
35
|
if path && File.exist?(path)
|
43
|
-
source = File.read(
|
36
|
+
source = File.read(path)
|
44
37
|
end
|
45
38
|
if source
|
46
39
|
instance_eval source
|
@@ -51,9 +44,7 @@ module Bard
|
|
51
44
|
|
52
45
|
def server key, &block
|
53
46
|
key = key.to_sym
|
54
|
-
@servers[key]
|
55
|
-
@servers[key].instance_eval &block if block_given?
|
56
|
-
@servers[key]
|
47
|
+
@servers[key] = Server.define(project_name, key, &block)
|
57
48
|
end
|
58
49
|
|
59
50
|
def [] key
|
data/lib/bard/copy.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require "uri"
|
2
|
+
require "bard/command"
|
3
|
+
|
1
4
|
module Bard
|
2
5
|
class Copy < Struct.new(:path, :from, :to, :verbose)
|
3
6
|
def self.file path, from:, to:, verbose: false
|
@@ -19,33 +22,20 @@ module Bard
|
|
19
22
|
end
|
20
23
|
|
21
24
|
def scp_using_local direction, server
|
22
|
-
|
23
|
-
port = uri.port ? "-p#{uri.port}" : ""
|
24
|
-
gateway = server.gateway ? "-oProxyCommand='ssh #{port} #{uri.user}@#{uri.host} -W %h:%p'" : ""
|
25
|
+
gateway = server.gateway ? "-oProxyCommand='ssh #{server.ssh_uri(:gateway)} -W %h:%p'" : ""
|
25
26
|
|
26
27
|
ssh_key = server.ssh_key ? "-i #{server.ssh_key}" : ""
|
27
28
|
|
28
|
-
|
29
|
-
port = uri.port ? "-P#{uri.port}" : ""
|
30
|
-
from_and_to = [path, "#{uri.user}@#{uri.host}:#{server.path}/#{path}"]
|
31
|
-
|
29
|
+
from_and_to = [path, server.scp_uri(path)]
|
32
30
|
from_and_to.reverse! if direction == :from
|
33
|
-
command = "scp #{gateway} #{ssh_key} #{port} #{from_and_to.join(" ")}"
|
34
31
|
|
32
|
+
command = ["scp", gateway, ssh_key, *from_and_to].join(" ")
|
35
33
|
Bard::Command.run! command, verbose: verbose
|
36
34
|
end
|
37
35
|
|
38
36
|
def scp_as_mediator
|
39
37
|
raise NotImplementedError if from.gateway || to.gateway || from.ssh_key || to.ssh_key
|
40
|
-
|
41
|
-
from_uri = URI.parse("ssh://#{from.ssh}")
|
42
|
-
from_str = "scp://#{from_uri.user}@#{from_uri.host}:#{from_uri.port || 22}/#{from.path}/#{path}"
|
43
|
-
|
44
|
-
to_uri = URI.parse("ssh://#{to.ssh}")
|
45
|
-
to_str = "scp://#{to_uri.user}@#{to_uri.host}:#{to_uri.port || 22}/#{to.path}/#{path}"
|
46
|
-
|
47
|
-
command = "scp -o ForwardAgent=yes #{from_str} #{to_str}"
|
48
|
-
|
38
|
+
command = "scp -o ForwardAgent=yes #{from.scp_uri(path)} #{to.scp_uri(path)}"
|
49
39
|
Bard::Command.run! command, verbose: verbose
|
50
40
|
end
|
51
41
|
|
@@ -55,46 +45,31 @@ module Bard
|
|
55
45
|
elsif to.key == :local
|
56
46
|
rsync_using_local :from, from
|
57
47
|
else
|
58
|
-
rsync_as_mediator
|
48
|
+
rsync_as_mediator
|
59
49
|
end
|
60
50
|
end
|
61
51
|
|
62
52
|
def rsync_using_local direction, server
|
63
|
-
|
64
|
-
port = uri.port ? "-p#{uri.port}" : ""
|
65
|
-
gateway = server.gateway ? "-oProxyCommand=\"ssh #{port} #{uri.user}@#{uri.host} -W %h:%p\"" : ""
|
53
|
+
gateway = server.gateway ? "-oProxyCommand=\"ssh #{server.ssh_uri(:gateway)} -W %h:%p\"" : ""
|
66
54
|
|
67
55
|
ssh_key = server.ssh_key ? "-i #{server.ssh_key}" : ""
|
68
|
-
|
69
|
-
port = uri.port ? "-p#{uri.port}" : ""
|
70
|
-
ssh = "-e'ssh #{ssh_key} #{port} #{gateway}'"
|
56
|
+
ssh = "-e'ssh #{gateway} -p#{server.ssh_uri.port || 22}'"
|
71
57
|
|
72
|
-
|
73
|
-
dest_path = "./#{dest_path}"
|
74
|
-
from_and_to = [dest_path, "#{uri.user}@#{uri.host}:#{server.path}/#{path}"]
|
58
|
+
from_and_to = ["./#{path}", server.rsync_uri(path)]
|
75
59
|
from_and_to.reverse! if direction == :from
|
76
60
|
from_and_to[-1].sub! %r(/[^/]+$), '/'
|
77
61
|
|
78
62
|
command = "rsync #{ssh} --delete --info=progress2 -az #{from_and_to.join(" ")}"
|
79
|
-
|
80
63
|
Bard::Command.run! command, verbose: verbose
|
81
64
|
end
|
82
65
|
|
83
|
-
def rsync_as_mediator
|
66
|
+
def rsync_as_mediator
|
84
67
|
raise NotImplementedError if from.gateway || to.gateway || from.ssh_key || to.ssh_key
|
85
68
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
from_uri = URI.parse("ssh://#{from.ssh}")
|
90
|
-
from_str = "-p#{from_uri.port || 22} #{from_uri.user}@#{from_uri.host}"
|
91
|
-
|
92
|
-
to_uri = URI.parse("ssh://#{to.ssh}")
|
93
|
-
to_str = "#{to_uri.user}@#{to_uri.host}:#{to.path}/#{path}"
|
94
|
-
to_str.sub! %r(/[^/]+$), '/'
|
95
|
-
|
96
|
-
command = %(ssh -A #{from_str} 'rsync -e \"ssh -A -p#{to_uri.port || 22} -o StrictHostKeyChecking=no\" --delete --info=progress2 -az #{from.path}/#{path} #{to_str}')
|
69
|
+
from_str = "-p#{from.ssh_uri.port || 22} #{from.ssh_uri.user}@#{from.ssh_uri.host}"
|
70
|
+
to_str = to.rsync_uri(path).sub(%r(/[^/]+$), '/')
|
97
71
|
|
72
|
+
command = %(ssh -A #{from_str} 'rsync -e \"ssh -A -p#{to.ssh_uri.port || 22} -o StrictHostKeyChecking=no\" --delete --info=progress2 -az #{from.path}/#{path} #{to_str}')
|
98
73
|
Bard::Command.run! command, verbose: verbose
|
99
74
|
end
|
100
75
|
end
|
data/lib/bard/git.rb
CHANGED
data/lib/bard/ping.rb
CHANGED
data/lib/bard/provision/ssh.rb
CHANGED
data/lib/bard/provision.rb
CHANGED
@@ -3,17 +3,10 @@ module Bard
|
|
3
3
|
def self.call(...) = new(...).call
|
4
4
|
|
5
5
|
def call
|
6
|
-
SSH.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
Repo.call(*values)
|
11
|
-
MasterKey.call(*values)
|
12
|
-
RVM.call(*values)
|
13
|
-
App.call(*values)
|
14
|
-
Passenger.call(*values)
|
15
|
-
Data.call(*values)
|
16
|
-
HTTP.call(*values)
|
6
|
+
%w[SSH User Apt MySQL Repo MasterKey RVM App Passenger Data HTTP].each do |step|
|
7
|
+
require "bard/provision/#{step.downcase}"
|
8
|
+
self.class.const_get(step).call(*values)
|
9
|
+
end
|
17
10
|
end
|
18
11
|
|
19
12
|
private
|
@@ -28,15 +21,3 @@ module Bard
|
|
28
21
|
end
|
29
22
|
end
|
30
23
|
|
31
|
-
require "bard/provision/ssh"
|
32
|
-
require "bard/provision/user"
|
33
|
-
require "bard/provision/apt"
|
34
|
-
require "bard/provision/mysql"
|
35
|
-
require "bard/provision/repo"
|
36
|
-
require "bard/provision/master_key"
|
37
|
-
require "bard/provision/rvm"
|
38
|
-
require "bard/provision/app"
|
39
|
-
require "bard/provision/passenger"
|
40
|
-
require "bard/provision/data"
|
41
|
-
require "bard/provision/http"
|
42
|
-
|
data/lib/bard/server.rb
CHANGED
@@ -3,7 +3,13 @@ require "bard/command"
|
|
3
3
|
require "bard/copy"
|
4
4
|
|
5
5
|
module Bard
|
6
|
-
class Server < Struct.new(:project_name, :key, :ssh, :path, :ping, :gateway, :ssh_key, :env
|
6
|
+
class Server < Struct.new(:project_name, :key, :ssh, :path, :ping, :gateway, :ssh_key, :env)
|
7
|
+
def self.define project_name, key, &block
|
8
|
+
new(project_name, key).tap do |server|
|
9
|
+
server.instance_eval &block
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
def self.setting *fields
|
8
14
|
fields.each do |field|
|
9
15
|
define_method field do |*args|
|
@@ -18,20 +24,19 @@ module Bard
|
|
18
24
|
end
|
19
25
|
end
|
20
26
|
|
21
|
-
setting :ssh, :path, :ping, :gateway, :ssh_key, :env
|
27
|
+
setting :ssh, :path, :ping, :gateway, :ssh_key, :env
|
22
28
|
|
23
29
|
def ping(*args)
|
24
30
|
if args.length == 0
|
25
|
-
(super() || [nil]).map(&method(:normalize_ping))
|
31
|
+
(super() || [nil]).map(&method(:normalize_ping)).flatten
|
26
32
|
else
|
27
33
|
self.ping = args
|
28
34
|
end
|
29
35
|
end
|
30
36
|
|
31
37
|
private def normalize_ping value
|
32
|
-
return
|
33
|
-
|
34
|
-
normalized = "https://#{uri.host}" # default if none specified
|
38
|
+
return [] if value == false
|
39
|
+
normalized = "https://#{ssh_uri.host}" # default if none specified
|
35
40
|
if value =~ %r{^/}
|
36
41
|
normalized += value
|
37
42
|
elsif value.to_s.length > 0
|
@@ -55,7 +60,24 @@ module Bard
|
|
55
60
|
|
56
61
|
def ssh_uri which=:ssh
|
57
62
|
value = send(which)
|
58
|
-
URI
|
63
|
+
URI("ssh://#{value}")
|
64
|
+
end
|
65
|
+
|
66
|
+
def scp_uri file_path=nil
|
67
|
+
ssh_uri.dup.tap do |uri|
|
68
|
+
uri.scheme = "scp"
|
69
|
+
uri.path = "/#{path}"
|
70
|
+
uri.path += "/#{file_path}" if file_path
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def rsync_uri file_path=nil
|
75
|
+
ssh_uri.dup.tap do |uri|
|
76
|
+
uri.scheme = nil
|
77
|
+
uri.port = nil
|
78
|
+
uri.path = ":#{path}"
|
79
|
+
uri.path += "/#{file_path}" if file_path
|
80
|
+
end.to_s[2..]
|
59
81
|
end
|
60
82
|
|
61
83
|
def with(attrs)
|
data/lib/bard/version.rb
CHANGED