github_changelog_generator 1.3.11 → 1.4.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 +4 -4
- data/.coveralls.yml +1 -0
- data/.hound.yml +2 -0
- data/.rspec +2 -0
- data/.rubocop.yml +8 -0
- data/.rubocop_todo.yml +81 -0
- data/.travis.yml +12 -10
- data/CHANGELOG.md +145 -113
- data/Gemfile +14 -4
- data/Gemfile.lock +75 -11
- data/README.md +17 -1
- data/Rakefile +5 -7
- data/bin/github_changelog_generator +2 -2
- data/bump_gemfile.rb +42 -48
- data/github_changelog_generator.gemspec +9 -10
- data/lib/CHANGELOG.md +2 -0
- data/lib/github_changelog_generator.rb +194 -346
- data/lib/github_changelog_generator/fetcher.rb +209 -0
- data/lib/github_changelog_generator/generator.rb +11 -8
- data/lib/github_changelog_generator/parser.rb +99 -86
- data/lib/github_changelog_generator/reader.rb +87 -0
- data/lib/github_changelog_generator/version.rb +1 -1
- data/spec/files/angular.js.md +9395 -0
- data/spec/files/bundler.md +1911 -0
- data/spec/files/github-changelog-generator.md +305 -0
- data/spec/spec_helper.rb +117 -0
- data/spec/unit/reader_spec.rb +113 -0
- metadata +22 -4
@@ -0,0 +1,209 @@
|
|
1
|
+
require "logger"
|
2
|
+
|
3
|
+
module GitHubChangelogGenerator
|
4
|
+
# A Fetcher responsible for all requests to GitHub and all basic manipulation with related data
|
5
|
+
# (such as filtering, validating, e.t.c)
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
# fetcher = GitHubChangelogGenerator::Fetcher.new options
|
9
|
+
class Fetcher
|
10
|
+
PER_PAGE_NUMBER = 30
|
11
|
+
GH_RATE_LIMIT_EXCEEDED_MSG = "Warning: GitHub API rate limit (5000 per hour) exceeded, change log may be " \
|
12
|
+
"missing some issues. You can limit the number of issues fetched using the `--max-issues NUM` argument."
|
13
|
+
|
14
|
+
def initialize(options = {})
|
15
|
+
@options = options
|
16
|
+
|
17
|
+
@user = @options[:user]
|
18
|
+
@project = @options[:project]
|
19
|
+
@github_token = fetch_github_token
|
20
|
+
@tag_times_hash = {}
|
21
|
+
|
22
|
+
@logger = Logger.new(STDOUT)
|
23
|
+
@logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
24
|
+
"#{msg}\n"
|
25
|
+
end
|
26
|
+
github_options = { per_page: PER_PAGE_NUMBER }
|
27
|
+
github_options[:oauth_token] = @github_token unless @github_token.nil?
|
28
|
+
github_options[:endpoint] = options[:github_endpoint] unless options[:github_endpoint].nil?
|
29
|
+
github_options[:site] = options[:github_endpoint] unless options[:github_site].nil?
|
30
|
+
|
31
|
+
begin
|
32
|
+
@github = Github.new github_options
|
33
|
+
rescue
|
34
|
+
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns GitHub token. First try to use variable, provided by --token option,
|
39
|
+
# otherwise try to fetch it from CHANGELOG_GITHUB_TOKEN env variable.
|
40
|
+
#
|
41
|
+
# @return [String]
|
42
|
+
def fetch_github_token
|
43
|
+
env_var = @options[:token] ? @options[:token] : (ENV.fetch "CHANGELOG_GITHUB_TOKEN", nil)
|
44
|
+
|
45
|
+
unless env_var
|
46
|
+
@logger.warn "Warning: No token provided (-t option) and variable $CHANGELOG_GITHUB_TOKEN was not found.".yellow
|
47
|
+
@logger.warn "This script can make only 50 requests to GitHub API per hour without token!".yellow
|
48
|
+
end
|
49
|
+
|
50
|
+
env_var
|
51
|
+
end
|
52
|
+
|
53
|
+
# Fetch all tags from repo
|
54
|
+
# @return [Array] array of tags
|
55
|
+
def get_all_tags
|
56
|
+
if @options[:verbose]
|
57
|
+
print "Fetching tags...\r"
|
58
|
+
end
|
59
|
+
|
60
|
+
tags = []
|
61
|
+
|
62
|
+
begin
|
63
|
+
response = @github.repos.tags @options[:user], @options[:project]
|
64
|
+
page_i = 0
|
65
|
+
count_pages = response.count_pages
|
66
|
+
response.each_page do |page|
|
67
|
+
page_i += PER_PAGE_NUMBER
|
68
|
+
print "Fetching tags... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r"
|
69
|
+
tags.concat(page)
|
70
|
+
end
|
71
|
+
print " \r"
|
72
|
+
|
73
|
+
if tags.count == 0
|
74
|
+
@logger.warn "Warning: Can't find any tags in repo.\
|
75
|
+
Make sure, that you push tags to remote repo via 'git push --tags'".yellow
|
76
|
+
elsif @options[:verbose]
|
77
|
+
@logger.info "Found #{tags.count} tags"
|
78
|
+
end
|
79
|
+
|
80
|
+
rescue
|
81
|
+
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
82
|
+
end
|
83
|
+
|
84
|
+
tags
|
85
|
+
end
|
86
|
+
|
87
|
+
# This method fetch all closed issues and separate them to pull requests and pure issues
|
88
|
+
# (pull request is kind of issue in term of GitHub)
|
89
|
+
# @return [Tuple] with issues and pull requests
|
90
|
+
def fetch_issues_and_pull_requests
|
91
|
+
if @options[:verbose]
|
92
|
+
print "Fetching closed issues...\r"
|
93
|
+
end
|
94
|
+
issues = []
|
95
|
+
|
96
|
+
begin
|
97
|
+
response = @github.issues.list user: @options[:user],
|
98
|
+
repo: @options[:project],
|
99
|
+
state: "closed",
|
100
|
+
filter: "all",
|
101
|
+
labels: nil
|
102
|
+
page_i = 0
|
103
|
+
count_pages = response.count_pages
|
104
|
+
response.each_page do |page|
|
105
|
+
page_i += PER_PAGE_NUMBER
|
106
|
+
print "Fetching issues... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r"
|
107
|
+
issues.concat(page)
|
108
|
+
break if @options[:max_issues] && issues.length >= @options[:max_issues]
|
109
|
+
end
|
110
|
+
rescue
|
111
|
+
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
112
|
+
end
|
113
|
+
|
114
|
+
print " \r"
|
115
|
+
|
116
|
+
if @options[:verbose]
|
117
|
+
@logger.info "Received issues: #{issues.count}"
|
118
|
+
end
|
119
|
+
|
120
|
+
# remove pull request from issues:
|
121
|
+
issues.partition { |x|
|
122
|
+
x[:pull_request].nil?
|
123
|
+
}
|
124
|
+
end
|
125
|
+
|
126
|
+
# Fetch all pull requests. We need them to detect :merged_at parameter
|
127
|
+
# @return [Array] all pull requests
|
128
|
+
def fetch_pull_requests
|
129
|
+
pull_requests = []
|
130
|
+
begin
|
131
|
+
response = @github.pull_requests.list @options[:user], @options[:project], state: "closed"
|
132
|
+
page_i = 0
|
133
|
+
response.each_page do |page|
|
134
|
+
page_i += PER_PAGE_NUMBER
|
135
|
+
count_pages = response.count_pages
|
136
|
+
print "Fetching merged dates... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r"
|
137
|
+
pull_requests.concat(page)
|
138
|
+
end
|
139
|
+
rescue
|
140
|
+
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
141
|
+
end
|
142
|
+
|
143
|
+
print " \r"
|
144
|
+
pull_requests
|
145
|
+
end
|
146
|
+
|
147
|
+
# Fetch event for all issues and add them to :events
|
148
|
+
# @param [Array] issues
|
149
|
+
# @return [Void]
|
150
|
+
def fetch_events_async(issues)
|
151
|
+
i = 0
|
152
|
+
max_thread_number = 50
|
153
|
+
threads = []
|
154
|
+
issues.each_slice(max_thread_number) { |issues_slice|
|
155
|
+
issues_slice.each { |issue|
|
156
|
+
threads << Thread.new {
|
157
|
+
begin
|
158
|
+
obj = @github.issues.events.list user: @options[:user],
|
159
|
+
repo: @options[:project],
|
160
|
+
issue_number: issue["number"]
|
161
|
+
rescue
|
162
|
+
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
163
|
+
end
|
164
|
+
issue[:events] = obj.body
|
165
|
+
print "Fetching events for issues and PR: #{i + 1}/#{issues.count}\r"
|
166
|
+
i += 1
|
167
|
+
}
|
168
|
+
}
|
169
|
+
threads.each(&:join)
|
170
|
+
threads = []
|
171
|
+
}
|
172
|
+
|
173
|
+
# to clear line from prev print
|
174
|
+
print " \r"
|
175
|
+
|
176
|
+
if @options[:verbose]
|
177
|
+
@logger.info "Fetching events for issues and PR: #{i} Done!"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Try to find tag date in local hash.
|
182
|
+
# Otherwise fFetch tag time and put it to local hash file.
|
183
|
+
# @param [String] tag_name name of the tag
|
184
|
+
# @return [Time] time of specified tag
|
185
|
+
def get_time_of_tag(tag_name)
|
186
|
+
fail ChangelogGeneratorError, "tag_name is nil".red if tag_name.nil?
|
187
|
+
|
188
|
+
if @tag_times_hash[tag_name["name"]]
|
189
|
+
return @tag_times_hash[tag_name["name"]]
|
190
|
+
end
|
191
|
+
|
192
|
+
begin
|
193
|
+
github_git_data_commits_get = @github.git_data.commits.get @options[:user],
|
194
|
+
@options[:project],
|
195
|
+
tag_name["commit"]["sha"]
|
196
|
+
rescue
|
197
|
+
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
198
|
+
end
|
199
|
+
time_string = github_git_data_commits_get["committer"]["date"]
|
200
|
+
@tag_times_hash[tag_name["name"]] = Time.parse(time_string)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Fetch commit for specifed event
|
204
|
+
# @return [Hash]
|
205
|
+
def fetch_commit(event)
|
206
|
+
@github.git_data.commits.get @options[:user], @options[:project], event[:commit_id]
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
@@ -1,12 +1,18 @@
|
|
1
1
|
module GitHubChangelogGenerator
|
2
2
|
class Generator
|
3
|
-
|
4
3
|
def initialize(options = nil)
|
5
4
|
@options = options
|
6
5
|
end
|
7
6
|
|
7
|
+
# Parse issue and generate single line formatted issue line.
|
8
|
+
#
|
9
|
+
# Example output:
|
10
|
+
# - Add coveralls integration [\#223](https://github.com/skywinder/github-changelog-generator/pull/223) ([skywinder](https://github.com/skywinder))
|
11
|
+
#
|
12
|
+
# @param [Hash] issue Fetched issue from GitHub
|
13
|
+
# @return [String] Markdown-formatted single issue
|
8
14
|
def get_string_for_issue(issue)
|
9
|
-
encapsulated_title =
|
15
|
+
encapsulated_title = encapsulate_string issue[:title]
|
10
16
|
|
11
17
|
title_with_number = "#{encapsulated_title} [\\##{issue[:number]}](#{issue.html_url})"
|
12
18
|
|
@@ -23,17 +29,14 @@ module GitHubChangelogGenerator
|
|
23
29
|
end
|
24
30
|
|
25
31
|
def encapsulate_string(string)
|
26
|
-
|
27
32
|
string.gsub! '\\', '\\\\'
|
28
33
|
|
29
34
|
encpas_chars = %w(> * _ \( \) [ ] #)
|
30
|
-
encpas_chars.each
|
35
|
+
encpas_chars.each do |char|
|
31
36
|
string.gsub! char, "\\#{char}"
|
32
|
-
|
37
|
+
end
|
33
38
|
|
34
39
|
string
|
35
40
|
end
|
36
|
-
|
37
41
|
end
|
38
|
-
|
39
|
-
end
|
42
|
+
end
|
@@ -1,114 +1,142 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require_relative
|
2
|
+
require "optparse"
|
3
|
+
require "pp"
|
4
|
+
require_relative "version"
|
5
5
|
|
6
6
|
module GitHubChangelogGenerator
|
7
7
|
class Parser
|
8
8
|
def self.parse_options
|
9
|
-
|
10
9
|
options = {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
10
|
+
tag1: nil,
|
11
|
+
tag2: nil,
|
12
|
+
dateformat: "%Y-%m-%d",
|
13
|
+
output: "CHANGELOG.md",
|
14
|
+
issues: true,
|
15
|
+
add_issues_wo_labels: true,
|
16
|
+
add_pr_wo_labels: true,
|
17
|
+
pulls: true,
|
18
|
+
filter_issues_by_milestone: true,
|
19
|
+
author: true,
|
20
|
+
unreleased: true,
|
21
|
+
unreleased_label: "Unreleased",
|
22
|
+
compare_link: true,
|
23
|
+
include_labels: %w(bug enhancement),
|
24
|
+
exclude_labels: %w(duplicate question invalid wontfix),
|
25
|
+
max_issues: nil,
|
26
|
+
simple_list: false,
|
27
|
+
verbose: true,
|
28
|
+
|
29
|
+
merge_prefix: "**Merged pull requests:**",
|
30
|
+
issue_prefix: "**Closed issues:**",
|
31
|
+
bug_prefix: "**Fixed bugs:**",
|
32
|
+
enhancement_prefix: "**Implemented enhancements:**",
|
33
|
+
branch: "origin"
|
31
34
|
}
|
32
35
|
|
33
|
-
parser = OptionParser.new
|
34
|
-
opts.banner =
|
35
|
-
opts.on(
|
36
|
+
parser = OptionParser.new do |opts|
|
37
|
+
opts.banner = "Usage: github_changelog_generator [options]"
|
38
|
+
opts.on("-u", "--user [USER]", "Username of the owner of target GitHub repo") do |last|
|
36
39
|
options[:user] = last
|
37
40
|
end
|
38
|
-
opts.on(
|
41
|
+
opts.on("-p", "--project [PROJECT]", "Name of project on GitHub") do |last|
|
39
42
|
options[:project] = last
|
40
43
|
end
|
41
|
-
opts.on(
|
44
|
+
opts.on("-t", "--token [TOKEN]", "To make more than 50 requests per hour your GitHub token is required. You can generate it at: https://github.com/settings/tokens/new") do |last|
|
42
45
|
options[:token] = last
|
43
46
|
end
|
44
|
-
opts.on(
|
45
|
-
options[:
|
47
|
+
opts.on("-f", "--date-format [FORMAT]", "Date format. Default is %Y-%m-%d") do |last|
|
48
|
+
options[:dateformat] = last
|
46
49
|
end
|
47
|
-
opts.on(
|
50
|
+
opts.on("-o", "--output [NAME]", "Output file. Default is CHANGELOG.md") do |last|
|
48
51
|
options[:output] = last
|
49
52
|
end
|
50
|
-
opts.on(
|
53
|
+
opts.on("--[no-]issues", "Include closed issues in changelog. Default is true") do |v|
|
51
54
|
options[:issues] = v
|
52
55
|
end
|
53
|
-
opts.on(
|
56
|
+
opts.on("--[no-]issues-wo-labels", "Include closed issues without labels in changelog. Default is true") do |v|
|
54
57
|
options[:add_issues_wo_labels] = v
|
55
58
|
end
|
56
|
-
opts.on(
|
59
|
+
opts.on("--[no-]pr-wo-labels", "Include pull requests without labels in changelog. Default is true") do |v|
|
57
60
|
options[:add_pr_wo_labels] = v
|
58
61
|
end
|
59
|
-
opts.on(
|
62
|
+
opts.on("--[no-]pull-requests", "Include pull-requests in changelog. Default is true") do |v|
|
60
63
|
options[:pulls] = v
|
61
64
|
end
|
62
|
-
opts.on(
|
65
|
+
opts.on("--[no-]filter-by-milestone", "Use milestone to detect when issue was resolved. Default is true") do |last|
|
63
66
|
options[:filter_issues_by_milestone] = last
|
64
67
|
end
|
65
|
-
opts.on(
|
68
|
+
opts.on("--[no-]author", "Add author of pull-request in the end. Default is true") do |author|
|
66
69
|
options[:author] = author
|
67
70
|
end
|
68
|
-
opts.on(
|
71
|
+
opts.on("--unreleased-only", "Generate log from unreleased closed issues only.") do |v|
|
69
72
|
options[:unreleased_only] = v
|
70
73
|
end
|
71
|
-
opts.on(
|
74
|
+
opts.on("--[no-]unreleased", "Add to log unreleased closed issues. Default is true") do |v|
|
72
75
|
options[:unreleased] = v
|
73
76
|
end
|
74
|
-
opts.on(
|
77
|
+
opts.on("--unreleased-label [label]", "Add to log unreleased closed issues. Default is true") do |v|
|
75
78
|
options[:unreleased_label] = v
|
76
79
|
end
|
77
|
-
opts.on(
|
80
|
+
opts.on("--[no-]compare-link", "Include compare link (Full Changelog) between older version and newer version. Default is true") do |v|
|
78
81
|
options[:compare_link] = v
|
79
82
|
end
|
80
|
-
opts.on(
|
83
|
+
opts.on("--include-labels x,y,z", Array, 'Only issues with the specified labels will be included in the changelog. Default is \'bug,enhancement\'') do |list|
|
81
84
|
options[:include_labels] = list
|
82
85
|
end
|
83
|
-
opts.on(
|
86
|
+
opts.on("--exclude-labels x,y,z", Array, 'Issues with the specified labels will be always excluded from changelog. Default is \'duplicate,question,invalid,wontfix\'') do |list|
|
84
87
|
options[:exclude_labels] = list
|
85
88
|
end
|
86
|
-
opts.on(
|
89
|
+
opts.on("--max-issues [NUMBER]", Integer, "Max number of issues to fetch from GitHub. Default is unlimited") do |max|
|
90
|
+
options[:max_issues] = max
|
91
|
+
end
|
92
|
+
opts.on("--github-site [URL]", "The Enterprise Github site on which your project is hosted.") do |last|
|
87
93
|
options[:github_site] = last
|
88
94
|
end
|
89
|
-
opts.on(
|
95
|
+
opts.on("--github-api [URL]", "The enterprise endpoint to use for your Github API.") do |last|
|
90
96
|
options[:github_endpoint] = last
|
91
97
|
end
|
92
|
-
opts.on(
|
98
|
+
opts.on("--simple-list", "Create simple list from issues and pull requests. Default is false.") do |v|
|
93
99
|
options[:simple_list] = v
|
94
100
|
end
|
95
|
-
opts.on(
|
101
|
+
opts.on("--[no-]verbose", "Run verbosely. Default is true") do |v|
|
96
102
|
options[:verbose] = v
|
97
103
|
end
|
98
|
-
opts.on(
|
104
|
+
opts.on("-v", "--version", "Print version number") do |_v|
|
99
105
|
puts "Version: #{GitHubChangelogGenerator::VERSION}"
|
100
106
|
exit
|
101
107
|
end
|
102
|
-
opts.on(
|
108
|
+
opts.on("-h", "--help", "Displays Help") do
|
103
109
|
puts opts
|
104
110
|
exit
|
105
111
|
end
|
106
|
-
|
112
|
+
end
|
107
113
|
|
108
114
|
parser.parse!
|
109
115
|
|
116
|
+
detect_user_and_project(options)
|
117
|
+
|
118
|
+
if !options[:user] || !options[:project]
|
119
|
+
puts parser.banner
|
120
|
+
exit
|
121
|
+
end
|
122
|
+
|
123
|
+
if ARGV[1]
|
124
|
+
options[:tag1] = ARGV[0]
|
125
|
+
options[:tag2] = ARGV[1]
|
126
|
+
end
|
127
|
+
|
128
|
+
if options[:verbose]
|
129
|
+
puts "Performing task with options:"
|
130
|
+
pp options
|
131
|
+
puts ""
|
132
|
+
end
|
133
|
+
|
134
|
+
options
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.detect_user_and_project(options)
|
110
138
|
if ARGV[0] && !ARGV[1]
|
111
|
-
github_site = options[:github_site] ? options[:github_site] :
|
139
|
+
github_site = options[:github_site] ? options[:github_site] : "github.com"
|
112
140
|
# this match should parse strings such "https://github.com/skywinder/Github-Changelog-Generator" or "skywinder/Github-Changelog-Generator" to user and name
|
113
141
|
match = /(?:.+#{Regexp.escape(github_site)}\/)?(.+)\/(.+)/.match(ARGV[0])
|
114
142
|
|
@@ -122,52 +150,37 @@ module GitHubChangelogGenerator
|
|
122
150
|
exit
|
123
151
|
else
|
124
152
|
options[:user] = match[1]
|
125
|
-
options[:project]= match[2]
|
153
|
+
options[:project] = match[2]
|
126
154
|
end
|
127
155
|
|
128
|
-
|
129
156
|
end
|
130
157
|
|
131
158
|
if !options[:user] && !options[:project]
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
# git@github.com:skywinder/Github-Changelog-Generator.git
|
136
|
-
match = /.*(?:[:\/])((?:-|\w|\.)*)\/((?:-|\w|\.)*)(?:\.git).*/.match(remote)
|
137
|
-
|
138
|
-
if match && match[1] && match[2]
|
139
|
-
puts "Detected user:#{match[1]}, project:#{match[2]}"
|
140
|
-
options[:user], options[:project] = match[1], match[2]
|
159
|
+
if ENV["RUBYLIB"] =~ /ruby-debug-ide/
|
160
|
+
options[:user] = "skywinder"
|
161
|
+
options[:project] = "changelog_test"
|
141
162
|
else
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
163
|
+
remote = `git config --get remote.#{options[:branch]}.url`
|
164
|
+
# try to find repo in format:
|
165
|
+
# origin git@github.com:skywinder/Github-Changelog-Generator.git (fetch)
|
166
|
+
# git@github.com:skywinder/Github-Changelog-Generator.git
|
167
|
+
match = /.*(?:[:\/])((?:-|\w|\.)*)\/((?:-|\w|\.)*)(?:\.git).*/.match(remote)
|
168
|
+
|
146
169
|
if match && match[1] && match[2]
|
147
170
|
puts "Detected user:#{match[1]}, project:#{match[2]}"
|
148
171
|
options[:user], options[:project] = match[1], match[2]
|
172
|
+
else
|
173
|
+
# try to find repo in format:
|
174
|
+
# origin https://github.com/skywinder/ChangelogMerger (fetch)
|
175
|
+
# https://github.com/skywinder/ChangelogMerger
|
176
|
+
match = /.*\/((?:-|\w|\.)*)\/((?:-|\w|\.)*).*/.match(remote)
|
177
|
+
if match && match[1] && match[2]
|
178
|
+
puts "Detected user:#{match[1]}, project:#{match[2]}"
|
179
|
+
options[:user], options[:project] = match[1], match[2]
|
180
|
+
end
|
149
181
|
end
|
150
182
|
end
|
151
183
|
end
|
152
|
-
|
153
|
-
|
154
|
-
if !options[:user] || !options[:project]
|
155
|
-
puts parser.banner
|
156
|
-
exit
|
157
|
-
end
|
158
|
-
|
159
|
-
if ARGV[1]
|
160
|
-
options[:tag1] = ARGV[0]
|
161
|
-
options[:tag2] = ARGV[1]
|
162
|
-
end
|
163
|
-
|
164
|
-
if options[:verbose]
|
165
|
-
puts 'Performing task with options:'
|
166
|
-
pp options
|
167
|
-
puts ''
|
168
|
-
end
|
169
|
-
|
170
|
-
options
|
171
184
|
end
|
172
185
|
end
|
173
186
|
end
|