github_changelog_generator 1.4.0 → 1.4.1
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/.overcommit.yml +36 -0
- data/.rubocop_todo.yml +18 -25
- data/CHANGELOG.md +4 -2
- data/Gemfile +3 -3
- data/Gemfile.lock +26 -25
- data/README.md +23 -22
- data/lib/CHANGELOG.md +0 -2
- data/lib/github_changelog_generator.rb +19 -12
- data/lib/github_changelog_generator/fetcher.rb +75 -60
- data/lib/github_changelog_generator/parser.rb +7 -2
- data/lib/github_changelog_generator/version.rb +1 -1
- data/spec/unit/fetcher_spec.rb +59 -0
- metadata +5 -3
- data/bump_gemfile.rb +0 -221
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0fcb32379ceff6a504557e39d110ceea33c6a6b8
|
|
4
|
+
data.tar.gz: 1eb24513e63a4e8541c576f009d8c03ed2cfd801
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6c7d27dc252e59527346607198d7335f6aebcbf1eaf201179a5904884235258bcfbd4bb20c8a4a12ea8dbb668ff06ea88c46aa04c7706617e900bf35de863a1d
|
|
7
|
+
data.tar.gz: f281e4ec517f746d11b973ba45713af5cc8bcd08b3dbab7247916af6612655ccbd31e76f7d9b0fd025a2cbdb0107a0cd96c011ec548aa1cb5db522fec287f1f3
|
data/.overcommit.yml
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Use this file to configure the Overcommit hooks you wish to use. This will
|
|
2
|
+
# extend the default configuration defined in:
|
|
3
|
+
# https://github.com/brigade/overcommit/blob/master/config/default.yml
|
|
4
|
+
#
|
|
5
|
+
# At the topmost level of this YAML file is a key representing type of hook
|
|
6
|
+
# being run (e.g. pre-commit, commit-msg, etc.). Within each type you can
|
|
7
|
+
# customize each hook, such as whether to only run it on certain files (via
|
|
8
|
+
# `include`), whether to only display output if it fails (via `quiet`), etc.
|
|
9
|
+
#
|
|
10
|
+
# For a complete list of hooks, see:
|
|
11
|
+
# https://github.com/brigade/overcommit/tree/master/lib/overcommit/hook
|
|
12
|
+
#
|
|
13
|
+
# For a complete list of options that you can use to customize hooks, see:
|
|
14
|
+
# https://github.com/brigade/overcommit#configuration
|
|
15
|
+
#
|
|
16
|
+
# Uncomment the following lines to make the configuration take effect.
|
|
17
|
+
|
|
18
|
+
PreCommit:
|
|
19
|
+
RuboCop:
|
|
20
|
+
enabled: true
|
|
21
|
+
#command: ['bundle', 'exec', 'rubocop']
|
|
22
|
+
on_warn: fail # Treat all warnings as failures
|
|
23
|
+
#
|
|
24
|
+
# TrailingWhitespace:
|
|
25
|
+
# exclude:
|
|
26
|
+
# - '**/db/structure.sql' # Ignore trailing whitespace in generated files
|
|
27
|
+
#
|
|
28
|
+
#PostCheckout:
|
|
29
|
+
# ALL: # Special hook name that customizes all hooks of this type
|
|
30
|
+
# quiet: true # Change all post-checkout hooks to only display output on failure
|
|
31
|
+
#
|
|
32
|
+
# IndexTags:
|
|
33
|
+
# enabled: true # Generate a tags file with `ctags` each time HEAD changes
|
|
34
|
+
CommitMsg:
|
|
35
|
+
CapitalizedSubject:
|
|
36
|
+
enabled: false
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
# This configuration was generated by `rubocop --auto-gen-config`
|
|
2
|
-
# on 2015-
|
|
2
|
+
# on 2015-05-14 16:51:06 +0300 using RuboCop version 0.31.0.
|
|
3
3
|
# The point is for the user to remove these configuration records
|
|
4
4
|
# one by one as the offenses are removed from the code base.
|
|
5
5
|
# Note that changes in the inspected code, or installation of new
|
|
6
6
|
# versions of RuboCop, may require this file to be generated again.
|
|
7
7
|
|
|
8
|
-
# Offense count:
|
|
8
|
+
# Offense count: 15
|
|
9
9
|
Metrics/AbcSize:
|
|
10
|
-
|
|
10
|
+
Enabled: false
|
|
11
11
|
|
|
12
12
|
# Offense count: 2
|
|
13
13
|
Metrics/BlockNesting:
|
|
14
14
|
Max: 4
|
|
15
15
|
|
|
16
|
-
# Offense count:
|
|
16
|
+
# Offense count: 3
|
|
17
17
|
# Configuration parameters: CountComments.
|
|
18
18
|
Metrics/ClassLength:
|
|
19
|
-
Max:
|
|
19
|
+
Max: 337
|
|
20
20
|
|
|
21
|
-
# Offense count:
|
|
21
|
+
# Offense count: 5
|
|
22
22
|
Metrics/CyclomaticComplexity:
|
|
23
23
|
Max: 15
|
|
24
24
|
|
|
25
|
-
# Offense count:
|
|
25
|
+
# Offense count: 22
|
|
26
26
|
# Configuration parameters: CountComments.
|
|
27
27
|
Metrics/MethodLength:
|
|
28
|
-
|
|
28
|
+
Enabled: false
|
|
29
29
|
|
|
30
30
|
# Offense count: 5
|
|
31
31
|
Metrics/PerceivedComplexity:
|
|
32
32
|
Max: 18
|
|
33
33
|
|
|
34
|
-
# Offense count:
|
|
34
|
+
# Offense count: 4
|
|
35
35
|
Style/AccessorMethodName:
|
|
36
36
|
Enabled: false
|
|
37
37
|
|
|
@@ -41,31 +41,23 @@ Style/AccessorMethodName:
|
|
|
41
41
|
Style/AndOr:
|
|
42
42
|
Enabled: false
|
|
43
43
|
|
|
44
|
-
# Offense count:
|
|
44
|
+
# Offense count: 19
|
|
45
45
|
# Cop supports --auto-correct.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
# Offense count: 7
|
|
50
|
-
# Configuration parameters: IndentWhenRelativeTo, SupportedStyles, IndentOneStep.
|
|
51
|
-
Style/CaseIndentation:
|
|
46
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods.
|
|
47
|
+
Style/BlockDelimiters:
|
|
52
48
|
Enabled: false
|
|
53
49
|
|
|
54
50
|
# Offense count: 4
|
|
55
51
|
Style/Documentation:
|
|
56
52
|
Enabled: false
|
|
57
53
|
|
|
58
|
-
# Offense count:
|
|
59
|
-
# Configuration parameters: AllowedVariables.
|
|
60
|
-
Style/GlobalVars:
|
|
61
|
-
Enabled: false
|
|
62
|
-
|
|
63
|
-
# Offense count: 6
|
|
54
|
+
# Offense count: 5
|
|
64
55
|
# Configuration parameters: MinBodyLength.
|
|
65
56
|
Style/GuardClause:
|
|
66
57
|
Enabled: false
|
|
67
58
|
|
|
68
|
-
# Offense count:
|
|
59
|
+
# Offense count: 15
|
|
60
|
+
# Cop supports --auto-correct.
|
|
69
61
|
# Configuration parameters: MaxLineLength.
|
|
70
62
|
Style/IfUnlessModifier:
|
|
71
63
|
Enabled: false
|
|
@@ -75,7 +67,8 @@ Style/IfUnlessModifier:
|
|
|
75
67
|
Style/Next:
|
|
76
68
|
Enabled: false
|
|
77
69
|
|
|
78
|
-
# Offense count:
|
|
79
|
-
#
|
|
70
|
+
# Offense count: 3
|
|
71
|
+
# Cop supports --auto-correct.
|
|
72
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
|
|
80
73
|
Style/RegexpLiteral:
|
|
81
74
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
## [
|
|
3
|
+
## [1.4.0](https://github.com/skywinder/github-changelog-generator/tree/1.4.0) (2015-05-07)
|
|
4
4
|
|
|
5
|
-
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.11...
|
|
5
|
+
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.11...1.4.0)
|
|
6
6
|
|
|
7
7
|
**Implemented enhancements:**
|
|
8
8
|
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
|
|
19
19
|
- Cleanup [\#220](https://github.com/skywinder/github-changelog-generator/pull/220) ([tuexss](https://github.com/tuexss))
|
|
20
20
|
|
|
21
|
+
- Implement fetcher class [\#227](https://github.com/skywinder/github-changelog-generator/pull/227) ([skywinder](https://github.com/skywinder))
|
|
22
|
+
|
|
21
23
|
- Add coveralls integration [\#223](https://github.com/skywinder/github-changelog-generator/pull/223) ([skywinder](https://github.com/skywinder))
|
|
22
24
|
|
|
23
25
|
- Rspec & rubocop integration [\#217](https://github.com/skywinder/github-changelog-generator/pull/217) ([skywinder](https://github.com/skywinder))
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
GEM
|
|
2
2
|
remote: https://rubygems.org/
|
|
3
3
|
specs:
|
|
4
|
-
addressable (2.3.
|
|
4
|
+
addressable (2.3.8)
|
|
5
5
|
ast (2.0.0)
|
|
6
6
|
astrolabe (1.3.0)
|
|
7
7
|
parser (>= 2.2.0.pre.3, < 3.0)
|
|
8
8
|
codeclimate-test-reporter (0.4.7)
|
|
9
9
|
simplecov (>= 0.7.1, < 1.0.0)
|
|
10
|
-
colorize (0.7.
|
|
11
|
-
coveralls (0.
|
|
12
|
-
|
|
10
|
+
colorize (0.7.7)
|
|
11
|
+
coveralls (0.8.1)
|
|
12
|
+
json (~> 1.8)
|
|
13
13
|
rest-client (>= 1.6.8, < 2)
|
|
14
|
-
simplecov (~> 0.
|
|
14
|
+
simplecov (~> 0.10.0)
|
|
15
15
|
term-ansicolor (~> 1.3)
|
|
16
16
|
thor (~> 0.19.1)
|
|
17
17
|
descendants_tracker (0.0.4)
|
|
18
18
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
19
19
|
diff-lcs (1.2.5)
|
|
20
20
|
docile (1.1.5)
|
|
21
|
-
domain_name (0.5.
|
|
21
|
+
domain_name (0.5.24)
|
|
22
22
|
unf (>= 0.0.5, < 1.0.0)
|
|
23
23
|
faraday (0.9.1)
|
|
24
24
|
multipart-post (>= 1.2, < 3)
|
|
@@ -30,11 +30,12 @@ GEM
|
|
|
30
30
|
multi_json (>= 1.7.5, < 2.0)
|
|
31
31
|
nokogiri (~> 1.6.3)
|
|
32
32
|
oauth2
|
|
33
|
-
hashie (3.4.
|
|
33
|
+
hashie (3.4.1)
|
|
34
34
|
http-cookie (1.0.2)
|
|
35
35
|
domain_name (~> 0.5)
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
json (1.8.2)
|
|
37
|
+
jwt (1.5.0)
|
|
38
|
+
mime-types (2.5)
|
|
38
39
|
mini_portile (0.6.2)
|
|
39
40
|
multi_json (1.11.0)
|
|
40
41
|
multi_xml (0.5.5)
|
|
@@ -48,10 +49,10 @@ GEM
|
|
|
48
49
|
multi_json (~> 1.3)
|
|
49
50
|
multi_xml (~> 0.5)
|
|
50
51
|
rack (~> 1.2)
|
|
51
|
-
parser (2.2.
|
|
52
|
+
parser (2.2.2.2)
|
|
52
53
|
ast (>= 1.1, < 3.0)
|
|
53
|
-
powerpack (0.1.
|
|
54
|
-
rack (1.6.
|
|
54
|
+
powerpack (0.1.1)
|
|
55
|
+
rack (1.6.1)
|
|
55
56
|
rainbow (2.0.0)
|
|
56
57
|
rake (10.4.2)
|
|
57
58
|
rest-client (1.8.0)
|
|
@@ -62,45 +63,45 @@ GEM
|
|
|
62
63
|
rspec-core (~> 3.2.0)
|
|
63
64
|
rspec-expectations (~> 3.2.0)
|
|
64
65
|
rspec-mocks (~> 3.2.0)
|
|
65
|
-
rspec-core (3.2.
|
|
66
|
+
rspec-core (3.2.3)
|
|
66
67
|
rspec-support (~> 3.2.0)
|
|
67
|
-
rspec-expectations (3.2.
|
|
68
|
+
rspec-expectations (3.2.1)
|
|
68
69
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
69
70
|
rspec-support (~> 3.2.0)
|
|
70
71
|
rspec-mocks (3.2.1)
|
|
71
72
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
72
73
|
rspec-support (~> 3.2.0)
|
|
73
74
|
rspec-support (3.2.2)
|
|
74
|
-
rubocop (0.
|
|
75
|
+
rubocop (0.31.0)
|
|
75
76
|
astrolabe (~> 1.3)
|
|
76
|
-
parser (>= 2.2.
|
|
77
|
+
parser (>= 2.2.2.1, < 3.0)
|
|
77
78
|
powerpack (~> 0.1)
|
|
78
79
|
rainbow (>= 1.99.1, < 3.0)
|
|
79
80
|
ruby-progressbar (~> 1.4)
|
|
80
81
|
ruby-progressbar (1.7.5)
|
|
81
|
-
simplecov (0.
|
|
82
|
+
simplecov (0.10.0)
|
|
82
83
|
docile (~> 1.1.0)
|
|
83
|
-
|
|
84
|
-
simplecov-html (~> 0.
|
|
85
|
-
simplecov-html (0.
|
|
84
|
+
json (~> 1.8)
|
|
85
|
+
simplecov-html (~> 0.10.0)
|
|
86
|
+
simplecov-html (0.10.0)
|
|
86
87
|
term-ansicolor (1.3.0)
|
|
87
88
|
tins (~> 1.0)
|
|
88
89
|
thor (0.19.1)
|
|
89
90
|
thread_safe (0.3.5)
|
|
90
|
-
tins (1.
|
|
91
|
+
tins (1.5.1)
|
|
91
92
|
unf (0.1.4)
|
|
92
93
|
unf_ext
|
|
93
|
-
unf_ext (0.0.
|
|
94
|
+
unf_ext (0.0.7.1)
|
|
94
95
|
|
|
95
96
|
PLATFORMS
|
|
96
97
|
ruby
|
|
97
98
|
|
|
98
99
|
DEPENDENCIES
|
|
99
100
|
codeclimate-test-reporter
|
|
100
|
-
colorize
|
|
101
|
+
colorize (>= 0.7.7)
|
|
101
102
|
coveralls
|
|
102
|
-
github_api
|
|
103
|
-
rake
|
|
103
|
+
github_api (>= 0.12.3)
|
|
104
|
+
rake (>= 10.4.2)
|
|
104
105
|
rspec
|
|
105
106
|
rubocop
|
|
106
107
|
simplecov
|
data/README.md
CHANGED
|
@@ -83,28 +83,29 @@ As output you will get `CHANGELOG.md` file with pretty *Markdown-formatted* chan
|
|
|
83
83
|
Type `github_changelog_generator --help` for detailed usage.
|
|
84
84
|
|
|
85
85
|
Usage: changelog_generator [options]
|
|
86
|
-
-u, --user [USER]
|
|
87
|
-
-p, --project [PROJECT]
|
|
88
|
-
-t, --token [TOKEN]
|
|
89
|
-
-f, --date-format [FORMAT]
|
|
90
|
-
-o, --output [NAME]
|
|
91
|
-
--[no-]verbose
|
|
92
|
-
--[no-]issues
|
|
93
|
-
--[no-]issues-wo-labels
|
|
94
|
-
--[no-]pr-wo-labels
|
|
95
|
-
--[no-]pull-requests
|
|
96
|
-
--[no-]filter-by-milestone
|
|
97
|
-
--[no-]author
|
|
98
|
-
--unreleased-only
|
|
99
|
-
--[no-]unreleased
|
|
100
|
-
--[no-]compare-link
|
|
101
|
-
--include-labels x,y,z
|
|
102
|
-
--exclude-labels x,y,z
|
|
103
|
-
--max-issues [NUMBER]
|
|
104
|
-
--github-site [URL]
|
|
105
|
-
--github-api [URL]
|
|
106
|
-
|
|
107
|
-
-
|
|
86
|
+
-u, --user [USER] Username of the owner of target GitHub repo
|
|
87
|
+
-p, --project [PROJECT] Name of project on GitHub
|
|
88
|
+
-t, --token [TOKEN] To make more than 50 requests per hour your GitHub token required. You can generate it here: https://github.com/settings/tokens/new
|
|
89
|
+
-f, --date-format [FORMAT] Date format. Default is %d/%m/%y
|
|
90
|
+
-o, --output [NAME] Output file. Default is CHANGELOG.md
|
|
91
|
+
--[no-]verbose Run verbosely. Default is true
|
|
92
|
+
--[no-]issues Include closed issues to changelog. Default is true
|
|
93
|
+
--[no-]issues-wo-labels Include closed issues without labels to changelog. Default is true
|
|
94
|
+
--[no-]pr-wo-labels Include pull requests without labels to changelog. Default is true
|
|
95
|
+
--[no-]pull-requests Include pull-requests to changelog. Default is true
|
|
96
|
+
--[no-]filter-by-milestone Use milestone to detect when issue was resolved. Default is true
|
|
97
|
+
--[no-]author Add author of pull-request in the end. Default is true
|
|
98
|
+
--unreleased-only Generate log from unreleased closed issues only.
|
|
99
|
+
--[no-]unreleased Add to log unreleased closed issues. Default is true
|
|
100
|
+
--[no-]compare-link Include compare link between older version and newer version. Default is true
|
|
101
|
+
--include-labels x,y,z Issues only with that labels will be included to changelog. Default is 'bug,enhancement'
|
|
102
|
+
--exclude-labels x,y,z Issues with that labels will be always excluded from changelog. Default is 'duplicate,question,invalid,wontfix'
|
|
103
|
+
--max-issues [NUMBER] Max number of issues to fetch from GitHub. Default is unlimited.
|
|
104
|
+
--github-site [URL] The Enterprise Github site on which your project is hosted.
|
|
105
|
+
--github-api [URL] The enterprise endpoint to use for your Github API.
|
|
106
|
+
--future-release [RELEASE-VERSION] Put the unreleased changes in the specified release number.
|
|
107
|
+
-v, --version Print version number
|
|
108
|
+
-h, --help Displays Help
|
|
108
109
|
|
|
109
110
|
|
|
110
111
|
### GitHub token
|
data/lib/CHANGELOG.md
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
**Merged pull requests:**
|
|
8
8
|
|
|
9
|
-
- This PR SHOULD NOT appear in change log! [\#6](https://github.com/skywinder/changelog_test/pull/6) ([skywinder](https://github.com/skywinder))
|
|
10
|
-
|
|
11
9
|
- Add automatically generated change log file. [\#5](https://github.com/skywinder/changelog_test/pull/5) ([skywinder](https://github.com/skywinder))
|
|
12
10
|
|
|
13
11
|
## [v0.0.3](https://github.com/skywinder/changelog_test/tree/v0.0.3) (2015-03-04)
|
|
@@ -32,7 +32,8 @@ module GitHubChangelogGenerator
|
|
|
32
32
|
# @all_tags = get_filtered_tags
|
|
33
33
|
@all_tags = @fetcher.get_all_tags
|
|
34
34
|
|
|
35
|
-
@issues
|
|
35
|
+
# TODO: refactor this double asssign of @issues and @pull_requests and move all logic in one method
|
|
36
|
+
@issues, @pull_requests = @fetcher.fetch_closed_issues_and_pr
|
|
36
37
|
|
|
37
38
|
@pull_requests = @options[:pulls] ? get_filtered_pull_requests : []
|
|
38
39
|
|
|
@@ -120,7 +121,7 @@ module GitHubChangelogGenerator
|
|
|
120
121
|
# And exclude all from :exclude_labels array.
|
|
121
122
|
# @return [Array] filtered PR's
|
|
122
123
|
def get_filtered_pull_requests
|
|
123
|
-
|
|
124
|
+
filter_merged_pull_requests
|
|
124
125
|
|
|
125
126
|
filtered_pull_requests = include_issues_by_labels(@pull_requests)
|
|
126
127
|
|
|
@@ -133,14 +134,15 @@ module GitHubChangelogGenerator
|
|
|
133
134
|
filtered_pull_requests
|
|
134
135
|
end
|
|
135
136
|
|
|
136
|
-
# This method
|
|
137
|
+
# This method filter only merged PR and
|
|
138
|
+
# fetch missing required attributes for pull requests
|
|
137
139
|
# :merged_at - is a date, when issue PR was merged.
|
|
138
|
-
# More correct to use
|
|
139
|
-
def
|
|
140
|
+
# More correct to use merged date, rather than closed date.
|
|
141
|
+
def filter_merged_pull_requests
|
|
140
142
|
if @options[:verbose]
|
|
141
143
|
print "Fetching merged dates...\r"
|
|
142
144
|
end
|
|
143
|
-
pull_requests = @fetcher.
|
|
145
|
+
pull_requests = @fetcher.fetch_closed_pull_requests
|
|
144
146
|
|
|
145
147
|
@pull_requests.each { |pr|
|
|
146
148
|
fetched_pr = pull_requests.find { |fpr|
|
|
@@ -150,8 +152,8 @@ module GitHubChangelogGenerator
|
|
|
150
152
|
pull_requests.delete(fetched_pr)
|
|
151
153
|
}
|
|
152
154
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
@pull_requests.select! do |pr|
|
|
156
|
+
!pr[:merged_at].nil?
|
|
155
157
|
end
|
|
156
158
|
end
|
|
157
159
|
|
|
@@ -217,7 +219,7 @@ module GitHubChangelogGenerator
|
|
|
217
219
|
output_filename = "#{@options[:output]}"
|
|
218
220
|
File.open(output_filename, "w") { |file| file.write(log) }
|
|
219
221
|
puts "Done!"
|
|
220
|
-
puts "Generated log placed in #{
|
|
222
|
+
puts "Generated log placed in #{Dir.pwd}/#{output_filename}"
|
|
221
223
|
end
|
|
222
224
|
|
|
223
225
|
# The full cycle of generation for whole project
|
|
@@ -279,7 +281,7 @@ module GitHubChangelogGenerator
|
|
|
279
281
|
threads.each(&:join)
|
|
280
282
|
|
|
281
283
|
if @options[:verbose]
|
|
282
|
-
puts "Fetching tags dates: #{i}
|
|
284
|
+
puts "Fetching tags dates: #{i}"
|
|
283
285
|
end
|
|
284
286
|
end
|
|
285
287
|
|
|
@@ -388,8 +390,13 @@ module GitHubChangelogGenerator
|
|
|
388
390
|
# @return [String] Ready and parsed section
|
|
389
391
|
def create_log(pull_requests, issues, newer_tag, older_tag_name = nil)
|
|
390
392
|
newer_tag_time = newer_tag.nil? ? Time.new : @fetcher.get_time_of_tag(newer_tag)
|
|
391
|
-
|
|
392
|
-
|
|
393
|
+
if newer_tag.nil? && @options[:future_release]
|
|
394
|
+
newer_tag_name = @options[:future_release]
|
|
395
|
+
newer_tag_link = @options[:future_release]
|
|
396
|
+
else
|
|
397
|
+
newer_tag_name = newer_tag.nil? ? @options[:unreleased_label] : newer_tag["name"]
|
|
398
|
+
newer_tag_link = newer_tag.nil? ? "HEAD" : newer_tag_name
|
|
399
|
+
end
|
|
393
400
|
|
|
394
401
|
github_site = options[:github_site] || "https://github.com"
|
|
395
402
|
project_url = "#{github_site}/#{@options[:user]}/#{@options[:project]}"
|
|
@@ -8,31 +8,30 @@ module GitHubChangelogGenerator
|
|
|
8
8
|
# fetcher = GitHubChangelogGenerator::Fetcher.new options
|
|
9
9
|
class Fetcher
|
|
10
10
|
PER_PAGE_NUMBER = 30
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
CHANGELOG_GITHUB_TOKEN = "CHANGELOG_GITHUB_TOKEN"
|
|
12
|
+
GH_RATE_LIMIT_EXCEEDED_MSG = "Warning: Can't finish operation: GitHub API rate limit exceeded, change log may be " \
|
|
13
|
+
"missing some issues. You can limit the number of issues fetched using the `--max-issues NUM` argument."
|
|
14
|
+
NO_TOKEN_PROVIDED = "Warning: No token provided (-t option) and variable $CHANGELOG_GITHUB_TOKEN was not found. " \
|
|
15
|
+
"This script can make only 50 requests to GitHub API per hour without token!"
|
|
13
16
|
|
|
14
17
|
def initialize(options = {})
|
|
15
18
|
@options = options
|
|
16
19
|
|
|
17
|
-
@user = @options[:user]
|
|
18
|
-
@project = @options[:project]
|
|
19
|
-
@github_token = fetch_github_token
|
|
20
|
-
@tag_times_hash = {}
|
|
21
|
-
|
|
22
20
|
@logger = Logger.new(STDOUT)
|
|
23
21
|
@logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
|
24
22
|
"#{msg}\n"
|
|
25
23
|
end
|
|
24
|
+
|
|
25
|
+
@user = @options[:user]
|
|
26
|
+
@project = @options[:project]
|
|
27
|
+
@github_token = fetch_github_token
|
|
28
|
+
@tag_times_hash = {}
|
|
26
29
|
github_options = { per_page: PER_PAGE_NUMBER }
|
|
27
30
|
github_options[:oauth_token] = @github_token unless @github_token.nil?
|
|
28
31
|
github_options[:endpoint] = options[:github_endpoint] unless options[:github_endpoint].nil?
|
|
29
32
|
github_options[:site] = options[:github_endpoint] unless options[:github_site].nil?
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
@github = Github.new github_options
|
|
33
|
-
rescue
|
|
34
|
-
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
|
35
|
-
end
|
|
34
|
+
@github = check_github_response { Github.new github_options }
|
|
36
35
|
end
|
|
37
36
|
|
|
38
37
|
# Returns GitHub token. First try to use variable, provided by --token option,
|
|
@@ -40,11 +39,10 @@ module GitHubChangelogGenerator
|
|
|
40
39
|
#
|
|
41
40
|
# @return [String]
|
|
42
41
|
def fetch_github_token
|
|
43
|
-
env_var = @options[:token] ? @options[:token] : (ENV.fetch
|
|
42
|
+
env_var = @options[:token] ? @options[:token] : (ENV.fetch CHANGELOG_GITHUB_TOKEN, nil)
|
|
44
43
|
|
|
45
44
|
unless env_var
|
|
46
|
-
@logger.warn
|
|
47
|
-
@logger.warn "This script can make only 50 requests to GitHub API per hour without token!".yellow
|
|
45
|
+
@logger.warn NO_TOKEN_PROVIDED.yellow
|
|
48
46
|
end
|
|
49
47
|
|
|
50
48
|
env_var
|
|
@@ -59,35 +57,47 @@ module GitHubChangelogGenerator
|
|
|
59
57
|
|
|
60
58
|
tags = []
|
|
61
59
|
|
|
62
|
-
|
|
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"
|
|
60
|
+
check_github_response { github_fetch_tags(tags) }
|
|
72
61
|
|
|
73
|
-
|
|
74
|
-
|
|
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
|
|
62
|
+
tags
|
|
63
|
+
end
|
|
79
64
|
|
|
80
|
-
|
|
65
|
+
def check_github_response
|
|
66
|
+
begin
|
|
67
|
+
value = yield
|
|
68
|
+
rescue Github::Error::Unauthorized => e
|
|
69
|
+
@logger.error e.body.red
|
|
70
|
+
abort "Error: wrong GitHub token"
|
|
71
|
+
rescue Github::Error::Forbidden => e
|
|
72
|
+
@logger.warn e.body.red
|
|
81
73
|
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
|
82
74
|
end
|
|
75
|
+
value
|
|
76
|
+
end
|
|
83
77
|
|
|
84
|
-
|
|
78
|
+
def github_fetch_tags(tags)
|
|
79
|
+
response = @github.repos.tags @options[:user], @options[:project]
|
|
80
|
+
page_i = 0
|
|
81
|
+
count_pages = response.count_pages
|
|
82
|
+
response.each_page do |page|
|
|
83
|
+
page_i += PER_PAGE_NUMBER
|
|
84
|
+
print_in_same_line("Fetching tags... #{page_i}/#{count_pages * PER_PAGE_NUMBER}")
|
|
85
|
+
tags.concat(page)
|
|
86
|
+
end
|
|
87
|
+
print_empty_line
|
|
88
|
+
|
|
89
|
+
if tags.count == 0
|
|
90
|
+
@logger.warn "Warning: Can't find any tags in repo.\
|
|
91
|
+
Make sure, that you push tags to remote repo via 'git push --tags'".yellow
|
|
92
|
+
else
|
|
93
|
+
@logger.info "Found #{tags.count} tags"
|
|
94
|
+
end
|
|
85
95
|
end
|
|
86
96
|
|
|
87
97
|
# This method fetch all closed issues and separate them to pull requests and pure issues
|
|
88
98
|
# (pull request is kind of issue in term of GitHub)
|
|
89
|
-
# @return [Tuple] with issues
|
|
90
|
-
def
|
|
99
|
+
# @return [Tuple] with (issues, pull-requests)
|
|
100
|
+
def fetch_closed_issues_and_pr
|
|
91
101
|
if @options[:verbose]
|
|
92
102
|
print "Fetching closed issues...\r"
|
|
93
103
|
end
|
|
@@ -103,47 +113,54 @@ Make sure, that you push tags to remote repo via 'git push --tags'".yellow
|
|
|
103
113
|
count_pages = response.count_pages
|
|
104
114
|
response.each_page do |page|
|
|
105
115
|
page_i += PER_PAGE_NUMBER
|
|
106
|
-
|
|
116
|
+
print_in_same_line("Fetching issues... #{page_i}/#{count_pages * PER_PAGE_NUMBER}")
|
|
107
117
|
issues.concat(page)
|
|
108
118
|
break if @options[:max_issues] && issues.length >= @options[:max_issues]
|
|
109
119
|
end
|
|
120
|
+
print_empty_line
|
|
121
|
+
@logger.info "Received issues: #{issues.count}"
|
|
122
|
+
|
|
110
123
|
rescue
|
|
111
124
|
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
|
112
125
|
end
|
|
113
126
|
|
|
114
|
-
|
|
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|
|
|
127
|
+
# separate arrays of issues and pull requests:
|
|
128
|
+
issues.partition do |x|
|
|
122
129
|
x[:pull_request].nil?
|
|
123
|
-
|
|
130
|
+
end
|
|
124
131
|
end
|
|
125
132
|
|
|
126
133
|
# Fetch all pull requests. We need them to detect :merged_at parameter
|
|
127
134
|
# @return [Array] all pull requests
|
|
128
|
-
def
|
|
135
|
+
def fetch_closed_pull_requests
|
|
129
136
|
pull_requests = []
|
|
130
137
|
begin
|
|
131
138
|
response = @github.pull_requests.list @options[:user], @options[:project], state: "closed"
|
|
132
139
|
page_i = 0
|
|
140
|
+
count_pages = response.count_pages
|
|
133
141
|
response.each_page do |page|
|
|
134
142
|
page_i += PER_PAGE_NUMBER
|
|
135
|
-
|
|
136
|
-
|
|
143
|
+
log_string = "Fetching merged dates... #{page_i}/#{count_pages * PER_PAGE_NUMBER}"
|
|
144
|
+
print_in_same_line(log_string)
|
|
137
145
|
pull_requests.concat(page)
|
|
138
146
|
end
|
|
147
|
+
print_empty_line
|
|
139
148
|
rescue
|
|
140
149
|
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
|
141
150
|
end
|
|
142
151
|
|
|
143
|
-
|
|
152
|
+
@logger.info "Fetching merged dates: #{pull_requests.count}"
|
|
144
153
|
pull_requests
|
|
145
154
|
end
|
|
146
155
|
|
|
156
|
+
def print_in_same_line(log_string)
|
|
157
|
+
print log_string + "\r"
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def print_empty_line
|
|
161
|
+
print_in_same_line(" ")
|
|
162
|
+
end
|
|
163
|
+
|
|
147
164
|
# Fetch event for all issues and add them to :events
|
|
148
165
|
# @param [Array] issues
|
|
149
166
|
# @return [Void]
|
|
@@ -151,9 +168,9 @@ Make sure, that you push tags to remote repo via 'git push --tags'".yellow
|
|
|
151
168
|
i = 0
|
|
152
169
|
max_thread_number = 50
|
|
153
170
|
threads = []
|
|
154
|
-
issues.each_slice(max_thread_number)
|
|
155
|
-
issues_slice.each
|
|
156
|
-
threads << Thread.new
|
|
171
|
+
issues.each_slice(max_thread_number) do |issues_slice|
|
|
172
|
+
issues_slice.each do |issue|
|
|
173
|
+
threads << Thread.new do
|
|
157
174
|
begin
|
|
158
175
|
obj = @github.issues.events.list user: @options[:user],
|
|
159
176
|
repo: @options[:project],
|
|
@@ -162,20 +179,18 @@ Make sure, that you push tags to remote repo via 'git push --tags'".yellow
|
|
|
162
179
|
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
|
163
180
|
end
|
|
164
181
|
issue[:events] = obj.body
|
|
165
|
-
|
|
182
|
+
print_in_same_line("Fetching events for issues and PR: #{i + 1}/#{issues.count}")
|
|
166
183
|
i += 1
|
|
167
|
-
|
|
168
|
-
|
|
184
|
+
end
|
|
185
|
+
end
|
|
169
186
|
threads.each(&:join)
|
|
170
187
|
threads = []
|
|
171
|
-
|
|
188
|
+
end
|
|
172
189
|
|
|
173
190
|
# to clear line from prev print
|
|
174
|
-
|
|
191
|
+
print_empty_line
|
|
175
192
|
|
|
176
|
-
|
|
177
|
-
@logger.info "Fetching events for issues and PR: #{i} Done!"
|
|
178
|
-
end
|
|
193
|
+
@logger.info "Fetching events for issues and PR: #{i}"
|
|
179
194
|
end
|
|
180
195
|
|
|
181
196
|
# Try to find tag date in local hash.
|
|
@@ -98,6 +98,9 @@ module GitHubChangelogGenerator
|
|
|
98
98
|
opts.on("--simple-list", "Create simple list from issues and pull requests. Default is false.") do |v|
|
|
99
99
|
options[:simple_list] = v
|
|
100
100
|
end
|
|
101
|
+
opts.on("--future-release [RELEASE-VERSION]", "Put the unreleased changes in the specified release number.") do |future_release|
|
|
102
|
+
options[:future_release] = future_release
|
|
103
|
+
end
|
|
101
104
|
opts.on("--[no-]verbose", "Run verbosely. Default is true") do |v|
|
|
102
105
|
options[:verbose] = v
|
|
103
106
|
end
|
|
@@ -168,7 +171,8 @@ module GitHubChangelogGenerator
|
|
|
168
171
|
|
|
169
172
|
if match && match[1] && match[2]
|
|
170
173
|
puts "Detected user:#{match[1]}, project:#{match[2]}"
|
|
171
|
-
options[:user]
|
|
174
|
+
options[:user] = match[1]
|
|
175
|
+
options[:project] = match[2]
|
|
172
176
|
else
|
|
173
177
|
# try to find repo in format:
|
|
174
178
|
# origin https://github.com/skywinder/ChangelogMerger (fetch)
|
|
@@ -176,7 +180,8 @@ module GitHubChangelogGenerator
|
|
|
176
180
|
match = /.*\/((?:-|\w|\.)*)\/((?:-|\w|\.)*).*/.match(remote)
|
|
177
181
|
if match && match[1] && match[2]
|
|
178
182
|
puts "Detected user:#{match[1]}, project:#{match[2]}"
|
|
179
|
-
options[:user]
|
|
183
|
+
options[:user] = match[1]
|
|
184
|
+
options[:project] = match[2]
|
|
180
185
|
end
|
|
181
186
|
end
|
|
182
187
|
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
VALID_TOKEN = "0123456789abcdef"
|
|
2
|
+
INVALID_TOKEN = "0000000000000000"
|
|
3
|
+
|
|
4
|
+
DEFAULT_OPTIONS = { user: "skywinder",
|
|
5
|
+
project: "changelog_test" }
|
|
6
|
+
|
|
7
|
+
def options_with_invalid_token
|
|
8
|
+
options = DEFAULT_OPTIONS
|
|
9
|
+
options[:token] = INVALID_TOKEN
|
|
10
|
+
options
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe GitHubChangelogGenerator::Fetcher do
|
|
14
|
+
before(:all) do
|
|
15
|
+
@fetcher = GitHubChangelogGenerator::Fetcher.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "#fetch_github_token" do
|
|
19
|
+
token = GitHubChangelogGenerator::Fetcher::CHANGELOG_GITHUB_TOKEN
|
|
20
|
+
context "when token in ENV exist" do
|
|
21
|
+
before { stub_const("ENV", ENV.to_hash.merge(token => VALID_TOKEN)) }
|
|
22
|
+
subject { @fetcher.fetch_github_token }
|
|
23
|
+
it { is_expected.to eq(VALID_TOKEN) }
|
|
24
|
+
end
|
|
25
|
+
context "when token in ENV is nil" do
|
|
26
|
+
before { stub_const("ENV", ENV.to_hash.merge(token => nil)) }
|
|
27
|
+
subject { @fetcher.fetch_github_token }
|
|
28
|
+
it { is_expected.to be_nil }
|
|
29
|
+
end
|
|
30
|
+
context "when token in options and ENV is nil" do
|
|
31
|
+
before do
|
|
32
|
+
stub_const("ENV", ENV.to_hash.merge(token => nil))
|
|
33
|
+
@fetcher = GitHubChangelogGenerator::Fetcher.new(token: VALID_TOKEN)
|
|
34
|
+
end
|
|
35
|
+
subject { @fetcher.fetch_github_token }
|
|
36
|
+
it { is_expected.to eq(VALID_TOKEN) }
|
|
37
|
+
end
|
|
38
|
+
context "when token in options and ENV specified" do
|
|
39
|
+
before do
|
|
40
|
+
stub_const("ENV", ENV.to_hash.merge(token => "no_matter_what"))
|
|
41
|
+
@fetcher = GitHubChangelogGenerator::Fetcher.new(token: VALID_TOKEN)
|
|
42
|
+
end
|
|
43
|
+
subject { @fetcher.fetch_github_token }
|
|
44
|
+
it { is_expected.to eq(VALID_TOKEN) }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "#github_fetch_tags" do
|
|
49
|
+
context "when wrong token provided" do
|
|
50
|
+
before do
|
|
51
|
+
options = options_with_invalid_token
|
|
52
|
+
@fetcher = GitHubChangelogGenerator::Fetcher.new(options)
|
|
53
|
+
end
|
|
54
|
+
it "should raise Unauthorized error" do
|
|
55
|
+
expect { @fetcher.github_fetch_tags [] }.to raise_error Github::Error::Unauthorized
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: github_changelog_generator
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.4.
|
|
4
|
+
version: 1.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Petr Korolev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-05-
|
|
11
|
+
date: 2015-05-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -78,6 +78,7 @@ files:
|
|
|
78
78
|
- ".coveralls.yml"
|
|
79
79
|
- ".gitignore"
|
|
80
80
|
- ".hound.yml"
|
|
81
|
+
- ".overcommit.yml"
|
|
81
82
|
- ".rspec"
|
|
82
83
|
- ".rubocop.yml"
|
|
83
84
|
- ".rubocop_todo.yml"
|
|
@@ -88,7 +89,6 @@ files:
|
|
|
88
89
|
- README.md
|
|
89
90
|
- Rakefile
|
|
90
91
|
- bin/github_changelog_generator
|
|
91
|
-
- bump_gemfile.rb
|
|
92
92
|
- github_changelog_generator.gemspec
|
|
93
93
|
- images/logo.jpg
|
|
94
94
|
- lib/CHANGELOG.md
|
|
@@ -102,6 +102,7 @@ files:
|
|
|
102
102
|
- spec/files/bundler.md
|
|
103
103
|
- spec/files/github-changelog-generator.md
|
|
104
104
|
- spec/spec_helper.rb
|
|
105
|
+
- spec/unit/fetcher_spec.rb
|
|
105
106
|
- spec/unit/reader_spec.rb
|
|
106
107
|
homepage: https://github.com/skywinder/Github-Changelog-Generator
|
|
107
108
|
licenses:
|
|
@@ -133,5 +134,6 @@ test_files:
|
|
|
133
134
|
- spec/files/bundler.md
|
|
134
135
|
- spec/files/github-changelog-generator.md
|
|
135
136
|
- spec/spec_helper.rb
|
|
137
|
+
- spec/unit/fetcher_spec.rb
|
|
136
138
|
- spec/unit/reader_spec.rb
|
|
137
139
|
has_rdoc:
|
data/bump_gemfile.rb
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
require "optparse"
|
|
3
|
-
|
|
4
|
-
SPEC_TYPE = "gemspec"
|
|
5
|
-
|
|
6
|
-
:major
|
|
7
|
-
:minor
|
|
8
|
-
:patch
|
|
9
|
-
|
|
10
|
-
@options = { dry_run: false, bump_number: :patch }
|
|
11
|
-
|
|
12
|
-
OptionParser.new { |opts|
|
|
13
|
-
opts.banner = "Usage: bump.rb [options]"
|
|
14
|
-
|
|
15
|
-
opts.on("-d", "--dry-run", "Dry run") do |v|
|
|
16
|
-
@options[:dry_run] = v
|
|
17
|
-
end
|
|
18
|
-
opts.on("-a", "--major", "Bump major version") do |_v|
|
|
19
|
-
@options[:bump_number] = :major
|
|
20
|
-
end
|
|
21
|
-
opts.on("-m", "--minor", "Bump minor version") do |_v|
|
|
22
|
-
@options[:bump_number] = :minor
|
|
23
|
-
end
|
|
24
|
-
opts.on("-p", "--patch", "Bump patch version") do |_v|
|
|
25
|
-
@options[:bump_number] = :patch
|
|
26
|
-
end
|
|
27
|
-
opts.on("-r", "--revert", "Revert last bump") do |v|
|
|
28
|
-
@options[:revert] = v
|
|
29
|
-
end
|
|
30
|
-
}.parse!
|
|
31
|
-
|
|
32
|
-
p @options
|
|
33
|
-
|
|
34
|
-
def check_repo_is_clean_or_dry_run
|
|
35
|
-
value = `#{"git status --porcelain"}`
|
|
36
|
-
|
|
37
|
-
if value.empty?
|
|
38
|
-
puts "Repo is clean -> continue"
|
|
39
|
-
else
|
|
40
|
-
if @options[:dry_run]
|
|
41
|
-
puts 'Repo not clean, "Dry run" enabled -> continue'
|
|
42
|
-
else
|
|
43
|
-
puts "Repository not clean -> exit"
|
|
44
|
-
exit
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def find_spec_file
|
|
50
|
-
list_of_specs = execute_line("find . -name '*.#{SPEC_TYPE}'")
|
|
51
|
-
arr = list_of_specs.split("\n")
|
|
52
|
-
|
|
53
|
-
spec_file = ""
|
|
54
|
-
|
|
55
|
-
case arr.count
|
|
56
|
-
when 0
|
|
57
|
-
puts "No #{SPEC_TYPE} files found. -> Exit."
|
|
58
|
-
exit
|
|
59
|
-
when 1
|
|
60
|
-
spec_file = arr[0]
|
|
61
|
-
else
|
|
62
|
-
puts "Which spec should be used?"
|
|
63
|
-
arr.each_with_index { |file, index| puts "#{index + 1}. #{file}" }
|
|
64
|
-
input_index = Integer(gets.chomp)
|
|
65
|
-
spec_file = arr[input_index - 1]
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
if spec_file.nil?
|
|
69
|
-
puts "Can't find specified spec file -> exit"
|
|
70
|
-
exit
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
spec_file.sub("./", "")
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def find_current_gem_file
|
|
77
|
-
list_of_specs = execute_line("find . -name '*.gem'")
|
|
78
|
-
arr = list_of_specs.split("\n")
|
|
79
|
-
|
|
80
|
-
spec_file = ""
|
|
81
|
-
|
|
82
|
-
case arr.count
|
|
83
|
-
when 0
|
|
84
|
-
puts "No #{SPEC_TYPE} files found. -> Exit."
|
|
85
|
-
exit
|
|
86
|
-
when 1
|
|
87
|
-
spec_file = arr[0]
|
|
88
|
-
else
|
|
89
|
-
puts "Which spec should be used?"
|
|
90
|
-
arr.each_with_index { |file, index| puts "#{index + 1}. #{file}" }
|
|
91
|
-
input_index = Integer(gets.chomp)
|
|
92
|
-
spec_file = arr[input_index - 1]
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
if spec_file.nil?
|
|
96
|
-
puts "Can't find specified spec file -> exit"
|
|
97
|
-
exit
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
spec_file.sub("./", "")
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def find_version_in_podspec(podspec)
|
|
104
|
-
readme = File.read(podspec)
|
|
105
|
-
|
|
106
|
-
# try to find version in format 1.22.333
|
|
107
|
-
re = /(\d+)\.(\d+)\.(\d+)/m
|
|
108
|
-
|
|
109
|
-
match_result = re.match(readme)
|
|
110
|
-
|
|
111
|
-
unless match_result
|
|
112
|
-
puts "Not found any versions"
|
|
113
|
-
exit
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
puts "Found version #{match_result[0]}"
|
|
117
|
-
[match_result[0], match_result.captures]
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def bump_version(versions_array)
|
|
121
|
-
bumped_result = versions_array.dup
|
|
122
|
-
bumped_result.map!(&:to_i)
|
|
123
|
-
|
|
124
|
-
case @options[:bump_number]
|
|
125
|
-
when :major
|
|
126
|
-
bumped_result[0] += 1
|
|
127
|
-
bumped_result[1] = 0
|
|
128
|
-
bumped_result[2] = 0
|
|
129
|
-
when :minor
|
|
130
|
-
bumped_result[1] += 1
|
|
131
|
-
bumped_result[2] = 0
|
|
132
|
-
when :patch
|
|
133
|
-
bumped_result[2] += 1
|
|
134
|
-
else
|
|
135
|
-
fail("unknown bump_number")
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
bumped_version = bumped_result.join(".")
|
|
139
|
-
puts "Bump version: #{versions_array.join('.')} -> #{bumped_version}"
|
|
140
|
-
bumped_version
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
def execute_line(line)
|
|
144
|
-
output = `#{line}`
|
|
145
|
-
check_exit_status(output)
|
|
146
|
-
|
|
147
|
-
output
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def execute_line_if_not_dry_run(line)
|
|
151
|
-
if @options[:dry_run]
|
|
152
|
-
puts "Dry run: #{line}"
|
|
153
|
-
nil
|
|
154
|
-
else
|
|
155
|
-
puts line
|
|
156
|
-
value = `#{line}`
|
|
157
|
-
puts value
|
|
158
|
-
check_exit_status(value)
|
|
159
|
-
value
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def check_exit_status(output)
|
|
164
|
-
if $CHILD_STATUS.exitstatus != 0
|
|
165
|
-
puts "Output:\n#{output}\nExit status = #{$CHILD_STATUS.exitstatus} ->Terminate script."
|
|
166
|
-
exit
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
def run_bumping_script
|
|
171
|
-
check_repo_is_clean_or_dry_run
|
|
172
|
-
spec_file = find_spec_file
|
|
173
|
-
result, versions_array = find_version_in_podspec(spec_file)
|
|
174
|
-
bumped_version = bump_version(versions_array)
|
|
175
|
-
|
|
176
|
-
unless @options[:dry_run]
|
|
177
|
-
puts "Are you sure? Press Y to continue:"
|
|
178
|
-
str = gets.chomp
|
|
179
|
-
if str != "Y"
|
|
180
|
-
puts "-> exit"
|
|
181
|
-
exit
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
execute_line_if_not_dry_run("sed -i \"\" \"s/#{result}/#{bumped_version}/\" README.md")
|
|
186
|
-
execute_line_if_not_dry_run("sed -i \"\" \"s/#{result}/#{bumped_version}/\" #{spec_file}")
|
|
187
|
-
execute_line_if_not_dry_run("git commit --all -m \"Update #{$SPEC_TYPE} to version #{bumped_version}\"")
|
|
188
|
-
execute_line_if_not_dry_run("git tag #{bumped_version}")
|
|
189
|
-
execute_line_if_not_dry_run("git push")
|
|
190
|
-
execute_line_if_not_dry_run("git push --tags")
|
|
191
|
-
execute_line_if_not_dry_run("gem build #{spec_file}")
|
|
192
|
-
|
|
193
|
-
gem = find_current_gem_file
|
|
194
|
-
execute_line_if_not_dry_run("gem push #{gem}")
|
|
195
|
-
# execute_line_if_not_dry_run("pod trunk push #{spec_file}")
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
def revert_last_bump
|
|
199
|
-
spec_file = find_spec_file
|
|
200
|
-
result, _ = find_version_in_podspec(spec_file)
|
|
201
|
-
|
|
202
|
-
puts "DELETE tag #{result} and HARD reset HEAD~1?\nPress Y to continue:"
|
|
203
|
-
str = gets.chomp
|
|
204
|
-
if str != "Y"
|
|
205
|
-
puts "-> exit"
|
|
206
|
-
exit
|
|
207
|
-
end
|
|
208
|
-
execute_line_if_not_dry_run("git tag -d #{result}")
|
|
209
|
-
execute_line_if_not_dry_run("git reset --hard HEAD~1")
|
|
210
|
-
execute_line_if_not_dry_run("git push --delete origin #{result}")
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
if __FILE__ == $PROGRAM_NAME
|
|
214
|
-
|
|
215
|
-
if @options[:revert]
|
|
216
|
-
revert_last_bump
|
|
217
|
-
else
|
|
218
|
-
run_bumping_script
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
end
|