hrk 0.0.6 → 0.0.8

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
2
  SHA1:
3
- metadata.gz: 9a5606eeb5d8dc713063b4d76ef4633a60d0ba61
4
- data.tar.gz: db35ff5cc2c2ea9445087056d1057a4a1db4100f
3
+ metadata.gz: e8df14c2ca4330a91a5cf758825844724e93a4b6
4
+ data.tar.gz: 4cf32f72933c72821c09b662ed07fbb62525e3bf
5
5
  SHA512:
6
- metadata.gz: 425ecb4c9bb064204f13a074b1e3b21b1c066a754241a5d62bfa66ff6a01d9b2bd69736aa85f778e5d9996f50f697ec4b9514ad56f4b5d9ed8a431b62cca0eb9
7
- data.tar.gz: c3d7d9ae715a2a0ba7846c6915b975bbf6e589dafd06b0554ca9f2e604491447fc1c2f8531a54b79fc6b6a07be1af6a5b147b048f4405182c82416284d2aed78
6
+ metadata.gz: fbaf173a98a54834352a8bd0122d21561760f4a6d8f77922b44aac0a2d702b7ecac4a72ac51cdb4fd93c2669693b8a270c6bc91cb99a5940adf3a0f47e67032a
7
+ data.tar.gz: 98edc74b9c2f69ca20be31d9d3b84319da03046a02aff5bf55bb94d17c47103159482daa6f1ccc122b2e0291cfa7fe269780aa5c899de6eb272f63b971e61e3b
data/README.md CHANGED
@@ -138,6 +138,7 @@ $ hrk -r demo run rake db:migrate && \ # happens on demo
138
138
  **...I place the "-r remote" argument at the end of the command, the heroku way**
139
139
 
140
140
  It just works.
141
+
141
142
  ```bash
142
143
  # this command
143
144
  $ hrk run console -r demo
@@ -145,6 +146,17 @@ $ hrk run console -r demo
145
146
  $ hrk -r demo run console
146
147
  ```
147
148
 
149
+ **...I prefer naming my app instead of the remote?**
150
+
151
+ You can use either the -r or -a option, either will work as expected and the
152
+ latest option will be memorized for subsequent uses.
153
+
154
+ ```bash
155
+ $ hrk maintenance:on -a my-super-duper-app && \ # happens on my-super-duper-app
156
+ hrk run console && \ # again on my-super-duper-app
157
+ hrk maintenance:off # aaand on my-super-duper-app
158
+ ```
159
+
148
160
  ## Do I still need the heroku toolbelt?
149
161
 
150
162
  Yes. The hrk command calls the heroku command for you, it does not replace it.
data/lib/hrk/env.rb CHANGED
@@ -5,16 +5,16 @@ require 'tmpdir'
5
5
 
6
6
  module Hrk
7
7
  class Env
8
- def remote= remote_name
9
- if remote_name
10
- socket_path.write remote_name unless remote == remote_name
8
+ def remote= *args
9
+ if args
10
+ socket_path.write args.join(' ') unless remote == args
11
11
  else
12
12
  socket_path.delete if remote?
13
13
  end
14
14
  end
15
15
 
16
16
  def remote
17
- socket_path.read if remote?
17
+ socket_path.read.split(' ', 2) if remote?
18
18
  end
19
19
 
20
20
  def remote?
@@ -3,29 +3,33 @@ module Hrk
3
3
  class Command
4
4
  attr_reader :env
5
5
 
6
+ ARG = /\A-[ar]\Z/
7
+
6
8
  def initialize
7
9
  @env = Hrk::Env.new
8
10
  end
9
11
 
10
12
  def call *args
11
- remote = remote_name args
13
+ remote, command = remote_and_command args
12
14
  if remote
13
15
  @env.remote = remote
14
- Hrk::Heroku.new(remote).call(remoteless_command(remote, args))
16
+ Hrk::Heroku.new(*remote).call(*command)
15
17
  else
16
18
  raise ArgumentError.new("No remote has been previously defined and the command does not explicitely mention a remote") unless @env.remote?
17
- Hrk::Heroku.new(@env.remote).call(args.join(' '))
19
+ Hrk::Heroku.new(*@env.remote).call(*command)
18
20
  end
19
21
  end
20
22
 
