Compare commits
57 Commits
estahn-fea
...
1.4.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e864abd623 | ||
|
|
6710078766 | ||
|
|
f0736e67a5 | ||
|
|
784bd50a8f | ||
|
|
a9eabfc38b | ||
|
|
8123b3e2fa | ||
|
|
2b148f2e69 | ||
|
|
6a7dbeb450 | ||
|
|
8aa5d524b7 | ||
|
|
0a35113a88 | ||
|
|
79a84a14f4 | ||
|
|
6d8dbd16ad | ||
|
|
cf8df992c5 | ||
|
|
b620ad0d1b | ||
|
|
b7980c8900 | ||
|
|
e27fe24a76 | ||
|
|
088c98d0bf | ||
|
|
9ab84ac181 | ||
|
|
f04d581dbc | ||
|
|
911b91c0ab | ||
|
|
26e202d7f0 | ||
|
|
c2e5118cc9 | ||
|
|
b598bd5ba1 | ||
|
|
1673677df0 | ||
|
|
c44be45ce4 | ||
|
|
177b7aa18f | ||
|
|
e495b58682 | ||
|
|
e82a75611c | ||
|
|
38576e23e3 | ||
|
|
79d228c7a0 | ||
|
|
e1161f9d90 | ||
|
|
31c5ac4c55 | ||
|
|
dae68ee3b5 | ||
|
|
2b656c83b6 | ||
|
|
4e9ed5df28 | ||
|
|
47bba9d384 | ||
|
|
ce7f35777b | ||
|
|
115762af82 | ||
|
|
a50ad5b5c9 | ||
|
|
da60c73502 | ||
|
|
b5d073c0af | ||
|
|
6fcd0c95ed | ||
|
|
5c66591d71 | ||
|
|
77941049e6 | ||
|
|
ca334b430c | ||
|
|
1498790a78 | ||
|
|
55001f48c2 | ||
|
|
643b266679 | ||
|
|
2590883c3a | ||
|
|
51755cbe34 | ||
|
|
d361baaec5 | ||
|
|
ae0d1d16de | ||
|
|
c8584a1749 | ||
|
|
7c29f3ddd2 | ||
|
|
a2cf6810ad | ||
|
|
629a08b890 | ||
|
|
4f9bb03265 |
2
.hound.yml
Normal file
2
.hound.yml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ruby:
|
||||||
|
config_file: .rubocop.yml
|
||||||
@@ -4,5 +4,5 @@ Metrics/LineLength:
|
|||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
#http://viget.com/extend/just-use-double-quoted-ruby-strings
|
#http://viget.com/extend/just-use-double-quoted-ruby-strings
|
||||||
#Style/StringLiterals:
|
Style/StringLiterals:
|
||||||
# EnforcedStyle: double_quotes
|
EnforcedStyle: double_quotes
|
||||||
|
|||||||
@@ -1,35 +1,35 @@
|
|||||||
# This configuration was generated by `rubocop --auto-gen-config`
|
# This configuration was generated by `rubocop --auto-gen-config`
|
||||||
# on 2015-03-27 03:03:45 +0200 using RuboCop version 0.29.1.
|
# on 2015-04-04 02:29:34 +0300 using RuboCop version 0.29.1.
|
||||||
# The point is for the user to remove these configuration records
|
# The point is for the user to remove these configuration records
|
||||||
# one by one as the offenses are removed from the code base.
|
# one by one as the offenses are removed from the code base.
|
||||||
# Note that changes in the inspected code, or installation of new
|
# Note that changes in the inspected code, or installation of new
|
||||||
# versions of RuboCop, may require this file to be generated again.
|
# versions of RuboCop, may require this file to be generated again.
|
||||||
|
|
||||||
# Offense count: 20
|
# Offense count: 21
|
||||||
Metrics/AbcSize:
|
Metrics/AbcSize:
|
||||||
Max: 114
|
Max: 71
|
||||||
|
|
||||||
# Offense count: 1
|
# Offense count: 2
|
||||||
Metrics/BlockNesting:
|
Metrics/BlockNesting:
|
||||||
Max: 4
|
Max: 4
|
||||||
|
|
||||||
# Offense count: 2
|
# Offense count: 2
|
||||||
# Configuration parameters: CountComments.
|
# Configuration parameters: CountComments.
|
||||||
Metrics/ClassLength:
|
Metrics/ClassLength:
|
||||||
Max: 471
|
Max: 457
|
||||||
|
|
||||||
# Offense count: 6
|
# Offense count: 6
|
||||||
Metrics/CyclomaticComplexity:
|
Metrics/CyclomaticComplexity:
|
||||||
Max: 18
|
Max: 15
|
||||||
|
|
||||||
# Offense count: 27
|
# Offense count: 28
|
||||||
# Configuration parameters: CountComments.
|
# Configuration parameters: CountComments.
|
||||||
Metrics/MethodLength:
|
Metrics/MethodLength:
|
||||||
Max: 147
|
Max: 118
|
||||||
|
|
||||||
# Offense count: 6
|
# Offense count: 5
|
||||||
Metrics/PerceivedComplexity:
|
Metrics/PerceivedComplexity:
|
||||||
Max: 20
|
Max: 18
|
||||||
|
|
||||||
# Offense count: 3
|
# Offense count: 3
|
||||||
Style/AccessorMethodName:
|
Style/AccessorMethodName:
|
||||||
@@ -41,7 +41,7 @@ Style/AccessorMethodName:
|
|||||||
Style/AndOr:
|
Style/AndOr:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 29
|
# Offense count: 27
|
||||||
# Cop supports --auto-correct.
|
# Cop supports --auto-correct.
|
||||||
Style/Blocks:
|
Style/Blocks:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
@@ -51,7 +51,7 @@ Style/Blocks:
|
|||||||
Style/CaseIndentation:
|
Style/CaseIndentation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Offense count: 5
|
# Offense count: 4
|
||||||
Style/Documentation:
|
Style/Documentation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
|||||||
18
.travis.yml
18
.travis.yml
@@ -1,17 +1,17 @@
|
|||||||
---
|
|
||||||
sudo: false
|
sudo: false
|
||||||
cache: bundler
|
cache: bundler
|
||||||
language: ruby
|
language: ruby
|
||||||
|
|
||||||
rvm:
|
rvm:
|
||||||
- 2.1.0
|
- 2.1.0
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- bundle exec rake
|
- bundle exec rake
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email:
|
email:
|
||||||
recipients:
|
recipients:
|
||||||
- sky4winder+githubchangeloggenerator@gmail.com
|
- sky4winder+githubchangeloggenerator@gmail.com
|
||||||
on_success: never # [always|never|change]
|
on_success: never
|
||||||
on_failure: change # [always|never|change]
|
on_failure: change
|
||||||
|
addons:
|
||||||
|
code_climate:
|
||||||
|
repo_token:
|
||||||
|
secure: iMpV5IAvH+/EVGZrpWnt2BnmNFzSbsRcIumsr4ZyLC8N5nrCSXyjCSy0g48btL3Sj0bSgK9hcrJsmrFd2bkqFleyAcPAzNyUQzBuIRZx47O8yFmbZ+Pj+l3+KOlmcbzJNHfDfxkxuWTmTAcSDfsiyApin721T/ey3SUuwKpZNUc=
|
||||||
|
|||||||
454
CHANGELOG.md
454
CHANGELOG.md
@@ -1,304 +1,336 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
## [1.3.10](https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.10) (2015-03-18)
|
## [Unreleased](https://github.com/skywinder/github-changelog-generator/tree/HEAD)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.3.9...1.3.10)
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.11...HEAD)
|
||||||
|
|
||||||
**Fixed bugs:**
|
|
||||||
|
|
||||||
- Exclude closed PR's from changelog. [\#69](https://github.com/skywinder/Github-Changelog-Generator/issues/69)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Fix termination in case of empty unreleased section with `--unreleased-only` option. [\#70](https://github.com/skywinder/Github-Changelog-Generator/pull/70) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
## [1.3.9](https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.9) (2015-03-06)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.3.8...1.3.9)
|
|
||||||
|
|
||||||
**Implemented enhancements:**
|
**Implemented enhancements:**
|
||||||
|
|
||||||
- Improve method of detecting owner and repository [\#63](https://github.com/skywinder/Github-Changelog-Generator/issues/63)
|
- Parsing of existing Change Log file [\#212](https://github.com/skywinder/github-changelog-generator/issues/212)
|
||||||
|
|
||||||
**Merged pull requests:**
|
- Warn users about 0 tags in repo. [\#208](https://github.com/skywinder/github-changelog-generator/issues/208)
|
||||||
|
|
||||||
- Resolved concurrency problem in case of issues \> 2048 [\#65](https://github.com/skywinder/Github-Changelog-Generator/pull/65) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
## [1.3.8](https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.8) (2015-03-05)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.3.6...1.3.8)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Fix `git remote` parsing in case, when script running without parameters inside destination directory [\#61](https://github.com/skywinder/Github-Changelog-Generator/pull/61) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
## [1.3.6](https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.6) (2015-03-05)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.3.5...1.3.6)
|
|
||||||
|
|
||||||
## [1.3.5](https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.5) (2015-03-04)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.3.4...1.3.5)
|
|
||||||
|
|
||||||
**Fixed bugs:**
|
|
||||||
|
|
||||||
- Pull Requests in Wrong Tag [\#60](https://github.com/skywinder/Github-Changelog-Generator/issues/60)
|
|
||||||
|
|
||||||
## [1.3.4](https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.4) (2015-03-03)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.3.3...1.3.4)
|
|
||||||
|
|
||||||
**Fixed bugs:**
|
|
||||||
|
|
||||||
- --no-issues appears to break PRs [\#59](https://github.com/skywinder/Github-Changelog-Generator/issues/59)
|
|
||||||
|
|
||||||
## [1.3.3](https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.3) (2015-03-03)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.3.2...1.3.3)
|
|
||||||
|
|
||||||
**Closed issues:**
|
**Closed issues:**
|
||||||
|
|
||||||
- Add \# character to encapsulate list. [\#58](https://github.com/skywinder/Github-Changelog-Generator/issues/58)
|
- Add CodeClimate and Inch CI [\#219](https://github.com/skywinder/github-changelog-generator/issues/219)
|
||||||
|
|
||||||
## [1.3.2](https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.2) (2015-03-03)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.3.1...1.3.2)
|
|
||||||
|
|
||||||
**Fixed bugs:**
|
|
||||||
|
|
||||||
- generation failed if github commit api return `404 Not Found` [\#57](https://github.com/skywinder/Github-Changelog-Generator/issues/57)
|
|
||||||
|
|
||||||
## [1.3.1](https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.1) (2015-02-27)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.3.0...1.3.1)
|
|
||||||
|
|
||||||
## [1.3.0](https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.0) (2015-02-26)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.2.8...1.3.0)
|
|
||||||
|
|
||||||
**Implemented enhancements:**
|
|
||||||
|
|
||||||
- Do not show `Unreleased` section, when it's empty. [\#55](https://github.com/skywinder/Github-Changelog-Generator/issues/55)
|
|
||||||
|
|
||||||
- Separate list exclude and include labels [\#52](https://github.com/skywinder/Github-Changelog-Generator/issues/52)
|
|
||||||
|
|
||||||
- Unreleased issues in separate section [\#47](https://github.com/skywinder/Github-Changelog-Generator/issues/47)
|
|
||||||
|
|
||||||
- Separate by lists: Enhancements, Bugs, Pull requests. [\#31](https://github.com/skywinder/Github-Changelog-Generator/issues/31)
|
|
||||||
|
|
||||||
**Fixed bugs:**
|
|
||||||
|
|
||||||
- Test pull request with invalid label \(\#26\) in changelog appeared. [\#44](https://github.com/skywinder/Github-Changelog-Generator/issues/44)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
**Merged pull requests:**
|
||||||
|
|
||||||
- Implement filtering of Pull Requests by milestones [\#50](https://github.com/skywinder/Github-Changelog-Generator/pull/50) ([skywinder](https://github.com/skywinder))
|
- Cleanup [\#220](https://github.com/skywinder/github-changelog-generator/pull/220) ([tuexss](https://github.com/tuexss))
|
||||||
|
|
||||||
## [1.2.8](https://github.com/skywinder/Github-Changelog-Generator/tree/1.2.8) (2015-02-17)
|
- Add coveralls integration [\#223](https://github.com/skywinder/github-changelog-generator/pull/223) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.2.7...1.2.8)
|
- Rspec & rubocop integration [\#217](https://github.com/skywinder/github-changelog-generator/pull/217) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
- Implement Reader class to parse ChangeLog.md [\#216](https://github.com/skywinder/github-changelog-generator/pull/216) ([estahn](https://github.com/estahn))
|
||||||
|
|
||||||
|
- Relatively require github\_changelog\_generator library [\#207](https://github.com/skywinder/github-changelog-generator/pull/207) ([sneal](https://github.com/sneal))
|
||||||
|
|
||||||
|
- Add --max-issues argument to limit requests [\#76](https://github.com/skywinder/github-changelog-generator/pull/76) ([sneal](https://github.com/sneal))
|
||||||
|
|
||||||
|
## [1.3.11](https://github.com/skywinder/github-changelog-generator/tree/1.3.11) (2015-03-21)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.10...1.3.11)
|
||||||
|
|
||||||
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- Add fallback with warning message to prevent crash in case of exceed API Rate Limit \(temporary workaround for \#71\) [\#75](https://github.com/skywinder/github-changelog-generator/pull/75) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
## [1.3.10](https://github.com/skywinder/github-changelog-generator/tree/1.3.10) (2015-03-18)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.9...1.3.10)
|
||||||
|
|
||||||
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- Fix termination in case of empty unreleased section with `--unreleased-only` option. [\#70](https://github.com/skywinder/github-changelog-generator/pull/70) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
## [1.3.9](https://github.com/skywinder/github-changelog-generator/tree/1.3.9) (2015-03-06)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.8...1.3.9)
|
||||||
|
|
||||||
|
**Implemented enhancements:**
|
||||||
|
|
||||||
|
- Improve method of detecting owner and repository [\#63](https://github.com/skywinder/github-changelog-generator/issues/63)
|
||||||
|
|
||||||
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- Resolved concurrency problem in case of issues \> 2048 [\#65](https://github.com/skywinder/github-changelog-generator/pull/65) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
## [1.3.8](https://github.com/skywinder/github-changelog-generator/tree/1.3.8) (2015-03-05)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.6...1.3.8)
|
||||||
|
|
||||||
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- Fix `git remote` parsing in case, when script running without parameters inside destination directory [\#61](https://github.com/skywinder/github-changelog-generator/pull/61) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
## [1.3.6](https://github.com/skywinder/github-changelog-generator/tree/1.3.6) (2015-03-05)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.5...1.3.6)
|
||||||
|
|
||||||
|
## [1.3.5](https://github.com/skywinder/github-changelog-generator/tree/1.3.5) (2015-03-04)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.4...1.3.5)
|
||||||
|
|
||||||
|
**Fixed bugs:**
|
||||||
|
|
||||||
|
- Pull Requests in Wrong Tag [\#60](https://github.com/skywinder/github-changelog-generator/issues/60)
|
||||||
|
|
||||||
|
## [1.3.4](https://github.com/skywinder/github-changelog-generator/tree/1.3.4) (2015-03-03)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.3...1.3.4)
|
||||||
|
|
||||||
|
**Fixed bugs:**
|
||||||
|
|
||||||
|
- --no-issues appears to break PRs [\#59](https://github.com/skywinder/github-changelog-generator/issues/59)
|
||||||
|
|
||||||
|
## [1.3.3](https://github.com/skywinder/github-changelog-generator/tree/1.3.3) (2015-03-03)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.2...1.3.3)
|
||||||
|
|
||||||
**Closed issues:**
|
**Closed issues:**
|
||||||
|
|
||||||
- Bugs, that closed simultaneously with push not appeared in correct version. [\#37](https://github.com/skywinder/Github-Changelog-Generator/issues/37)
|
- Add \# character to encapsulate list. [\#58](https://github.com/skywinder/github-changelog-generator/issues/58)
|
||||||
|
|
||||||
**Merged pull requests:**
|
## [1.3.2](https://github.com/skywinder/github-changelog-generator/tree/1.3.2) (2015-03-03)
|
||||||
|
|
||||||
- Feature/fix 37 [\#49](https://github.com/skywinder/Github-Changelog-Generator/pull/49) ([skywinder](https://github.com/skywinder))
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.1...1.3.2)
|
||||||
|
|
||||||
- Prettify output [\#48](https://github.com/skywinder/Github-Changelog-Generator/pull/48) ([skywinder](https://github.com/skywinder))
|
**Fixed bugs:**
|
||||||
|
|
||||||
## [1.2.7](https://github.com/skywinder/Github-Changelog-Generator/tree/1.2.7) (2015-01-26)
|
- generation failed if github commit api return `404 Not Found` [\#57](https://github.com/skywinder/github-changelog-generator/issues/57)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.2.6...1.2.7)
|
## [1.3.1](https://github.com/skywinder/github-changelog-generator/tree/1.3.1) (2015-02-27)
|
||||||
|
|
||||||
**Merged pull requests:**
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.3.0...1.3.1)
|
||||||
|
|
||||||
- Add compare link between older version and newer version [\#46](https://github.com/skywinder/Github-Changelog-Generator/pull/46) ([sue445](https://github.com/sue445))
|
## [1.3.0](https://github.com/skywinder/github-changelog-generator/tree/1.3.0) (2015-02-26)
|
||||||
|
|
||||||
## [1.2.6](https://github.com/skywinder/Github-Changelog-Generator/tree/1.2.6) (2015-01-21)
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.2.8...1.3.0)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.2.5...1.2.6)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- fix link tag format [\#45](https://github.com/skywinder/Github-Changelog-Generator/pull/45) ([sugamasao](https://github.com/sugamasao))
|
|
||||||
|
|
||||||
## [1.2.5](https://github.com/skywinder/Github-Changelog-Generator/tree/1.2.5) (2015-01-15)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.2.4...1.2.5)
|
|
||||||
|
|
||||||
**Implemented enhancements:**
|
**Implemented enhancements:**
|
||||||
|
|
||||||
- Use milestone to specify in which version bug was fixed [\#22](https://github.com/skywinder/Github-Changelog-Generator/issues/22)
|
- Do not show `Unreleased` section, when it's empty. [\#55](https://github.com/skywinder/github-changelog-generator/issues/55)
|
||||||
|
|
||||||
|
- Separate list exclude and include labels [\#52](https://github.com/skywinder/github-changelog-generator/issues/52)
|
||||||
|
|
||||||
|
- Unreleased issues in separate section [\#47](https://github.com/skywinder/github-changelog-generator/issues/47)
|
||||||
|
|
||||||
|
- Separate by lists: Enhancements, Bugs, Pull requests. [\#31](https://github.com/skywinder/github-changelog-generator/issues/31)
|
||||||
|
|
||||||
**Fixed bugs:**
|
**Fixed bugs:**
|
||||||
|
|
||||||
- Error when trying to generate log for repo without tags [\#32](https://github.com/skywinder/Github-Changelog-Generator/issues/32)
|
- Pull request with invalid label \(\#26\) in changelog appeared. [\#44](https://github.com/skywinder/github-changelog-generator/issues/44)
|
||||||
|
|
||||||
**Merged pull requests:**
|
**Merged pull requests:**
|
||||||
|
|
||||||
- PrettyPrint class is included using lowercase 'pp' [\#43](https://github.com/skywinder/Github-Changelog-Generator/pull/43) ([schwing](https://github.com/schwing))
|
- Implement filtering of Pull Requests by milestones [\#50](https://github.com/skywinder/github-changelog-generator/pull/50) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
- support enterprise github via command line options [\#42](https://github.com/skywinder/Github-Changelog-Generator/pull/42) ([glenlovett](https://github.com/glenlovett))
|
## [1.2.8](https://github.com/skywinder/github-changelog-generator/tree/1.2.8) (2015-02-17)
|
||||||
|
|
||||||
## [1.2.4](https://github.com/skywinder/Github-Changelog-Generator/tree/1.2.4) (2014-12-16)
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.2.7...1.2.8)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.2.3...1.2.4)
|
**Closed issues:**
|
||||||
|
|
||||||
**Fixed bugs:**
|
- Bugs, that closed simultaneously with push not appeared in correct version. [\#37](https://github.com/skywinder/github-changelog-generator/issues/37)
|
||||||
|
|
||||||
- Sometimes user is NULL during merges [\#41](https://github.com/skywinder/Github-Changelog-Generator/issues/41)
|
**Merged pull requests:**
|
||||||
|
|
||||||
- Crash when try generate log for rails [\#35](https://github.com/skywinder/Github-Changelog-Generator/issues/35)
|
- Feature/fix 37 [\#49](https://github.com/skywinder/github-changelog-generator/pull/49) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
## [1.2.3](https://github.com/skywinder/Github-Changelog-Generator/tree/1.2.3) (2014-12-16)
|
- Prettify output [\#48](https://github.com/skywinder/github-changelog-generator/pull/48) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.2.2...1.2.3)
|
## [1.2.7](https://github.com/skywinder/github-changelog-generator/tree/1.2.7) (2015-01-26)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.2.6...1.2.7)
|
||||||
|
|
||||||
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- Add compare link between older version and newer version [\#46](https://github.com/skywinder/github-changelog-generator/pull/46) ([sue445](https://github.com/sue445))
|
||||||
|
|
||||||
|
## [1.2.6](https://github.com/skywinder/github-changelog-generator/tree/1.2.6) (2015-01-21)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.2.5...1.2.6)
|
||||||
|
|
||||||
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- fix link tag format [\#45](https://github.com/skywinder/github-changelog-generator/pull/45) ([sugamasao](https://github.com/sugamasao))
|
||||||
|
|
||||||
|
## [1.2.5](https://github.com/skywinder/github-changelog-generator/tree/1.2.5) (2015-01-15)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.2.4...1.2.5)
|
||||||
|
|
||||||
**Implemented enhancements:**
|
**Implemented enhancements:**
|
||||||
|
|
||||||
- Add ability to run with one parameter instead -u -p [\#38](https://github.com/skywinder/Github-Changelog-Generator/issues/38)
|
- Use milestone to specify in which version bug was fixed [\#22](https://github.com/skywinder/github-changelog-generator/issues/22)
|
||||||
|
|
||||||
- Detailed output [\#33](https://github.com/skywinder/Github-Changelog-Generator/issues/33)
|
|
||||||
|
|
||||||
**Fixed bugs:**
|
**Fixed bugs:**
|
||||||
|
|
||||||
- Docs lacking or basic behavior not as advertised [\#30](https://github.com/skywinder/Github-Changelog-Generator/issues/30)
|
- Error when trying to generate log for repo without tags [\#32](https://github.com/skywinder/github-changelog-generator/issues/32)
|
||||||
|
|
||||||
**Merged pull requests:**
|
**Merged pull requests:**
|
||||||
|
|
||||||
- Implement async fetching [\#39](https://github.com/skywinder/Github-Changelog-Generator/pull/39) ([skywinder](https://github.com/skywinder))
|
- PrettyPrint class is included using lowercase 'pp' [\#43](https://github.com/skywinder/github-changelog-generator/pull/43) ([schwing](https://github.com/schwing))
|
||||||
|
|
||||||
- Fix crash when user is NULL [\#40](https://github.com/skywinder/Github-Changelog-Generator/pull/40) ([skywinder](https://github.com/skywinder))
|
- support enterprise github via command line options [\#42](https://github.com/skywinder/github-changelog-generator/pull/42) ([glenlovett](https://github.com/glenlovett))
|
||||||
|
|
||||||
## [1.2.2](https://github.com/skywinder/Github-Changelog-Generator/tree/1.2.2) (2014-12-10)
|
## [1.2.4](https://github.com/skywinder/github-changelog-generator/tree/1.2.4) (2014-12-16)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.2.1...1.2.2)
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.2.3...1.2.4)
|
||||||
|
|
||||||
**Fixed bugs:**
|
**Fixed bugs:**
|
||||||
|
|
||||||
- Encapsulate \[ \> \* \_ \ \] signs in issues names [\#34](https://github.com/skywinder/Github-Changelog-Generator/issues/34)
|
- Sometimes user is NULL during merges [\#41](https://github.com/skywinder/github-changelog-generator/issues/41)
|
||||||
|
|
||||||
**Merged pull requests:**
|
- Crash when try generate log for rails [\#35](https://github.com/skywinder/github-changelog-generator/issues/35)
|
||||||
|
|
||||||
- Add a Bitdeli Badge to README [\#36](https://github.com/skywinder/Github-Changelog-Generator/pull/36) ([bitdeli-chef](https://github.com/bitdeli-chef))
|
## [1.2.3](https://github.com/skywinder/github-changelog-generator/tree/1.2.3) (2014-12-16)
|
||||||
|
|
||||||
## [1.2.1](https://github.com/skywinder/Github-Changelog-Generator/tree/1.2.1) (2014-11-22)
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.2.2...1.2.3)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.2.0...1.2.1)
|
|
||||||
|
|
||||||
**Fixed bugs:**
|
|
||||||
|
|
||||||
- Script fills changelog only for first 30 tags. [\#20](https://github.com/skywinder/Github-Changelog-Generator/issues/20)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Issues for last tag not in list [\#29](https://github.com/skywinder/Github-Changelog-Generator/pull/29) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
- Disable default --filter-pull-requests option. [\#28](https://github.com/skywinder/Github-Changelog-Generator/pull/28) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
## [1.2.0](https://github.com/skywinder/Github-Changelog-Generator/tree/1.2.0) (2014-11-19)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.1.4...1.2.0)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Add filter for pull-requests labels. \(option --filter-pull-requests\) [\#27](https://github.com/skywinder/Github-Changelog-Generator/pull/27) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
- Add ability to insert authors of pull-requests \(--\[no-\]author option\) [\#25](https://github.com/skywinder/Github-Changelog-Generator/pull/25) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
- Don't receive issues in case of --no-isses flag specied [\#24](https://github.com/skywinder/Github-Changelog-Generator/pull/24) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
## [1.1.4](https://github.com/skywinder/Github-Changelog-Generator/tree/1.1.4) (2014-11-18)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.1.2...1.1.4)
|
|
||||||
|
|
||||||
**Implemented enhancements:**
|
**Implemented enhancements:**
|
||||||
|
|
||||||
- Implement ability to retrieve GitHub token from ENV variable \(to not put it to script directly\) [\#19](https://github.com/skywinder/Github-Changelog-Generator/issues/19)
|
- Add ability to run with one parameter instead -u -p [\#38](https://github.com/skywinder/github-changelog-generator/issues/38)
|
||||||
|
|
||||||
**Merged pull requests:**
|
- Detailed output [\#33](https://github.com/skywinder/github-changelog-generator/issues/33)
|
||||||
|
|
||||||
- Sort tags by date [\#23](https://github.com/skywinder/Github-Changelog-Generator/pull/23) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
## [1.1.2](https://github.com/skywinder/Github-Changelog-Generator/tree/1.1.2) (2014-11-12)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.1.1...1.1.2)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Fix bug with dot signs in project name [\#18](https://github.com/skywinder/Github-Changelog-Generator/pull/18) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
- Fix bug with dot signs in user name [\#17](https://github.com/skywinder/Github-Changelog-Generator/pull/17) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
## [1.1.1](https://github.com/skywinder/Github-Changelog-Generator/tree/1.1.1) (2014-11-10)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.1.0...1.1.1)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Remove duplicates of issues and pull-requests with same number [\#15](https://github.com/skywinder/Github-Changelog-Generator/pull/15) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
- Sort issues by tags [\#14](https://github.com/skywinder/Github-Changelog-Generator/pull/14) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
- Add ability to add or exclude issues without any labels [\#13](https://github.com/skywinder/Github-Changelog-Generator/pull/13) ([skywinder](https://github.com/skywinder))
|
|
||||||
|
|
||||||
## [1.1.0](https://github.com/skywinder/Github-Changelog-Generator/tree/1.1.0) (2014-11-10)
|
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.0.1...1.1.0)
|
|
||||||
|
|
||||||
**Implemented enhancements:**
|
|
||||||
|
|
||||||
- Detect username and project form origin [\#11](https://github.com/skywinder/Github-Changelog-Generator/issues/11)
|
|
||||||
|
|
||||||
**Fixed bugs:**
|
**Fixed bugs:**
|
||||||
|
|
||||||
- Bug with wrong credentials in 1.0.1 [\#12](https://github.com/skywinder/Github-Changelog-Generator/issues/12)
|
- Docs lacking or basic behavior not as advertised [\#30](https://github.com/skywinder/github-changelog-generator/issues/30)
|
||||||
|
|
||||||
- Markdown formating in the last line wrong [\#9](https://github.com/skywinder/Github-Changelog-Generator/issues/9)
|
**Merged pull requests:**
|
||||||
|
|
||||||
## [1.0.1](https://github.com/skywinder/Github-Changelog-Generator/tree/1.0.1) (2014-11-10)
|
- Implement async fetching [\#39](https://github.com/skywinder/github-changelog-generator/pull/39) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/1.0.0...1.0.1)
|
- Fix crash when user is NULL [\#40](https://github.com/skywinder/github-changelog-generator/pull/40) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
## [1.0.0](https://github.com/skywinder/Github-Changelog-Generator/tree/1.0.0) (2014-11-07)
|
## [1.2.2](https://github.com/skywinder/github-changelog-generator/tree/1.2.2) (2014-12-10)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/0.1.0...1.0.0)
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.2.1...1.2.2)
|
||||||
|
|
||||||
**Implemented enhancements:**
|
|
||||||
|
|
||||||
- Add support for fixed issues and implemented enchanments. [\#6](https://github.com/skywinder/Github-Changelog-Generator/issues/6)
|
|
||||||
|
|
||||||
- Implement option to specify output filename [\#4](https://github.com/skywinder/Github-Changelog-Generator/issues/4)
|
|
||||||
|
|
||||||
**Fixed bugs:**
|
**Fixed bugs:**
|
||||||
|
|
||||||
- Last tag not appeared in changelog [\#5](https://github.com/skywinder/Github-Changelog-Generator/issues/5)
|
- Encapsulate \[ \> \* \_ \ \] signs in issues names [\#34](https://github.com/skywinder/github-changelog-generator/issues/34)
|
||||||
|
|
||||||
**Merged pull requests:**
|
**Merged pull requests:**
|
||||||
|
|
||||||
- Implement support of different tags. [\#8](https://github.com/skywinder/Github-Changelog-Generator/pull/8) ([skywinder](https://github.com/skywinder))
|
- Add a Bitdeli Badge to README [\#36](https://github.com/skywinder/github-changelog-generator/pull/36) ([bitdeli-chef](https://github.com/bitdeli-chef))
|
||||||
|
|
||||||
- Add support for issues in CHANGELOG [\#7](https://github.com/skywinder/Github-Changelog-Generator/pull/7) ([skywinder](https://github.com/skywinder))
|
## [1.2.1](https://github.com/skywinder/github-changelog-generator/tree/1.2.1) (2014-11-22)
|
||||||
|
|
||||||
## [0.1.0](https://github.com/skywinder/Github-Changelog-Generator/tree/0.1.0) (2014-11-07)
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.2.0...1.2.1)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/0.0.2...0.1.0)
|
**Fixed bugs:**
|
||||||
|
|
||||||
|
- Script fills changelog only for first 30 tags. [\#20](https://github.com/skywinder/github-changelog-generator/issues/20)
|
||||||
|
|
||||||
**Merged pull requests:**
|
**Merged pull requests:**
|
||||||
|
|
||||||
- Fix parsing date of pull request [\#3](https://github.com/skywinder/Github-Changelog-Generator/pull/3) ([skywinder](https://github.com/skywinder))
|
- Issues for last tag not in list [\#29](https://github.com/skywinder/github-changelog-generator/pull/29) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
- Add changelog generation for last tag [\#2](https://github.com/skywinder/Github-Changelog-Generator/pull/2) ([skywinder](https://github.com/skywinder))
|
- Disable default --filter-pull-requests option. [\#28](https://github.com/skywinder/github-changelog-generator/pull/28) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
- Add option \(-o --output\) to specify name of the output file. [\#1](https://github.com/skywinder/Github-Changelog-Generator/pull/1) ([skywinder](https://github.com/skywinder))
|
## [1.2.0](https://github.com/skywinder/github-changelog-generator/tree/1.2.0) (2014-11-19)
|
||||||
|
|
||||||
## [0.0.2](https://github.com/skywinder/Github-Changelog-Generator/tree/0.0.2) (2014-11-06)
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.1.4...1.2.0)
|
||||||
|
|
||||||
[Full Changelog](https://github.com/skywinder/Github-Changelog-Generator/compare/0.0.1...0.0.2)
|
**Merged pull requests:**
|
||||||
|
|
||||||
## [0.0.1](https://github.com/skywinder/Github-Changelog-Generator/tree/0.0.1) (2014-11-06)
|
- Add filter for pull-requests labels. \(option --filter-pull-requests\) [\#27](https://github.com/skywinder/github-changelog-generator/pull/27) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
- Add ability to insert authors of pull-requests \(--\[no-\]author option\) [\#25](https://github.com/skywinder/github-changelog-generator/pull/25) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
- Don't receive issues in case of --no-isses flag specied [\#24](https://github.com/skywinder/github-changelog-generator/pull/24) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
## [1.1.4](https://github.com/skywinder/github-changelog-generator/tree/1.1.4) (2014-11-18)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.1.2...1.1.4)
|
||||||
|
|
||||||
|
**Implemented enhancements:**
|
||||||
|
|
||||||
|
- Implement ability to retrieve GitHub token from ENV variable \(to not put it to script directly\) [\#19](https://github.com/skywinder/github-changelog-generator/issues/19)
|
||||||
|
|
||||||
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- Sort tags by date [\#23](https://github.com/skywinder/github-changelog-generator/pull/23) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
## [1.1.2](https://github.com/skywinder/github-changelog-generator/tree/1.1.2) (2014-11-12)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.1.1...1.1.2)
|
||||||
|
|
||||||
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- Fix bug with dot signs in project name [\#18](https://github.com/skywinder/github-changelog-generator/pull/18) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
- Fix bug with dot signs in user name [\#17](https://github.com/skywinder/github-changelog-generator/pull/17) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
## [1.1.1](https://github.com/skywinder/github-changelog-generator/tree/1.1.1) (2014-11-10)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.1.0...1.1.1)
|
||||||
|
|
||||||
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- Remove duplicates of issues and pull-requests with same number [\#15](https://github.com/skywinder/github-changelog-generator/pull/15) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
- Sort issues by tags [\#14](https://github.com/skywinder/github-changelog-generator/pull/14) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
- Add ability to add or exclude issues without any labels [\#13](https://github.com/skywinder/github-changelog-generator/pull/13) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
## [1.1.0](https://github.com/skywinder/github-changelog-generator/tree/1.1.0) (2014-11-10)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.0.1...1.1.0)
|
||||||
|
|
||||||
|
**Implemented enhancements:**
|
||||||
|
|
||||||
|
- Detect username and project form origin [\#11](https://github.com/skywinder/github-changelog-generator/issues/11)
|
||||||
|
|
||||||
|
**Fixed bugs:**
|
||||||
|
|
||||||
|
- Bug with wrong credentials in 1.0.1 [\#12](https://github.com/skywinder/github-changelog-generator/issues/12)
|
||||||
|
|
||||||
|
- Markdown formating in the last line wrong [\#9](https://github.com/skywinder/github-changelog-generator/issues/9)
|
||||||
|
|
||||||
|
## [1.0.1](https://github.com/skywinder/github-changelog-generator/tree/1.0.1) (2014-11-10)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/1.0.0...1.0.1)
|
||||||
|
|
||||||
|
## [1.0.0](https://github.com/skywinder/github-changelog-generator/tree/1.0.0) (2014-11-07)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/0.1.0...1.0.0)
|
||||||
|
|
||||||
|
**Implemented enhancements:**
|
||||||
|
|
||||||
|
- Add support for fixed issues and implemented enchanments. [\#6](https://github.com/skywinder/github-changelog-generator/issues/6)
|
||||||
|
|
||||||
|
- Implement option to specify output filename [\#4](https://github.com/skywinder/github-changelog-generator/issues/4)
|
||||||
|
|
||||||
|
**Fixed bugs:**
|
||||||
|
|
||||||
|
- Last tag not appeared in changelog [\#5](https://github.com/skywinder/github-changelog-generator/issues/5)
|
||||||
|
|
||||||
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- Implement support of different tags. [\#8](https://github.com/skywinder/github-changelog-generator/pull/8) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
- Add support for issues in CHANGELOG [\#7](https://github.com/skywinder/github-changelog-generator/pull/7) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
## [0.1.0](https://github.com/skywinder/github-changelog-generator/tree/0.1.0) (2014-11-07)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/0.0.2...0.1.0)
|
||||||
|
|
||||||
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- Fix parsing date of pull request [\#3](https://github.com/skywinder/github-changelog-generator/pull/3) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
- Add changelog generation for last tag [\#2](https://github.com/skywinder/github-changelog-generator/pull/2) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
- Add option \(-o --output\) to specify name of the output file. [\#1](https://github.com/skywinder/github-changelog-generator/pull/1) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
|
## [0.0.2](https://github.com/skywinder/github-changelog-generator/tree/0.0.2) (2014-11-06)
|
||||||
|
|
||||||
|
[Full Changelog](https://github.com/skywinder/github-changelog-generator/compare/0.0.1...0.0.2)
|
||||||
|
|
||||||
|
## [0.0.1](https://github.com/skywinder/github-changelog-generator/tree/0.0.1) (2014-11-06)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
17
Gemfile
17
Gemfile
@@ -1,13 +1,14 @@
|
|||||||
source 'https://rubygems.org'
|
source "https://rubygems.org"
|
||||||
|
|
||||||
gem 'rake'
|
gem "rake"
|
||||||
|
|
||||||
gem 'github_api'
|
gem "github_api"
|
||||||
gem 'colorize'
|
gem "colorize"
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'rspec'
|
gem "rspec"
|
||||||
gem 'rubocop'
|
gem "rubocop"
|
||||||
gem 'coveralls', require: false
|
gem "coveralls", require: false
|
||||||
gem 'simplecov', require: false
|
gem "simplecov", require: false
|
||||||
|
gem "codeclimate-test-reporter"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ GEM
|
|||||||
ast (2.0.0)
|
ast (2.0.0)
|
||||||
astrolabe (1.3.0)
|
astrolabe (1.3.0)
|
||||||
parser (>= 2.2.0.pre.3, < 3.0)
|
parser (>= 2.2.0.pre.3, < 3.0)
|
||||||
|
codeclimate-test-reporter (0.4.7)
|
||||||
|
simplecov (>= 0.7.1, < 1.0.0)
|
||||||
colorize (0.7.5)
|
colorize (0.7.5)
|
||||||
coveralls (0.7.12)
|
coveralls (0.7.12)
|
||||||
multi_json (~> 1.10)
|
multi_json (~> 1.10)
|
||||||
@@ -94,6 +96,7 @@ PLATFORMS
|
|||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
|
codeclimate-test-reporter
|
||||||
colorize
|
colorize
|
||||||
coveralls
|
coveralls
|
||||||
github_api
|
github_api
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
|
[](http://badge.fury.io/rb/github_changelog_generator)
|
||||||
[](https://gemnasium.com/skywinder/github-changelog-generator)
|
[](https://gemnasium.com/skywinder/github-changelog-generator)
|
||||||
[](https://travis-ci.org/skywinder/github-changelog-generator)
|
[](https://travis-ci.org/skywinder/github-changelog-generator)
|
||||||
[](https://coveralls.io/r/skywinder/github-changelog-generator)
|
|
||||||
[](https://codeclimate.com/github/skywinder/github-changelog-generator)
|
|
||||||
[](http://inch-ci.org/github/skywinder/github-changelog-generator)
|
[](http://inch-ci.org/github/skywinder/github-changelog-generator)
|
||||||
|
[](https://codeclimate.com/github/skywinder/github-changelog-generator)
|
||||||
|
[](https://codeclimate.com/github/skywinder/github-changelog-generator)
|
||||||
|
|
||||||
GitHub Changelog Generator 
|
GitHub Changelog Generator 
|
||||||
==================
|
==================
|
||||||
@@ -110,7 +111,7 @@ Type `github_changelog_generator --help` for detailed usage.
|
|||||||
|
|
||||||
Since GitHub allows you to make only 50 requests without authentication it's recommended to run this script with a token (`-t, --token` option)
|
Since GitHub allows you to make only 50 requests without authentication it's recommended to run this script with a token (`-t, --token` option)
|
||||||
|
|
||||||
**You can easily [generate it here](https://github.com/settings/applications)**.
|
**You can easily [generate it here](https://github.com/settings/tokens)**.
|
||||||
|
|
||||||
And:
|
And:
|
||||||
|
|
||||||
@@ -155,6 +156,8 @@ Here is a [wikipage list of alternatives](https://github.com/skywinder/Github-Ch
|
|||||||
### Projects using this library
|
### Projects using this library
|
||||||
[Wikipage with list of projects](https://github.com/skywinder/Github-Changelog-Generator/wiki/Projects-using-Github-Changelog-Generator)
|
[Wikipage with list of projects](https://github.com/skywinder/Github-Changelog-Generator/wiki/Projects-using-Github-Changelog-Generator)
|
||||||
|
|
||||||
|
If you've used this project in a live app, please let me know! Nothing makes me happier than seeing someone else take my work and go wild with it.
|
||||||
|
|
||||||
*If you are using `github_changelog_generator` for generation change log in your project or know another project that uses it, please add it to [this] (https://github.com/skywinder/Github-Changelog-Generator/wiki/Projects-using-Github-Changelog-Generator) list.*
|
*If you are using `github_changelog_generator` for generation change log in your project or know another project that uses it, please add it to [this] (https://github.com/skywinder/Github-Changelog-Generator/wiki/Projects-using-Github-Changelog-Generator) list.*
|
||||||
|
|
||||||
## Am I missing some essential feature?
|
## Am I missing some essential feature?
|
||||||
|
|||||||
4
Rakefile
4
Rakefile
@@ -1,5 +1,5 @@
|
|||||||
require 'rubocop/rake_task'
|
require "rubocop/rake_task"
|
||||||
require 'rspec/core/rake_task'
|
require "rspec/core/rake_task"
|
||||||
|
|
||||||
RuboCop::RakeTask.new
|
RuboCop::RakeTask.new
|
||||||
RSpec::Core::RakeTask.new(:rspec)
|
RSpec::Core::RakeTask.new(:rspec)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#! /usr/bin/env ruby
|
#! /usr/bin/env ruby
|
||||||
|
|
||||||
require_relative '../lib/github_changelog_generator'
|
require_relative "../lib/github_changelog_generator"
|
||||||
GitHubChangelogGenerator::ChangelogGenerator.new.compound_changelog
|
GitHubChangelogGenerator::ChangelogGenerator.new.compound_changelog
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
require 'optparse'
|
require "optparse"
|
||||||
|
|
||||||
SPEC_TYPE = 'gemspec'
|
SPEC_TYPE = "gemspec"
|
||||||
|
|
||||||
:major
|
:major
|
||||||
:minor
|
:minor
|
||||||
@@ -10,21 +10,21 @@ SPEC_TYPE = 'gemspec'
|
|||||||
@options = { dry_run: false, bump_number: :patch }
|
@options = { dry_run: false, bump_number: :patch }
|
||||||
|
|
||||||
OptionParser.new { |opts|
|
OptionParser.new { |opts|
|
||||||
opts.banner = 'Usage: bump.rb [options]'
|
opts.banner = "Usage: bump.rb [options]"
|
||||||
|
|
||||||
opts.on('-d', '--dry-run', 'Dry run') do |v|
|
opts.on("-d", "--dry-run", "Dry run") do |v|
|
||||||
@options[:dry_run] = v
|
@options[:dry_run] = v
|
||||||
end
|
end
|
||||||
opts.on('-a', '--major', 'Bump major version') do |_v|
|
opts.on("-a", "--major", "Bump major version") do |_v|
|
||||||
@options[:bump_number] = :major
|
@options[:bump_number] = :major
|
||||||
end
|
end
|
||||||
opts.on('-m', '--minor', 'Bump minor version') do |_v|
|
opts.on("-m", "--minor", "Bump minor version") do |_v|
|
||||||
@options[:bump_number] = :minor
|
@options[:bump_number] = :minor
|
||||||
end
|
end
|
||||||
opts.on('-p', '--patch', 'Bump patch version') do |_v|
|
opts.on("-p", "--patch", "Bump patch version") do |_v|
|
||||||
@options[:bump_number] = :patch
|
@options[:bump_number] = :patch
|
||||||
end
|
end
|
||||||
opts.on('-r', '--revert', 'Revert last bump') do |v|
|
opts.on("-r", "--revert", "Revert last bump") do |v|
|
||||||
@options[:revert] = v
|
@options[:revert] = v
|
||||||
end
|
end
|
||||||
}.parse!
|
}.parse!
|
||||||
@@ -32,15 +32,15 @@ OptionParser.new { |opts|
|
|||||||
p @options
|
p @options
|
||||||
|
|
||||||
def check_repo_is_clean_or_dry_run
|
def check_repo_is_clean_or_dry_run
|
||||||
value = `#{'git status --porcelain'}`
|
value = `#{"git status --porcelain"}`
|
||||||
|
|
||||||
if value.empty?
|
if value.empty?
|
||||||
puts 'Repo is clean -> continue'
|
puts "Repo is clean -> continue"
|
||||||
else
|
else
|
||||||
if @options[:dry_run]
|
if @options[:dry_run]
|
||||||
puts 'Repo not clean, "Dry run" enabled -> continue'
|
puts 'Repo not clean, "Dry run" enabled -> continue'
|
||||||
else
|
else
|
||||||
puts 'Repository not clean -> exit'
|
puts "Repository not clean -> exit"
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -50,7 +50,7 @@ def find_spec_file
|
|||||||
list_of_specs = execute_line("find . -name '*.#{SPEC_TYPE}'")
|
list_of_specs = execute_line("find . -name '*.#{SPEC_TYPE}'")
|
||||||
arr = list_of_specs.split("\n")
|
arr = list_of_specs.split("\n")
|
||||||
|
|
||||||
spec_file = ''
|
spec_file = ""
|
||||||
|
|
||||||
case arr.count
|
case arr.count
|
||||||
when 0
|
when 0
|
||||||
@@ -59,7 +59,7 @@ def find_spec_file
|
|||||||
when 1
|
when 1
|
||||||
spec_file = arr[0]
|
spec_file = arr[0]
|
||||||
else
|
else
|
||||||
puts 'Which spec should be used?'
|
puts "Which spec should be used?"
|
||||||
arr.each_with_index { |file, index| puts "#{index + 1}. #{file}" }
|
arr.each_with_index { |file, index| puts "#{index + 1}. #{file}" }
|
||||||
input_index = Integer(gets.chomp)
|
input_index = Integer(gets.chomp)
|
||||||
spec_file = arr[input_index - 1]
|
spec_file = arr[input_index - 1]
|
||||||
@@ -70,14 +70,14 @@ def find_spec_file
|
|||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
|
|
||||||
spec_file.sub('./', '')
|
spec_file.sub("./", "")
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_current_gem_file
|
def find_current_gem_file
|
||||||
list_of_specs = execute_line("find . -name '*.gem'")
|
list_of_specs = execute_line("find . -name '*.gem'")
|
||||||
arr = list_of_specs.split("\n")
|
arr = list_of_specs.split("\n")
|
||||||
|
|
||||||
spec_file = ''
|
spec_file = ""
|
||||||
|
|
||||||
case arr.count
|
case arr.count
|
||||||
when 0
|
when 0
|
||||||
@@ -86,7 +86,7 @@ def find_current_gem_file
|
|||||||
when 1
|
when 1
|
||||||
spec_file = arr[0]
|
spec_file = arr[0]
|
||||||
else
|
else
|
||||||
puts 'Which spec should be used?'
|
puts "Which spec should be used?"
|
||||||
arr.each_with_index { |file, index| puts "#{index + 1}. #{file}" }
|
arr.each_with_index { |file, index| puts "#{index + 1}. #{file}" }
|
||||||
input_index = Integer(gets.chomp)
|
input_index = Integer(gets.chomp)
|
||||||
spec_file = arr[input_index - 1]
|
spec_file = arr[input_index - 1]
|
||||||
@@ -97,7 +97,7 @@ def find_current_gem_file
|
|||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
|
|
||||||
spec_file.sub('./', '')
|
spec_file.sub("./", "")
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_version_in_podspec(podspec)
|
def find_version_in_podspec(podspec)
|
||||||
@@ -109,7 +109,7 @@ def find_version_in_podspec(podspec)
|
|||||||
match_result = re.match(readme)
|
match_result = re.match(readme)
|
||||||
|
|
||||||
unless match_result
|
unless match_result
|
||||||
puts 'Not found any versions'
|
puts "Not found any versions"
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -132,10 +132,10 @@ def bump_version(versions_array)
|
|||||||
when :patch
|
when :patch
|
||||||
bumped_result[2] += 1
|
bumped_result[2] += 1
|
||||||
else
|
else
|
||||||
fail('unknown bump_number')
|
fail("unknown bump_number")
|
||||||
end
|
end
|
||||||
|
|
||||||
bumped_version = bumped_result.join('.')
|
bumped_version = bumped_result.join(".")
|
||||||
puts "Bump version: #{versions_array.join('.')} -> #{bumped_version}"
|
puts "Bump version: #{versions_array.join('.')} -> #{bumped_version}"
|
||||||
bumped_version
|
bumped_version
|
||||||
end
|
end
|
||||||
@@ -174,10 +174,10 @@ def run_bumping_script
|
|||||||
bumped_version = bump_version(versions_array)
|
bumped_version = bump_version(versions_array)
|
||||||
|
|
||||||
unless @options[:dry_run]
|
unless @options[:dry_run]
|
||||||
puts 'Are you sure? Press Y to continue:'
|
puts "Are you sure? Press Y to continue:"
|
||||||
str = gets.chomp
|
str = gets.chomp
|
||||||
if str != 'Y'
|
if str != "Y"
|
||||||
puts '-> exit'
|
puts "-> exit"
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -186,8 +186,8 @@ def run_bumping_script
|
|||||||
execute_line_if_not_dry_run("sed -i \"\" \"s/#{result}/#{bumped_version}/\" #{spec_file}")
|
execute_line_if_not_dry_run("sed -i \"\" \"s/#{result}/#{bumped_version}/\" #{spec_file}")
|
||||||
execute_line_if_not_dry_run("git commit --all -m \"Update #{$SPEC_TYPE} to version #{bumped_version}\"")
|
execute_line_if_not_dry_run("git commit --all -m \"Update #{$SPEC_TYPE} to version #{bumped_version}\"")
|
||||||
execute_line_if_not_dry_run("git tag #{bumped_version}")
|
execute_line_if_not_dry_run("git tag #{bumped_version}")
|
||||||
execute_line_if_not_dry_run('git push')
|
execute_line_if_not_dry_run("git push")
|
||||||
execute_line_if_not_dry_run('git push --tags')
|
execute_line_if_not_dry_run("git push --tags")
|
||||||
execute_line_if_not_dry_run("gem build #{spec_file}")
|
execute_line_if_not_dry_run("gem build #{spec_file}")
|
||||||
|
|
||||||
gem = find_current_gem_file
|
gem = find_current_gem_file
|
||||||
@@ -201,12 +201,12 @@ def revert_last_bump
|
|||||||
|
|
||||||
puts "DELETE tag #{result} and HARD reset HEAD~1?\nPress Y to continue:"
|
puts "DELETE tag #{result} and HARD reset HEAD~1?\nPress Y to continue:"
|
||||||
str = gets.chomp
|
str = gets.chomp
|
||||||
if str != 'Y'
|
if str != "Y"
|
||||||
puts '-> exit'
|
puts "-> exit"
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
execute_line_if_not_dry_run("git tag -d #{result}")
|
execute_line_if_not_dry_run("git tag -d #{result}")
|
||||||
execute_line_if_not_dry_run('git reset --hard HEAD~1')
|
execute_line_if_not_dry_run("git reset --hard HEAD~1")
|
||||||
execute_line_if_not_dry_run("git push --delete origin #{result}")
|
execute_line_if_not_dry_run("git push --delete origin #{result}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
|
||||||
lib = File.expand_path('../lib', __FILE__)
|
lib = File.expand_path("../lib", __FILE__)
|
||||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||||
require 'github_changelog_generator/version'
|
require "github_changelog_generator/version"
|
||||||
|
|
||||||
Gem::Specification.new do |spec|
|
Gem::Specification.new do |spec|
|
||||||
spec.name = 'github_changelog_generator'
|
spec.name = "github_changelog_generator"
|
||||||
spec.version = GitHubChangelogGenerator::VERSION
|
spec.version = GitHubChangelogGenerator::VERSION
|
||||||
spec.default_executable = 'github_changelog_generator'
|
spec.default_executable = "github_changelog_generator"
|
||||||
|
|
||||||
spec.required_ruby_version = '>= 1.9.3'
|
spec.required_ruby_version = ">= 1.9.3"
|
||||||
spec.authors = ['Petr Korolev']
|
spec.authors = ["Petr Korolev"]
|
||||||
spec.email = 'sky4winder+github_changelog_generator@gmail.com'
|
spec.email = "sky4winder+github_changelog_generator@gmail.com"
|
||||||
spec.date = `date +"%Y-%m-%d"`.strip!
|
spec.date = `date +"%Y-%m-%d"`.strip!
|
||||||
spec.summary = 'Script, that automatically generate changelog from your tags, issues, labels and pull requests.'
|
spec.summary = "Script, that automatically generate changelog from your tags, issues, labels and pull requests."
|
||||||
spec.description = 'Changelog generation has never been so easy. Fully automate changelog generation - this gem generate change log file based on tags, issues and merged pull requests from Github issue tracker.'
|
spec.description = "Changelog generation has never been so easy. Fully automate changelog generation - this gem generate change log file based on tags, issues and merged pull requests from Github issue tracker."
|
||||||
spec.homepage = 'https://github.com/skywinder/Github-Changelog-Generator'
|
spec.homepage = "https://github.com/skywinder/Github-Changelog-Generator"
|
||||||
spec.license = 'MIT'
|
spec.license = "MIT"
|
||||||
|
|
||||||
spec.files = `git ls-files -z`.split("\x0")
|
spec.files = `git ls-files -z`.split("\x0")
|
||||||
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
||||||
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
||||||
spec.require_paths = ['lib']
|
spec.require_paths = ["lib"]
|
||||||
|
|
||||||
spec.add_development_dependency 'bundler', '~> 1.7'
|
spec.add_development_dependency "bundler", "~> 1.7"
|
||||||
spec.add_development_dependency 'rake', '~> 10.0'
|
spec.add_development_dependency "rake", "~> 10.0"
|
||||||
|
|
||||||
spec.add_runtime_dependency('github_api', ['~> 0.12'])
|
spec.add_runtime_dependency("github_api", ["~> 0.12"])
|
||||||
spec.add_runtime_dependency('colorize', ['~> 0.7'])
|
spec.add_runtime_dependency("colorize", ["~> 0.7"])
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
**Merged pull requests:**
|
**Merged pull requests:**
|
||||||
|
|
||||||
|
- This PR SHOULD NOT appear in change log! [\#6](https://github.com/skywinder/changelog_test/pull/6) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
- Add automatically generated change log file. [\#5](https://github.com/skywinder/changelog_test/pull/5) ([skywinder](https://github.com/skywinder))
|
- Add automatically generated change log file. [\#5](https://github.com/skywinder/changelog_test/pull/5) ([skywinder](https://github.com/skywinder))
|
||||||
|
|
||||||
## [v0.0.3](https://github.com/skywinder/changelog_test/tree/v0.0.3) (2015-03-04)
|
## [v0.0.3](https://github.com/skywinder/changelog_test/tree/v0.0.3) (2015-03-04)
|
||||||
|
|||||||
@@ -1,59 +1,62 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
require 'github_api'
|
require "github_api"
|
||||||
require 'json'
|
require "json"
|
||||||
require 'colorize'
|
require "colorize"
|
||||||
require 'benchmark'
|
require "benchmark"
|
||||||
|
|
||||||
require_relative 'github_changelog_generator/parser'
|
require_relative "github_changelog_generator/parser"
|
||||||
require_relative 'github_changelog_generator/generator'
|
require_relative "github_changelog_generator/generator"
|
||||||
require_relative 'github_changelog_generator/version'
|
require_relative "github_changelog_generator/version"
|
||||||
require_relative 'github_changelog_generator/reader'
|
require_relative "github_changelog_generator/reader"
|
||||||
|
require_relative "github_changelog_generator/fetcher"
|
||||||
|
|
||||||
module GitHubChangelogGenerator
|
module GitHubChangelogGenerator
|
||||||
|
# Default error for ChangelogGenerator
|
||||||
|
class ChangelogGeneratorError < StandardError
|
||||||
|
end
|
||||||
|
|
||||||
|
# Main class and entry point for this script.
|
||||||
class ChangelogGenerator
|
class ChangelogGenerator
|
||||||
attr_accessor :options, :all_tags, :github
|
attr_accessor :options, :all_tags, :github
|
||||||
|
|
||||||
PER_PAGE_NUMBER = 30
|
# Class, responsible for whole change log generation cycle
|
||||||
GH_RATE_LIMIT_EXCEEDED_MSG = 'Warning: GitHub API rate limit (5000 per hour) exceeded, change log may be ' \
|
# @return initialised instance of ChangelogGenerator
|
||||||
'missing some issues. You can limit the number of issues fetched using the `--max-issues NUM` argument.'
|
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@options = Parser.parse_options
|
@options = Parser.parse_options
|
||||||
|
|
||||||
fetch_github_token
|
@fetcher = GitHubChangelogGenerator::Fetcher.new @options
|
||||||
|
|
||||||
github_options = { per_page: PER_PAGE_NUMBER }
|
@generator = Generator.new @options
|
||||||
github_options[:oauth_token] = @github_token unless @github_token.nil?
|
|
||||||
github_options[:endpoint] = options[:github_endpoint] unless options[:github_endpoint].nil?
|
|
||||||
github_options[:site] = options[:github_endpoint] unless options[:github_site].nil?
|
|
||||||
|
|
||||||
begin
|
# @all_tags = get_filtered_tags
|
||||||
@github = Github.new github_options
|
@all_tags = @fetcher.get_all_tags
|
||||||
rescue
|
|
||||||
puts GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
|
||||||
end
|
|
||||||
|
|
||||||
@generator = Generator.new(@options)
|
@issues, @pull_requests = @fetcher.fetch_issues_and_pull_requests
|
||||||
|
|
||||||
@all_tags = get_all_tags
|
@pull_requests = @options[:pulls] ? get_filtered_pull_requests : []
|
||||||
@issues, @pull_requests = fetch_issues_and_pull_requests
|
|
||||||
|
|
||||||
if @options[:pulls]
|
@issues = @options[:issues] ? get_filtered_issues : []
|
||||||
@pull_requests = get_filtered_pull_requests
|
|
||||||
else
|
|
||||||
@pull_requests = []
|
|
||||||
end
|
|
||||||
|
|
||||||
if @options[:issues]
|
|
||||||
@issues = get_filtered_issues
|
|
||||||
else
|
|
||||||
@issues = []
|
|
||||||
end
|
|
||||||
|
|
||||||
fetch_event_for_issues_and_pr
|
fetch_event_for_issues_and_pr
|
||||||
detect_actual_closed_dates
|
detect_actual_closed_dates
|
||||||
@tag_times_hash = {}
|
end
|
||||||
|
|
||||||
|
# Return tags after filtering tags in lists provided by option: --between-tags & --exclude-tags
|
||||||
|
#
|
||||||
|
# @return [Array]
|
||||||
|
def get_filtered_tags
|
||||||
|
all_tags = @fetcher.get_all_tags
|
||||||
|
filtered_tags = []
|
||||||
|
if @options[:between_tags]
|
||||||
|
@options[:between_tags].each do |tag|
|
||||||
|
unless all_tags.include? tag
|
||||||
|
puts "Warning: can't find tag #{tag}, specified with --between-tags option.".yellow
|
||||||
|
end
|
||||||
|
end
|
||||||
|
filtered_tags = all_tags.select { |tag| @options[:between_tags].include? tag }
|
||||||
|
end
|
||||||
|
filtered_tags
|
||||||
end
|
end
|
||||||
|
|
||||||
def detect_actual_closed_dates
|
def detect_actual_closed_dates
|
||||||
@@ -77,22 +80,24 @@ module GitHubChangelogGenerator
|
|||||||
threads.each(&:join)
|
threads.each(&:join)
|
||||||
|
|
||||||
if @options[:verbose]
|
if @options[:verbose]
|
||||||
puts 'Fetching closed dates for issues: Done!'
|
puts "Fetching closed dates for issues: Done!"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Fill :actual_date parameter of specified issue by closed date of the commit, it it was closed by commit.
|
||||||
|
# @param [Hash] issue
|
||||||
def find_closed_date_by_commit(issue)
|
def find_closed_date_by_commit(issue)
|
||||||
unless issue['events'].nil?
|
unless issue["events"].nil?
|
||||||
# if it's PR -> then find "merged event", in case of usual issue -> fond closed date
|
# if it's PR -> then find "merged event", in case of usual issue -> fond closed date
|
||||||
compare_string = issue[:merged_at].nil? ? 'closed' : 'merged'
|
compare_string = issue[:merged_at].nil? ? "closed" : "merged"
|
||||||
# reverse! - to find latest closed event. (event goes in date order)
|
# reverse! - to find latest closed event. (event goes in date order)
|
||||||
issue['events'].reverse!.each { |event|
|
issue["events"].reverse!.each { |event|
|
||||||
if event[:event].eql? compare_string
|
if event[:event].eql? compare_string
|
||||||
if event[:commit_id].nil?
|
if event[:commit_id].nil?
|
||||||
issue[:actual_date] = issue[:closed_at]
|
issue[:actual_date] = issue[:closed_at]
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
commit = @github.git_data.commits.get @options[:user], @options[:project], event[:commit_id]
|
commit = @fetcher.fetch_commit(event)
|
||||||
issue[:actual_date] = commit[:author][:date]
|
issue[:actual_date] = commit[:author][:date]
|
||||||
rescue
|
rescue
|
||||||
puts "Warning: Can't fetch commit #{event[:commit_id]}. It is probably referenced from another repo.".yellow
|
puts "Warning: Can't fetch commit #{event[:commit_id]}. It is probably referenced from another repo.".yellow
|
||||||
@@ -110,25 +115,32 @@ module GitHubChangelogGenerator
|
|||||||
puts JSON.pretty_generate(json)
|
puts JSON.pretty_generate(json)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This method fetches missing params for PR and filter them by specified options
|
||||||
|
# It include add all PR's with labels from @options[:include_labels] array
|
||||||
|
# And exclude all from :exclude_labels array.
|
||||||
|
# @return [Array] filtered PR's
|
||||||
|
def get_filtered_pull_requests
|
||||||
|
fetch_merged_at_pull_requests
|
||||||
|
|
||||||
|
filtered_pull_requests = include_issues_by_labels(@pull_requests)
|
||||||
|
|
||||||
|
filtered_pull_requests = exclude_issues_by_labels(filtered_pull_requests)
|
||||||
|
|
||||||
|
if @options[:verbose]
|
||||||
|
puts "Filtered pull requests: #{filtered_pull_requests.count}"
|
||||||
|
end
|
||||||
|
|
||||||
|
filtered_pull_requests
|
||||||
|
end
|
||||||
|
|
||||||
|
# This method fetch missing required attributes for pull requests
|
||||||
|
# :merged_at - is a date, when issue PR was merged.
|
||||||
|
# More correct to use this date, not closed date.
|
||||||
def fetch_merged_at_pull_requests
|
def fetch_merged_at_pull_requests
|
||||||
if @options[:verbose]
|
if @options[:verbose]
|
||||||
print "Fetching merged dates...\r"
|
print "Fetching merged dates...\r"
|
||||||
end
|
end
|
||||||
pull_requests = []
|
pull_requests = @fetcher.fetch_pull_requests
|
||||||
begin
|
|
||||||
response = @github.pull_requests.list @options[:user], @options[:project], state: 'closed'
|
|
||||||
page_i = 0
|
|
||||||
response.each_page do |page|
|
|
||||||
page_i += PER_PAGE_NUMBER
|
|
||||||
count_pages = response.count_pages
|
|
||||||
print "Fetching merged dates... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r"
|
|
||||||
pull_requests.concat(page)
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
puts GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
|
||||||
end
|
|
||||||
|
|
||||||
print " \r"
|
|
||||||
|
|
||||||
@pull_requests.each { |pr|
|
@pull_requests.each { |pr|
|
||||||
fetched_pr = pull_requests.find { |fpr|
|
fetched_pr = pull_requests.find { |fpr|
|
||||||
@@ -139,43 +151,39 @@ module GitHubChangelogGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
if @options[:verbose]
|
if @options[:verbose]
|
||||||
puts 'Fetching merged dates: Done!'
|
puts "Fetching merged dates: Done!"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_filtered_pull_requests
|
# Include issues with labels, specified in :include_labels
|
||||||
fetch_merged_at_pull_requests
|
# @param [Array] issues to filter
|
||||||
|
# @return [Array] filtered array of issues
|
||||||
|
def include_issues_by_labels(issues)
|
||||||
|
filtered_issues = @options[:include_labels].nil? ? issues : issues.select { |issue| (issue.labels.map(&:name) & @options[:include_labels]).any? }
|
||||||
|
|
||||||
filtered_pull_requests = @pull_requests.select { |pr| !pr[:merged_at].nil? }
|
if @options[:add_issues_wo_labels]
|
||||||
|
issues_wo_labels = issues.select { |issue|
|
||||||
unless @options[:include_labels].nil?
|
!issue.labels.map(&:name).any?
|
||||||
filtered_pull_requests = @pull_requests.select { |issue|
|
|
||||||
# add all labels from @options[:include_labels] array
|
|
||||||
(issue.labels.map(&:name) & @options[:include_labels]).any?
|
|
||||||
}
|
}
|
||||||
|
filtered_issues |= issues_wo_labels
|
||||||
end
|
end
|
||||||
|
filtered_issues
|
||||||
|
end
|
||||||
|
|
||||||
|
# delete all labels with labels from @options[:exclude_labels] array
|
||||||
|
# @param [Array] issues
|
||||||
|
# @return [Array] filtered array
|
||||||
|
def exclude_issues_by_labels(issues)
|
||||||
unless @options[:exclude_labels].nil?
|
unless @options[:exclude_labels].nil?
|
||||||
filtered_pull_requests = filtered_pull_requests.select { |issue|
|
issues = issues.select { |issue|
|
||||||
# delete all labels from @options[:exclude_labels] array
|
|
||||||
!(issue.labels.map(&:name) & @options[:exclude_labels]).any?
|
!(issue.labels.map(&:name) & @options[:exclude_labels]).any?
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
issues
|
||||||
if @options[:add_issues_wo_labels]
|
|
||||||
issues_wo_labels = @pull_requests.select { |issue|
|
|
||||||
!issue.labels.map(&:name).any?
|
|
||||||
}
|
|
||||||
filtered_pull_requests |= issues_wo_labels
|
|
||||||
end
|
|
||||||
|
|
||||||
if @options[:verbose]
|
|
||||||
puts "Filtered pull requests: #{filtered_pull_requests.count}"
|
|
||||||
end
|
|
||||||
|
|
||||||
filtered_pull_requests
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The entry point of this script to generate change log
|
||||||
|
# @raise (ChangelogGeneratorError) Is thrown when one of specified tags was not found in list of tags.
|
||||||
def compound_changelog
|
def compound_changelog
|
||||||
log = "# Change Log\n\n"
|
log = "# Change Log\n\n"
|
||||||
|
|
||||||
@@ -185,7 +193,7 @@ module GitHubChangelogGenerator
|
|||||||
tag1 = @options[:tag1]
|
tag1 = @options[:tag1]
|
||||||
tag2 = @options[:tag2]
|
tag2 = @options[:tag2]
|
||||||
tags_strings = []
|
tags_strings = []
|
||||||
all_tags.each { |x| tags_strings.push(x['name']) }
|
all_tags.each { |x| tags_strings.push(x["name"]) }
|
||||||
|
|
||||||
if tags_strings.include?(tag1)
|
if tags_strings.include?(tag1)
|
||||||
if tags_strings.include?(tag2)
|
if tags_strings.include?(tag2)
|
||||||
@@ -195,12 +203,10 @@ module GitHubChangelogGenerator
|
|||||||
index2 = hash[tag2]
|
index2 = hash[tag2]
|
||||||
log += generate_log_between_tags(all_tags[index1], all_tags[index2])
|
log += generate_log_between_tags(all_tags[index1], all_tags[index2])
|
||||||
else
|
else
|
||||||
puts "Can't find tag #{tag2} -> exit"
|
fail ChangelogGeneratorError, "Can't find tag #{tag2} -> exit".red
|
||||||
exit
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
puts "Can't find tag #{tag1} -> exit"
|
fail ChangelogGeneratorError, "Can't find tag #{tag1} -> exit".red
|
||||||
exit
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log += generate_log_for_all_tags
|
log += generate_log_for_all_tags
|
||||||
@@ -209,25 +215,27 @@ module GitHubChangelogGenerator
|
|||||||
log += "\n\n\\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*"
|
log += "\n\n\\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*"
|
||||||
|
|
||||||
output_filename = "#{@options[:output]}"
|
output_filename = "#{@options[:output]}"
|
||||||
File.open(output_filename, 'w') { |file| file.write(log) }
|
File.open(output_filename, "w") { |file| file.write(log) }
|
||||||
puts 'Done!'
|
puts "Done!"
|
||||||
puts "Generated log placed in #{`pwd`.strip!}/#{output_filename}"
|
puts "Generated log placed in #{`pwd`.strip!}/#{output_filename}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The full cycle of generation for whole project
|
||||||
|
# @return [String] The complete change log
|
||||||
def generate_log_for_all_tags
|
def generate_log_for_all_tags
|
||||||
fetch_tags_dates
|
fetch_tags_dates
|
||||||
|
|
||||||
if @options[:verbose]
|
if @options[:verbose]
|
||||||
puts 'Sorting tags...'
|
puts "Sorting tags..."
|
||||||
end
|
end
|
||||||
|
|
||||||
@all_tags.sort_by! { |x| get_time_of_tag(x) }.reverse!
|
@all_tags.sort_by! { |x| @fetcher.get_time_of_tag(x) }.reverse!
|
||||||
|
|
||||||
if @options[:verbose]
|
if @options[:verbose]
|
||||||
puts 'Generating log...'
|
puts "Generating log..."
|
||||||
end
|
end
|
||||||
|
|
||||||
log = ''
|
log = ""
|
||||||
|
|
||||||
if @options[:unreleased] && @all_tags.count != 0
|
if @options[:unreleased] && @all_tags.count != 0
|
||||||
unreleased_log = generate_log_between_tags(all_tags[0], nil)
|
unreleased_log = generate_log_between_tags(all_tags[0], nil)
|
||||||
@@ -246,6 +254,7 @@ module GitHubChangelogGenerator
|
|||||||
log
|
log
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Async fetching of all tags dates
|
||||||
def fetch_tags_dates
|
def fetch_tags_dates
|
||||||
if @options[:verbose]
|
if @options[:verbose]
|
||||||
print "Fetching tag dates...\r"
|
print "Fetching tag dates...\r"
|
||||||
@@ -256,9 +265,8 @@ module GitHubChangelogGenerator
|
|||||||
i = 0
|
i = 0
|
||||||
all = @all_tags.count
|
all = @all_tags.count
|
||||||
@all_tags.each { |tag|
|
@all_tags.each { |tag|
|
||||||
# explicit set @tag_times_hash to write data safety.
|
|
||||||
threads << Thread.new {
|
threads << Thread.new {
|
||||||
get_time_of_tag(tag, @tag_times_hash)
|
@fetcher.get_time_of_tag(tag)
|
||||||
if @options[:verbose]
|
if @options[:verbose]
|
||||||
print "Fetching tags dates: #{i + 1}/#{all}\r"
|
print "Fetching tags dates: #{i + 1}/#{all}\r"
|
||||||
i += 1
|
i += 1
|
||||||
@@ -275,55 +283,15 @@ module GitHubChangelogGenerator
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_all_tags
|
# Generate log only between 2 specified tags
|
||||||
if @options[:verbose]
|
# @param [String] older_tag all issues before this tag date will be excluded. May be nil, if it's first tag
|
||||||
print "Fetching tags...\r"
|
# @param [String] newer_tag all issue after this tag will be excluded. May be nil for unreleased section
|
||||||
end
|
|
||||||
|
|
||||||
tags = []
|
|
||||||
|
|
||||||
begin
|
|
||||||
response = @github.repos.tags @options[:user], @options[:project]
|
|
||||||
page_i = 0
|
|
||||||
count_pages = response.count_pages
|
|
||||||
response.each_page do |page|
|
|
||||||
page_i += PER_PAGE_NUMBER
|
|
||||||
print "Fetching tags... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r"
|
|
||||||
tags.concat(page)
|
|
||||||
end
|
|
||||||
print " \r"
|
|
||||||
|
|
||||||
if tags.count == 0
|
|
||||||
puts "Warning: Can't find any tags in repo. Make sure, that you push tags to remote repo via 'git push --tags'".yellow
|
|
||||||
elsif @options[:verbose]
|
|
||||||
puts "Found #{tags.count} tags"
|
|
||||||
end
|
|
||||||
|
|
||||||
rescue
|
|
||||||
puts GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
|
||||||
end
|
|
||||||
|
|
||||||
tags
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_github_token
|
|
||||||
env_var = @options[:token] ? @options[:token] : (ENV.fetch 'CHANGELOG_GITHUB_TOKEN', nil)
|
|
||||||
|
|
||||||
unless env_var
|
|
||||||
puts 'Warning: No token provided (-t option) and variable $CHANGELOG_GITHUB_TOKEN was not found.'.yellow
|
|
||||||
puts 'This script can make only 50 requests per hour to GitHub API without a token!'.yellow
|
|
||||||
end
|
|
||||||
|
|
||||||
@github_token ||= env_var
|
|
||||||
end
|
|
||||||
|
|
||||||
def generate_log_between_tags(older_tag, newer_tag)
|
def generate_log_between_tags(older_tag, newer_tag)
|
||||||
# older_tag nil - means it's first tag, newer_tag nil - means it unreleased section
|
|
||||||
filtered_pull_requests = delete_by_time(@pull_requests, :actual_date, older_tag, newer_tag)
|
filtered_pull_requests = delete_by_time(@pull_requests, :actual_date, older_tag, newer_tag)
|
||||||
filtered_issues = delete_by_time(@issues, :actual_date, older_tag, newer_tag)
|
filtered_issues = delete_by_time(@issues, :actual_date, older_tag, newer_tag)
|
||||||
|
|
||||||
newer_tag_name = newer_tag.nil? ? nil : newer_tag['name']
|
newer_tag_name = newer_tag.nil? ? nil : newer_tag["name"]
|
||||||
older_tag_name = older_tag.nil? ? nil : older_tag['name']
|
older_tag_name = older_tag.nil? ? nil : older_tag["name"]
|
||||||
|
|
||||||
if @options[:filter_issues_by_milestone]
|
if @options[:filter_issues_by_milestone]
|
||||||
# delete excess irrelevant issues (according milestones)
|
# delete excess irrelevant issues (according milestones)
|
||||||
@@ -333,7 +301,7 @@ module GitHubChangelogGenerator
|
|||||||
|
|
||||||
if filtered_issues.empty? && filtered_pull_requests.empty? && newer_tag.nil?
|
if filtered_issues.empty? && filtered_pull_requests.empty? && newer_tag.nil?
|
||||||
# do not generate empty unreleased section
|
# do not generate empty unreleased section
|
||||||
return ''
|
return ""
|
||||||
end
|
end
|
||||||
|
|
||||||
create_log(filtered_pull_requests, filtered_issues, newer_tag, older_tag_name)
|
create_log(filtered_pull_requests, filtered_issues, newer_tag, older_tag_name)
|
||||||
@@ -374,11 +342,17 @@ module GitHubChangelogGenerator
|
|||||||
filtered_issues
|
filtered_issues
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_by_time(array, hash_key, older_tag = nil, newer_tag = nil)
|
# Method filter issues, that belong only specified tag range
|
||||||
fail 'At least one of the tags should be not nil!' if older_tag.nil? && newer_tag.nil?
|
# @param [Array] array of issues to filter
|
||||||
|
# @param [Symbol] hash_key key of date value default is :actual_date
|
||||||
|
# @param [String] older_tag all issues before this tag date will be excluded. May be nil, if it's first tag
|
||||||
|
# @param [String] newer_tag all issue after this tag will be excluded. May be nil for unreleased section
|
||||||
|
# @return [Array] filtered issues
|
||||||
|
def delete_by_time(array, hash_key = :actual_date, older_tag = nil, newer_tag = nil)
|
||||||
|
fail ChangelogGeneratorError, "At least one of the tags should be not nil!".red if older_tag.nil? && newer_tag.nil?
|
||||||
|
|
||||||
newer_tag_time = get_time_of_tag(newer_tag)
|
newer_tag_time = newer_tag && @fetcher.get_time_of_tag(newer_tag)
|
||||||
older_tag_time = get_time_of_tag(older_tag)
|
older_tag_time = older_tag && @fetcher.get_time_of_tag(older_tag)
|
||||||
|
|
||||||
array.select { |req|
|
array.select { |req|
|
||||||
if req[hash_key]
|
if req[hash_key]
|
||||||
@@ -405,16 +379,19 @@ module GitHubChangelogGenerator
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param [Array] pull_requests
|
# Generates log for section with header and body
|
||||||
# @param [Array] issues
|
#
|
||||||
# @param [String] older_tag_name
|
# @param [Array] pull_requests List or PR's in new section
|
||||||
# @return [String]
|
# @param [Array] issues List of issues in new section
|
||||||
|
# @param [String] newer_tag Name of the newer tag. Could be nil for `Unreleased` section
|
||||||
|
# @param [String] older_tag_name Older tag, used for the links. Could be nil for last tag.
|
||||||
|
# @return [String] Ready and parsed section
|
||||||
def create_log(pull_requests, issues, newer_tag, older_tag_name = nil)
|
def create_log(pull_requests, issues, newer_tag, older_tag_name = nil)
|
||||||
newer_tag_time = newer_tag.nil? ? Time.new : get_time_of_tag(newer_tag)
|
newer_tag_time = newer_tag.nil? ? Time.new : @fetcher.get_time_of_tag(newer_tag)
|
||||||
newer_tag_name = newer_tag.nil? ? @options[:unreleased_label] : newer_tag['name']
|
newer_tag_name = newer_tag.nil? ? @options[:unreleased_label] : newer_tag["name"]
|
||||||
newer_tag_link = newer_tag.nil? ? 'HEAD' : newer_tag_name
|
newer_tag_link = newer_tag.nil? ? "HEAD" : newer_tag_name
|
||||||
|
|
||||||
github_site = options[:github_site] || 'https://github.com'
|
github_site = options[:github_site] || "https://github.com"
|
||||||
project_url = "#{github_site}/#{@options[:user]}/#{@options[:project]}"
|
project_url = "#{github_site}/#{@options[:user]}/#{@options[:project]}"
|
||||||
|
|
||||||
log = generate_header(newer_tag_name, newer_tag_link, newer_tag_time, older_tag_name, project_url)
|
log = generate_header(newer_tag_name, newer_tag_link, newer_tag_time, older_tag_name, project_url)
|
||||||
@@ -428,12 +405,12 @@ module GitHubChangelogGenerator
|
|||||||
issues.each { |dict|
|
issues.each { |dict|
|
||||||
added = false
|
added = false
|
||||||
dict.labels.each { |label|
|
dict.labels.each { |label|
|
||||||
if label.name == 'bug'
|
if label.name == "bug"
|
||||||
bugs_a.push dict
|
bugs_a.push dict
|
||||||
added = true
|
added = true
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
if label.name == 'enhancement'
|
if label.name == "enhancement"
|
||||||
enhancement_a.push dict
|
enhancement_a.push dict
|
||||||
added = true
|
added = true
|
||||||
next
|
next
|
||||||
@@ -444,22 +421,26 @@ module GitHubChangelogGenerator
|
|||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
log += generate_log_from_array(enhancement_a, @options[:enhancement_prefix])
|
log += generate_sub_section(enhancement_a, @options[:enhancement_prefix])
|
||||||
log += generate_log_from_array(bugs_a, @options[:bug_prefix])
|
log += generate_sub_section(bugs_a, @options[:bug_prefix])
|
||||||
log += generate_log_from_array(issues_a, @options[:issue_prefix])
|
log += generate_sub_section(issues_a, @options[:issue_prefix])
|
||||||
end
|
end
|
||||||
|
|
||||||
if @options[:pulls]
|
if @options[:pulls]
|
||||||
# Generate pull requests:
|
# Generate pull requests:
|
||||||
log += generate_log_from_array(pull_requests, @options[:merge_prefix])
|
log += generate_sub_section(pull_requests, @options[:merge_prefix])
|
||||||
end
|
end
|
||||||
|
|
||||||
log
|
log
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_log_from_array(issues, prefix)
|
# @param [Array] issues List of issues on sub-section
|
||||||
log = ''
|
# @param [String] prefix Nae of sub-section
|
||||||
if options[:simple_list].nil? && issues.any?
|
# @return [String] Generate ready-to-go sub-section
|
||||||
|
def generate_sub_section(issues, prefix)
|
||||||
|
log = ""
|
||||||
|
|
||||||
|
if options[:simple_list] != true && issues.any?
|
||||||
log += "#{prefix}\n\n"
|
log += "#{prefix}\n\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -472,70 +453,41 @@ module GitHubChangelogGenerator
|
|||||||
log
|
log
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_header(newer_tag_name, newer_tag_name2, newer_tag_time, older_tag_name, project_url)
|
# It generate one header for section with specific parameters.
|
||||||
log = ''
|
#
|
||||||
|
# @param [String] newer_tag_name - name of newer tag
|
||||||
|
# @param [String] newer_tag_link - used for links. Could be same as #newer_tag_name or some specific value, like HEAD
|
||||||
|
# @param [Time] newer_tag_time - time, when newer tag created
|
||||||
|
# @param [String] older_tag_link - tag name, used for links.
|
||||||
|
# @param [String] project_url - url for current project.
|
||||||
|
# @return [String] - Generate one ready-to-add section.
|
||||||
|
def generate_header(newer_tag_name, newer_tag_link, newer_tag_time, older_tag_link, project_url)
|
||||||
|
log = ""
|
||||||
|
|
||||||
# Generate date string:
|
# Generate date string:
|
||||||
time_string = newer_tag_time.strftime @options[:dateformat]
|
time_string = newer_tag_time.strftime @options[:dateformat]
|
||||||
|
|
||||||
# Generate tag name and link
|
# Generate tag name and link
|
||||||
if newer_tag_name.equal? @options[:unreleased_label]
|
if newer_tag_name.equal? @options[:unreleased_label]
|
||||||
log += "## [#{newer_tag_name}](#{project_url}/tree/#{newer_tag_name2})\n\n"
|
log += "## [#{newer_tag_name}](#{project_url}/tree/#{newer_tag_link})\n\n"
|
||||||
else
|
else
|
||||||
log += "## [#{newer_tag_name}](#{project_url}/tree/#{newer_tag_name2}) (#{time_string})\n\n"
|
log += "## [#{newer_tag_name}](#{project_url}/tree/#{newer_tag_link}) (#{time_string})\n\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
if @options[:compare_link] && older_tag_name
|
if @options[:compare_link] && older_tag_link
|
||||||
# Generate compare link
|
# Generate compare link
|
||||||
log += "[Full Changelog](#{project_url}/compare/#{older_tag_name}...#{newer_tag_name2})\n\n"
|
log += "[Full Changelog](#{project_url}/compare/#{older_tag_link}...#{newer_tag_link})\n\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
log
|
log
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_time_of_tag(tag_name, tag_times_hash = @tag_times_hash)
|
# Filter issues according labels
|
||||||
if tag_name.nil?
|
# @return [Array] Filtered issues
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if tag_times_hash[tag_name['name']]
|
|
||||||
return @tag_times_hash[tag_name['name']]
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
|
||||||
github_git_data_commits_get = @github.git_data.commits.get @options[:user], @options[:project], tag_name['commit']['sha']
|
|
||||||
rescue
|
|
||||||
puts GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
|
||||||
end
|
|
||||||
time_string = github_git_data_commits_get['committer']['date']
|
|
||||||
@tag_times_hash[tag_name['name']] = Time.parse(time_string)
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_filtered_issues
|
def get_filtered_issues
|
||||||
issues = @issues
|
filtered_issues = include_issues_by_labels(@issues)
|
||||||
|
|
||||||
filtered_issues = issues
|
filtered_issues = exclude_issues_by_labels(filtered_issues)
|
||||||
|
|
||||||
unless @options[:include_labels].nil?
|
|
||||||
filtered_issues = issues.select { |issue|
|
|
||||||
# add all labels from @options[:include_labels] array
|
|
||||||
(issue.labels.map(&:name) & @options[:include_labels]).any?
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
unless @options[:exclude_labels].nil?
|
|
||||||
filtered_issues = filtered_issues.select { |issue|
|
|
||||||
# delete all labels from @options[:exclude_labels] array
|
|
||||||
!(issue.labels.map(&:name) & @options[:exclude_labels]).any?
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
if @options[:add_issues_wo_labels]
|
|
||||||
issues_wo_labels = issues.select { |issue|
|
|
||||||
!issue.labels.map(&:name).any?
|
|
||||||
}
|
|
||||||
filtered_issues |= issues_wo_labels
|
|
||||||
end
|
|
||||||
|
|
||||||
if @options[:verbose]
|
if @options[:verbose]
|
||||||
puts "Filtered issues: #{filtered_issues.count}"
|
puts "Filtered issues: #{filtered_issues.count}"
|
||||||
@@ -544,42 +496,8 @@ module GitHubChangelogGenerator
|
|||||||
filtered_issues
|
filtered_issues
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_issues_and_pull_requests
|
# Fetch event for issues and pull requests
|
||||||
if @options[:verbose]
|
# @return [Array] array of fetched issues
|
||||||
print "Fetching closed issues...\r"
|
|
||||||
end
|
|
||||||
issues = []
|
|
||||||
|
|
||||||
begin
|
|
||||||
response = @github.issues.list user: @options[:user], repo: @options[:project], state: 'closed', filter: 'all', labels: nil
|
|
||||||
page_i = 0
|
|
||||||
count_pages = response.count_pages
|
|
||||||
response.each_page do |page|
|
|
||||||
page_i += PER_PAGE_NUMBER
|
|
||||||
print "Fetching issues... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r"
|
|
||||||
issues.concat(page)
|
|
||||||
break if @options[:max_issues] && issues.length >= @options[:max_issues]
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
puts GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
|
||||||
end
|
|
||||||
|
|
||||||
print " \r"
|
|
||||||
|
|
||||||
if @options[:verbose]
|
|
||||||
puts "Received issues: #{issues.count}"
|
|
||||||
end
|
|
||||||
|
|
||||||
# remove pull request from issues:
|
|
||||||
issues_wo_pr = issues.select { |x|
|
|
||||||
x.pull_request.nil?
|
|
||||||
}
|
|
||||||
pull_requests = issues.select { |x|
|
|
||||||
!x.pull_request.nil?
|
|
||||||
}
|
|
||||||
[issues_wo_pr, pull_requests]
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_event_for_issues_and_pr
|
def fetch_event_for_issues_and_pr
|
||||||
if @options[:verbose]
|
if @options[:verbose]
|
||||||
print "Fetching events for issues and PR: 0/#{@issues.count + @pull_requests.count}\r"
|
print "Fetching events for issues and PR: 0/#{@issues.count + @pull_requests.count}\r"
|
||||||
@@ -587,36 +505,7 @@ module GitHubChangelogGenerator
|
|||||||
|
|
||||||
# Async fetching events:
|
# Async fetching events:
|
||||||
|
|
||||||
fetch_events_async(@issues + @pull_requests)
|
@fetcher.fetch_events_async(@issues + @pull_requests)
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_events_async(issues)
|
|
||||||
i = 0
|
|
||||||
max_thread_number = 50
|
|
||||||
threads = []
|
|
||||||
issues.each_slice(max_thread_number) { |issues_slice|
|
|
||||||
issues_slice.each { |issue|
|
|
||||||
threads << Thread.new {
|
|
||||||
begin
|
|
||||||
obj = @github.issues.events.list user: @options[:user], repo: @options[:project], issue_number: issue['number']
|
|
||||||
rescue
|
|
||||||
puts GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
|
||||||
end
|
|
||||||
issue[:events] = obj.body
|
|
||||||
print "Fetching events for issues and PR: #{i + 1}/#{@issues.count + @pull_requests.count}\r"
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
threads.each(&:join)
|
|
||||||
threads = []
|
|
||||||
}
|
|
||||||
|
|
||||||
# to clear line from prev print
|
|
||||||
print " \r"
|
|
||||||
|
|
||||||
if @options[:verbose]
|
|
||||||
puts "Fetching events for issues and PR: #{i} Done!"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
209
lib/github_changelog_generator/fetcher.rb
Normal file
209
lib/github_changelog_generator/fetcher.rb
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
require "logger"
|
||||||
|
|
||||||
|
module GitHubChangelogGenerator
|
||||||
|
# A Fetcher responsible for all requests to GitHub and all basic manipulation with related data
|
||||||
|
# (such as filtering, validating, e.t.c)
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# fetcher = GitHubChangelogGenerator::Fetcher.new options
|
||||||
|
class Fetcher
|
||||||
|
PER_PAGE_NUMBER = 30
|
||||||
|
GH_RATE_LIMIT_EXCEEDED_MSG = "Warning: GitHub API rate limit (5000 per hour) exceeded, change log may be " \
|
||||||
|
"missing some issues. You can limit the number of issues fetched using the `--max-issues NUM` argument."
|
||||||
|
|
||||||
|
def initialize(options = {})
|
||||||
|
@options = options
|
||||||
|
|
||||||
|
@user = @options[:user]
|
||||||
|
@project = @options[:project]
|
||||||
|
@github_token = fetch_github_token
|
||||||
|
@tag_times_hash = {}
|
||||||
|
|
||||||
|
@logger = Logger.new(STDOUT)
|
||||||
|
@logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
||||||
|
"#{msg}\n"
|
||||||
|
end
|
||||||
|
github_options = { per_page: PER_PAGE_NUMBER }
|
||||||
|
github_options[:oauth_token] = @github_token unless @github_token.nil?
|
||||||
|
github_options[:endpoint] = options[:github_endpoint] unless options[:github_endpoint].nil?
|
||||||
|
github_options[:site] = options[:github_endpoint] unless options[:github_site].nil?
|
||||||
|
|
||||||
|
begin
|
||||||
|
@github = Github.new github_options
|
||||||
|
rescue
|
||||||
|
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns GitHub token. First try to use variable, provided by --token option,
|
||||||
|
# otherwise try to fetch it from CHANGELOG_GITHUB_TOKEN env variable.
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def fetch_github_token
|
||||||
|
env_var = @options[:token] ? @options[:token] : (ENV.fetch "CHANGELOG_GITHUB_TOKEN", nil)
|
||||||
|
|
||||||
|
unless env_var
|
||||||
|
@logger.warn "Warning: No token provided (-t option) and variable $CHANGELOG_GITHUB_TOKEN was not found.".yellow
|
||||||
|
@logger.warn "This script can make only 50 requests to GitHub API per hour without token!".yellow
|
||||||
|
end
|
||||||
|
|
||||||
|
env_var
|
||||||
|
end
|
||||||
|
|
||||||
|
# Fetch all tags from repo
|
||||||
|
# @return [Array] array of tags
|
||||||
|
def get_all_tags
|
||||||
|
if @options[:verbose]
|
||||||
|
print "Fetching tags...\r"
|
||||||
|
end
|
||||||
|
|
||||||
|
tags = []
|
||||||
|
|
||||||
|
begin
|
||||||
|
response = @github.repos.tags @options[:user], @options[:project]
|
||||||
|
page_i = 0
|
||||||
|
count_pages = response.count_pages
|
||||||
|
response.each_page do |page|
|
||||||
|
page_i += PER_PAGE_NUMBER
|
||||||
|
print "Fetching tags... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r"
|
||||||
|
tags.concat(page)
|
||||||
|
end
|
||||||
|
print " \r"
|
||||||
|
|
||||||
|
if tags.count == 0
|
||||||
|
@logger.warn "Warning: Can't find any tags in repo.\
|
||||||
|
Make sure, that you push tags to remote repo via 'git push --tags'".yellow
|
||||||
|
elsif @options[:verbose]
|
||||||
|
@logger.info "Found #{tags.count} tags"
|
||||||
|
end
|
||||||
|
|
||||||
|
rescue
|
||||||
|
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
||||||
|
end
|
||||||
|
|
||||||
|
tags
|
||||||
|
end
|
||||||
|
|
||||||
|
# This method fetch all closed issues and separate them to pull requests and pure issues
|
||||||
|
# (pull request is kind of issue in term of GitHub)
|
||||||
|
# @return [Tuple] with issues and pull requests
|
||||||
|
def fetch_issues_and_pull_requests
|
||||||
|
if @options[:verbose]
|
||||||
|
print "Fetching closed issues...\r"
|
||||||
|
end
|
||||||
|
issues = []
|
||||||
|
|
||||||
|
begin
|
||||||
|
response = @github.issues.list user: @options[:user],
|
||||||
|
repo: @options[:project],
|
||||||
|
state: "closed",
|
||||||
|
filter: "all",
|
||||||
|
labels: nil
|
||||||
|
page_i = 0
|
||||||
|
count_pages = response.count_pages
|
||||||
|
response.each_page do |page|
|
||||||
|
page_i += PER_PAGE_NUMBER
|
||||||
|
print "Fetching issues... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r"
|
||||||
|
issues.concat(page)
|
||||||
|
break if @options[:max_issues] && issues.length >= @options[:max_issues]
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
||||||
|
end
|
||||||
|
|
||||||
|
print " \r"
|
||||||
|
|
||||||
|
if @options[:verbose]
|
||||||
|
@logger.info "Received issues: #{issues.count}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# remove pull request from issues:
|
||||||
|
issues.partition { |x|
|
||||||
|
x[:pull_request].nil?
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Fetch all pull requests. We need them to detect :merged_at parameter
|
||||||
|
# @return [Array] all pull requests
|
||||||
|
def fetch_pull_requests
|
||||||
|
pull_requests = []
|
||||||
|
begin
|
||||||
|
response = @github.pull_requests.list @options[:user], @options[:project], state: "closed"
|
||||||
|
page_i = 0
|
||||||
|
response.each_page do |page|
|
||||||
|
page_i += PER_PAGE_NUMBER
|
||||||
|
count_pages = response.count_pages
|
||||||
|
print "Fetching merged dates... #{page_i}/#{count_pages * PER_PAGE_NUMBER}\r"
|
||||||
|
pull_requests.concat(page)
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
||||||
|
end
|
||||||
|
|
||||||
|
print " \r"
|
||||||
|
pull_requests
|
||||||
|
end
|
||||||
|
|
||||||
|
# Fetch event for all issues and add them to :events
|
||||||
|
# @param [Array] issues
|
||||||
|
# @return [Void]
|
||||||
|
def fetch_events_async(issues)
|
||||||
|
i = 0
|
||||||
|
max_thread_number = 50
|
||||||
|
threads = []
|
||||||
|
issues.each_slice(max_thread_number) { |issues_slice|
|
||||||
|
issues_slice.each { |issue|
|
||||||
|
threads << Thread.new {
|
||||||
|
begin
|
||||||
|
obj = @github.issues.events.list user: @options[:user],
|
||||||
|
repo: @options[:project],
|
||||||
|
issue_number: issue["number"]
|
||||||
|
rescue
|
||||||
|
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
||||||
|
end
|
||||||
|
issue[:events] = obj.body
|
||||||
|
print "Fetching events for issues and PR: #{i + 1}/#{issues.count}\r"
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
threads.each(&:join)
|
||||||
|
threads = []
|
||||||
|
}
|
||||||
|
|
||||||
|
# to clear line from prev print
|
||||||
|
print " \r"
|
||||||
|
|
||||||
|
if @options[:verbose]
|
||||||
|
@logger.info "Fetching events for issues and PR: #{i} Done!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Try to find tag date in local hash.
|
||||||
|
# Otherwise fFetch tag time and put it to local hash file.
|
||||||
|
# @param [String] tag_name name of the tag
|
||||||
|
# @return [Time] time of specified tag
|
||||||
|
def get_time_of_tag(tag_name)
|
||||||
|
fail ChangelogGeneratorError, "tag_name is nil".red if tag_name.nil?
|
||||||
|
|
||||||
|
if @tag_times_hash[tag_name["name"]]
|
||||||
|
return @tag_times_hash[tag_name["name"]]
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
github_git_data_commits_get = @github.git_data.commits.get @options[:user],
|
||||||
|
@options[:project],
|
||||||
|
tag_name["commit"]["sha"]
|
||||||
|
rescue
|
||||||
|
@logger.warn GH_RATE_LIMIT_EXCEEDED_MSG.yellow
|
||||||
|
end
|
||||||
|
time_string = github_git_data_commits_get["committer"]["date"]
|
||||||
|
@tag_times_hash[tag_name["name"]] = Time.parse(time_string)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Fetch commit for specifed event
|
||||||
|
# @return [Hash]
|
||||||
|
def fetch_commit(event)
|
||||||
|
@github.git_data.commits.get @options[:user], @options[:project], event[:commit_id]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -4,6 +4,13 @@ module GitHubChangelogGenerator
|
|||||||
@options = options
|
@options = options
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Parse issue and generate single line formatted issue line.
|
||||||
|
#
|
||||||
|
# Example output:
|
||||||
|
# - Add coveralls integration [\#223](https://github.com/skywinder/github-changelog-generator/pull/223) ([skywinder](https://github.com/skywinder))
|
||||||
|
#
|
||||||
|
# @param [Hash] issue Fetched issue from GitHub
|
||||||
|
# @return [String] Markdown-formatted single issue
|
||||||
def get_string_for_issue(issue)
|
def get_string_for_issue(issue)
|
||||||
encapsulated_title = encapsulate_string issue[:title]
|
encapsulated_title = encapsulate_string issue[:title]
|
||||||
|
|
||||||
@@ -12,7 +19,7 @@ module GitHubChangelogGenerator
|
|||||||
unless issue.pull_request.nil?
|
unless issue.pull_request.nil?
|
||||||
if @options[:author]
|
if @options[:author]
|
||||||
if issue.user.nil?
|
if issue.user.nil?
|
||||||
title_with_number += ' ({Null user})'
|
title_with_number += " ({Null user})"
|
||||||
else
|
else
|
||||||
title_with_number += " ([#{issue.user.login}](#{issue.user.html_url}))"
|
title_with_number += " ([#{issue.user.login}](#{issue.user.html_url}))"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
require 'optparse'
|
require "optparse"
|
||||||
require 'pp'
|
require "pp"
|
||||||
require_relative 'version'
|
require_relative "version"
|
||||||
|
|
||||||
module GitHubChangelogGenerator
|
module GitHubChangelogGenerator
|
||||||
class Parser
|
class Parser
|
||||||
@@ -9,8 +9,8 @@ module GitHubChangelogGenerator
|
|||||||
options = {
|
options = {
|
||||||
tag1: nil,
|
tag1: nil,
|
||||||
tag2: nil,
|
tag2: nil,
|
||||||
dateformat: '%Y-%m-%d',
|
dateformat: "%Y-%m-%d",
|
||||||
output: 'CHANGELOG.md',
|
output: "CHANGELOG.md",
|
||||||
issues: true,
|
issues: true,
|
||||||
add_issues_wo_labels: true,
|
add_issues_wo_labels: true,
|
||||||
add_pr_wo_labels: true,
|
add_pr_wo_labels: true,
|
||||||
@@ -18,7 +18,7 @@ module GitHubChangelogGenerator
|
|||||||
filter_issues_by_milestone: true,
|
filter_issues_by_milestone: true,
|
||||||
author: true,
|
author: true,
|
||||||
unreleased: true,
|
unreleased: true,
|
||||||
unreleased_label: 'Unreleased',
|
unreleased_label: "Unreleased",
|
||||||
compare_link: true,
|
compare_link: true,
|
||||||
include_labels: %w(bug enhancement),
|
include_labels: %w(bug enhancement),
|
||||||
exclude_labels: %w(duplicate question invalid wontfix),
|
exclude_labels: %w(duplicate question invalid wontfix),
|
||||||
@@ -26,86 +26,86 @@ module GitHubChangelogGenerator
|
|||||||
simple_list: false,
|
simple_list: false,
|
||||||
verbose: true,
|
verbose: true,
|
||||||
|
|
||||||
merge_prefix: '**Merged pull requests:**',
|
merge_prefix: "**Merged pull requests:**",
|
||||||
issue_prefix: '**Closed issues:**',
|
issue_prefix: "**Closed issues:**",
|
||||||
bug_prefix: '**Fixed bugs:**',
|
bug_prefix: "**Fixed bugs:**",
|
||||||
enhancement_prefix: '**Implemented enhancements:**',
|
enhancement_prefix: "**Implemented enhancements:**",
|
||||||
branch: 'origin'
|
branch: "origin"
|
||||||
}
|
}
|
||||||
|
|
||||||
parser = OptionParser.new do |opts|
|
parser = OptionParser.new do |opts|
|
||||||
opts.banner = 'Usage: github_changelog_generator [options]'
|
opts.banner = "Usage: github_changelog_generator [options]"
|
||||||
opts.on('-u', '--user [USER]', 'Username of the owner of target GitHub repo') do |last|
|
opts.on("-u", "--user [USER]", "Username of the owner of target GitHub repo") do |last|
|
||||||
options[:user] = last
|
options[:user] = last
|
||||||
end
|
end
|
||||||
opts.on('-p', '--project [PROJECT]', 'Name of project on GitHub') do |last|
|
opts.on("-p", "--project [PROJECT]", "Name of project on GitHub") do |last|
|
||||||
options[:project] = last
|
options[:project] = last
|
||||||
end
|
end
|
||||||
opts.on('-t', '--token [TOKEN]', 'To make more than 50 requests per hour your GitHub token is required. You can generate it at: https://github.com/settings/tokens/new') do |last|
|
opts.on("-t", "--token [TOKEN]", "To make more than 50 requests per hour your GitHub token is required. You can generate it at: https://github.com/settings/tokens/new") do |last|
|
||||||
options[:token] = last
|
options[:token] = last
|
||||||
end
|
end
|
||||||
opts.on('-f', '--date-format [FORMAT]', 'Date format. Default is %Y-%m-%d') do |last|
|
opts.on("-f", "--date-format [FORMAT]", "Date format. Default is %Y-%m-%d") do |last|
|
||||||
options[:dateformat] = last
|
options[:dateformat] = last
|
||||||
end
|
end
|
||||||
opts.on('-o', '--output [NAME]', 'Output file. Default is CHANGELOG.md') do |last|
|
opts.on("-o", "--output [NAME]", "Output file. Default is CHANGELOG.md") do |last|
|
||||||
options[:output] = last
|
options[:output] = last
|
||||||
end
|
end
|
||||||
opts.on('--[no-]issues', 'Include closed issues in changelog. Default is true') do |v|
|
opts.on("--[no-]issues", "Include closed issues in changelog. Default is true") do |v|
|
||||||
options[:issues] = v
|
options[:issues] = v
|
||||||
end
|
end
|
||||||
opts.on('--[no-]issues-wo-labels', 'Include closed issues without labels in changelog. Default is true') do |v|
|
opts.on("--[no-]issues-wo-labels", "Include closed issues without labels in changelog. Default is true") do |v|
|
||||||
options[:add_issues_wo_labels] = v
|
options[:add_issues_wo_labels] = v
|
||||||
end
|
end
|
||||||
opts.on('--[no-]pr-wo-labels', 'Include pull requests without labels in changelog. Default is true') do |v|
|
opts.on("--[no-]pr-wo-labels", "Include pull requests without labels in changelog. Default is true") do |v|
|
||||||
options[:add_pr_wo_labels] = v
|
options[:add_pr_wo_labels] = v
|
||||||
end
|
end
|
||||||
opts.on('--[no-]pull-requests', 'Include pull-requests in changelog. Default is true') do |v|
|
opts.on("--[no-]pull-requests", "Include pull-requests in changelog. Default is true") do |v|
|
||||||
options[:pulls] = v
|
options[:pulls] = v
|
||||||
end
|
end
|
||||||
opts.on('--[no-]filter-by-milestone', 'Use milestone to detect when issue was resolved. Default is true') do |last|
|
opts.on("--[no-]filter-by-milestone", "Use milestone to detect when issue was resolved. Default is true") do |last|
|
||||||
options[:filter_issues_by_milestone] = last
|
options[:filter_issues_by_milestone] = last
|
||||||
end
|
end
|
||||||
opts.on('--[no-]author', 'Add author of pull-request in the end. Default is true') do |author|
|
opts.on("--[no-]author", "Add author of pull-request in the end. Default is true") do |author|
|
||||||
options[:author] = author
|
options[:author] = author
|
||||||
end
|
end
|
||||||
opts.on('--unreleased-only', 'Generate log from unreleased closed issues only.') do |v|
|
opts.on("--unreleased-only", "Generate log from unreleased closed issues only.") do |v|
|
||||||
options[:unreleased_only] = v
|
options[:unreleased_only] = v
|
||||||
end
|
end
|
||||||
opts.on('--[no-]unreleased', 'Add to log unreleased closed issues. Default is true') do |v|
|
opts.on("--[no-]unreleased", "Add to log unreleased closed issues. Default is true") do |v|
|
||||||
options[:unreleased] = v
|
options[:unreleased] = v
|
||||||
end
|
end
|
||||||
opts.on('--unreleased-label [label]', 'Add to log unreleased closed issues. Default is true') do |v|
|
opts.on("--unreleased-label [label]", "Add to log unreleased closed issues. Default is true") do |v|
|
||||||
options[:unreleased_label] = v
|
options[:unreleased_label] = v
|
||||||
end
|
end
|
||||||
opts.on('--[no-]compare-link', 'Include compare link (Full Changelog) between older version and newer version. Default is true') do |v|
|
opts.on("--[no-]compare-link", "Include compare link (Full Changelog) between older version and newer version. Default is true") do |v|
|
||||||
options[:compare_link] = v
|
options[:compare_link] = v
|
||||||
end
|
end
|
||||||
opts.on('--include-labels x,y,z', Array, 'Only issues with the specified labels will be included in the changelog. Default is \'bug,enhancement\'') do |list|
|
opts.on("--include-labels x,y,z", Array, 'Only issues with the specified labels will be included in the changelog. Default is \'bug,enhancement\'') do |list|
|
||||||
options[:include_labels] = list
|
options[:include_labels] = list
|
||||||
end
|
end
|
||||||
opts.on('--exclude-labels x,y,z', Array, 'Issues with the specified labels will be always excluded from changelog. Default is \'duplicate,question,invalid,wontfix\'') do |list|
|
opts.on("--exclude-labels x,y,z", Array, 'Issues with the specified labels will be always excluded from changelog. Default is \'duplicate,question,invalid,wontfix\'') do |list|
|
||||||
options[:exclude_labels] = list
|
options[:exclude_labels] = list
|
||||||
end
|
end
|
||||||
opts.on('--max-issues [NUMBER]', Integer, 'Max number of issues to fetch from GitHub. Default is unlimited') do |max|
|
opts.on("--max-issues [NUMBER]", Integer, "Max number of issues to fetch from GitHub. Default is unlimited") do |max|
|
||||||
options[:max_issues] = max
|
options[:max_issues] = max
|
||||||
end
|
end
|
||||||
opts.on('--github-site [URL]', 'The Enterprise Github site on which your project is hosted.') do |last|
|
opts.on("--github-site [URL]", "The Enterprise Github site on which your project is hosted.") do |last|
|
||||||
options[:github_site] = last
|
options[:github_site] = last
|
||||||
end
|
end
|
||||||
opts.on('--github-api [URL]', 'The enterprise endpoint to use for your Github API.') do |last|
|
opts.on("--github-api [URL]", "The enterprise endpoint to use for your Github API.") do |last|
|
||||||
options[:github_endpoint] = last
|
options[:github_endpoint] = last
|
||||||
end
|
end
|
||||||
opts.on('--simple-list', 'Create simple list from issues and pull requests. Default is false.') do |v|
|
opts.on("--simple-list", "Create simple list from issues and pull requests. Default is false.") do |v|
|
||||||
options[:simple_list] = v
|
options[:simple_list] = v
|
||||||
end
|
end
|
||||||
opts.on('--[no-]verbose', 'Run verbosely. Default is true') do |v|
|
opts.on("--[no-]verbose", "Run verbosely. Default is true") do |v|
|
||||||
options[:verbose] = v
|
options[:verbose] = v
|
||||||
end
|
end
|
||||||
opts.on('-v', '--version', 'Print version number') do |_v|
|
opts.on("-v", "--version", "Print version number") do |_v|
|
||||||
puts "Version: #{GitHubChangelogGenerator::VERSION}"
|
puts "Version: #{GitHubChangelogGenerator::VERSION}"
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
opts.on('-h', '--help', 'Displays Help') do
|
opts.on("-h", "--help", "Displays Help") do
|
||||||
puts opts
|
puts opts
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
@@ -113,8 +113,30 @@ module GitHubChangelogGenerator
|
|||||||
|
|
||||||
parser.parse!
|
parser.parse!
|
||||||
|
|
||||||
|
detect_user_and_project(options)
|
||||||
|
|
||||||
|
if !options[:user] || !options[:project]
|
||||||
|
puts parser.banner
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
|
||||||
|
if ARGV[1]
|
||||||
|
options[:tag1] = ARGV[0]
|
||||||
|
options[:tag2] = ARGV[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
if options[:verbose]
|
||||||
|
puts "Performing task with options:"
|
||||||
|
pp options
|
||||||
|
puts ""
|
||||||
|
end
|
||||||
|
|
||||||
|
options
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.detect_user_and_project(options)
|
||||||
if ARGV[0] && !ARGV[1]
|
if ARGV[0] && !ARGV[1]
|
||||||
github_site = options[:github_site] ? options[:github_site] : 'github.com'
|
github_site = options[:github_site] ? options[:github_site] : "github.com"
|
||||||
# this match should parse strings such "https://github.com/skywinder/Github-Changelog-Generator" or "skywinder/Github-Changelog-Generator" to user and name
|
# this match should parse strings such "https://github.com/skywinder/Github-Changelog-Generator" or "skywinder/Github-Changelog-Generator" to user and name
|
||||||
match = /(?:.+#{Regexp.escape(github_site)}\/)?(.+)\/(.+)/.match(ARGV[0])
|
match = /(?:.+#{Regexp.escape(github_site)}\/)?(.+)\/(.+)/.match(ARGV[0])
|
||||||
|
|
||||||
@@ -134,44 +156,31 @@ module GitHubChangelogGenerator
|
|||||||
end
|
end
|
||||||
|
|
||||||
if !options[:user] && !options[:project]
|
if !options[:user] && !options[:project]
|
||||||
remote = `git config --get remote.#{options[:branch]}.url`
|
if ENV["RUBYLIB"] =~ /ruby-debug-ide/
|
||||||
# try to find repo in format:
|
options[:user] = "skywinder"
|
||||||
# origin git@github.com:skywinder/Github-Changelog-Generator.git (fetch)
|
options[:project] = "changelog_test"
|
||||||
# git@github.com:skywinder/Github-Changelog-Generator.git
|
|
||||||
match = /.*(?:[:\/])((?:-|\w|\.)*)\/((?:-|\w|\.)*)(?:\.git).*/.match(remote)
|
|
||||||
|
|
||||||
if match && match[1] && match[2]
|
|
||||||
puts "Detected user:#{match[1]}, project:#{match[2]}"
|
|
||||||
options[:user], options[:project] = match[1], match[2]
|
|
||||||
else
|
else
|
||||||
|
remote = `git config --get remote.#{options[:branch]}.url`
|
||||||
# try to find repo in format:
|
# try to find repo in format:
|
||||||
# origin https://github.com/skywinder/ChangelogMerger (fetch)
|
# origin git@github.com:skywinder/Github-Changelog-Generator.git (fetch)
|
||||||
# https://github.com/skywinder/ChangelogMerger
|
# git@github.com:skywinder/Github-Changelog-Generator.git
|
||||||
match = /.*\/((?:-|\w|\.)*)\/((?:-|\w|\.)*).*/.match(remote)
|
match = /.*(?:[:\/])((?:-|\w|\.)*)\/((?:-|\w|\.)*)(?:\.git).*/.match(remote)
|
||||||
|
|
||||||
if match && match[1] && match[2]
|
if match && match[1] && match[2]
|
||||||
puts "Detected user:#{match[1]}, project:#{match[2]}"
|
puts "Detected user:#{match[1]}, project:#{match[2]}"
|
||||||
options[:user], options[:project] = match[1], match[2]
|
options[:user], options[:project] = match[1], match[2]
|
||||||
|
else
|
||||||
|
# try to find repo in format:
|
||||||
|
# origin https://github.com/skywinder/ChangelogMerger (fetch)
|
||||||
|
# https://github.com/skywinder/ChangelogMerger
|
||||||
|
match = /.*\/((?:-|\w|\.)*)\/((?:-|\w|\.)*).*/.match(remote)
|
||||||
|
if match && match[1] && match[2]
|
||||||
|
puts "Detected user:#{match[1]}, project:#{match[2]}"
|
||||||
|
options[:user], options[:project] = match[1], match[2]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if !options[:user] || !options[:project]
|
|
||||||
puts parser.banner
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
|
|
||||||
if ARGV[1]
|
|
||||||
options[:tag1] = ARGV[0]
|
|
||||||
options[:tag2] = ARGV[1]
|
|
||||||
end
|
|
||||||
|
|
||||||
if options[:verbose]
|
|
||||||
puts 'Performing task with options:'
|
|
||||||
pp options
|
|
||||||
puts ''
|
|
||||||
end
|
|
||||||
|
|
||||||
options
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ module GitHubChangelogGenerator
|
|||||||
class Reader
|
class Reader
|
||||||
def initialize(options = {})
|
def initialize(options = {})
|
||||||
defaults = {
|
defaults = {
|
||||||
heading_level: '##',
|
heading_level: "##",
|
||||||
heading_structures: [
|
heading_structures: [
|
||||||
/^## \[(?<version>.+?)\]\((?<url>.+?)\)( \((?<date>.+?)\))?$/,
|
/^## \[(?<version>.+?)\]\((?<url>.+?)\)( \((?<date>.+?)\))?$/,
|
||||||
/^## (?<version>.+?)( \((?<date>.+?)\))?$/
|
/^## (?<version>.+?)( \((?<date>.+?)\))?$/
|
||||||
@@ -49,7 +49,7 @@ module GitHubChangelogGenerator
|
|||||||
# @param [String] heading Heading from the ChangeLog File
|
# @param [String] heading Heading from the ChangeLog File
|
||||||
# @return [Hash] Returns a structured Hash with version, url and date
|
# @return [Hash] Returns a structured Hash with version, url and date
|
||||||
def parse_heading(heading)
|
def parse_heading(heading)
|
||||||
captures = { 'version' => nil, 'url' => nil, 'date' => nil }
|
captures = { "version" => nil, "url" => nil, "date" => nil }
|
||||||
|
|
||||||
@heading_structures.each do |regexp|
|
@heading_structures.each do |regexp|
|
||||||
matches = Regexp.new(regexp).match(heading)
|
matches = Regexp.new(regexp).match(heading)
|
||||||
@@ -73,7 +73,7 @@ module GitHubChangelogGenerator
|
|||||||
|
|
||||||
headings.each_with_index do |heading, index|
|
headings.each_with_index do |heading, index|
|
||||||
captures = parse_heading(heading)
|
captures = parse_heading(heading)
|
||||||
captures['content'] = sections.at(index + 1)
|
captures["content"] = sections.at(index + 1)
|
||||||
changelog.push captures
|
changelog.push captures
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
module GitHubChangelogGenerator
|
module GitHubChangelogGenerator
|
||||||
VERSION = '1.3.11'
|
VERSION = "1.4.0"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,15 +15,18 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
require 'coveralls'
|
require "codeclimate-test-reporter"
|
||||||
require 'simplecov'
|
require "simplecov"
|
||||||
|
require "coveralls"
|
||||||
|
|
||||||
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
||||||
|
Coveralls::SimpleCov::Formatter,
|
||||||
SimpleCov::Formatter::HTMLFormatter,
|
SimpleCov::Formatter::HTMLFormatter,
|
||||||
Coveralls::SimpleCov::Formatter
|
CodeClimate::TestReporter::Formatter
|
||||||
]
|
]
|
||||||
SimpleCov.start
|
SimpleCov.start
|
||||||
|
|
||||||
require 'github_changelog_generator'
|
require "github_changelog_generator"
|
||||||
|
|
||||||
# This file was generated by the `rspec --init` command. Conventionally, all
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
||||||
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
||||||
@@ -92,7 +95,7 @@ RSpec.configure do |config|
|
|||||||
# Use the documentation formatter for detailed output,
|
# Use the documentation formatter for detailed output,
|
||||||
# unless a formatter has already been configured
|
# unless a formatter has already been configured
|
||||||
# (e.g. via a command-line flag).
|
# (e.g. via a command-line flag).
|
||||||
config.default_formatter = 'doc'
|
config.default_formatter = "doc"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Print the 10 slowest examples and example groups at the
|
# Print the 10 slowest examples and example groups at the
|
||||||
|
|||||||
@@ -21,71 +21,71 @@ describe GitHubChangelogGenerator::Reader do
|
|||||||
@reader = GitHubChangelogGenerator::Reader.new
|
@reader = GitHubChangelogGenerator::Reader.new
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#parse_heading' do
|
describe "#parse_heading" do
|
||||||
context 'when heading is empty' do
|
context "when heading is empty" do
|
||||||
subject { @reader.parse_heading('## ') }
|
subject { @reader.parse_heading("## ") }
|
||||||
it { is_expected.to be_a(Hash) }
|
it { is_expected.to be_a(Hash) }
|
||||||
it { is_expected.to include('version', 'url', 'date') }
|
it { is_expected.to include("version", "url", "date") }
|
||||||
it { is_expected.to include('version' => nil, 'url' => nil, 'date' => nil) }
|
it { is_expected.to include("version" => nil, "url" => nil, "date" => nil) }
|
||||||
# TODO: Doesn't work?
|
# TODO: Doesn't work?
|
||||||
# it { is_expected.to have_all_string_keys }
|
# it { is_expected.to have_all_string_keys }
|
||||||
end
|
end
|
||||||
context 'when given version, url and date' do
|
context "when given version, url and date" do
|
||||||
subject { @reader.parse_heading('## [1.3.10](https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.10) (2015-03-18)') }
|
subject { @reader.parse_heading("## [1.3.10](https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.10) (2015-03-18)") }
|
||||||
it { is_expected.to include('version' => '1.3.10') }
|
it { is_expected.to include("version" => "1.3.10") }
|
||||||
it { is_expected.to include('url' => 'https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.10') }
|
it { is_expected.to include("url" => "https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.10") }
|
||||||
it { is_expected.to include('date' => '2015-03-18') }
|
it { is_expected.to include("date" => "2015-03-18") }
|
||||||
end
|
end
|
||||||
context 'when no url and date is provided' do
|
context "when no url and date is provided" do
|
||||||
subject { @reader.parse_heading('## foobar') }
|
subject { @reader.parse_heading("## foobar") }
|
||||||
it { is_expected.to include('version' => 'foobar', 'url' => nil, 'date' => nil) }
|
it { is_expected.to include("version" => "foobar", "url" => nil, "date" => nil) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#parse' do
|
describe "#parse" do
|
||||||
context 'when file is empty' do
|
context "when file is empty" do
|
||||||
subject { @reader.parse('') }
|
subject { @reader.parse("") }
|
||||||
it { is_expected.to be_an(Array) }
|
it { is_expected.to be_an(Array) }
|
||||||
it { is_expected.to be_empty }
|
it { is_expected.to be_empty }
|
||||||
end
|
end
|
||||||
context 'when file has only the header' do
|
context "when file has only the header" do
|
||||||
subject { @reader.parse('# Change Log') }
|
subject { @reader.parse("# Change Log") }
|
||||||
it { is_expected.to be_an(Array) }
|
it { is_expected.to be_an(Array) }
|
||||||
it { is_expected.to be_empty }
|
it { is_expected.to be_empty }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'example CHANGELOG files' do
|
describe "example CHANGELOG files" do
|
||||||
subject { @reader.read(File.expand_path(File.join(File.dirname(__FILE__), '..', 'files', self.class.description))) }
|
subject { @reader.read(File.expand_path(File.join(File.dirname(__FILE__), "..", "files", self.class.description))) }
|
||||||
context 'github-changelog-generator.md' do
|
context "github-changelog-generator.md" do
|
||||||
it { is_expected.to be_an(Array) }
|
it { is_expected.to be_an(Array) }
|
||||||
it { is_expected.not_to be_empty }
|
it { is_expected.not_to be_empty }
|
||||||
it { expect(subject.count).to eq(28) }
|
it { expect(subject.count).to eq(28) }
|
||||||
it { expect(subject.first).to include('version' => '1.3.10') }
|
it { expect(subject.first).to include("version" => "1.3.10") }
|
||||||
it { expect(subject.first).to include('url' => 'https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.10') }
|
it { expect(subject.first).to include("url" => "https://github.com/skywinder/Github-Changelog-Generator/tree/1.3.10") }
|
||||||
it { expect(subject.first).to include('date' => '2015-03-18') }
|
it { expect(subject.first).to include("date" => "2015-03-18") }
|
||||||
it { expect(subject.first).to include('content') }
|
it { expect(subject.first).to include("content") }
|
||||||
it 'content should not be empty' do
|
it "content should not be empty" do
|
||||||
expect(subject.first['content']).not_to be_empty
|
expect(subject.first["content"]).not_to be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
context 'bundler.md' do
|
context "bundler.md" do
|
||||||
it { is_expected.to be_an(Array) }
|
it { is_expected.to be_an(Array) }
|
||||||
it { is_expected.not_to be_empty }
|
it { is_expected.not_to be_empty }
|
||||||
it { expect(subject.count).to eq(151) }
|
it { expect(subject.count).to eq(151) }
|
||||||
it { expect(subject.first).to include('version' => '1.9.1') }
|
it { expect(subject.first).to include("version" => "1.9.1") }
|
||||||
it { expect(subject.first).to include('url' => nil) }
|
it { expect(subject.first).to include("url" => nil) }
|
||||||
it { expect(subject.first).to include('date' => '2015-03-21') }
|
it { expect(subject.first).to include("date" => "2015-03-21") }
|
||||||
it { expect(subject.first).to include('content') }
|
it { expect(subject.first).to include("content") }
|
||||||
it 'content should not be empty' do
|
it "content should not be empty" do
|
||||||
expect(subject.first['content']).not_to be_empty
|
expect(subject.first["content"]).not_to be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
context 'angular.js.md' do
|
context "angular.js.md" do
|
||||||
it { is_expected.to be_an(Array) }
|
it { is_expected.to be_an(Array) }
|
||||||
it { is_expected.not_to be_empty }
|
it { is_expected.not_to be_empty }
|
||||||
it do
|
it do
|
||||||
pending('Implement heading_level for parser.')
|
pending("Implement heading_level for parser.")
|
||||||
expect(subject.count).to eq(134)
|
expect(subject.count).to eq(134)
|
||||||
end
|
end
|
||||||
# it do
|
# it do
|
||||||
|
|||||||
Reference in New Issue
Block a user