github_changelog_generator 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f7ba2020d366356472460a09dbf5c2cfe9ef2283
4
- data.tar.gz: 989e55f94096faff75d82be77fb257e12b866a68
3
+ metadata.gz: 0fcb32379ceff6a504557e39d110ceea33c6a6b8
4
+ data.tar.gz: 1eb24513e63a4e8541c576f009d8c03ed2cfd801
5
5
  SHA512:
6
- metadata.gz: 6de4c6204ba73df6e31d3ba7283781bd75dcb791b775762b01f981b102719866b18c59cc01c87724c868100105a6ec7c8fab52f344836b96b99b260be7a2b52b
7
- data.tar.gz: 9d2325eaaf086863151fc60843ebe60d7949e5eec856f1e624c72fc4d48c6101171340e641d606d27bef8379c05e9771474fc286393adf970f55bd01e27b7343
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-04-04 02:29:34 +0300 using RuboCop version 0.29.1.
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: 21
8
+ # Offense count: 15
9
9
  Metrics/AbcSize:
10
- Max: 71
10
+ Enabled: false
11
11
 
12
12
  # Offense count: 2
13
13
  Metrics/BlockNesting:
14
14
  Max: 4
15
15
 
16
- # Offense count: 2
16
+ # Offense count: 3
17
17
  # Configuration parameters: CountComments.
18
18
  Metrics/ClassLength:
19
- Max: 457
19
+ Max: 337
20
20
 
21
- # Offense count: 6
21
+ # Offense count: 5
22
22
  Metrics/CyclomaticComplexity:
23
23
  Max: 15
24
24
 
25
- # Offense count: 28
25
+ # Offense count: 22
26
26
  # Configuration parameters: CountComments.
27
27
  Metrics/MethodLength:
28
- Max: 118
28
+ Enabled: false
29
29
 
30
30
  # Offense count: 5
31
31
  Metrics/PerceivedComplexity:
32
32
  Max: 18
33
33
 
34
- # Offense count: 3
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: 27
44
+ # Offense count: 19
45
45
  # Cop supports --auto-correct.
46
- Style/Blocks:
47
- Enabled: false
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: 1
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: 17
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: 5
79
- # Configuration parameters: MaxSlashes.
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
- ## [Unreleased](https://github.com/skywinder/github-changelog-generator/tree/HEAD)
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...HEAD)
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
@@ -1,9 +1,9 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "rake"
3
+ gem "rake", ">=10.4.2"
4
4
 
5
- gem "github_api"
6
- gem "colorize"
5
+ gem "github_api", ">=0.12.3"
6
+ gem "colorize", ">=0.7.7"
7
7
 
8
8
  group :test do
9
9
  gem "rspec"
data/Gemfile.lock CHANGED
@@ -1,24 +1,24 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- addressable (2.3.7)
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.5)
11
- coveralls (0.7.12)
12
- multi_json (~> 1.10)
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.9.1)
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.23)
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.0)
33
+ hashie (3.4.1)
34
34
  http-cookie (1.0.2)
35
35
  domain_name (~> 0.5)
36
- jwt (1.4.1)
37
- mime-types (2.4.3)
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.0.3)
52
+ parser (2.2.2.2)
52
53
  ast (>= 1.1, < 3.0)
53
- powerpack (0.1.0)
54
- rack (1.6.0)
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.2)
66
+ rspec-core (3.2.3)
66
67
  rspec-support (~> 3.2.0)
67
- rspec-expectations (3.2.0)
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.29.1)
75
+ rubocop (0.31.0)
75
76
  astrolabe (~> 1.3)
76
- parser (>= 2.2.0.1, < 3.0)
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.9.2)
82
+ simplecov (0.10.0)
82
83
  docile (~> 1.1.0)
83
- multi_json (~> 1.0)
84
- simplecov-html (~> 0.9.0)
85
- simplecov-html (0.9.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.3.5)
91
+ tins (1.5.1)
91
92
  unf (0.1.4)
92
93
  unf_ext
93
- unf_ext (0.0.6)
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] 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
- -v, --version Print version number
107
- -h, --help Displays Help
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, @pull_requests = @fetcher.fetch_issues_and_pull_requests
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
- fetch_merged_at_pull_requests
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 fetch missing required attributes for pull requests
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 this date, not closed date.
139
- def fetch_merged_at_pull_requests
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.fetch_pull_requests
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
- if @options[:verbose]
154
- puts "Fetching merged dates: Done!"
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 #{`pwd`.strip!}/#{output_filename}"
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} Done!"
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
- newer_tag_name = newer_tag.nil? ? @options[:unreleased_label] : newer_tag["name"]
392
- newer_tag_link = newer_tag.nil? ? "HEAD" : newer_tag_name
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
- 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."
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
- begin
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 "CHANGELOG_GITHUB_TOKEN", nil)
42
+ env_var = @options[:token] ? @options[:token] : (ENV.fetch CHANGELOG_GITHUB_TOKEN, nil)
44
43
 
45
44
  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
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
- 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"
60
+ check_github_response { github_fetch_tags(tags) }
72
61
 
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
62
+ tags
63
+ end
79
64
 
80
- rescue
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
- tags
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 and pull requests
90
- def fetch_issues_and_pull_requests
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
- print "Fetching issues... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r"
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
- 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|
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 fetch_pull_requests
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
- count_pages = response.count_pages
136
- print "Fetching merged dates... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r"
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
- print " \r"
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) { |issues_slice|
155
- issues_slice.each { |issue|
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
- print "Fetching events for issues and PR: #{i + 1}/#{issues.count}\r"
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
- print " \r"
191
+ print_empty_line
175
192
 
176
- if @options[:verbose]
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], options[:project] = match[1], match[2]
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], options[:project] = match[1], match[2]
183
+ options[:user] = match[1]
184
+ options[:project] = match[2]
180
185
  end
181
186
  end
182
187
  end
@@ -1,3 +1,3 @@
1
1
  module GitHubChangelogGenerator
2
- VERSION = "1.4.0"
2
+ VERSION = "1.4.1"
3
3
  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.0
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-07 00:00:00.000000000 Z
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