px_github_changelog_generator 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +9 -0
  3. data/README.md +357 -0
  4. data/Rakefile +19 -0
  5. data/bin/git-generate-changelog +5 -0
  6. data/bin/github_changelog_generator +5 -0
  7. data/lib/github_changelog_generator/argv_parser.rb +225 -0
  8. data/lib/github_changelog_generator/file_parser_chooser.rb +27 -0
  9. data/lib/github_changelog_generator/generator/entry.rb +218 -0
  10. data/lib/github_changelog_generator/generator/generator.rb +177 -0
  11. data/lib/github_changelog_generator/generator/generator_fetcher.rb +202 -0
  12. data/lib/github_changelog_generator/generator/generator_processor.rb +237 -0
  13. data/lib/github_changelog_generator/generator/generator_tags.rb +210 -0
  14. data/lib/github_changelog_generator/generator/section.rb +129 -0
  15. data/lib/github_changelog_generator/helper.rb +37 -0
  16. data/lib/github_changelog_generator/octo_fetcher.rb +535 -0
  17. data/lib/github_changelog_generator/options.rb +159 -0
  18. data/lib/github_changelog_generator/parser.rb +89 -0
  19. data/lib/github_changelog_generator/parser_file.rb +101 -0
  20. data/lib/github_changelog_generator/reader.rb +88 -0
  21. data/lib/github_changelog_generator/ssl_certs/cacert.pem +3138 -0
  22. data/lib/github_changelog_generator/task.rb +68 -0
  23. data/lib/github_changelog_generator/version.rb +5 -0
  24. data/lib/github_changelog_generator.rb +49 -0
  25. data/man/git-generate-changelog.1 +393 -0
  26. data/man/git-generate-changelog.1.html +359 -0
  27. data/man/git-generate-changelog.html +270 -0
  28. data/man/git-generate-changelog.md +274 -0
  29. data/spec/files/angular.js.md +9395 -0
  30. data/spec/files/bundler.md +1911 -0
  31. data/spec/files/config_example +5 -0
  32. data/spec/files/github-changelog-generator.md +305 -0
  33. data/spec/github_changelog_generator_spec.rb +32 -0
  34. data/spec/install_gem_in_bundler.gemfile +5 -0
  35. data/spec/spec_helper.rb +74 -0
  36. data/spec/unit/generator/entry_spec.rb +766 -0
  37. data/spec/unit/generator/generator_processor_spec.rb +203 -0
  38. data/spec/unit/generator/generator_spec.rb +47 -0
  39. data/spec/unit/generator/generator_tags_spec.rb +337 -0
  40. data/spec/unit/generator/section_spec.rb +43 -0
  41. data/spec/unit/octo_fetcher_spec.rb +590 -0
  42. data/spec/unit/options_spec.rb +67 -0
  43. data/spec/unit/parser_file_spec.rb +94 -0
  44. data/spec/unit/parser_spec.rb +54 -0
  45. data/spec/unit/reader_spec.rb +120 -0
  46. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits/when_API_is_valid/returns_commits.json +1 -0
  47. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_commits_before/when_API_is_valid/returns_commits.json +1 -0
  48. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issue_with_proper_key/values.json +1 -0
  49. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues.json +1 -0
  50. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_issues_with_labels.json +1 -0
  51. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_pull_request_with_proper_key/values.json +1 -0
  52. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid/returns_pull_requests_with_labels.json +1 -0
  53. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_issues_and_pr/when_API_call_is_valid.json +1 -0
  54. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_correct_pull_request_keys.json +1 -0
  55. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid/returns_pull_requests.json +1 -0
  56. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_closed_pull_requests/when_API_call_is_valid.json +1 -0
  57. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid/returns_commit.json +1 -0
  58. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_commit/when_API_call_is_valid.json +1 -0
  59. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid/returns_date.json +1 -0
  60. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_date_of_tag/when_API_call_is_valid.json +1 -0
  61. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid/populates_issues.json +1 -0
  62. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_fetch_events_async/when_API_call_is_valid.json +1 -0
  63. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags.json +1 -0
  64. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid/should_return_tags_count.json +1 -0
  65. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_API_call_is_valid.json +1 -0
  66. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_wrong_token_provided/should_raise_Unauthorized_error.json +1 -0
  67. data/spec/vcr/GitHubChangelogGenerator_OctoFetcher/_github_fetch_tags/when_wrong_token_provided.json +1 -0
  68. metadata +250 -0
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "github_changelog_generator/helper"
4
+ require "github_changelog_generator/argv_parser"
5
+ require "github_changelog_generator/parser_file"
6
+ require "github_changelog_generator/file_parser_chooser"
7
+
8
+ module GitHubChangelogGenerator
9
+ class Parser
10
+ class << self
11
+ PARSERS = [
12
+ ArgvParser, # Parse arguments first to get initial options populated
13
+ FileParserChooser, # Then parse possible configuration files
14
+ ArgvParser # Lastly parse arguments again to keep the given arguments the strongest
15
+ ].freeze
16
+
17
+ def parse_options(argv = ARGV)
18
+ options = default_options
19
+
20
+ PARSERS.each do |parser|
21
+ parser.new(options).parse!(argv)
22
+ end
23
+
24
+ abort_if_user_and_project_not_given!(options)
25
+
26
+ options.print_options
27
+
28
+ options
29
+ end
30
+
31
+ def abort_if_user_and_project_not_given!(options)
32
+ return if options[:user] && options[:project]
33
+
34
+ warn "Configure which user and project to work on."
35
+ warn "Options --user and --project, or settings to that effect. See --help for more."
36
+ warn ArgvParser.banner
37
+
38
+ Kernel.abort
39
+ end
40
+
41
+ # @return [Options] Default options
42
+ def default_options
43
+ Options.new(
44
+ date_format: "%Y-%m-%d",
45
+ output: "CHANGELOG.md",
46
+ base: "HISTORY.md",
47
+ issues: true,
48
+ add_issues_wo_labels: true,
49
+ add_pr_wo_labels: true,
50
+ pulls: true,
51
+ filter_issues_by_milestone: true,
52
+ issues_of_open_milestones: true,
53
+ author: true,
54
+ unreleased: true,
55
+ unreleased_label: "Unreleased",
56
+ compare_link: true,
57
+ exclude_labels: ["duplicate", "question", "invalid", "wontfix", "Duplicate", "Question", "Invalid", "Wontfix", "Meta: Exclude From Changelog"],
58
+ summary_labels: ["Release summary", "release-summary", "Summary", "summary"],
59
+ breaking_labels: ["backwards-incompatible", "Backwards incompatible", "breaking"],
60
+ enhancement_labels: ["enhancement", "Enhancement", "Type: Enhancement"],
61
+ bug_labels: ["bug", "Bug", "Type: Bug"],
62
+ deprecated_labels: ["deprecated", "Deprecated", "Type: Deprecated"],
63
+ removed_labels: ["removed", "Removed", "Type: Removed"],
64
+ security_labels: ["security", "Security", "Type: Security"],
65
+ configure_sections: {},
66
+ add_sections: {},
67
+ issue_line_labels: [],
68
+ max_issues: nil,
69
+ simple_list: false,
70
+ ssl_ca_file: nil,
71
+ verbose: true,
72
+ header: "# Changelog",
73
+ merge_prefix: "**Merged pull requests:**",
74
+ issue_prefix: "**Closed issues:**",
75
+ summary_prefix: "",
76
+ breaking_prefix: "**Breaking changes:**",
77
+ enhancement_prefix: "**Implemented enhancements:**",
78
+ bug_prefix: "**Fixed bugs:**",
79
+ deprecated_prefix: "**Deprecated:**",
80
+ removed_prefix: "**Removed:**",
81
+ security_prefix: "**Security fixes:**",
82
+ http_cache: true,
83
+ require: [],
84
+ config_file: ".github_changelog_generator"
85
+ )
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GitHubChangelogGenerator
4
+ ParserError = Class.new(StandardError)
5
+
6
+ # ParserFile is a configuration file reader which sets options in the
7
+ # given Hash.
8
+ #
9
+ # In your project's root, you can put a file named
10
+ # <tt>.github_changelog_generator</tt> to override defaults.
11
+ #
12
+ # Example:
13
+ # header_label=# My Super Changelog
14
+ # ; Comments are allowed
15
+ # future-release=5.0.0
16
+ # # Ruby-style comments, too
17
+ # since-tag=1.0.0
18
+ #
19
+ # The configuration format is <tt>some-key=value</tt> or <tt>some_key=value</tt>.
20
+ #
21
+ class ParserFile
22
+ # @param options [Hash] options to be configured from file contents
23
+ # @param io [nil, IO] configuration file handle
24
+ def initialize(options, io = nil)
25
+ @options = options
26
+ @io = io
27
+ end
28
+
29
+ # Sets options using configuration file content
30
+ def parse!
31
+ return unless @io
32
+
33
+ @io.each_with_index { |line, i| parse_line!(line, i + 1) }
34
+ @io.close
35
+ end
36
+
37
+ private
38
+
39
+ def parse_line!(line, line_number)
40
+ return if non_configuration_line?(line)
41
+
42
+ option_name, value = extract_pair(line)
43
+ @options[option_key_for(option_name)] = convert_value(value, option_name)
44
+ rescue StandardError
45
+ raise ParserError, "Failed on line ##{line_number}: \"#{line.gsub(/[\n\r]+/, '')}\""
46
+ end
47
+
48
+ # Returns true if the line starts with a pound sign or a semi-colon.
49
+ def non_configuration_line?(line)
50
+ line =~ /^[\#;]/ || line =~ /^\s+$/
51
+ end
52
+
53
+ # Returns a the option name as a symbol and its string value sans newlines.
54
+ #
55
+ # @param line [String] unparsed line from config file
56
+ # @return [Array<Symbol, String>]
57
+ def extract_pair(line)
58
+ key, value = line.split("=", 2)
59
+ [key.tr("-", "_").to_sym, value.gsub(/[\n\r]+/, "")]
60
+ end
61
+
62
+ KNOWN_ARRAY_KEYS = %i[exclude_labels include_labels
63
+ summary_labels breaking_labels enhancement_labels bug_labels
64
+ deprecated_labels removed_labels security_labels
65
+ issue_line_labels between_tags exclude_tags]
66
+ KNOWN_INTEGER_KEYS = [:max_issues]
67
+
68
+ def convert_value(value, option_name)
69
+ if KNOWN_ARRAY_KEYS.include?(option_name)
70
+ value.split(",")
71
+ elsif KNOWN_INTEGER_KEYS.include?(option_name)
72
+ value.to_i
73
+ elsif value =~ /^(true|t|yes|y|1)$/i
74
+ true
75
+ elsif value =~ /^(false|f|no|n|0)$/i
76
+ false
77
+ else
78
+ value
79
+ end
80
+ end
81
+
82
+ IRREGULAR_OPTIONS = {
83
+ bugs_label: :bug_prefix,
84
+ enhancement_label: :enhancement_prefix,
85
+ issues_label: :issue_prefix,
86
+ header_label: :header,
87
+ front_matter: :frontmatter,
88
+ pr_label: :merge_prefix,
89
+ breaking_label: :breaking_prefix,
90
+ issues_wo_labels: :add_issues_wo_labels,
91
+ pr_wo_labels: :add_pr_wo_labels,
92
+ pull_requests: :pulls,
93
+ filter_by_milestone: :filter_issues_by_milestone,
94
+ github_api: :github_endpoint
95
+ }
96
+
97
+ def option_key_for(option_name)
98
+ IRREGULAR_OPTIONS.fetch(option_name) { option_name }
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Author:: Enrico Stahn <mail@enricostahn.com>
5
+ #
6
+ # Copyright 2014, Zanui, <engineering@zanui.com.au>
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+
21
+ module GitHubChangelogGenerator
22
+ # A Reader to read an existing ChangeLog file and return a structured object
23
+ #
24
+ # Example:
25
+ # reader = GitHubChangelogGenerator::Reader.new
26
+ # content = reader.read('./CHANGELOG.md')
27
+ class Reader
28
+ def initialize(options = {})
29
+ defaults = {
30
+ heading_level: "##",
31
+ heading_structures: [
32
+ /^## \[(?<version>.+?)\](\((?<url>.+?)\))?( \((?<date>.+?)\))?$/, # rubocop:disable Lint/MixedRegexpCaptureTypes
33
+ /^## (?<version>.+?)( \((?<date>.+?)\))?$/ # rubocop:disable Lint/MixedRegexpCaptureTypes
34
+ ]
35
+ }
36
+
37
+ @options = options.merge(defaults)
38
+
39
+ @heading_level = @options[:heading_level]
40
+ @heading_structures = @options[:heading_structures]
41
+ end
42
+
43
+ # Parse a single heading and return a Hash
44
+ #
45
+ # The following heading structures are currently valid:
46
+ # - ## [v1.0.2](https://github.com/zanui/chef-thumbor/tree/v1.0.1) (2015-03-24)
47
+ # - ## [v1.0.2](https://github.com/zanui/chef-thumbor/tree/v1.0.1)
48
+ # - ## [v1.0.2] (2015-03-24)
49
+ # - ## [v1.0.2]
50
+ # - ## v1.0.2 (2015-03-24)
51
+ # - ## v1.0.2
52
+ #
53
+ # @param [String] heading Heading from the ChangeLog File
54
+ # @return [Hash] Returns a structured Hash with version, url and date
55
+ def parse_heading(heading)
56
+ captures = { "version" => nil, "url" => nil, "date" => nil }
57
+
58
+ @heading_structures.each do |regexp|
59
+ matches = Regexp.new(regexp).match(heading)
60
+ if matches
61
+ captures.merge!(Hash[matches.names.zip(matches.captures)])
62
+ break
63
+ end
64
+ end
65
+
66
+ captures
67
+ end
68
+
69
+ # Parse the given ChangeLog data into a list of Hashes
70
+ #
71
+ # @param [String] data File data from the ChangeLog.md
72
+ # @return [Array<Hash>] Parsed data, e.g. [{ 'version' => ..., 'url' => ..., 'date' => ..., 'content' => ...}, ...]
73
+ def parse(data)
74
+ sections = data.split(/^## .+?$/)
75
+ headings = data.scan(/^## .+?$/)
76
+
77
+ headings.each_with_index.map do |heading, index|
78
+ section = parse_heading(heading)
79
+ section["content"] = sections.at(index + 1)
80
+ section
81
+ end
82
+ end
83
+
84
+ def read(file_path)
85
+ parse File.read(file_path)
86
+ end
87
+ end
88
+ end