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 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