rainforest-cli 0.0.14 → 0.0.15

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 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