rainforest-cli 0.0.14 → 0.0.15

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: 0f42f5204c7270c3eac865f11542df5a4018a95a
4
- data.tar.gz: 4d3e1c7e16bbb265f6d1fb0f9f3602b8f48dc8e5
3
+ metadata.gz: d6657daf2f5330f8a36eb5b428301d948126a7d9
4
+ data.tar.gz: f2211772f11f76f7c9c3e0c1c276e8a2fbf76e69
5
5
  SHA512:
6
- metadata.gz: 39cac3328e88e9d2cc174c0386f135ff11d7cd52b012b0daea620733a3aab1e0f7f0ee02623c156e1a2eb8e69c55422426f2c3a2364aff7c84f447b9e583abc7
7
- data.tar.gz: 9cd678e820f6dc9385a2db12b4d5d29ea58dbb50c590a48a055f4723bb734dc5ff9ab2b89046420b408f2aca2cb4196d3b93d19e5190067a6fd694fe55a76d6e
6
+ metadata.gz: c83670311447e58b3fd6a7dbf389eea91efcef1d2d3e41ce52d35e99e8cb53a158cb3c974e5ac1fe17e758f2b56bed285cb3359707f89c0d588f8f2fea74a283
7
+ data.tar.gz: e0f16437e179732e4e9dbf5b2ccec0700f154af7f5612f75299ce7bf7b1e3cb8337eb452e86dbd9becc358748c843368f0f5032977d28ddc1300d0f049e42e13
checksums.yaml.gz.sig CHANGED
Binary file
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "spec/test-repo"]
2
+ path = spec/test-repo
3
+ url = https://github.com/rainforestapp/test-repo.git
data/.rspec CHANGED
@@ -1,3 +1,2 @@
1
1
  --color
2
2
  --require spec_helper
3
- --profile
data/README.md CHANGED
@@ -38,12 +38,14 @@ The options are:
38
38
  - `--fg` - results in the foreground - this is what you want to make the build pass / fail dependent on rainforest results
39
39
  - `--site-id` - only run tests for a specific site. Get in touch with us for help on getting that you site id if you are unable to.
