bard 1.9.6 → 2.0.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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -2
  3. data/CLAUDE.md +1 -1
  4. data/PLUGINS.md +31 -46
  5. data/bard.gemspec +2 -1
  6. data/features/ci.feature +1 -0
  7. data/features/data.feature +1 -0
  8. data/features/deploy.feature +1 -0
  9. data/features/deploy_git_workflow.feature +1 -0
  10. data/features/run.feature +1 -0
  11. data/features/step_definitions/bard_steps.rb +1 -0
  12. data/features/support/test_server.rb +3 -3
  13. data/lib/bard/cli.rb +9 -28
  14. data/lib/bard/command.rb +9 -88
  15. data/lib/bard/config.rb +38 -177
  16. data/lib/bard/copy.rb +28 -82
  17. data/lib/bard/plugins/data.rb +56 -0
  18. data/lib/bard/{ci → plugins/deploy/ci}/github_actions.rb +2 -2
  19. data/lib/bard/{ci → plugins/deploy/ci}/jenkins.rb +1 -1
  20. data/lib/bard/{ci → plugins/deploy/ci}/local.rb +1 -1
  21. data/lib/bard/{ci → plugins/deploy/ci}/runner.rb +3 -3
  22. data/lib/bard/{ci.rb → plugins/deploy/ci.rb} +1 -1
  23. data/lib/bard/plugins/deploy/ssh_strategy.rb +27 -0
  24. data/lib/bard/{deploy_strategy.rb → plugins/deploy/strategy.rb} +1 -4
  25. data/lib/bard/plugins/deploy.rb +240 -0
  26. data/lib/bard/{git.rb → plugins/git.rb} +6 -3
  27. data/lib/bard/{github.rb → plugins/github.rb} +2 -2
  28. data/lib/bard/{deploy_strategy/github_pages.rb → plugins/github_pages/strategy.rb} +3 -4
  29. data/lib/bard/plugins/github_pages.rb +11 -15
  30. data/lib/bard/plugins/hurt.rb +12 -4
  31. data/{install_files → lib/bard/plugins/install}/.github/dependabot.yml +2 -1
  32. data/{install_files → lib/bard/plugins/install}/.github/workflows/cache-ci.yml +1 -1
  33. data/{install_files → lib/bard/plugins/install}/.github/workflows/ci.yml +2 -2
  34. data/lib/bard/plugins/install.rb +7 -3
  35. data/lib/bard/plugins/open.rb +20 -0
  36. data/lib/bard/{ping.rb → plugins/ping/check.rb} +4 -4
  37. data/lib/bard/plugins/ping/target_methods.rb +23 -0
  38. data/lib/bard/plugins/ping.rb +8 -4
  39. data/lib/bard/plugins/run.rb +19 -0
  40. data/lib/bard/plugins/setup.rb +54 -0
  41. data/lib/bard/plugins/ssh/connection.rb +75 -0
  42. data/lib/bard/plugins/ssh/copy.rb +95 -0
  43. data/lib/bard/{ssh_server.rb → plugins/ssh/server.rb} +10 -42
  44. data/lib/bard/plugins/ssh/target_methods.rb +20 -0
  45. data/lib/bard/plugins/ssh.rb +10 -0
  46. data/lib/bard/plugins/url/target_methods.rb +23 -0
  47. data/lib/bard/plugins/url.rb +1 -0
  48. data/lib/bard/plugins/vim.rb +5 -4
  49. data/lib/bard/retryable.rb +25 -0
  50. data/lib/bard/target.rb +21 -230
  51. data/lib/bard/version.rb +1 -1
  52. data/lib/bard.rb +1 -3
  53. data/spec/acceptance/docker/Dockerfile +1 -1
  54. data/spec/bard/capability_spec.rb +8 -50
  55. data/spec/bard/ci/github_actions_spec.rb +1 -1
  56. data/spec/bard/ci/jenkins_spec.rb +1 -1
  57. data/spec/bard/ci/runner_spec.rb +3 -3
  58. data/spec/bard/ci_spec.rb +1 -1
  59. data/spec/bard/cli/ci_spec.rb +4 -23
  60. data/spec/bard/cli/data_spec.rb +7 -26
  61. data/spec/bard/cli/deploy_spec.rb +43 -40
  62. data/spec/bard/cli/hurt_spec.rb +2 -8
  63. data/spec/bard/cli/install_spec.rb +4 -10
  64. data/spec/bard/cli/master_key_spec.rb +5 -19
  65. data/spec/bard/cli/open_spec.rb +17 -35
  66. data/spec/bard/cli/ping_spec.rb +10 -25
  67. data/spec/bard/cli/run_spec.rb +10 -23
  68. data/spec/bard/cli/setup_spec.rb +10 -27
  69. data/spec/bard/cli/ssh_spec.rb +10 -25
  70. data/spec/bard/cli/stage_spec.rb +17 -32
  71. data/spec/bard/cli/vim_spec.rb +5 -11
  72. data/spec/bard/command_spec.rb +1 -10
  73. data/spec/bard/config_spec.rb +68 -116
  74. data/spec/bard/copy_spec.rb +54 -18
  75. data/spec/bard/deploy_strategy/ssh_spec.rb +65 -7
  76. data/spec/bard/deploy_strategy_spec.rb +1 -1
  77. data/spec/bard/dynamic_dsl_spec.rb +18 -98
  78. data/spec/bard/git_spec.rb +9 -5
  79. data/spec/bard/github_spec.rb +1 -1
  80. data/spec/bard/ping_spec.rb +5 -5
  81. data/spec/bard/ssh_copy_spec.rb +44 -0
  82. data/spec/bard/ssh_server_spec.rb +1 -98
  83. data/spec/bard/target_spec.rb +61 -108
  84. metadata +50 -124
  85. data/lib/bard/ci/retryable.rb +0 -27
  86. data/lib/bard/cli/ci.rb +0 -73
  87. data/lib/bard/cli/command.rb +0 -26
  88. data/lib/bard/cli/data.rb +0 -45
  89. data/lib/bard/cli/deploy.rb +0 -116
  90. data/lib/bard/cli/hurt.rb +0 -15
  91. data/lib/bard/cli/install.rb +0 -11
  92. data/lib/bard/cli/master_key.rb +0 -17
  93. data/lib/bard/cli/new.rb +0 -101
  94. data/lib/bard/cli/new_rails_template.rb +0 -197
  95. data/lib/bard/cli/open.rb +0 -18
  96. data/lib/bard/cli/ping.rb +0 -12
  97. data/lib/bard/cli/provision.rb +0 -34
  98. data/lib/bard/cli/run.rb +0 -26
  99. data/lib/bard/cli/setup.rb +0 -56
  100. data/lib/bard/cli/ssh.rb +0 -14
  101. data/lib/bard/cli/stage.rb +0 -35
  102. data/lib/bard/cli/vim.rb +0 -8
  103. data/lib/bard/default_config.rb +0 -35
  104. data/lib/bard/deploy_strategy/ssh.rb +0 -19
  105. data/lib/bard/deprecation.rb +0 -19
  106. data/lib/bard/github_pages.rb +0 -134
  107. data/lib/bard/plugin.rb +0 -100
  108. data/lib/bard/plugins/backup.rb +0 -19
  109. data/lib/bard/plugins/jenkins.rb +0 -6
  110. data/lib/bard/plugins/new.rb +0 -5
  111. data/lib/bard/plugins/provision.rb +0 -5
  112. data/lib/bard/provision/app.rb +0 -10
  113. data/lib/bard/provision/apt.rb +0 -16
  114. data/lib/bard/provision/authorizedkeys.rb +0 -25
  115. data/lib/bard/provision/data.rb +0 -27
  116. data/lib/bard/provision/deploy.rb +0 -10
  117. data/lib/bard/provision/http.rb +0 -16
  118. data/lib/bard/provision/logrotation.rb +0 -30
  119. data/lib/bard/provision/masterkey.rb +0 -18
  120. data/lib/bard/provision/mysql.rb +0 -22
  121. data/lib/bard/provision/passenger.rb +0 -37
  122. data/lib/bard/provision/repo.rb +0 -72
  123. data/lib/bard/provision/rvm.rb +0 -22
  124. data/lib/bard/provision/ssh.rb +0 -79
  125. data/lib/bard/provision/swapfile.rb +0 -23
  126. data/lib/bard/provision/user.rb +0 -42
  127. data/lib/bard/provision.rb +0 -16
  128. data/lib/bard/server.rb +0 -160
  129. data/spec/bard/cli/command_spec.rb +0 -50
  130. data/spec/bard/cli/new_spec.rb +0 -73
  131. data/spec/bard/cli/provision_spec.rb +0 -42
  132. data/spec/bard/deprecation_spec.rb +0 -281
  133. data/spec/bard/github_pages_spec.rb +0 -143
  134. data/spec/bard/plugin_spec.rb +0 -79
  135. data/spec/bard/provision/app_spec.rb +0 -33
  136. data/spec/bard/provision/apt_spec.rb +0 -39
  137. data/spec/bard/provision/authorizedkeys_spec.rb +0 -40
  138. data/spec/bard/provision/data_spec.rb +0 -54
  139. data/spec/bard/provision/deploy_spec.rb +0 -33
  140. data/spec/bard/provision/http_spec.rb +0 -57
  141. data/spec/bard/provision/logrotation_spec.rb +0 -34
  142. data/spec/bard/provision/masterkey_spec.rb +0 -63
  143. data/spec/bard/provision/mysql_spec.rb +0 -55
  144. data/spec/bard/provision/passenger_spec.rb +0 -81
  145. data/spec/bard/provision/repo_spec.rb +0 -208
  146. data/spec/bard/provision/rvm_spec.rb +0 -49
  147. data/spec/bard/provision/ssh_spec.rb +0 -242
  148. data/spec/bard/provision/swapfile_spec.rb +0 -33
  149. data/spec/bard/provision/user_spec.rb +0 -103
  150. data/spec/bard/provision_spec.rb +0 -28
  151. data/spec/bard/server_spec.rb +0 -127
  152. /data/lib/bard/{ci → plugins/deploy/ci}/state.rb +0 -0
  153. /data/{install_files → lib/bard/plugins/install}/apt_dependencies.rb +0 -0
  154. /data/{install_files → lib/bard/plugins/install}/ci +0 -0
  155. /data/{install_files → lib/bard/plugins/install}/setup +0 -0
  156. /data/{install_files → lib/bard/plugins/install}/specified_bundler.rb +0 -0
  157. /data/{install_files → lib/bard/plugins/install}/specified_ruby.rb +0 -0
