aptible-cli 0.7.4 → 0.7.5
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/appveyor.yml +31 -0
- data/aptible-cli.gemspec +1 -1
- data/lib/aptible/cli/agent.rb +45 -1
- data/lib/aptible/cli/helpers/tunnel.rb +22 -4
- data/lib/aptible/cli/subcommands/db.rb +1 -1
- data/lib/aptible/cli/version.rb +1 -1
- data/spec/aptible/cli/agent_spec.rb +75 -4
- data/spec/aptible/cli/helpers/git_remote_handle_strategy_spec.rb +5 -3
- data/spec/aptible/cli/helpers/tunnel_spec.rb +4 -4
- data/spec/mock/ssh.bat +2 -0
- data/spec/shared/mock_ssh_context.rb +1 -1
- data/spec/spec_helper.rb +6 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a46c716db34062c50939791b35288542ab1dacc4
|
4
|
+
data.tar.gz: 54293b621aba536d05c4ea25740fe61530e9209f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35fadaf8062518242be514c26c66f406cb9f3ebf79128986852a4a51ef84365610f5058b90fbdcf426a18e5bfc68d4ec3afd03935b6e08d9955961bc1f24d0bb
|
7
|
+
data.tar.gz: 96a7acb0ac08381a76753035670d6e26f3d72347ce1b5c2f64f7259a960b73ad12de3e35aedd0b30890a7d2701785059f45218a107fc35a6626106875aafe367
|
data/appveyor.yml
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
version: 1.0.{build}-{branch}
|
2
|
+
|
3
|
+
environment:
|
4
|
+
matrix:
|
5
|
+
- RUBY_VERSION: 200
|
6
|
+
- RUBY_VERSION: 21
|
7
|
+
- RUBY_VERSION: 22
|
8
|
+
- RUBY_VERSION: 23
|
9
|
+
|
10
|
+
install:
|
11
|
+
# The SSL_CERT_* environment variables are here since otherwise calls to
|
12
|
+
# codecov.io wtill not work. These variables do have to be set in order for
|
13
|
+
# the gem to make calls to the Aptible API, since otherwise Ruby will fail
|
14
|
+
# with a certificate verification error.
|
15
|
+
- set SSL_CERT_DIR=%PROGRAMFILES%\Git\mingw64\ssl\certs
|
16
|
+
- set SSL_CERT_FILE=%PROGRAMFILES%\Git\mingw64\ssl\cert.pem
|
17
|
+
# Override PATHEXT so our ssh bat file has a higher precedence.
|
18
|
+
- set PATHEXT=.BAT;.COM;.EXE;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
|
19
|
+
- set PATH=C:\Ruby%RUBY_VERSION%-x64\bin;%PATH%
|
20
|
+
- bundle config --local path vendor/bundle
|
21
|
+
- bundle install
|
22
|
+
|
23
|
+
build: off
|
24
|
+
|
25
|
+
before_test:
|
26
|
+
- ruby -v
|
27
|
+
- gem -v
|
28
|
+
- bundle -v
|
29
|
+
|
30
|
+
test_script:
|
31
|
+
- bundle exec rake ci
|
data/aptible-cli.gemspec
CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_dependency 'git'
|
28
28
|
spec.add_dependency 'term-ansicolor'
|
29
29
|
spec.add_dependency 'chronic_duration', '~> 0.10.6'
|
30
|
-
|
30
|
+
spec.add_dependency 'win32-process' if Gem.win_platform?
|
31
31
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
32
32
|
spec.add_development_dependency 'aptible-tasks', '>= 0.2.0'
|
33
33
|
spec.add_development_dependency 'rake'
|
data/lib/aptible/cli/agent.rb
CHANGED
@@ -44,9 +44,19 @@ module Aptible
|
|
44
44
|
true
|
45
45
|
end
|
46
46
|
|
47
|
+
def initialize(*)
|
48
|
+
nag_toolbelt unless toolbelt?
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
47
52
|
desc 'version', 'Print Aptible CLI version'
|
48
53
|
def version
|
49
|
-
|
54
|
+
bits = [
|
55
|
+
'aptible-cli',
|
56
|
+
"v#{Aptible::CLI::VERSION}"
|
57
|
+
]
|
58
|
+
bits << 'toolbelt' if toolbelt?
|
59
|
+
puts bits.join ' '
|
50
60
|
end
|
51
61
|
|
52
62
|
desc 'login', 'Log in to Aptible'
|
@@ -104,6 +114,40 @@ module Aptible
|
|
104
114
|
say "DEPRECATION NOTICE: #{msg}"
|
105
115
|
say 'Please contact support@aptible.com with any questions.'
|
106
116
|
end
|
117
|
+
|
118
|
+
def nag_toolbelt
|
119
|
+
# If you're reading this, it's possible you decided to not use the
|
120
|
+
# toolbelt and are a looking for a way to disable this warning. Look no
|
121
|
+
# further: to do so, edit the file `.aptible/nag_toolbelt` and put a
|
122
|
+
# timestamp far into the future. For example, writing 1577836800 will
|
123
|
+
# disable the warning until 2020.
|
124
|
+
nag_file = File.join ENV['HOME'], '.aptible', 'nag_toolbelt'
|
125
|
+
nag_frequency = 12.hours
|
126
|
+
|
127
|
+
last_nag = begin
|
128
|
+
Integer(File.read(nag_file))
|
129
|
+
rescue Errno::ENOENT, ArgumentError
|
130
|
+
0
|
131
|
+
end
|
132
|
+
|
133
|
+
now = Time.now.utc.to_i
|
134
|
+
|
135
|
+
if last_nag < now - nag_frequency
|
136
|
+
$stderr.puts yellow([
|
137
|
+
'You have installed the Aptible CLI from source.',
|
138
|
+
'This is not recommended: some functionality may not work!',
|
139
|
+
'Review this support topic for more information:',
|
140
|
+
'https://www.aptible.com/support/topics/cli/how-to-install-cli/'
|
141
|
+
].join("\n"))
|
142
|
+
|
143
|
+
FileUtils.mkdir_p(File.dirname(nag_file))
|
144
|
+
File.open(nag_file, 'w', 0o600) { |f| f.write(now.to_s) }
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def toolbelt?
|
149
|
+
ENV['APTIBLE_TOOLBELT']
|
150
|
+
end
|
107
151
|
end
|
108
152
|
end
|
109
153
|
end
|
@@ -1,9 +1,27 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'open3'
|
3
|
+
require 'win32-process' if Gem.win_platform?
|
3
4
|
|
4
5
|
module Aptible
|
5
6
|
module CLI
|
6
7
|
module Helpers
|
8
|
+
# The :new_pgroup key specifies the CREATE_NEW_PROCESS_GROUP flag for
|
9
|
+
# CreateProcessW() in the Windows API. This is a Windows only option.
|
10
|
+
# true means the new process is the root process of the new process
|
11
|
+
# group.
|
12
|
+
# This flag is necessary for Process.kill(:SIGINT, pid) on the
|
13
|
+
# subprocess.
|
14
|
+
STOP_SIGNAL = if Gem.win_platform?
|
15
|
+
:SIGINT
|
16
|
+
else
|
17
|
+
:SIGHUP
|
18
|
+
end
|
19
|
+
SPAWN_OPTS = if Gem.win_platform?
|
20
|
+
{ new_pgroup: true }
|
21
|
+
else
|
22
|
+
{}
|
23
|
+
end
|
24
|
+
|
7
25
|
class Tunnel
|
8
26
|
def initialize(env, ssh_cmd)
|
9
27
|
@env = env
|
@@ -37,9 +55,9 @@ module Aptible
|
|
37
55
|
|
38
56
|
out_read, out_write = IO.pipe
|
39
57
|
err_read, err_write = IO.pipe
|
40
|
-
|
41
|
-
|
42
|
-
|
58
|
+
|
59
|
+
@pid = Process.spawn(tunnel_env, *tunnel_cmd, SPAWN_OPTS
|
60
|
+
.merge(in: :close, out: out_write, err: err_write))
|
43
61
|
|
44
62
|
# Wait for the tunnel to come up before returning. The other end
|
45
63
|
# will send a message on stdout to indicate that the tunnel is ready.
|
@@ -59,7 +77,7 @@ module Aptible
|
|
59
77
|
def stop
|
60
78
|
fail 'You must call #start before calling #stop' if @pid.nil?
|
61
79
|
begin
|
62
|
-
Process.kill(
|
80
|
+
Process.kill(STOP_SIGNAL, @pid)
|
63
81
|
rescue Errno::ESRCH
|
64
82
|
nil # Dear Rubocop: I know what I'm doing.
|
65
83
|
end
|
@@ -22,7 +22,7 @@ module Aptible
|
|
22
22
|
|
23
23
|
desc 'db:create HANDLE', 'Create a new database'
|
24
24
|
option :type, default: 'postgresql'
|
25
|
-
option :size, default: 10
|
25
|
+
option :size, default: 10, type: :numeric
|
26
26
|
option :environment
|
27
27
|
define_method 'db:create' do |handle|
|
28
28
|
environment = ensure_environment(options)
|
data/lib/aptible/cli/version.rb
CHANGED
@@ -7,9 +7,19 @@ describe Aptible::CLI::Agent do
|
|
7
7
|
|
8
8
|
describe '#version' do
|
9
9
|
it 'should print the version' do
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
ClimateControl.modify(APTIBLE_TOOLBELT: nil) do
|
11
|
+
version = Aptible::CLI::VERSION
|
12
|
+
expect(STDOUT).to receive(:puts).with "aptible-cli v#{version}"
|
13
|
+
subject.version
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should print the version (with toolbelt)' do
|
18
|
+
ClimateControl.modify(APTIBLE_TOOLBELT: '1') do
|
19
|
+
version = Aptible::CLI::VERSION
|
20
|
+
expect(STDOUT).to receive(:puts).with "aptible-cli v#{version} toolbelt"
|
21
|
+
subject.version
|
22
|
+
end
|
13
23
|
end
|
14
24
|
end
|
15
25
|
|
@@ -158,11 +168,72 @@ describe Aptible::CLI::Agent do
|
|
158
168
|
end
|
159
169
|
end
|
160
170
|
|
171
|
+
describe '#nag_toolbelt' do
|
172
|
+
let!(:work_dir) { Dir.mktmpdir }
|
173
|
+
after { FileUtils.remove_entry work_dir }
|
174
|
+
around { |example| ClimateControl.modify(HOME: work_dir) { example.run } }
|
175
|
+
|
176
|
+
let(:nag_dir) { File.join(work_dir, '.aptible') }
|
177
|
+
let(:nag_file) { File.join(nag_dir, 'nag_toolbelt') }
|
178
|
+
|
179
|
+
it 'warns if the nag file is not present' do
|
180
|
+
expect($stderr).to receive(:puts).at_least(:once)
|
181
|
+
subject.send(:nag_toolbelt)
|
182
|
+
expect(Integer(File.read(nag_file))).to be_within(5).of(Time.now.utc.to_i)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'warns if the nag file contains an old timestamp' do
|
186
|
+
Dir.mkdir(nag_dir)
|
187
|
+
File.open(nag_file, 'w') do |f|
|
188
|
+
f.write((Time.now.utc.to_i - 1.day).to_i.to_s)
|
189
|
+
end
|
190
|
+
|
191
|
+
expect($stderr).to receive(:puts).at_least(:once)
|
192
|
+
subject.send(:nag_toolbelt)
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'does not warn if the nag file contains a recent timestamp' do
|
196
|
+
Dir.mkdir(nag_dir)
|
197
|
+
File.open(nag_file, 'w') do |f|
|
198
|
+
f.write((Time.now.utc.to_i - 3.hours).to_i.to_s)
|
199
|
+
end
|
200
|
+
|
201
|
+
expect($stderr).not_to receive(:puts)
|
202
|
+
subject.send(:nag_toolbelt)
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'does not warn if the nag file contains a recent timestamp (newline)' do
|
206
|
+
# In case a customer writes to the nag file to disable the nag, they're
|
207
|
+
# likely to add a trailing newline. Let's just make sure we support that.
|
208
|
+
Dir.mkdir(nag_dir)
|
209
|
+
File.open(nag_file, 'w') do |f|
|
210
|
+
f.write("#{(Time.now.utc.to_i - 3.hours).to_i}\n")
|
211
|
+
end
|
212
|
+
|
213
|
+
expect($stderr).not_to receive(:puts)
|
214
|
+
subject.send(:nag_toolbelt)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'warns if the nag file contains an invalid timestamp' do
|
218
|
+
Dir.mkdir(nag_dir)
|
219
|
+
File.open(nag_file, 'w') { |f| f.write('foobar') }
|
220
|
+
|
221
|
+
expect($stderr).to receive(:puts).at_least(:once)
|
222
|
+
subject.send(:nag_toolbelt)
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'is compatible with itself' do
|
226
|
+
expect($stderr).to receive(:puts).once
|
227
|
+
2.times { subject.send(:nag_toolbelt) }
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
161
231
|
context 'load' do
|
162
232
|
it 'loads without git' do
|
163
233
|
mocks = File.expand_path('../../../mock', __FILE__)
|
164
234
|
bins = File.expand_path('../../../../bin', __FILE__)
|
165
|
-
|
235
|
+
sep = File::PATH_SEPARATOR
|
236
|
+
ClimateControl.modify PATH: [mocks, bins, ENV['PATH']].join(sep) do
|
166
237
|
_, _, status = Open3.capture3('aptible version')
|
167
238
|
expect(status).to eq(0)
|
168
239
|
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Aptible::CLI::Helpers::App::GitRemoteHandleStrategy do
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
around do |example|
|
5
|
+
Dir.mktmpdir do |work_dir|
|
6
|
+
Dir.chdir(work_dir) { example.run }
|
7
|
+
end
|
8
|
+
end
|
7
9
|
|
8
10
|
context 'with git repo' do
|
9
11
|
before { `git init` }
|
@@ -4,7 +4,7 @@ describe Aptible::CLI::Helpers::Tunnel do
|
|
4
4
|
include_context 'mock ssh'
|
5
5
|
|
6
6
|
it 'forwards traffic to the remote port given by the server (1234)' do
|
7
|
-
helper = described_class.new({}, ['
|
7
|
+
helper = described_class.new({}, ['ssh'])
|
8
8
|
|
9
9
|
helper.start(0)
|
10
10
|
helper.stop
|
@@ -23,7 +23,7 @@ describe Aptible::CLI::Helpers::Tunnel do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'accepts a desired local port' do
|
26
|
-
helper = described_class.new({}, ['
|
26
|
+
helper = described_class.new({}, ['ssh'])
|
27
27
|
helper.start(5678)
|
28
28
|
helper.stop
|
29
29
|
|
@@ -35,13 +35,13 @@ describe Aptible::CLI::Helpers::Tunnel do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'captures and displays port discovery errors' do
|
38
|
-
helper = described_class.new({ 'FAIL_PORT' => '1' }, ['
|
38
|
+
helper = described_class.new({ 'FAIL_PORT' => '1' }, ['ssh'])
|
39
39
|
expect { helper.start }
|
40
40
|
.to raise_error(/Failed to request.*Something went wrong/m)
|
41
41
|
end
|
42
42
|
|
43
43
|
it 'captures and displays tunnel errors' do
|
44
|
-
helper = described_class.new({ 'FAIL_TUNNEL' => '1' }, ['
|
44
|
+
helper = described_class.new({ 'FAIL_TUNNEL' => '1' }, ['ssh'])
|
45
45
|
expect { helper.start(0) }
|
46
46
|
.to raise_error(/Tunnel did not come up.*Something went wrong/m)
|
47
47
|
end
|
data/spec/mock/ssh.bat
ADDED
@@ -9,7 +9,7 @@ shared_context 'mock ssh' do
|
|
9
9
|
around do |example|
|
10
10
|
mocks_path = File.expand_path('../../mock', __FILE__)
|
11
11
|
env = {
|
12
|
-
PATH: "#{mocks_path}
|
12
|
+
PATH: "#{mocks_path}#{File::PATH_SEPARATOR}#{ENV['PATH']}",
|
13
13
|
SSH_MOCK_OUTFILE: ssh_mock_outfile.path
|
14
14
|
}
|
15
15
|
|
data/spec/spec_helper.rb
CHANGED
@@ -21,4 +21,10 @@ require 'aptible/cli'
|
|
21
21
|
|
22
22
|
RSpec.configure do |config|
|
23
23
|
config.before {}
|
24
|
+
|
25
|
+
# We make the CLI believe it's running in a toolbelt context to avoid running
|
26
|
+
# the toolbelt nag every time it initializes.
|
27
|
+
config.around(:each) do |example|
|
28
|
+
ClimateControl.modify(APTIBLE_TOOLBELT: '1') { example.run }
|
29
|
+
end
|
24
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aptible-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Frank Macreery
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aptible-api
|
@@ -222,6 +222,7 @@ files:
|
|
222
222
|
- LICENSE.md
|
223
223
|
- README.md
|
224
224
|
- Rakefile
|
225
|
+
- appveyor.yml
|
225
226
|
- aptible-cli.gemspec
|
226
227
|
- bin/aptible
|
227
228
|
- codecov.yml
|
@@ -266,6 +267,7 @@ files:
|
|
266
267
|
- spec/fabricators/vhost_fabricator.rb
|
267
268
|
- spec/mock/git
|
268
269
|
- spec/mock/ssh
|
270
|
+
- spec/mock/ssh.bat
|
269
271
|
- spec/mock/ssh_mock.rb
|
270
272
|
- spec/shared/mock_ssh_context.rb
|
271
273
|
- spec/spec_helper.rb
|
@@ -315,6 +317,7 @@ test_files:
|
|
315
317
|
- spec/fabricators/vhost_fabricator.rb
|
316
318
|
- spec/mock/git
|
317
319
|
- spec/mock/ssh
|
320
|
+
- spec/mock/ssh.bat
|
318
321
|
- spec/mock/ssh_mock.rb
|
319
322
|
- spec/shared/mock_ssh_context.rb
|
320
323
|
- spec/spec_helper.rb
|