40
40
  - `--custom-url` - use a custom url for this run. Example use case: an ad-hoc QA environment with [Fourchette](https://github.com/rainforestapp/fourchette). You will need to specify a `site_id` too for this to work. Please note that we will be creating environments under the hood and will not affect your test permanently.
41
+ - `--git-trigger` - only trigger a run when the last commit (for a git repo in the current working directory) has contains `@rainforest` and a list of one or more tags. E.g. "Fix checkout process. @rainforest #checkout" would trigger a run for everything tagged `checkout`. This over-rides `--tag` and any tests specified. If no `@rainforest` is detected it will exit 0.
41
42
 
42
43
 
43
44
  ## Contributing
44
45
 
45
46
  1. Fork it
46
- 2. Create your feature branch (`git checkout -b my-new-feature`)
47
- 3. Commit your changes (`git commit -am 'Add some feature'`)
48
- 4. Push to the branch (`git push origin my-new-feature`)
49
- 5. Create new Pull Request
47
+ 2. Make sure you init the submodules (`git submodule init && git submodule update`)
48
+ 3. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 5. Push to the branch (`git push origin my-new-feature`)
51
+ 6. Create new Pull Request
@@ -0,0 +1,19 @@
1
+ require 'optparse'
2
+
3
+ module Rainforest
4
+ module Cli
5
+ class GitTrigger
6
+ def self.git_trigger_should_run?(commit_message)
7
+ commit_message.include?('@rainforest')
8
+ end
9
+
10
+ def self.extract_hashtags(commit_message)
11
+ commit_message.scan(/#([\w_-]+)/).flatten.map {|s| s.gsub('#','') }
12
+ end
13
+
14
+ def self.last_commit_message
15
+ `git log -1 --pretty=%B`.strip
16
+ end
17
+ end
18
+ end
19
+ end
@@ -29,6 +29,10 @@ module Rainforest
29
29
  @import_name = value
30
30
  end
31
31
 
32
+ opts.on("--git-trigger", "Only run if the last commit contains @rainforestapp") do |value|
33
+ @git_trigger = true
34
+ end
35
+
32
36
  opts.on("--fg", "Run the tests in foreground.") do |value|
33
37
  @foreground = value
34
38
  end
@@ -72,6 +76,10 @@ module Rainforest
72
76
  @tests
73
77
  end
74
78
 
79
+ def git_trigger?
80
+ @git_trigger
81
+ end
82
+
75
83
  def failfast?
76
84
  @failfast
77
85
  end
@@ -1,5 +1,5 @@
1
1
  module Rainforest
2
2
  module Cli
3
- VERSION = "0.0.14"
3
+ VERSION = "0.0.15"
4
4
  end
5
5
  end
@@ -1,8 +1,10 @@
1
1
  require "rainforest/cli/version"
2
2
  require "rainforest/cli/options"
3
+ require "rainforest/cli/git_trigger"
3
4
  require "rainforest/cli/csv_importer"
4
5
  require "httparty"
5
6
  require "json"
7
+ require "logger"
6
8
 
7
9
  module Rainforest
8
10
  module Cli
@@ -11,29 +13,63 @@ module Rainforest
11
13
  def self.start(args)
12
14
  @options = OptionParser.new(args)
13
15
 
16
+ unless @options.token
17
+ logger.fatal "You must pass your API token using: --token TOKEN"
18
+ exit 2
19
+ end
20
+
14
21
  if @options.custom_url && @options.site_id.nil?
15
- puts "The site-id and custom-url options work together, you need both of them."
16
- exit 1
22
+ logger.fatal "The site-id and custom-url options are both required."
23
+ exit 2
17
24
  end
18
25
 
19
26
  if @options.import_file_name && @options.import_name
20
27
  unless File.exists?(@options.import_file_name)
21
- puts "Input file: #{@options.import_file_name} not found"
28
+ logger.fatal "Input file: #{@options.import_file_name} not found"
22
29
  exit 2
23
30
  end
24
31
 
25
32
  delete_generator(@options.import_name)
26
33
  CSVImporter.new(@options.import_name, @options.import_file_name, @options.token).import
27
34
  elsif @options.import_file_name || @options.import_name
28
- puts "You must pass both --import-variable-csv-file and --import-variable-name"
35
+ logger.fatal "You must pass both --import-variable-csv-file and --import-variable-name"
29
36
  exit 2
30
37
  end
31
38
 
32
39
  post_opts = {}
33
- if !@options.tags.empty?
34
- post_opts[:tags] = @options.tags
40
+
41
+ if @options.git_trigger?
42
+ logger.debug "Checking last git commit message:"
43
+ commit_message = GitTrigger.last_commit_message
44
+ logger.debug commit_message
45
+
46
+ # Show some messages to users about tests/tags being overriden
47
+ unless @options.tags.empty?
48
+ logger.warn "Specified tags are ignored when using --git-trigger"
49
+ else
50
+ logger.warn "Specified tests are ignored when using --git-trigger"
51
+ end
52
+
53
+ if GitTrigger.git_trigger_should_run?(commit_message)
54
+ tags = GitTrigger.extract_hashtags(commit_message)
55
+ if tags.empty?
56
+ logger.error "Triggered via git, but no hashtags detected. Please use commit message format:"
57
+ logger.error "\t'some message. @rainforest #tag1 #tag2"
58
+ exit 2
59
+ else
60
+ post_opts[:tags] = [tags.join(',')]
61
+ end
62
+ else
63
+ logger.info "Not triggering as @rainforest was not mentioned in last commit message."
64
+ exit 0
65
+ end
35
66
  else
36
- post_opts[:tests] = @options.tests
67
+ # Not using git_trigger, so look for the
68
+ if !@options.tags.empty?
69
+ post_opts[:tags] = @options.tags
70
+ else
71
+ post_opts[:tests] = @options.tests
72
+ end
37
73
  end
38
74
 
39
75
  post_opts[:conflict] = @options.conflict if @options.conflict
@@ -43,12 +79,13 @@ module Rainforest
43
79
 
44
80
  post_opts[:environment_id] = get_environment_id(@options.custom_url) if @options.custom_url
45
81
 
46
- puts "Issuing run"
82
+ logger.debug "POST options: #{post_opts.inspect}"
83
+ logger.info "Issuing run"
47
84
 
48
85
  response = post(API_URL + '/runs', post_opts)
49
86
 
50
87
  if response['error']
51
- puts "Error starting your run: #{response['error']}"
88
+ logger.fatal "Error starting your run: #{response['error']}"
52
89
  exit 1
53
90
  end
54
91
 
@@ -62,10 +99,10 @@ module Rainforest
62
99
  response = get "#{API_URL}/runs/#{run_id}?gem_version=#{Rainforest::Cli::VERSION}"
63
100
  if response
64
101
  if %w(queued in_progress sending_webhook waiting_for_callback).include?(response["state"])
65
- puts "Run #{run_id} is #{response['state']} and is #{response['current_progress']['percent']}% complete"
102
+ logger.info "Run #{run_id} is #{response['state']} and is #{response['current_progress']['percent']}% complete"
66
103
  running = false if response["result"] == 'failed' && @options.failfast?
67
104
  else
68
- puts "Run #{run_id} is now #{response["state"]} and has #{response["result"]}"
105
+ logger.info "Run #{run_id} is now #{response["state"]} and has #{response["result"]}"
69
106
  running = false
70
107
  end
71
108
  end
@@ -121,8 +158,8 @@ module Rainforest
121
158
  begin
122
159
  URI.parse(url)
123
160
  rescue URI::InvalidURIError
124
- puts "The custom URL is invalid"
125
- exit 1
161
+ logger.fatal "The custom URL is invalid"
162
+ exit 2
126
163
  end
127
164
 
128
165
  env_post_body = { name: 'temporary-env-for-custom-url-via-CLI', url: url }
@@ -131,11 +168,15 @@ module Rainforest
131
168
  if environment['error']
132
169
  # I am talking about a URL here because the environments are pretty
133
170
  # much hidden from clients so far.
134
- puts "Error creating the ad-hoc URL: #{environment['error']}"
171
+ logger.fatal "Error creating the ad-hoc URL: #{environment['error']}"
135
172
  exit 1
136
173
  end
137
174
 
138
175
  return environment['id']
139
176
  end
177
+
178
+ def self.logger
179
+ @logger ||= Logger.new(STDOUT)
180
+ end
140
181
  end
141
182
  end
data/spec/cli_spec.rb CHANGED
@@ -9,28 +9,120 @@ describe Rainforest::Cli do
9
9
  let(:ok_progress) { {"state" => "in_progress", "current_progress" => {"percent" => "1"} } }
10
10
 
11
11
  context "with bad parameters" do
12
+ context "no token" do
13
+ let(:params) { %w(--custom-url http://ad-hoc.example.com) }
14
+ it 'errors out' do
15
+ expect_any_instance_of(Logger).to receive(:fatal).with('You must pass your API token using: --token TOKEN')
16
+ begin
17
+ described_class.start(params)
18
+ rescue SystemExit => e
19
+ # That's fine, this is expected but tested in a differnet assertion
20
+ end
21
+ end
22
+
23
+ it 'exits with exit code 2' do
24
+ expect {
25
+ described_class.start(params)
26
+ }.to raise_error { |error|
27
+ expect(error).to be_a(SystemExit)
28
+ expect(error.status).to eq 2
29
+ }
30
+ end
31
+ end
32
+
12
33
  context "with custom-url with no site-id" do
34
+ let(:params) { %w(--token x --custom-url http://ad-hoc.example.com) }
35
+
13
36
  it 'errors out' do
14
- expect(STDOUT).to receive(:puts).with('The site-id and custom-url options work together, you need both of them.')
37
+ expect_any_instance_of(Logger).to receive(:fatal).with('The site-id and custom-url options are both required.')
15
38
  begin
16
- described_class.start(%w(--custom-url http://ad-hoc.example.com))
39
+ described_class.start(params)
17
40
  rescue SystemExit => e
18
41
  # That's fine, this is expected but tested in a differnet assertion
19
42
  end
20
43
  end
21
44
 
22
- it 'exits with exit code 1' do
45
+ it 'exits with exit code 2' do
23
46
  expect {
24
- described_class.start(%w(--custom-url http://ad-hoc.example.com))
47
+ described_class.start(params)
25
48
  }.to raise_error { |error|
26
49
  expect(error).to be_a(SystemExit)
27
- expect(error.status).to eq 1
50
+ expect(error.status).to eq 2
28
51
  }
29
52
  end
30
53
  end
31
54
  end
32
55
 
56
+ context "git-trigger" do
57
+ let(:params) { %w(--token x --git-trigger) }
58
+ let(:commit_message) { 'a test commit message' }
59
+
60
+ def start_with_params(params, expected_exit_code = 2)
61
+ begin
62
+ described_class.start(params)
63
+ rescue SystemExit => error
64
+ expect(error.status).to eq expected_exit_code
65
+ end
66
+ end
67
+
68
+ before do
69
+ Rainforest::Cli::GitTrigger.stub(:last_commit_message) { commit_message }
70
+ end
71
+
72
+ describe "with tags parameter passed" do
73
+ let(:params) { %w(--token x --tag x --git-trigger) }
74
+
75
+ it "warns about the parameter being ignored" do
76
+ expect_any_instance_of(Logger).to receive(:warn).with("Specified tags are ignored when using --git-trigger")
77
+
78
+ start_with_params(params, 0)
79
+ end
80
+ end
81
+
82
+ describe "with tags parameter passed" do
83
+ let(:params) { %w(all --token x --git-trigger) }
84
+
85
+ it "warns about the parameter being ignored" do
86
+ expect_any_instance_of(Logger).to receive(:warn).with("Specified tests are ignored when using --git-trigger")
87
+
88
+ start_with_params(params, 0)
89
+ end
90
+ end
91
+
92
+ describe "with no @rainforest in the commit message" do
93
+ it "exit 0's and logs the reason" do
94
+ expect_any_instance_of(Logger).to receive(:info).with("Not triggering as @rainforest was not mentioned in last commit message.")
95
+ start_with_params(params, 0)
96
+ end
97
+ end
98
+
99
+ describe "with @rainforest in the commit message, but no tags" do
100
+ let(:commit_message) { 'a test commit message @rainforest' }
101
+
102
+ it "exit 2's and logs the reason" do
103
+ expect_any_instance_of(Logger).to receive(:error).with("Triggered via git, but no hashtags detected. Please use commit message format:")
104
+ expect_any_instance_of(Logger).to receive(:error).with("\t'some message. @rainforest #tag1 #tag2")
105
+
106
+ start_with_params(params, 2)
107
+ end
108
+ end
109
+
110
+ describe "with @rainforest in the commit message + hashtags" do
111
+ let(:commit_message) { 'a test commit message @rainforest #run-me' }
112
+
113
+ it "starts the run with the specified tags" do
114
+ expect(described_class).to receive(:post).with(
115
+ "http://app.rainforest.dev/api/1/runs",
116
+ { :tags=>['run-me'], :gem_version=>Rainforest::Cli::VERSION }
117
+ ).and_return( {} )
118
+
119
+ start_with_params(params, 0)
120
+ end
121
+ end
122
+ end
123
+
33
124
  context "with site-id and custom-url" do
125
+ let(:params) { %w(--token x --site 3 --custom-url http://ad-hoc.example.com) }
34
126
  it "creates a new environment" do
35
127
  allow(described_class).to receive(:post).and_return { exit }
36
128
  expect(described_class).to receive(:post).with(
@@ -48,7 +140,7 @@ describe Rainforest::Cli do
48
140
  # call, not the call to create a run, so I exit, but rescue from it here
49
141
  # so that the spec doesn't fail. It's horrible, sorry!
50
142
  begin
51
- described_class.start(%w(--site 3 --custom-url http://ad-hoc.example.com))
143
+ described_class.start(params)
52
144
  rescue SystemExit => e
53
145
  # That's fine, this is expected but tested in a differnet assertion
54
146
  end
@@ -59,9 +151,9 @@ describe Rainforest::Cli do
59
151
 
60
152
  expect(described_class).to receive(:post).with(
61
153
  "http://app.rainforest.dev/api/1/runs",
62
- { :tests=>[], :site_id=>3, :gem_version=>"0.0.13", :environment_id=>333 }
154
+ { :tests=>[], :site_id=>3, :gem_version=>Rainforest::Cli::VERSION, :environment_id=>333 }
63
155
  ).and_return( {} )
64
- described_class.start(%w(--site 3 --custom-url http://ad-hoc.example.com))
156
+ described_class.start(params)
65
157
  end
66
158
  end
67
159
 
@@ -104,12 +196,12 @@ describe Rainforest::Cli do
104
196
  describe ".get_environment_id" do
105
197
  context "with an invalid URL" do
106
198
  it 'errors out and exits' do
107
- expect(STDOUT).to receive(:puts).with("The custom URL is invalid")
199
+ expect_any_instance_of(Logger).to receive(:fatal).with("The custom URL is invalid")
108
200
  expect {
109
201
  described_class.get_environment_id('http://some=weird')
110
202
  }.to raise_error { |error|
111
203
  expect(error).to be_a(SystemExit)
112
- expect(error.status).to eq 1
204
+ expect(error.status).to eq 2
113
205
  }
114
206
  end
115
207
  end
@@ -120,7 +212,7 @@ describe Rainforest::Cli do
120
212
  end
121
213
 
122
214
  it 'errors out and exits' do
123
- expect(STDOUT).to receive(:puts).with("Error creating the ad-hoc URL: Some API error")
215
+ expect_any_instance_of(Logger).to receive(:fatal).with("Error creating the ad-hoc URL: Some API error")
124
216
  expect {
125
217
  described_class.get_environment_id('http://example.com')
126
218
  }.to raise_error { |error|
@@ -0,0 +1,29 @@
1
+ describe Rainforest::Cli::GitTrigger do
2
+ subject { described_class }
3
+
4
+ describe ".last_commit_message" do
5
+ it "returns a string" do
6
+ default_dir = Dir.pwd
7
+
8
+ Dir.chdir(File.join([default_dir, 'spec', 'test-repo']))
9
+ expect(described_class.last_commit_message).to eq "Initial commit"
10
+ Dir.chdir(default_dir)
11
+ end
12
+ end
13
+
14
+ describe ".git_trigger_should_run?" do
15
+ it "returns true when @rainforest is in the string" do
16
+ expect(described_class.git_trigger_should_run?('hello, world')).to eq false
17
+ expect(described_class.git_trigger_should_run?('hello @rainforest')).to eq true
18
+ end
19
+ end
20
+
21
+ describe ".extract_hashtags" do
22
+ it "returns a list of hashtags" do
23
+ expect(described_class.extract_hashtags('hello, world')).to eq []
24
+ expect(described_class.extract_hashtags('#hello, #world')).to eq ['hello', 'world']
25
+ expect(described_class.extract_hashtags('#hello,#world')).to eq ['hello', 'world']
26
+ expect(described_class.extract_hashtags('#dashes-work, #underscores_work #007')).to eq ['dashes-work', 'underscores_work', '007']
27
+ end
28
+ end
29
+ end
data/spec/options_spec.rb CHANGED
@@ -41,6 +41,12 @@ describe Rainforest::Cli::OptionParser do
41
41
  its(:browsers) { should == ["ie8", "chrome"]}
42
42
  end
43
43
 
44
+ context "it parses the --git-trigger flag" do
45
+ let(:args) { ["run", "--git-trigger", "all"] }
46
+ its(:tests) { should == ["all"]}
47
+ its(:git_trigger?) { should be_true }
48
+ end
49
+
44
50
  context "it parses the --fg flag" do
45
51
  let(:args) { ["run", "--fg", "all"] }
46
52
  its(:tests) { should == ["all"]}
data.tar.gz.sig CHANGED
@@ -1,2 +1,3 @@
1
- Z��Ki
2
- P3W�wl������Yj����ߌR
1
+ ^uMSy�1by��;.�)��3H"mn.[�yӃ3~���?��়�&BIO_-��<W�?��8貺tp�{�|��z�]�7�7���]Of}w
2
+ [N?zpw-va��|DN���]uT��@'@�r��X�����T��R[3k��S<�
3
+ HCӱ�$3ʁ�`Yn[-�-U�_�w�G���\WB�b�|G���G��&�"̈́�@�I�ۇB�<F��񧥺�j.�Y^��SNy�^�
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rainforest-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Mathieu
@@ -32,7 +32,7 @@ cert_chain:
32
32
  wWdLLpBZZ1O4GE0uzQovmTiis4iyCF+8tFIgjbM/FVwKUBV6OZpxs4FOBtR1mK6L
33
33
  lj0cPcKRm/FZUw==
34
34
  -----END CERTIFICATE-----
35
- date: 2014-09-08 00:00:00.000000000 Z
35
+ date: 2014-10-15 00:00:00.000000000 Z
36
36
  dependencies:
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: httparty
@@ -114,6 +114,7 @@ extensions: []
114
114
  extra_rdoc_files: []
115
115
  files:
116
116
  - ".gitignore"
117
+ - ".gitmodules"
117
118
  - ".rspec"
118
119
  - ".rvmrc"
119
120
  - ".travis.yml"
@@ -126,10 +127,12 @@ files:
126
127
  - certs/ukd1.pem
127
128
  - lib/rainforest/cli.rb
128
129
  - lib/rainforest/cli/csv_importer.rb
130
+ - lib/rainforest/cli/git_trigger.rb
129
131
  - lib/rainforest/cli/options.rb
130
132
  - lib/rainforest/cli/version.rb
131
133
  - rainforest-cli.gemspec
132
134
  - spec/cli_spec.rb
135
+ - spec/git_trigger_spec.rb
133
136
  - spec/options_spec.rb
134
137
  - spec/spec_helper.rb
135
138
  homepage: https://www.rainforestqa.com/
@@ -158,5 +161,6 @@ specification_version: 4
158
161
  summary: Command line utility for Rainforest QA
159
162
  test_files:
160
163
  - spec/cli_spec.rb
164
+ - spec/git_trigger_spec.rb
161
165
  - spec/options_spec.rb
162
166
  - spec/spec_helper.rb
metadata.gz.sig CHANGED
Binary file