@@ -1,23 +0,0 @@
1
- # setup swapfile
2
-
3
- class Bard::Provision::Swapfile < Bard::Provision
4
- def call
5
- print "Swapfile:"
6
-
7
- provision_server.run! <<~SH, home: true
8
- if [ ! -f /swapfile ]; then
9
- sudo fallocate -l $(grep MemTotal /proc/meminfo | awk '{print $2}')K /swapfile
10
- fi
11
- sudo chmod 600 /swapfile
12
- sudo swapon --show | grep -q '/swapfile' || sudo mkswap /swapfile
13
- sudo swapon --show | grep -q '/swapfile' || sudo swapon /swapfile
14
- grep -q '/swapfile none swap sw 0 0' /etc/fstab || echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
15
- SH
16
-
17
- provision_server.run! "sudo swapon --show | grep -q /swapfile", home: true
18
-
19
- puts " ✓"
20
- end
21
- end
22
-
23
-
@@ -1,42 +0,0 @@
1
- # rename user
2
-
3
- class Bard::Provision::User < Bard::Provision
4
- def call
5
- print "User:"
6
-
7
- if !ssh_with_user?(provision_server.ssh_uri, user: new_user)
8
- if !ssh_with_user?(provision_server.ssh_uri)
9
- raise "can't ssh in with user #{new_user} or #{old_user}"
10
- end
11
- print " Adding user #{new_user},"
12
- provision_server.run! [
13
- "sudo useradd -m -s /bin/bash #{new_user}",
14
- "sudo usermod -aG sudo #{new_user}",
15
- "echo \"#{new_user} ALL=(ALL) NOPASSWD:ALL\" | sudo tee -a /etc/sudoers",
16
- "sudo mkdir -p ~#{new_user}/.ssh",
17
- "sudo cp ~/.ssh/authorized_keys ~#{new_user}/.ssh/authorized_keys",
18
- "sudo chown -R #{new_user}:#{new_user} ~#{new_user}/.ssh",
19
- "sudo chmod +rx ~#{new_user}", # so nginx and passenger can read it
20
- ].join("; "), home: true
21
- end
22
-
23
- # provision with new user from now on
24
- ssh_url.gsub!("#{old_user}@", "#{new_user}@")
25
- puts " ✓"
26
- end
27
-
28
- private
29
-
30
- def new_user
31
- server.ssh_uri.user
32
- end
33
-
34
- def old_user
35
- provision_server.ssh_uri.user
36
- end
37
-
38
- def ssh_with_user? ssh_uri, user: ssh_uri.user
39
- system "ssh -o ConnectTimeout=2 -p#{ssh_uri.port || 22} #{user}@#{ssh_uri.host} : >/dev/null 2>&1"
40
- end
41
- end
42
-
@@ -1,16 +0,0 @@
1
- module Bard
2
- class Provision < Struct.new(:config, :ssh_url)
3
- def self.call(...) = new(...).call
4
-
5
- private
6
-
7
- def server
8
- config[:production]
9
- end
10
-
11
- def provision_server
12
- server.with(ssh: ssh_url)
13
- end
14
- end
15
- end
16
-
data/lib/bard/server.rb DELETED
@@ -1,160 +0,0 @@
1
- require "uri"
2
- require "bard/command"
3
- require "bard/copy"
4
- require "bard/deprecation"
5
-
6
- module Bard
7
- class Server < Struct.new(:project_name, :key, :ssh, :path, :ping, :gateway, :ssh_key, :env, :github_pages)
8
- def self.define project_name, key, &block
9
- new(project_name, key).tap do |server|
10
- server.instance_eval &block
11
- end
12
- end
13
-
14
- def self.setting *fields
15
- fields.each do |field|
16
- define_method field do |*args|
17
- if args.length == 1
18
- send :"#{field}=", args.first
19
- elsif args.length == 0
20
- super()
21
- else
22
- raise ArgumentError
23
- end
24
- end
25
- end
26
- end
27
-
28
- def self.setting_with_deprecation *fields, message:
29
- fields.each do |field|
30
- define_method field do |*args|
31
- if args.length == 1
32
- Deprecation.warn message
33
- send :"#{field}=", args.first
34
- elsif args.length == 0
35
- super()
36
- else
37
- raise ArgumentError
38
- end
39
- end
40
- end
41
- end
42
-
43
- setting :ssh, :ping, :github_pages
44
- setting_with_deprecation :gateway, :ssh_key, :env,
45
- message: "Separate SSH options are deprecated; pass as keyword arguments to `ssh` instead, e.g., `ssh \"user@host\", path: \"/app\"` (will be removed in v2.0)"
46
-
47
- def ping(*args)
48
- if args.length == 0
49
- (super() || [nil]).map(&method(:normalize_ping)).flatten
50
- else
51
- self.ping = args
52
- end
53
- end
54
-
55
- private def normalize_ping value
56
- return [] if value == false
57
- normalized = "https://#{ssh_uri.host}" # default if none specified
58
- if value =~ %r{^/}
59
- normalized += value
60
- elsif value.to_s.length > 0
61
- normalized = value
62
- end
63
- if normalized !~ /^http/
64
- normalized = "https://#{normalized}"
65
- end
66
- normalized
67
- end
68
-
69
- def path(*args)
70
- if args.length == 1
71
- Deprecation.warn "Separate SSH options are deprecated; pass as keyword arguments to `ssh` instead, e.g., `ssh \"user@host\", path: \"/app\"` (will be removed in v2.0)"
72
- self.path = args.first
73
- elsif args.length == 0
74
- super() || project_name
75
- else
76
- raise ArgumentError
77
- end
78
- end
79
-
80
- def strategy(name)
81
- Deprecation.warn "`strategy` is deprecated; use the strategy method directly, e.g., `jets \"url\"` instead of `strategy :jets` (will be removed in v2.0)"
82
- @strategy = name
83
- end
84
-
85
- def option(key, value)
86
- Deprecation.warn "`option` is deprecated; pass options as keyword arguments to the strategy method, e.g., `jets \"url\", run_tests: true` (will be removed in v2.0)"
87
- @options ||= {}
88
- @options[key] = value
89
- end
90
-
91
- def strategy_name
92
- @strategy
93
- end
94
-
95
- def strategy_options
96
- @options || {}
97
- end
98
-
99
- def ssh_uri which=:ssh
100
- value = send(which)
101
- URI("ssh://#{value}")
102
- end
103
-
104
- def port
105
- ssh_uri.port || 22
106
- end
107
-
108
- def scp_uri file_path=nil
109
- ssh_uri.dup.tap do |uri|
110
- uri.scheme = "scp"
111
- uri.path = "/#{path}"
112
- uri.path += "/#{file_path}" if file_path
113
- end
114
- end
115
-
116
- def rsync_uri file_path=nil
117
- str = ssh_uri.dup.tap do |uri|
118
- uri.send :set_scheme, nil
119
- uri.send :set_port, nil
120
- end.to_s[2..]
121
- str += ":#{path}"
122
- str += "/#{file_path}" if file_path
123
- str
124
- end
125
-
126
- def with(attrs)
127
- dup.tap do |s|
128
- attrs.each do |key, value|
129
- s.send key, value
130
- end
131
- end
132
- end
133
-
134
- def to_sym
135
- key
136
- end
137
-
138
- def run! command, home: false, verbose: false, quiet: false, capture: false
139
- result = Bard::Command.run!(command, on: self, home:, verbose:, quiet:)
140
- result if capture
141
- end
142
-
143
- def run command, home: false, verbose: false, quiet: false
144
- Bard::Command.run command, on: self, home:, verbose:, quiet:
145
- end
146
-
147
- def exec! command, home: false
148
- Bard::Command.exec! command, on: self, home:
149
- end
150
-
151
- def copy_file path, to:, verbose: false
152
- Bard::Copy.file path, from: self, to:, verbose:
153
- end
154
-
155
- def copy_dir path, to:, verbose: false
156
- Bard::Copy.dir path, from: self, to:, verbose:
157
- end
158
- end
159
- end
160
-
@@ -1,50 +0,0 @@
1
- require "spec_helper"
2
- require "bard/cli"
3
- require "bard/cli/command"
4
-
5
- class TestCommand < Bard::CLI::Command
6
- desc "test_command", "test command description"
7
- option :verbose, type: :boolean
8
-
9
- def test_command
10
- "executed"
11
- end
12
- end
13
-
14
- describe Bard::CLI::Command do
15
- let(:cli_mock) { double("cli") }
16
- let(:command) { TestCommand.new(cli_mock) }
17
-
18
- describe ".desc" do
19
- it "sets command and description" do
20
- expect(TestCommand.instance_variable_get(:@command)).to eq("test_command")
21
- expect(TestCommand.instance_variable_get(:@description)).to eq("test command description")
22
- end
23
- end
24
-
25
- describe ".option" do
26
- it "sets option arguments" do
27
- expect(TestCommand.instance_variable_get(:@option_args)).to eq([:verbose])
28
- expect(TestCommand.instance_variable_get(:@option_kwargs)).to eq({type: :boolean})
29
- end
30
- end
31
-
32
- describe ".setup" do
33
- let(:cli_double) { double("cli") }
34
-
35
- it "sets up the command on the CLI class" do
36
- expect(cli_double).to receive(:desc).with("test_command", "test command description")
37
- expect(cli_double).to receive(:option).with(:verbose, type: :boolean)
38
- expect(cli_double).to receive(:define_method)
39
-
40
- TestCommand.setup(cli_double)
41
- end
42
- end
43
-
44
- describe "delegation" do
45
- it "should delegate to the wrapped object" do
46
- allow(cli_mock).to receive(:some_method).and_return("delegated")
47
- expect(command.some_method).to eq("delegated")
48
- end
49
- end
50
- end
@@ -1,73 +0,0 @@
1
- require "spec_helper"
2
- require "bard/cli"
3
- require "bard/cli/new"
4
-
5
- describe Bard::CLI::New do
6
- let(:new_cli) { Bard::CLI::New.new(double("cli")) }
7
-
8
- before do
9
- allow(new_cli).to receive(:puts)
10
- allow(new_cli).to receive(:exit)
11
- allow(new_cli).to receive(:run!)
12
- allow(new_cli).to receive(:green).and_return("")
13
- allow(new_cli).to receive(:red).and_return("")
14
- allow(new_cli).to receive(:yellow).and_return("")
15
- allow(File).to receive(:read).and_return("master_key_content")
16
- end
17
-
18
- describe "#new" do
19
- context "with invalid project name" do
20
- before do
21
- allow(new_cli).to receive(:create_project)
22
- allow(new_cli).to receive(:push_to_github)
23
- allow(new_cli).to receive(:stage)
24
- end
25
-
26
- it "should reject names starting with uppercase" do
27
- expect(new_cli).to receive(:puts).with(/Invalid project name/)
28
- expect(new_cli).to receive(:exit).with(1)
29
-
30
- new_cli.new("InvalidProject")
31
- end
32
-
33
- it "should reject names with special characters" do
34
- expect(new_cli).to receive(:puts).with(/Invalid project name/)
35
- expect(new_cli).to receive(:exit).with(1)
36
-
37
- new_cli.new("invalid-project")
38
- end
39
-
40
- it "should reject names starting with numbers" do
41
- expect(new_cli).to receive(:puts).with(/Invalid project name/)
42
- expect(new_cli).to receive(:exit).with(1)
43
-
44
- new_cli.new("1invalidproject")
45
- end
46
- end
47
- end
48
-
49
- describe "#ruby_version" do
50
- it "returns the ruby version" do
51
- expect(new_cli.send(:ruby_version)).to eq("ruby-3.4.2")
52
- end
53
- end
54
-
55
- describe "#template_path" do
56
- it "returns the path to the rails template" do
57
- expect(new_cli.send(:template_path)).to match(/new_rails_template\.rb$/)
58
- end
59
- end
60
-
61
- describe "#install_and_extract_version" do
62
- it "correctly installs a gem and extracts its version", skip: !!ENV["CI"] do
63
- cmd = new_cli.send :build_bash_env do
64
- <<~SH
65
- #{new_cli.send(:build_gem_install, "bundler", "~> 2.0")}
66
- echo ${GEM_VERSION}
67
- SH
68
- end
69
- result = `#{cmd}`.strip
70
- expect(result).to match(/^2\.\d+\.\d+/)
71
- end
72
- end
73
- end
@@ -1,42 +0,0 @@
1
- require "spec_helper"
2
- require "bard/cli"
3
- require "bard/cli/provision"
4
-
5
- describe Bard::CLI::Provision do
6
- let(:config) { { production: double("production", ssh: "user@example.com") } }
7
- let(:provision_cli) { Bard::CLI::Provision.new(double("cli")) }
8
-
9
- before do
10
- allow(provision_cli).to receive(:config).and_return(config)
11
- allow(provision_cli).to receive(:options).and_return({ steps: ["SSH", "User"] })
12
- end
13
-
14
- describe "STEPS constant" do
15
- it "defines the provisioning steps" do
16
- expect(Bard::CLI::Provision::STEPS).to include("SSH", "User", "Apt", "MySQL", "Deploy")
17
- expect(Bard::CLI::Provision::STEPS).to be_a(Array)
18
- end
19
- end
20
-
21
- describe "#provision" do
22
- it "should run provision steps" do
23
- expect(Bard::Provision).to receive(:const_get).with("SSH").and_return(double("ssh_step", call: true))
24
- expect(Bard::Provision).to receive(:const_get).with("User").and_return(double("user_step", call: true))
25
-
26
- provision_cli.provision
27
- end
28
-
29
- it "should use production ssh by default" do
30
- allow(Bard::Provision).to receive(:const_get).and_return(double("step", call: true))
31
-
32
- provision_cli.provision
33
- end
34
-
35
- it "should accept custom ssh_url" do
36
- custom_ssh = "root@newserver.com"
37
- allow(Bard::Provision).to receive(:const_get).and_return(double("step", call: true))
38
-
39
- provision_cli.provision(custom_ssh)
40
- end
41
- end
42
- end
@@ -1,281 +0,0 @@
1
- require "bard/deprecation"
2
- require "bard/config"
3
- require "bard/server"
4
-
5
- describe Bard::Deprecation do
6
- before do
7
- Bard::Deprecation.reset!
8
- end
9
-
10
- describe ".warn" do
11
- it "outputs a deprecation warning to stderr" do
12
- expect {
13
- Bard::Deprecation.warn "test message"
14
- }.to output(/\[DEPRECATION\] test message/).to_stderr
15
- end
16
-
17
- it "includes the callsite location" do
18
- output = capture_stderr { Bard::Deprecation.warn "test message" }
19
- expect(output).to match(/called from.*deprecation_spec\.rb/)
20
- end
21
-
22
- it "only warns once per callsite" do
23
- output = capture_stderr do
24
- 3.times { Bard::Deprecation.warn "repeated message" }
25
- end
26
- expect(output.scan(/\[DEPRECATION\]/).count).to eq 1
27
- end
28
-
29
- it "warns separately for different callsites" do
30
- output = capture_stderr do
31
- Bard::Deprecation.warn "message 1"
32
- Bard::Deprecation.warn "message 2"
33
- end
34
- expect(output.scan(/\[DEPRECATION\]/).count).to eq 2
35
- end
36
- end
37
-
38
- describe ".reset!" do
39
- it "clears the warning cache" do
40
- capture_stderr { Bard::Deprecation.warn "test" }
41
- Bard::Deprecation.reset!
42
- output = capture_stderr { Bard::Deprecation.warn "test" }
43
- expect(output).to include("[DEPRECATION]")
44
- end
45
- end
46
-
47
- def capture_stderr
48
- original_stderr = $stderr
49
- $stderr = StringIO.new
50
- yield
51
- $stderr.string
52
- ensure
53
- $stderr = original_stderr
54
- end
55
- end
56
-
57
- describe "Deprecation warnings" do
58
- before do
59
- Bard::Deprecation.reset!
60
- end
61
-
62
- def capture_stderr
63
- original_stderr = $stderr
64
- $stderr = StringIO.new
65
- yield
66
- $stderr.string
67
- ensure
68
- $stderr = original_stderr
69
- end
70
-
71
- describe "Config#server" do
72
- it "warns when using server instead of target" do
73
- output = capture_stderr do
74
- Bard::Config.new("test", source: <<~SOURCE)
75
- server :production do
76
- ssh "user@host:22"
77
- end
78
- SOURCE
79
- end
80
- expect(output).to include("[DEPRECATION]")
81
- expect(output).to include("`server` is deprecated")
82
- expect(output).to include("use `target` instead")
83
- end
84
-
85
- it "does not warn when using target" do
86
- output = capture_stderr do
87
- Bard::Config.new("test", source: <<~SOURCE)
88
- target :production do
89
- ssh "user@host:22"
90
- end
91
- SOURCE
92
- end
93
- expect(output).not_to include("[DEPRECATION]")
94
- end
95
- end
96
-
97
- describe "Server SSH options" do
98
- it "warns when using separate path method" do
99
- output = capture_stderr do
100
- Bard::Server.define("test", :production) do
101
- ssh "user@host:22"
102
- path "/app"
103
- end
104
- end
105
- expect(output).to include("[DEPRECATION]")
106
- expect(output).to include("Separate SSH options are deprecated")
107
- end
108
-
109
- it "warns when using separate gateway method" do
110
- output = capture_stderr do
111
- Bard::Server.define("test", :production) do
112
- ssh "user@host:22"
113
- gateway "bastion@host:22"
114
- end
115
- end
116
- expect(output).to include("[DEPRECATION]")
117
- expect(output).to include("Separate SSH options are deprecated")
118
- end
119
-
120
- it "warns when using separate ssh_key method" do
121
- output = capture_stderr do
122
- Bard::Server.define("test", :production) do
123
- ssh "user@host:22"
124
- ssh_key "~/.ssh/id_rsa"
125
- end
126
- end
127
- expect(output).to include("[DEPRECATION]")
128
- expect(output).to include("Separate SSH options are deprecated")
129
- end
130
-
131
- it "warns when using separate env method" do
132
- output = capture_stderr do
133
- Bard::Server.define("test", :production) do
134
- ssh "user@host:22"
135
- env "RAILS_ENV=production"
136
- end
137
- end
138
- expect(output).to include("[DEPRECATION]")
139
- expect(output).to include("Separate SSH options are deprecated")
140
- end
141
- end
142
-
143
- describe "Server strategy configuration" do
144
- it "warns when using strategy method" do
145
- output = capture_stderr do
146
- Bard::Server.define("test", :production) do
147
- ssh "user@host:22"
148
- strategy :custom
149
- end
150
- end
151
- expect(output).to include("[DEPRECATION]")
152
- expect(output).to include("`strategy` is deprecated")
153
- end
154
-
155
- it "warns when using option method" do
156
- output = capture_stderr do
157
- Bard::Server.define("test", :production) do
158
- ssh "user@host:22"
159
- option :run_tests, true
160
- end
161
- end
162
- expect(output).to include("[DEPRECATION]")
163
- expect(output).to include("`option` is deprecated")
164
- end
165
-
166
- it "stores strategy name for backward compatibility" do
167
- server = nil
168
- capture_stderr do
169
- server = Bard::Server.define("test", :production) do
170
- ssh "user@host:22"
171
- strategy :jets
172
- end
173
- end
174
- expect(server.strategy_name).to eq :jets
175
- end
176
-
177
- it "stores strategy options for backward compatibility" do
178
- server = nil
179
- capture_stderr do
180
- server = Bard::Server.define("test", :production) do
181
- ssh "user@host:22"
182
- option :run_tests, true
183
- option :verbose, false
184
- end
185
- end
186
- expect(server.strategy_options).to eq({ run_tests: true, verbose: false })
187
- end
188
- end
189
-
190
- describe "Target (new API)" do
191
- it "does not warn when using hash options with ssh" do
192
- output = capture_stderr do
193
- Bard::Config.new("test", source: <<~SOURCE)
194
- target :production do
195
- ssh "user@host:22", path: "/app", gateway: "bastion@host:22"
196
- end
197
- SOURCE
198
- end
199
- expect(output).not_to include("[DEPRECATION]")
200
- end
201
-
202
- it "warns when using separate path method" do
203
- output = capture_stderr do
204
- Bard::Config.new("test", source: <<~SOURCE)
205
- target :production do
206
- ssh "user@host:22"
207
- path "/app"
208
- end
209
- SOURCE
210
- end
211
- expect(output).to include("[DEPRECATION]")
212
- expect(output).to include("Separate `path` call is deprecated")
213
- end
214
-
215
- it "warns when using separate gateway method" do
216
- output = capture_stderr do
217
- Bard::Config.new("test", source: <<~SOURCE)
218
- target :production do
219
- ssh "user@host:22"
220
- gateway "bastion@host:22"
221
- end
222
- SOURCE
223
- end
224
- expect(output).to include("[DEPRECATION]")
225
- expect(output).to include("Separate `gateway` call is deprecated")
226
- end
227
-
228
- it "warns when using separate ssh_key method" do
229
- output = capture_stderr do
230
- Bard::Config.new("test", source: <<~SOURCE)
231
- target :production do
232
- ssh "user@host:22"
233
- ssh_key "~/.ssh/id_rsa"
234
- end
235
- SOURCE
236
- end
237
- expect(output).to include("[DEPRECATION]")
238
- expect(output).to include("Separate `ssh_key` call is deprecated")
239
- end
240
-
241
- it "warns when using separate env method" do
242
- output = capture_stderr do
243
- Bard::Config.new("test", source: <<~SOURCE)
244
- target :production do
245
- ssh "user@host:22"
246
- env "RAILS_ENV=production"
247
- end
248
- SOURCE
249
- end
250
- expect(output).to include("[DEPRECATION]")
251
- expect(output).to include("Separate `env` call is deprecated")
252
- end
253
-
254
- it "warns when using strategy method" do
255
- output = capture_stderr do
256
- Bard::Config.new("test", source: <<~SOURCE)
257
- target :production do
258
- ssh "user@host:22"
259
- strategy :ssh
260
- end
261
- SOURCE
262
- end
263
- expect(output).to include("[DEPRECATION]")
264
- expect(output).to include("`strategy` is deprecated")
265
- end
266
-
267
- it "warns when using option method" do
268
- output = capture_stderr do
269
- Bard::Config.new("test", source: <<~SOURCE)
270
- target :production do
271
- ssh "user@host:22"
272
- strategy :ssh
273
- option :verbose, true
274
- end
275
- SOURCE
276
- end
277
- expect(output).to include("[DEPRECATION]")
278
- expect(output).to include("`option` is deprecated")
279
- end
280
- end
281
- end