gitarro 0.1.0

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 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: []