gitarro 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 21a43e24207cd6e412c688d57f5b72ed7ea32cec
4
+ data.tar.gz: 609ce571224ad1e2f22c07ac485827ecb9d58a48
5
+ SHA512:
6
+ metadata.gz: e15bf72520a193ba91c5c0a3a8d997e9d383602c79eee58268f23a8ee1d91a8cde6e6ff8548a94c43140d0e8a4b0e12365e04e0c0a05ff12de40c081f8e5c163
7
+ data.tar.gz: 340b3c242adc41878378ca5753ed4aa92ffbf0402fadffd4fc0a894f7477f603879d97abeedca827cd66243ea94d16490b94650430215c4d153a64e9e1cd19cc
data/bin/gitarro ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'English'
4
+ require 'octokit'
5
+ require 'optparse'
6
+ require 'gitarro/opt_parser'
7
+ require 'gitarro/git_op'
8
+ require 'gitarro/backend'
9
+
10
+ b = Backend.new
11
+ prs = b.open_prs
12
+
13
+ prs.each do |pr|
14
+ puts '=' * 30 + "\n" + "TITLE_PR: #{pr.title}, NR: #{pr.number}\n" + '=' * 30
15
+ # this check the last commit state, catch for review or not reviewd status.
16
+ comm_st = b.client.status(b.repo, pr.head.sha)
17
+ # pr number trigger.
18
+ break if b.trigger_by_pr_number(pr)
19
+ # retrigger if magic word found
20
+ b.retrigger_check(pr)
21
+ # check if changelog test was enabled
22
+ break if b.changelog_active(pr, comm_st)
23
+ # 0) do test for unreviewed pr
24
+ break if b.unreviewed_pr_test(pr, comm_st)
25
+ # we run the test in 2 conditions:
26
+ # 1) the context is not set, test didnt run
27
+ # 2) the pending status is set on commit, repeat always when pending set
28
+ # check the conditions 1,2 and it they happens run_test
29
+ break if b.reviewed_pr_test(comm_st, pr)
30
+ end
31
+ STDOUT.flush
32
+
33
+ # red balls for jenkins
34
+ exit 1 if b.j_status == 'failure'
@@ -0,0 +1,281 @@
1
+ #! /usr/bin/ruby
2
+
3
+ require 'octokit'
4
+ require 'optparse'
5
+ require 'English'
6
+ require_relative 'opt_parser'
7
+ require_relative 'git_op'
8
+
9
+ # This is a private class, which has the task to execute/run tests
10
+ # called by Backend
11
+ class TestExecutor
12
+ def initialize(options)
13
+ @options = options
14
+ @options.each do |key, value|
15
+ instance_variable_set("@#{key}", value)
16
+ self.class.send(:attr_accessor, key)
17
+ end
18
+ end
19
+
20
+ # this will clone the repo and execute the tests
21
+ def pr_test(pr)
22
+ git = GitOp.new(@git_dir, pr, @options)
23
+ # merge PR-branch to upstream branch
24
+ git.merge_pr_totarget(pr.base.ref, pr.head.ref)
25
+ # do valid tests and store the result
26
+ test_status = run_script
27
+ # del branch
28
+ git.del_pr_branch(pr.base.ref, pr.head.ref)
29
+ test_status
30
+ end
31
+
32
+ # run validation script for validating the PR.
33
+ def run_script
34
+ script_exists?(@test_file)
35
+ puts `#{@test_file}`
36
+ $CHILD_STATUS.exitstatus.nonzero? ? 'failure' : 'success'
37
+ end
38
+
39
+ private
40
+
41
+ def script_exists?(script)
42
+ n_exist = "\'#{script}\' doesn't exists.Enter valid file, -t option"
43
+ raise n_exist if File.file?(script) == false
44
+ end
45
+ end
46
+
47
+ # this the public class is the backend of gitarro,
48
+ # were we execute the tests and so on
49
+ class Backend
50
+ attr_accessor :j_status, :options, :client, :pr_files, :gbexec
51
+ # public method of backend
52
+ def initialize(option = nil)
53
+ Octokit.auto_paginate = true
54
+ @client = Octokit::Client.new(netrc: true)
55
+ @options = option.nil? ? OptParser.new.cmdline_options : option
56
+ @j_status = ''
57
+ @pr_files = []
58
+ # each options will generate a object variable dinamically
59
+ @options.each do |key, value|
60
+ instance_variable_set("@#{key}", value)
61
+ self.class.send(:attr_accessor, key)
62
+ end
63
+ @gbexec = TestExecutor.new(@options)
64
+ end
65
+
66
+ # public method for get prs opens
67
+ # given a repo
68
+ def open_prs
69
+ prs = @client.pull_requests(@repo, state: 'open')
70
+ puts 'no Pull request OPEN on the REPO!' unless prs.any?
71
+ prs
72
+ end
73
+
74
+ # public for etrigger the test
75
+ def retrigger_check(pr)
76
+ return unless retrigger_needed?(pr)
77
+ client.create_status(@repo, pr.head.sha, 'pending',
78
+ context: @context, description: @description,
79
+ target_url: @target_url)
80
+ exit 1 if @check
81
+ launch_test_and_setup_status(@repo, pr)
82
+ j_status == 'success' ? exit(0) : exit(1)
83
+ end
84
+
85
+ # public always rerun tests against the pr number if this exists
86
+ def trigger_by_pr_number(pr)
87
+ return false if @pr_number.nil?
88
+ return false if @pr_number != pr.number
89
+ puts "Got triggered by PR_NUMBER OPTION, rerunning on #{@pr_number}"
90
+ launch_test_and_setup_status(@repo, pr)
91
+ true
92
+ end
93
+
94
+ # public method, trigger changelogtest if option active
95
+ def changelog_active(pr, comm_st)
96
+ return false unless @changelog_test
97
+ return false unless changelog_changed(@repo, pr, comm_st)
98
+ true
99
+ end
100
+
101
+ def unreviewed_pr_test(pr, comm_st)
102
+ return unless unreviewed_pr_ck(comm_st)
103
+ pr_all_files_type(@repo, pr.number, @file_type)
104
+ return if empty_files_changed_by_pr
105
+ # gb.check is true when there is a job running as scheduler
106
+ # which doesn't execute the test but trigger another job
107
+ return false if @check
108
+ launch_test_and_setup_status(@repo, pr)
109
+ true
110
+ end
111
+
112
+ def reviewed_pr_test(comm_st, pr)
113
+ # if PR status is not on pending and the context is not set,
114
+ # we dont run the tests
115
+ return false unless context_pr(comm_st) == false ||
116
+ pending_pr(comm_st) == true
117
+ pr_all_files_type(@repo, pr.number, @file_type)
118
+ return true if changelog_active(pr, comm_st)
119
+ return false unless @pr_files.any?
120
+ exit 1 if @check
121
+ launch_test_and_setup_status(@repo, pr)
122
+ true
123
+ end
124
+
125
+ private
126
+
127
+ # this function setup first pending to PR, then execute the tests
128
+ # then set the status according to the results of script executed.
129
+ # pr_head = is the PR branch
130
+ # base = is a the upstream branch, where the pr targets
131
+ def launch_test_and_setup_status(repo, pr)
132
+ # pending
133
+ @client.create_status(repo, pr.head.sha, 'pending',
134
+ context: @context, description: @description,
135
+ target_url: @target_url)
136
+ # do tests
137
+ @j_status = gbexec.pr_test(pr)
138
+ # set status
139
+ @client.create_status(repo, pr.head.sha, @j_status,
140
+ context: @context, description: @description,
141
+ target_url: @target_url)
142
+ end
143
+
144
+ # this function will check if the PR contains in comment the magic word
145
+ # # for retrigger all the tests.
146
+ def magicword(repo, pr_number, context)
147
+ magic_word_trigger = "@gitarro rerun #{context} !!!"
148
+ pr_comment = @client.issue_comments(repo, pr_number)
149
+ # a pr contain always a comments, cannot be nil
150
+ pr_comment.each do |com|
151
+ # delete comment otherwise it will be retrigger infinetely
152
+ if com.body.include? magic_word_trigger
153
+ @client.delete_comment(repo, com.id)
154
+ return true
155
+ end
156
+ end
157
+ false
158
+ end
159
+
160
+ # check all files of a Prs Number if they are a specific type
161
+ # EX: Pr 56, we check if files are '.rb'
162
+ def pr_all_files_type(repo, pr_number, type)
163
+ files = @client.pull_request_files(repo, pr_number)
164
+ files.each do |file|
165
+ @pr_files.push(file.filename) if file.filename.include? type
166
+ end
167
+ end
168
+
169
+ # check if the commit of a pr is on pending
170
+ def pending_pr(comm_st)
171
+ # 2) pending
172
+ pending_on_context = false
173
+ (0..comm_st.statuses.size - 1).each do |pr_status|
174
+ if comm_st.statuses[pr_status]['context'] == @context &&
175
+ comm_st.statuses[pr_status]['state'] == 'pending'
176
+ pending_on_context = true
177
+ end
178
+ end
179
+ pending_on_context
180
+ end
181
+
182
+ # if the Pr contains magic word, test changelog
183
+ # is true
184
+ def magic_comment(repo, pr_num)
185
+ @client.issue_comments(repo, pr_num).each do |com|
186
+ if com.body.include?('no changelog needed!')
187
+ @j_status = 'success'
188
+ break
189
+ end
190
+ end
191
+ end
192
+
193
+ # check it the cm of pr contain the context from gitarro already
194
+ def context_pr(cm_st)
195
+ # 1) context_present == false triggers test. >
196
+ # this means the PR is not with context tagged
197
+ context_present = false
198
+ (0..cm_st.statuses.size - 1).each do |pr_status|
199
+ context_present = true if cm_st.statuses[pr_status]['context'] == @context
200
+ end
201
+ context_present
202
+ end
203
+
204
+ # if the pr has travis test and one custom, we will have 2 elements.
205
+ # in this case, if the 1st element doesn't have the state property
206
+ # state property is "pending", failure etc.
207
+ # if we don't have this, so we have 0 status
208
+ # the PRs is "unreviewed"
209
+ def unreviewed_pr_ck(comm_st)
210
+ puts comm_st.statuses[0]['state']
211
+ return false
212
+ rescue NoMethodError
213
+ return true
214
+ end
215
+
216
+ def success_status?(comm_st)
217
+ status = false
218
+ (0..comm_st.statuses.size - 1).each do |pr_status|
219
+ if comm_st.statuses[pr_status]['context'] == @context &&
220
+ comm_st.statuses[pr_status]['state'] == 'success'
221
+ status = true
222
+ end
223
+ end
224
+ status
225
+ end
226
+
227
+ def failed_status?(comm_st)
228
+ status = false
229
+ (0..comm_st.statuses.size - 1).each do |pr_status|
230
+ if comm_st.statuses[pr_status]['context'] == @context &&
231
+ comm_st.statuses[pr_status]['state'] == 'failure'
232
+ status = true
233
+ end
234
+ end
235
+ status
236
+ end
237
+
238
+ # control if the pr change add any files, specified
239
+ # it can be also a dir
240
+ def empty_files_changed_by_pr
241
+ return if pr_files.any?
242
+ puts "no files of type #{@file_type} found! skipping"
243
+ true
244
+ end
245
+
246
+ def do_changelog_test(repo, pr)
247
+ @j_status = 'failure'
248
+ pr_all_files_type(repo, pr.number, @file_type)
249
+ # if the pr contains changes on .changes file, test ok
250
+ @j_status = 'success' if @pr_files.any?
251
+ magic_comment(repo, pr.number)
252
+ @client.create_status(repo, pr.head.sha, @j_status,
253
+ context: @context, description: @description,
254
+ target_url: @target_url)
255
+ true
256
+ end
257
+
258
+ # do the changelog test and set status
259
+ def changelog_changed(repo, pr, comm_st)
260
+ return false unless @changelog_test
261
+ # only execute 1 time, don"t run if test is failed, or ok
262
+ return false if failed_status?(comm_st)
263
+ return false if success_status?(comm_st)
264
+ do_changelog_test(repo, pr)
265
+ end
266
+
267
+ def retrigger_needed?(pr)
268
+ # we want redo sometimes tests
269
+ return false unless magicword(@repo, pr.number, @context)
270
+ # changelog trigger
271
+ if @changelog_test
272
+ do_changelog_test(@repo, pr)
273
+ return false
274
+ end
275
+ pr_all_files_type(@repo, pr.number, @file_type)
276
+ return false unless @pr_files.any?
277
+ # if check is set, the comment in the trigger job will be del.
278
+ # so setting it to pending, it will be remembered
279
+ true
280
+ end
281
+ end
@@ -0,0 +1,128 @@
1
+ #! /usr/bin/ruby
2
+
3
+ require 'English'
4
+ require 'fileutils'
5
+ require 'timeout'
6
+
7
+ # git operation for gitarro
8
+ class GitOp
9
+ attr_reader :git_dir, :pr, :pr_fix, :repo_external, :repo_protocol
10
+ def initialize(git_dir, pr, options)
11
+ @git_dir = git_dir
12
+ # prefix for the test pr that gitarro tests.
13
+ @pr_fix = 'PR-'
14
+ # pr object for extract all relev. data.
15
+ @pr = pr
16
+ # All GitBot options
17
+ @options = options
18
+ # object to handle external repos
19
+ @repo_external = ExternalRepoGit.new(pr, options)
20
+ gh = 'https://github.com/'
21
+ gg = 'git@github.com:'
22
+ @repo_protocol = @options[:https] ? gh : gg
23
+ end
24
+
25
+ def ck_or_clone_git
26
+ return if File.directory?(git_dir)
27
+ FileUtils.mkdir_p(git_dir)
28
+ Dir.chdir git_dir
29
+ repo_url = "#{repo_protocol}#{@options[:repo]}.git"
30
+ puts `git clone #{repo_url}`
31
+ end
32
+
33
+ # this function merge the pr branch into target branch,
34
+ # where the author of pr wanted to submit
35
+ def goto_prj_dir
36
+ git_repo_dir = git_dir + '/' + @options[:repo].split('/')[1]
37
+ # chech that dir exist, otherwise clone it
38
+ ck_or_clone_git
39
+ begin
40
+ # /tmp/gitarro, this is in case the dir already exists
41
+ Dir.chdir git_repo_dir
42
+ rescue Errno::ENOENT
43
+ # this is in case we clone the repo
44
+ Dir.chdir @options[:repo].split('/')[1]
45
+ end
46
+ end
47
+
48
+ def check_git_dir
49
+ msg_err = 'gitarro is not working on a git directory'
50
+ raise msg_err if File.directory?('.git') == false
51
+ end
52
+
53
+ # this is for preventing that a test branch exists already
54
+ # and we have some internal error
55
+ def check_duplicata_pr_branch(pr)
56
+ puts `git branch --list #{pr}`
57
+ `git branch -D #{pr} 2>/dev/null` if $CHILD_STATUS.exitstatus.zero?
58
+ end
59
+
60
+ # merge pr_branch into upstream targeted branch
61
+ def merge_pr_totarget(upstream, pr_branch)
62
+ goto_prj_dir
63
+ check_git_dir
64
+ `git checkout #{upstream}`
65
+ check_duplicata_pr_branch("#{pr_fix}#{pr_branch}")
66
+ `git remote update`
67
+ `git fetch`
68
+ `git pull origin #{upstream}`
69
+ `git checkout -b #{pr_fix}#{pr_branch} origin/#{pr_branch}`
70
+ return if $CHILD_STATUS.exitstatus.zero?
71
+ # if it fails the PR contain a forked external repo
72
+ repo_external.checkout_into
73
+ end
74
+
75
+ # cleanup the pr_branch(delete it)
76
+ def del_pr_branch(upstream, pr)
77
+ `git checkout #{upstream}`
78
+ `git branch -D #{pr_fix}#{pr}`
79
+ end
80
+ end
81
+
82
+ # This private class handle the case the repo from PR
83
+ # comes from a user external repo
84
+ # PR open against: openSUSE/gitarro
85
+ # PR repo: MyUSER/gitarro
86
+ class ExternalRepoGit
87
+ attr_reader :pr, :rem_repo, :pr_fix
88
+ def initialize(pr, options)
89
+ # pr object for extract all relev. data.
90
+ @pr = pr
91
+ @pr_fix = 'PR-'
92
+ @options = options
93
+ end
94
+
95
+ def checkout_into
96
+ rem_repo = 'rem' + pr.head.ref
97
+ add_remote(rem_repo)
98
+ fetch_remote(rem_repo)
99
+ checkout_to_rem_branch(rem_repo)
100
+ remove_repo(rem_repo)
101
+ end
102
+
103
+ private
104
+
105
+ def checkout_to_rem_branch(rem_repo)
106
+ puts `git checkout -b #{pr_fix}#{branch_rem} #{rem_repo}/#{branch_rem}`
107
+ exit 1 if $CHILD_STATUS.exitstatus.nonzero?
108
+ end
109
+
110
+ def branch_rem
111
+ pr.head.ref
112
+ end
113
+
114
+ def add_remote(rem_repo)
115
+ repo_url = @options[:https] ? pr.head.repo.html_url : pr.head.repo.ssh_url
116
+ puts `git remote add #{rem_repo} #{repo_url}`
117
+ end
118
+
119
+ def fetch_remote(rem_repo)
120
+ puts `git remote update`
121
+ puts `git fetch`
122
+ puts `git pull #{rem_repo} #{pr.head.ref}`
123
+ end
124
+
125
+ def remove_repo(rem_repo)
126
+ puts `git remote remove #{rem_repo}`
127
+ end
128
+ end
@@ -0,0 +1,197 @@
1
+ #! /usr/bin/ruby
2
+
3
+ # this are the mandatory options
4
+ module MandatoryOptions
5
+ # primary
6
+ def context_opt(opt)
7
+ desc = 'Context to set on comment (test name). For example: python-test.'
8
+ opt.on('-c', "--context 'CONTEXT'", desc) do |context|
9
+ @options[:context] = context
10
+ end
11
+ end
12
+
13
+ def repo_opt(opt)
14
+ desc = 'GitHub repository to look for PRs. For example: openSUSE/gitarro.'
15
+ opt.on('-r', "--repo 'REPO'", desc) { |repo| @options[:repo] = repo }
16
+ end
17
+
18
+ def test_opt(opt)
19
+ desc = 'Command, or full path to script/binary to be used to run the test.'
20
+ opt.on('-t', "--test 'TEST.SH'", desc) do |test_file|
21
+ @options[:test_file] = test_file
22
+ end
23
+ end
24
+
25
+ def file_opt(opt)
26
+ file_description = 'pr_file type to run the test against: .py, .rb'
27
+ opt.on('-f', "--file \'.py\'", file_description) do |file_type|
28
+ @options[:file_type] = file_type
29
+ end
30
+ end
31
+
32
+ def git_opt(opt)
33
+ desc = 'Specify a location where gitarro will clone the GitHub project. '\
34
+ 'If the dir does not exists, gitarro will create one. '\
35
+ 'For example: /tmp/'
36
+ opt.on('-g', "--git_dir 'GIT_LOCAL_DIR'", desc) do |git_dir|
37
+ @options[:git_dir] = git_dir
38
+ end
39
+ end
40
+
41
+ def mandatory_options(opt)
42
+ opt.separator 'Mandatory options:'
43
+ repo_opt(opt)
44
+ context_opt(opt)
45
+ test_opt(opt)
46
+ file_opt(opt)
47
+ git_opt(opt)
48
+ end
49
+ end
50
+
51
+ # this are the optional options
52
+ module OptionalOptions
53
+ def check_opt(opt)
54
+ desc = 'Check if there is any PR requiring a test, but do not run it.'
55
+ opt.on('-C', '--check', desc) { |check| @options[:check] = check }
56
+ end
57
+
58
+ def desc_opt(opt)
59
+ opt.on('-d', "--description 'DESCRIPTION'", 'Test decription') do |d|
60
+ @options[:description] = d
61
+ end
62
+ end
63
+
64
+ def url_opt(opt)
65
+ desc = 'Specify the URL to append to add to the GitHub review. ' \
66
+ 'Usually you will use an URL to the Jenkins build log.'
67
+ opt.on('-u', "--url 'TARGET_URL'", desc) do |target_url|
68
+ @options[:target_url] = target_url
69
+ end
70
+ end
71
+
72
+ def https_opt(opt)
73
+ https_desc = 'If present, use https instead of ssh for git operations'
74
+ opt.on('--https', https_desc) { |https| @options[:https] = https }
75
+ end
76
+
77
+ def changelog_opt(opt)
78
+ desc = 'Check if the PR includes a changelog entry ' \
79
+ '(Automatically sets --file ".changes").'
80
+ opt.on('--changelogtest', desc) do |changelogtest|
81
+ @options[:changelog_test] = changelogtest
82
+ end
83
+ end
84
+
85
+ def pr_number(opt)
86
+ desc = 'Specify the PR number instead of checking all of them. ' \
87
+ 'Force to rerun against a specific PR number,' \
88
+ 'even if it is not needed.'
89
+ opt.on('-P', "--PR 'NUMBER'", desc) do |pr_number|
90
+ @options[:pr_number] = Integer(pr_number)
91
+ end
92
+ end
93
+
94
+ def optional_options(opt)
95
+ opt.separator ''
96
+ opt.separator 'Optional options:'
97
+ desc_opt(opt)
98
+ check_opt(opt)
99
+ changelog_opt(opt)
100
+ url_opt(opt)
101
+ pr_number(opt)
102
+ https_opt(opt)
103
+ end
104
+ end
105
+
106
+ # this class is only private and helper for main class OptParser
107
+ class OptParserInternal
108
+ include MandatoryOptions
109
+ include OptionalOptions
110
+ attr_accessor :options
111
+ def initialize
112
+ @options = {}
113
+ @options = options.clone if options.any?
114
+ end
115
+
116
+ # all this methods are private
117
+ def raise_incorrect_syntax(msg)
118
+ puts "Incorrect syntax: #{msg}\n\n"
119
+ puts 'Use option -h for help'
120
+ exit 1
121
+ end
122
+
123
+ def ck_mandatory_option(option)
124
+ return unless @options[option.to_sym].nil?
125
+ raise_incorrect_syntax("option --#{option} not found")
126
+ end
127
+
128
+ def parse(opt_parser)
129
+ parse_options(opt_parser)
130
+ mandatory_options = %w[repo context test_file file_type git_dir]
131
+ mandatory_options.each { |opt| ck_mandatory_option(opt) }
132
+ if @options[:test_file].nil? && @options[:changelog_test].nil?
133
+ raise_incorrect_syntax('Incorrect syntax (use -h for help)')
134
+ end
135
+ defaults_false
136
+ defaults_to_text
137
+ end
138
+
139
+ # option help
140
+ def option_help(opt)
141
+ opt.separator ''
142
+ opt.separator 'Help:'
143
+ opt.on('-h', '--help', 'help') do
144
+ opt.separator ''
145
+ opt.separator "Example: gitarro.rb -r openSUSE/gitarro -c 'python-test' "\
146
+ "-d 'someCoolTest' -g /tmp/pr-ruby01/ -t /tmp/test.sh "\
147
+ "-f '.py'"
148
+ puts @opt_parser
149
+ exit 0
150
+ end
151
+ end
152
+
153
+ private
154
+
155
+ def parse_options(opt_parser)
156
+ opt_parser.parse!
157
+ rescue OptionParser::ParseError
158
+ raise_incorrect_syntax($ERROR_INFO.to_s)
159
+ end
160
+
161
+ # set some default values
162
+ def defaults_false
163
+ @options[:check] = false if @options[:check].nil?
164
+ @options[:changelog_test] = false if @options[:changelog_test].nil?
165
+ @options[:target_url] = '' if @options[:target_url].nil?
166
+ @options[:https] = false if @options[:https].nil?
167
+ end
168
+
169
+ def defaults_to_text
170
+ desc = 'use option -d to set a custom test description.'
171
+ @options[:file_type] = '.changes' if @options[:changelog_test]
172
+ @options[:description] = desc if @options[:description].nil?
173
+ end
174
+ end
175
+
176
+ # Opt_parser class, is for getting needed options
177
+ # this is the public class used by backend
178
+ class OptParser < OptParserInternal
179
+ private
180
+
181
+ def option_banner(opt)
182
+ opt.banner = "Usage: gitarro.rb [options]\n\n" \
183
+ end
184
+
185
+ public
186
+
187
+ def cmdline_options
188
+ @opt_parser = OptionParser.new do |opt|
189
+ option_banner(opt)
190
+ mandatory_options(opt)
191
+ optional_options(opt)
192
+ option_help(opt)
193
+ end
194
+ parse(@opt_parser)
195
+ @options
196
+ end
197
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gitarro
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Dario Maiocchi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-09-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: english
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.9'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest-reporters
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: netrc
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.11'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: octokit
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.7'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.5'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.5'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.49'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.49'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.6'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.6'
125
+ description: gitarro run tests on GitHub PRs using almost any script,language or binary,
126
+ it integrate easy with other tools.
127
+ email: dmaiocchi@suse.com
128
+ executables:
129
+ - gitarro
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - bin/gitarro
134
+ - lib/gitarro/backend.rb
135
+ - lib/gitarro/git_op.rb
136
+ - lib/gitarro/opt_parser.rb
137
+ homepage: https://github.com/openSUSE/gitarro
138
+ licenses:
139
+ - MIT
140
+ metadata: {}
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubyforge_project:
157
+ rubygems_version: 2.5.2
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: gitarro gem
161
+ test_files: []