21
- private
22
-
23
- def remote_name args
24
- args.each_cons(2).detect { |(parameter, _)| parameter == '-r' }.join ' ' rescue nil
25
- end
26
-
27
- def remoteless_command remote, args
28
- args.join(' ').gsub(%r{\s*#{remote}\s*}, ' ').strip
23
+ def remote_and_command args
24
+ args.slice_before { |arg| arg =~ ARG }.inject([nil, []]) do |r, slice|
25
+ if slice.first =~ ARG
26
+ raise ArgumentError.new('Remote option without value') if slice.length < 2
27
+ raise ArgumentError.new('Too many remotes mentionned') if r.first
28
+ [slice.take(2), r.last + slice.drop(2)]
29
+ else
30
+ [r.first, r.last + slice]
31
+ end
32
+ end
29
33
  end
30
34
  end
31
35
  end
@@ -16,17 +16,25 @@ module Hrk
16
16
  def display
17
17
  puts <<-eos
18
18
  Usage:
19
- hrk [remote]: command...
19
+ hrk command [(-r remote | -a appname)]...
20
20
  hrk [h | help | -h | --help]
21
21
 
22
- hrk remembers the last remote you've used to send a command on this terminal,
23
- and use it by default when you omit the optional [remote] argument.
22
+ The hrk command remembers the last app you've send a command to on a terminal
23
+ to use it when you omit the optional -r or -a option on subsequent calls.
24
24
 
25
25
  The command is whatever you would give heroku, except (obviously) for the
26
26
  -r or -a argument.
27
27
 
28
+ Note that whatever argument and/or options the command is composed of should not
29
+ be tampered with and passed as is to the heroku toolbelt command.
30
+
28
31
  Options:
29
- -h --help Display this screen.
32
+ -h --help Display this screen.
33
+ -r remote Sets the remote for this command and the following
34
+ -a appname Sets the heroku app name for this command and the following
35
+
36
+ More on the hrk command on the gem's website:
37
+ https://github.com/Bastes/hrk
30
38
  eos
31
39
  end
32
40
 
data/lib/hrk/heroku.rb CHANGED
@@ -1,18 +1,19 @@
1
1
  module Hrk
2
2
  class Heroku
3
- def initialize remote
3
+ def initialize *remote
4
4
  @remote = remote
5
5
  end
6
6
 
7
- def call command
8
- validate! command
9
- system %Q(heroku #{command} #{@remote})
7
+ def call *command
8
+ validate! *command
9
+ system 'heroku', *(command + @remote)
10
10
  end
11
11
 
12
12
  private
13
13
 
14
- def validate! command
15
- raise ExplicitApplicationError.new, "You're calling a command on remote #{@remote} yet the command explicitly references #{command[%r{-[ar]\s+\S+}]}" if command =~ %r{ -[ra]\b}
14
+ def validate! *command
15
+ remote = (command.each_cons(2).detect { |(parameter, _)| parameter =~ %r{\A-[ar]\Z} }.join ' ' rescue nil)
16
+ raise ExplicitApplicationError.new, "You're calling a command on remote #{@remote.join " "} yet the command explicitly references #{remote}" if remote
16
17
  end
17
18
 
18
19
  class ExplicitApplicationError < Exception
data/lib/hrk.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  module Hrk
2
+ VERSION = '0.0.8'
3
+
2
4
  autoload :Env, 'hrk/env'
3
5
  autoload :Heroku, 'hrk/heroku'
4
6
  autoload :Execute, 'hrk/execute'
@@ -17,38 +17,48 @@ RSpec.describe Hrk::Execute::Command do
17
17
  let(:remote) { "remote-#{rand(1..9)}" }
18
18
  let(:args) { %w(whatever that:may -b) }
19
19
 
20
- [true, false].each do |result|
21
- describe "when the command returns #{result}" do
22
- before { allow(heroku).to receive(:call).and_return(result) }
23
-
24
- it { expect(command.call('-r', remote, *args)).to eq result }
20
+ %w(-a -r).each do |opt|
21
+ context "using #{opt}" do
22
+ [true, false].each do |result|
23
+ context "when the command returns #{result}" do
24
+ before { allow(heroku).to receive(:call).and_return(result) }
25
+
26
+ it { expect(command.call(opt, remote, *args)).to eq result }
27
+ end
28
+ end
29
+
30
+ describe 'interactions' do
31
+ before { command.call opt, remote, *args }
32
+
33
+ it { expect(Hrk::Heroku).to have_received(:new).with(opt, remote) }
34
+ it { expect(heroku).to have_received(:call).with(*%w{whatever that:may -b}) }
35
+ it { expect(command.env).to have_received(:remote=).with([opt, remote]) }
36
+ end
25
37
  end
26
38
  end
27
-
28
- describe 'interactions' do
29
- before { command.call '-r', remote, *args }
30
-
31
- it { expect(Hrk::Heroku).to have_received(:new).with("-r #{remote}") }
32
- it { expect(heroku).to have_received(:call).with("whatever that:may -b") }
33
- it { expect(command.env).to have_received(:remote=).with("-r #{remote}") }
34
- end
35
39
  end
36
40
 
37
- describe 'edge cases (no remote or improper remote)' do
38
- let(:other_args) { %W(something-#{rand(1..9)} or-another) }
41
+ describe 'edge cases (no remote, improper remote, too many remotes...)' do
42
+ let(:other_args) { %W(something-#{rand(1..9)} -o r --another) }
39
43
 
40
44
  before { expect(heroku).not_to receive(:call) }
41
45
  before { expect(command.env).not_to receive(:remote=) }
42
46
 
43
47
  it { expect { command.call }.to raise_error ArgumentError }
44
48
  it { expect { command.call "parameterless-remote", *other_args }.to raise_error ArgumentError }
49
+ it { expect { command.call *other_args }.to raise_error ArgumentError }
45
50
  it { expect { command.call *other_args, '-r' }.to raise_error ArgumentError }
51
+ it { expect { command.call *other_args, '-a' }.to raise_error ArgumentError }
52
+ it { expect { command.call '-r', 'remote', *other_args, '-r', 'other-remote' }.to raise_error ArgumentError }
53
+ it { expect { command.call '-r', 'remote', *other_args, '-a', 'app' }.to raise_error ArgumentError }
54
+ it { expect { command.call '-a', 'app', *other_args, '-a', 'other-app' }.to raise_error ArgumentError }
55
+ it { expect { command.call '-r', 'something', *other_args, '-a', 'something-else' }.to raise_error ArgumentError }
46
56
  end
47
57
  end
48
58
 
49
59
  context 'a remote was previously memorized' do
50
- let(:previous_remote) { "-r ye-olde-remote#{rand(1..9)}" }
51
- before { allow(command.env).to receive(:remote).and_return(previous_remote) }
60
+ let(:previous_remote) { "ye-olde-remote#{rand(1..9)}" }
61
+ before { allow(command.env).to receive(:remote).and_return(['-r', previous_remote]) }
52
62
  before { allow(command.env).to receive(:remote?).and_return(true) }
53
63
 
54
64
  describe 'standard case (a remote, a command)' do
@@ -66,9 +76,9 @@ RSpec.describe Hrk::Execute::Command do
66
76
  describe 'interactions' do
67
77
  before { command.call '-r', remote, *args }
68
78
 
69
- it { expect(Hrk::Heroku).to have_received(:new).with("-r #{remote}") }
70
- it { expect(heroku).to have_received(:call).with("whatever that:may -b") }
71
- it { expect(command.env).to have_received(:remote=).with("-r #{remote}") }
79
+ it { expect(Hrk::Heroku).to have_received(:new).with('-r', remote) }
80
+ it { expect(heroku).to have_received(:call).with(*%w{whatever that:may -b}) }
81
+ it { expect(command.env).to have_received(:remote=).with(['-r', remote]) }
72
82
  end
73
83
  end
74
84
 
@@ -86,10 +96,45 @@ RSpec.describe Hrk::Execute::Command do
86
96
  describe 'interactions' do
87
97
  before { command.call *args }
88
98
 
89
- it { expect(Hrk::Heroku).to have_received(:new).with(previous_remote) }
90
- it { expect(heroku).to have_received(:call).with("whatever that:may -b") }
99
+ it { expect(Hrk::Heroku).to have_received(:new).with('-r', previous_remote) }
100
+ it { expect(heroku).to have_received(:call).with(*%w{whatever that:may -b}) }
91
101
  end
92
102
  end
103
+
104
+ describe 'edge cases (improper remote, too many remotes...)' do
105
+ let(:other_args) { %W(--whatever#{rand(1..9)} dude) }
106
+
107
+ before { expect(heroku).not_to receive(:call) }
108
+ before { expect(command.env).not_to receive(:remote=) }
109
+
110
+ it { expect { command.call *other_args, '-r' }.to raise_error ArgumentError }
111
+ it { expect { command.call *other_args, '-a' }.to raise_error ArgumentError }
112
+ it { expect { command.call '-r', 'remote', *other_args, '-r', 'other-remote' }.to raise_error ArgumentError }
113
+ it { expect { command.call '-r', 'remote', *other_args, '-a', 'app' }.to raise_error ArgumentError }
114
+ it { expect { command.call '-a', 'app', *other_args, '-a', 'other-app' }.to raise_error ArgumentError }
115
+ it { expect { command.call '-r', 'something', *other_args, '-a', 'something-else' }.to raise_error ArgumentError }
116
+ end
117
+ end
118
+ end
119
+
120
+ describe '#remote_and_command' do
121
+ subject(:command) { Hrk::Execute::Command.new }
122
+
123
+ context '(standard cases, arguments parsed)' do
124
+ it { expect(command.remote_and_command(%w(run rake db:migrate))).to eq [nil, %w(run rake db:migrate)] }
125
+ it { expect(command.remote_and_command(%w(restart))).to eq [nil, %w(restart)] }
126
+ it { expect(command.remote_and_command(%w(-r demo restart))).to eq [%w(-r demo), %w(restart)] }
127
+ it { expect(command.remote_and_command(%w(run rake db:migrate -r prod))).to eq [%w(-r prod), %w(run rake db:migrate)] }
128
+ it { expect(command.remote_and_command(%w(some command -r test -i dont know --about))).to eq [%w(-r test), %w(some command -i dont know --about)] }
129
+ end
130
+
131
+ context '(edge cases, argument errors)' do
132
+ it { expect { command.remote_and_command(%w(-r staging logs -t -r test)) }.to raise_error ArgumentError }
133
+ it { expect { command.remote_and_command(%w(-a prod run rake db:migrate -r echo)) }.to raise_error ArgumentError }
134
+ it { expect { command.remote_and_command(%w(run console -r demo -a app)) }.to raise_error ArgumentError }
135
+ it { expect { command.remote_and_command(%w(-a one -a other maintenance:on)) }.to raise_error ArgumentError }
136
+ it { expect { command.remote_and_command(%w(maintenance:off -a)) }.to raise_error ArgumentError }
137
+ it { expect { command.remote_and_command(%w(restart -r)) }.to raise_error ArgumentError }
93
138
  end
94
139
  end
95
140
  end
@@ -3,48 +3,50 @@ require 'spec_helper'
3
3
  RSpec.describe Hrk::Heroku do
4
4
  describe '#call' do
5
5
  describe 'the system command ran' do
6
- def self.calling command, on_remote: 'whatever-app', starts: ''
7
- describe "calling '#{command}' on remote '#{on_remote}', system" do
8
- subject(:heroku) { Hrk::Heroku.new(on_remote) }
6
+ def self.calling command, on_remote: %W(-r whatever-app), starts: ''
7
+ describe "calling '#{command.join ' '}' on remote '#{on_remote}', system" do
8
+ subject(:heroku) { Hrk::Heroku.new(*on_remote) }
9
9
 
10
- before { heroku.call command }
10
+ before { heroku.call *command }
11
11
 
12
- it { expect(heroku).to have_received(:system).with(starts) }
12
+ it { expect(heroku).to have_received(:system).with(*starts) }
13
13
  end
14
14
  end
15
15
 
16
16
  before { allow(heroku).to receive(:system) }
17
17
 
18
- describe '(standard case)' do
19
- calling 'call rake db:rollback', on_remote: '-r demo', starts: 'heroku call rake db:rollback -r demo'
20
- calling 'call rake db:migrate', on_remote: '-r prod', starts: 'heroku call rake db:migrate -r prod'
21
- calling 'call console', on_remote: '-r staging', starts: 'heroku call console -r staging'
22
- calling 'logs -t', on_remote: '-r prod', starts: 'heroku logs -t -r prod'
23
- calling 'pgbackups:capture', on_remote: '-r demo', starts: 'heroku pgbackups:capture -r demo'
18
+ %w(-a -r).each do |opt|
19
+ describe "(standard case, using #{opt})" do
20
+ calling %w(call rake db:rollback), on_remote: %W(#{opt} demo), starts: %W(heroku call rake db:rollback #{opt} demo)
21
+ calling %w(call rake db:migrate), on_remote: %W(#{opt} prod), starts: %W(heroku call rake db:migrate #{opt} prod)
22
+ calling %w(call console), on_remote: %W(#{opt} staging), starts: %W(heroku call console #{opt} staging)
23
+ calling %w(logs -t), on_remote: %W(#{opt} prod), starts: %W(heroku logs -t #{opt} prod)
24
+ calling %w(pgbackups:capture), on_remote: %W(#{opt} demo), starts: %W(heroku pgbackups:capture #{opt} demo)
25
+ end
24
26
  end
25
27
 
26
28
  describe '(edge case)' do
27
- subject(:heroku) { Hrk::Heroku.new('some-remote') }
29
+ subject(:heroku) { Hrk::Heroku.new(*%w(-r some-remote)) }
28
30
 
29
- it { expect { heroku.call('run rake rake:db:migrate -r some-other-remote') }.to raise_exception(Hrk::Heroku::ExplicitApplicationError) }
30
- it { expect { heroku.call('run rake rake:db:migrate -a different-app') }.to raise_exception(Hrk::Heroku::ExplicitApplicationError) }
31
+ it { expect { heroku.call(*%w(run rake rake:db:migrate -r some-other-remote)) }.to raise_exception(Hrk::Heroku::ExplicitApplicationError) }
32
+ it { expect { heroku.call(*%w(run rake rake:db:migrate -a different-app)) }.to raise_exception(Hrk::Heroku::ExplicitApplicationError) }
31
33
  end
32
34
  end
33
35
 
34
36
  describe 'the result of the command' do
35
- subject(:heroku) { Hrk::Heroku.new('-r some-remote') }
36
- before { allow(heroku).to receive(:system).with('heroku some command -r some-remote').and_return(system_returns) }
37
+ subject(:heroku) { Hrk::Heroku.new(*%w(-r some-remote)) }
38
+ before { allow(heroku).to receive(:system).with(*%W(heroku some command -r some-remote)).and_return(system_returns) }
37
39
 
38
40
  context 'the command result is truthy' do
39
41
  let(:system_returns) { true }
40
42
 
41
- it { expect(heroku.call('some command')).to be_truthy }
43
+ it { expect(heroku.call(*%w(some command))).to be_truthy }
42
44
  end
43
45
 
44
46
  context 'the command result is falsy' do
45
47
  let(:system_returns) { false }
46
48
 
47
- it { expect(heroku.call('some command')).to be_falsy }
49
+ it { expect(heroku.call(*%w(some command))).to be_falsy }
48
50
  end
49
51
  end
50
52
  end
metadata CHANGED
@@ -1,75 +1,115 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hrk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michel Belleville
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-06 00:00:00.000000000 Z
11
+ date: 2015-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '='
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 3.1.0
20
- - - "<"
19
+ version: '3.1'
20
+ - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 4.0.0
22
+ version: 3.1.0
23
23
  type: :development
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - '='
27
+ - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: 3.1.0
30
- - - "<"
29
+ version: '3.1'
30
+ - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 4.0.0
32
+ version: 3.1.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: nyan-cat-formatter
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - '='
37
+ - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0.11'
40
- - - "<"
40
+ - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: '1.0'
42
+ version: '0.11'
43
43
  type: :development
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - '='
47
+ - - "~>"
48
48
  - !ruby/object:Gem::Version
49
49
  version: '0.11'
50
- - - "<"
50
+ - - ">="
51
51
  - !ruby/object:Gem::Version
52
- version: '1.0'
52
+ version: '0.11'
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: guard-rspec
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
- - - '='
57
+ - - "~>"
58
58
  - !ruby/object:Gem::Version
59
- version: 4.5.0
60
- - - "<"
59
+ version: '4.5'
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
- version: 5.0.0
62
+ version: 4.5.0
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - '='
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '4.5'
70
+ - - ">="
68
71
  - !ruby/object:Gem::Version
69
72
  version: 4.5.0
70
- - - "<"
73
+ - !ruby/object:Gem::Dependency
74
+ name: rake
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '10.1'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 10.1.0
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.1'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 10.1.0
93
+ - !ruby/object:Gem::Dependency
94
+ name: rubygems-tasks
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '0.2'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 0.2.4
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.2'
110
+ - - ">="
71
111
  - !ruby/object:Gem::Version
72
- version: 5.0.0
112
+ version: 0.2.4
73
113
  description: |
74
114
  Hrk gives you the hrk command that proxies commands to heroku, keeping track of
75
115
  the latest remote you used so you don't have to keep on typing it on every