pr_changelog 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '02288b5d68d67aba8bfeab47b86537f777f650c2'
4
- data.tar.gz: a3ac3dc43ce78f8c336c17c9ffaab36d19cc2d0a
3
+ metadata.gz: 0d8b03e0c652b5e8c54545bda41fc8db5892f5c4
4
+ data.tar.gz: 7d03c9f0832e52c65fe6cf40da38f5cf1a234622
5
5
  SHA512:
6
- metadata.gz: fdb606a52d240f3c1ae8f20a2794ef1b5f01ed996133cccf38e6f7824574e2fa25e6ec05638cdef4274ce1c005790daf4a70d2d9b861f4b76d3eefd8cc20c022
7
- data.tar.gz: f96c549aed74907e06404ace2e8e525136da7f3c56d5a86d1963cd2ef9f64316cacf0fde0c81a02df95344c17e9cfafe2c58cd3e4dbd9634c34fb91025798ec5
6
+ metadata.gz: 16911cf9a8c6e3a29d85fd0b7534f082fc1b4a229ae5ee244846466fb57aa0d8186ac925d3208eb1e03a53e368ef1ed447c28d266d7ad60a3f6aa9dddc2f66f5
7
+ data.tar.gz: 2abab755538b3cb4baef5d34945f84550fafdb0c4ac737ab4252a1e890bb2de09cafd5f48cfedadb12baa5b19f2022a181d55306bd5758d4f14d8736685d500d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pr_changelog (0.1.0)
4
+ pr_changelog (0.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -12,17 +12,17 @@ GEM
12
12
  pry (0.12.2)
13
13
  coderay (~> 1.1.0)
14
14
  method_source (~> 0.9.0)
15
- rake (10.5.0)
15
+ rake (12.3.2)
16
16
 
17
17
  PLATFORMS
18
18
  ruby
19
19
 
20
20
  DEPENDENCIES
21
21
  bundler (~> 2.0.1)
22
- minitest (~> 5.0)
22
+ minitest (~> 5.11.3)
23
23
  pr_changelog!
24
24
  pry (~> 0.12.2)
25
- rake (~> 10.0)
25
+ rake (~> 12.3.2)
26
26
 
27
27
  BUNDLED WITH
28
28
  2.0.1
data/README.md CHANGED
@@ -1,6 +1,22 @@
1
1
  # PR Changelog
2
2
 
3
- A script to generate a nice list of changes given two git references.
3
+ A script to generate a nice list of changes given two git references, like so:
4
+
5
+ ```markdown
6
+ ## Changes since 0.3.0 to 0.5.0
7
+
8
+ [New features]
9
+ - #61: ⭐️ Shake the phone to send feedback email
10
+
11
+ [Improvements]
12
+ - #64: 💎 Visual refinements for canvas 2.0
13
+ - #57: 💎 Memory performance tweaks
14
+ - #62: 💎 Visual polishing for top stories
15
+
16
+ [Internal]
17
+ - #65: 👨‍💻 Add formatting rules for xml files
18
+ - #60: 👨‍💻 Setup hockeyapp for crash reporting
19
+ ```
4
20
 
5
21
  It takes in account all the merged pull request to master between the two given references, then it formats it in a nice consumable way.
6
22
 
@@ -42,6 +58,26 @@ To get the changes between to git tags `0.3.0` and `0.5.0`, execute:
42
58
  $ pr_changelog 0.3.0 0.5.0
43
59
  ```
44
60
 
61
+ Will produce something like:
62
+
63
+ ```markdown
64
+ ## Changes from 0.3.0 to 0.5.0
65
+
66
+ - #64: Improvement: visual refinements for canvas 2.0
67
+ - #65: Internal: add formatting rules for xml files
68
+ - #63: Feature: add Footer story
69
+ - #57: Improvement: memory performance tweaks
70
+ - #61: Feature: shake the phone to send feedback email
71
+ - #62: Improvement: visual polishing for top stories
72
+ - #60: Internal: setup hockeyapp for crash reporting
73
+ ```
74
+
75
+ or
76
+
77
+ ```
78
+ $ pr_changelog --format pretty 0.3.0 0.5.0
79
+ ```
80
+
45
81
  Will produce:
46
82
 
47
83
  ```markdown
@@ -60,26 +96,6 @@ Will produce:
60
96
  - #60: 👨‍💻 Setup hockeyapp for crash reporting
61
97
  ```
62
98
 
63
- or
64
-
65
- ```
66
- $ pr_changelog --format plain 0.3.0 0.5.0
67
- ```
68
-
69
- Will produce something like:
70
-
71
- ```markdown
72
- ## Changes from 0.3.0 to 0.5.0
73
-
74
- - #64: Improvement: visual refinements for canvas 2.0
75
- - #65: Internal: add formatting rules for xml files
76
- - #63: Feature: Add Footer story
77
- - #57: Improvement: Memory performance tweaks
78
- - #61: Feature: shake the phone to send feedback email
79
- - #62: Improvement: visual polishing for top stories
80
- - #60: Internal: setup hockeyapp for crash reporting
81
- ```
82
-
83
99
  ## Contributing
84
100
 
85
101
  Bug reports and pull requests are welcome on GitHub at https://github.com/schibsted/pr_changelog. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrChangelog
4
+ # Represents a single change entry in the changelog
5
+ class ChangeLine
6
+ attr_reader :pr_number, :tag, :title
7
+
8
+ def initialize(pr_number, tag, title)
9
+ @pr_number = pr_number
10
+ @tag = tag
11
+ @title = title
12
+ end
13
+
14
+ def to_s
15
+ if tag.nil?
16
+ "- #{pr_number}: #{title.first_lowercase}"
17
+ else
18
+ "- #{pr_number}: #{tag}: #{title.first_lowercase}"
19
+ end
20
+ end
21
+
22
+ def formatted_title
23
+ title.first_uppercase
24
+ end
25
+
26
+ def emojified_for(tag_object)
27
+ "- #{pr_number}: #{tag_object.emoji} #{formatted_title}"
28
+ end
29
+ end
30
+ end
@@ -9,7 +9,7 @@ module PrChangelog
9
9
  [Options]
10
10
 
11
11
  -h, --help\tShow this help
12
- --format FORMAT_NAME\t(default "pretty"), options ("pretty", "plain")
12
+ --format FORMAT_NAME\t(default "plain"), options ("pretty", "plain")
13
13
 
14
14
  [Examples]
15
15
 
@@ -31,10 +31,10 @@ module PrChangelog
31
31
 
32
32
  def run
33
33
  changes = NotReleasedChanges.new(from_reference, to_reference)
34
- if format == 'plain'
35
- puts changes.formatted_changelog
36
- else
34
+ if format == 'pretty'
37
35
  puts changes.grouped_formatted_changelog
36
+ else
37
+ puts changes.formatted_changelog
38
38
  end
39
39
  end
40
40
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Some useful extensions on string
4
+ class String
5
+ def first_uppercase
6
+ return self unless length > 2
7
+
8
+ "#{self[0].upcase}#{self[1, length]}"
9
+ end
10
+
11
+ def first_lowercase
12
+ return self unless length > 2
13
+
14
+ "#{self[0].downcase}#{self[1, length]}"
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrChangelog
4
+ # A boundary class between git and the rest of the gem
5
+ class GitProxy
6
+ LOG_FORMAT = '- %cn: %s%n%w(80, 2, 2)%b'
7
+
8
+ def merge_commits_between(base_ref, current_ref)
9
+ `git log --merges #{base_ref}..#{current_ref} --format='#{LOG_FORMAT}'`
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrChangelog
4
+ # A class to group change lines by tag
5
+ class GroupedChanges
6
+ attr_reader :changes, :tags
7
+
8
+ def initialize(changes, tags)
9
+ @changes = changes
10
+ @tags = tags
11
+ end
12
+
13
+ def to_s
14
+ new_hash = {}
15
+ grouped_changes.each do |tag, change_lines|
16
+ new_key = tag.formatted_title
17
+ new_hash[new_key] = change_lines.map do |change_line|
18
+ change_line.emojified_for(tag)
19
+ end
20
+ end
21
+
22
+ new_hash.reduce('') do |string, pair|
23
+ tag = pair[0]
24
+ lines = pair[1].map { |l| " #{l}" }.join("\n")
25
+ string + "#{tag}\n#{lines}\n\n"
26
+ end.strip.chomp
27
+ end
28
+
29
+ private
30
+
31
+ def grouped_changes
32
+ @grouped_changes ||= changes.group_by do |change_line|
33
+ tags[change_line&.tag&.downcase] || tags['unclassified']
34
+ end.sort do |first_group, second_group|
35
+ first_group[0].sort_index <=> second_group[0].sort_index
36
+ end
37
+ end
38
+ end
39
+ end
@@ -4,20 +4,8 @@ module PrChangelog
4
4
  # Calculates a list of not released changes from `base_ref` to `current_ref`
5
5
  # those changes consist of the merged pull-request title
6
6
  class NotReleasedChanges
7
- LOG_FORMAT = '- %cn: %s%n%w(80, 2, 2)%b'
8
- GITHUB_MERGE_COMMIT_FORMAT = /Merge pull request (?<pr_number>#\d+) .*/.freeze
9
- MERGE_BRANCH_COMMIT_FORMAT = /(Merge branch '.*'\s?(into|of)? .*)|(Merge .* branch .*)/.freeze
10
- PARSED_MERGE_COMMIT_FORMAT = /^- #(?<pr_number>\d+):\s+(?<tag>[^\s]+):\s*(?<title>.*)$/.freeze
11
-
12
- attr_reader :base_ref, :current_ref
13
-
14
- def initialize(base_ref, current_ref)
15
- @base_ref = base_ref
16
- @current_ref = current_ref
17
- end
18
-
19
- Tag = Struct.new(:emoji, :title, :sort)
20
-
7
+ MERGE_COMMIT_FORMAT = /Merge pull request (?<pr_number>#\d+) .*/.freeze
8
+ TAGGED_TITLE = /^(?<tag>.+):\s*(?<title>.+)$/.freeze
21
9
  EMOJI_TAGS = {
22
10
  'feature' => Tag.new('⭐️', 'New features', 0),
23
11
  'fix' => Tag.new('🐛', 'Fixes', 1),
@@ -26,93 +14,63 @@ module PrChangelog
26
14
  'unclassified' => Tag.new('❓', 'Unclassified', 5)
27
15
  }.freeze
28
16
 
17
+ attr_reader :base_ref, :current_ref, :git_proxy
18
+
19
+ def initialize(base_ref, current_ref, git_proxy = GitProxy.new)
20
+ @base_ref = base_ref
21
+ @current_ref = current_ref
22
+ @git_proxy = git_proxy
23
+ end
24
+
29
25
  def formatted_changelog
30
- if formatted_change_list.positive?
31
- formatted_change_list.join("\n")
26
+ if parsed_change_list.count.positive?
27
+ parsed_change_list.map(&:to_s).join("\n")
32
28
  else
33
29
  "There are no changes since #{base_ref} to #{current_ref}"
34
30
  end
35
31
  end
36
32
 
37
33
  def grouped_formatted_changelog
38
- changes = formatted_change_list
39
- if changes.count.positive?
40
-
41
- grouped_changes = changes.group_by do |change_line|
42
- EMOJI_TAGS[tag_from(change_line)] || EMOJI_TAGS['unclassified']
43
- end
44
-
45
- sorted_hash = grouped_changes.sort do |first_pair, second_pair|
46
- first_pair[0].sort <=> second_pair[0].sort
47
- end
48
-
49
- new_hash = {}
50
- sorted_hash.each do |tag, change_lines|
51
- new_key = "[#{tag.title}]"
52
- new_hash[new_key] = change_lines.map do |change_line|
53
- emojify_tag_for(change_line)
54
- end
55
- end
56
-
57
- new_hash.reduce('') do |string, pair|
58
- tag = pair[0]
59
- lines = pair[1].map { |l| " #{l}" }.join("\n")
60
- string + "#{tag}\n#{lines}\n\n"
61
- end.chomp
34
+ if parsed_change_list.count.positive?
35
+ GroupedChanges.new(parsed_change_list, EMOJI_TAGS).to_s
62
36
  else
63
37
  "There are no changes since #{base_ref} to #{current_ref}"
64
38
  end
65
39
  end
66
40
 
67
- def formatted_change_list
68
- parsed_merge_commits.map do |pair|
69
- format_merge_commit(pair.first, pair.last)
70
- end
71
- end
72
-
73
41
  private
74
42
 
75
- def first_uppercase(line)
76
- return line unless line.length > 2
77
-
78
- "#{line[0].upcase}#{line[1, line.length]}"
79
- end
80
-
81
- def emojify_tag_for(change_line)
82
- match = change_line.match(PARSED_MERGE_COMMIT_FORMAT)
83
- return change_line unless match
84
-
85
- emoji_tag = EMOJI_TAGS[match[:tag].downcase].emoji || '❓'
86
- "- ##{match[:pr_number]}: #{emoji_tag} #{first_uppercase(match[:title])}"
87
- end
88
-
89
- def tag_from(merge_commit)
90
- match = merge_commit.match(PARSED_MERGE_COMMIT_FORMAT)
91
- return nil unless match
92
-
93
- match[:tag].downcase
43
+ def parsed_change_list
44
+ @parsed_change_list ||= parsed_merge_commits.map do |pair|
45
+ format_merge_commit(pair.first, pair.last)
46
+ end
94
47
  end
95
48
 
96
49
  def parsed_merge_commits
97
50
  merge_commits_not_merged_into_base_ref
98
51
  .split('- ')
99
52
  .reject(&:empty?)
100
- .reject { |line| line.match(MERGE_BRANCH_COMMIT_FORMAT) }
101
53
  .map { |e| e.split("\n") }
54
+ .select { |pair| pair.count == 2 }
102
55
  end
103
56
 
104
57
  def format_merge_commit(github_commit_title, commit_title)
105
58
  pr_number = pull_request_number_for(github_commit_title)
106
-
107
- "- #{pr_number}: #{commit_title.strip}"
59
+ commit_title.strip!
60
+ match = commit_title.match(TAGGED_TITLE)
61
+ if match
62
+ ChangeLine.new(pr_number, match[:tag], match[:title])
63
+ else
64
+ ChangeLine.new(pr_number, nil, commit_title)
65
+ end
108
66
  end
109
67
 
110
68
  def merge_commits_not_merged_into_base_ref
111
- `git log --merges #{base_ref}..#{current_ref} --format='#{LOG_FORMAT}'`
69
+ git_proxy.merge_commits_between(base_ref, current_ref)
112
70
  end
113
71
 
114
72
  def pull_request_number_for(github_commit_title)
115
- md = github_commit_title.match(GITHUB_MERGE_COMMIT_FORMAT)
73
+ md = github_commit_title.match(MERGE_COMMIT_FORMAT)
116
74
  md[:pr_number] if md
117
75
  end
118
76
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PrChangelog
4
+ # A way to classify particular change lines
5
+ class Tag
6
+ attr_reader :emoji, :title, :sort_index
7
+
8
+ def initialize(emoji, title, sort_index)
9
+ @emoji = emoji
10
+ @title = title
11
+ @sort_index = sort_index
12
+ end
13
+
14
+ def formatted_title
15
+ "[#{title}]"
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PrChangelog
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
5
5
  end
data/lib/pr_changelog.rb CHANGED
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'pr_changelog/version'
4
+ require 'pr_changelog/extensions/string'
4
5
  require 'pr_changelog/cli'
6
+ require 'pr_changelog/git_proxy'
7
+ require 'pr_changelog/tag'
8
+ require 'pr_changelog/change_line'
9
+ require 'pr_changelog/grouped_changes'
5
10
  require 'pr_changelog/not_released_changes'
6
11
 
7
12
  # Main module
data/pr_changelog.gemspec CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.require_paths = ['lib']
28
28
 
29
29
  spec.add_development_dependency 'bundler', '~> 2.0.1'
30
- spec.add_development_dependency 'minitest', '~> 5.0'
30
+ spec.add_development_dependency 'minitest', '~> 5.11.3'
31
31
  spec.add_development_dependency 'pry', '~> 0.12.2'
32
- spec.add_development_dependency 'rake', '~> 10.0'
32
+ spec.add_development_dependency 'rake', '~> 12.3.2'
33
33
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pr_changelog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felipe Espinoza
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '5.0'
33
+ version: 5.11.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '5.0'
40
+ version: 5.11.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: pry
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '10.0'
61
+ version: 12.3.2
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '10.0'
68
+ version: 12.3.2
69
69
  description:
70
70
  email:
71
71
  - felipe.espinoza@schibsted.com
@@ -86,8 +86,13 @@ files:
86
86
  - bin/setup
87
87
  - exe/pr_changelog
88
88
  - lib/pr_changelog.rb
89
+ - lib/pr_changelog/change_line.rb
89
90
  - lib/pr_changelog/cli.rb
91
+ - lib/pr_changelog/extensions/string.rb
92
+ - lib/pr_changelog/git_proxy.rb
93
+ - lib/pr_changelog/grouped_changes.rb
90
94
  - lib/pr_changelog/not_released_changes.rb
95
+ - lib/pr_changelog/tag.rb
91
96
  - lib/pr_changelog/version.rb
92
97
  - pr_changelog.gemspec
93
98
  homepage: https://github.com/schibsted/pr_changelog