pimpmychangelog 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Guardfile +7 -0
- data/Rakefile +1 -0
- data/bin/pimpmychangelog +5 -0
- data/lib/pimpmychangelog/cli.rb +24 -0
- data/lib/pimpmychangelog/parser.rb +27 -0
- data/lib/pimpmychangelog/pimper.rb +61 -0
- data/lib/pimpmychangelog/version.rb +3 -0
- data/lib/pimpmychangelog.rb +3 -0
- data/pimpmychangelog.gemspec +23 -0
- data/spec/parser_spec.rb +56 -0
- data/spec/pimper_spec.rb +97 -0
- data/spec/spec_helper.rb +3 -0
- metadata +108 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/bin/pimpmychangelog
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module PimpMyChangelog
|
2
|
+
class CLI
|
3
|
+
def self.run!(args)
|
4
|
+
unless args.size == 3
|
5
|
+
puts "Usage: pimpmychangelog github_user github_project CHANGELOG.md"
|
6
|
+
exit 1
|
7
|
+
end
|
8
|
+
|
9
|
+
new(*args).run
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :user, :project, :changelog_path
|
13
|
+
|
14
|
+
def initialize(user, project, changelog_path)
|
15
|
+
@user = user
|
16
|
+
@project = project
|
17
|
+
@changelog_path = changelog_path
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
puts Pimper.new(user, project, File.read(changelog_path)).better_changelog
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module PimpMyChangelog
|
2
|
+
class Parser
|
3
|
+
attr_reader :changelog
|
4
|
+
|
5
|
+
# @param [String] changelog
|
6
|
+
def initialize(changelog)
|
7
|
+
@changelog = changelog
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [String] the changelog content without the link definitions
|
11
|
+
def content
|
12
|
+
@changelog.split(Pimper::SEPARATOR).first
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Array] ordered array of issue numbers found in the changelog
|
16
|
+
# Example: ['12', '223', '470']
|
17
|
+
def issues
|
18
|
+
changelog.scan(/#(\d+)/).flatten.uniq.sort_by(&:to_i)
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Array] ordered array of contributors found in the changelog
|
22
|
+
# Example: ['gregbell', 'pcreux', 'samvincent']
|
23
|
+
def contributors
|
24
|
+
changelog.scan(/@(\w+)/).flatten.uniq.sort
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module PimpMyChangelog
|
2
|
+
|
3
|
+
class Pimper
|
4
|
+
SEPARATOR = "<!--- The following link definition list is generated by PimpMyChangelog --->"
|
5
|
+
|
6
|
+
attr_reader :user, :project, :changelog
|
7
|
+
|
8
|
+
# @param user [String] Github user of this changelog
|
9
|
+
# @param project [String] Github project of this changelog
|
10
|
+
# @param changelog [String] The changelog
|
11
|
+
def initialize(user, project, changelog)
|
12
|
+
@user = user
|
13
|
+
@project = project
|
14
|
+
@changelog = changelog
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [String] The changelog with contributors and issues as link
|
18
|
+
def better_changelog
|
19
|
+
parsed_changelog = Parser.new(changelog)
|
20
|
+
|
21
|
+
linkify_changelog(parsed_changelog.content) +
|
22
|
+
links_definitions(parsed_changelog.issues, parsed_changelog.contributors)
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
# @param [String] changelog
|
28
|
+
# @return [String] The changelog with users and issues linkified.
|
29
|
+
#
|
30
|
+
# Example: "@pcreux closes issue #123"
|
31
|
+
# # => "[@pcreux][] closes issue [#123][]"
|
32
|
+
def linkify_changelog(changelog)
|
33
|
+
changelog.
|
34
|
+
gsub(ISSUE_NUMBER_REGEXP, '\1[#\2][]\3').
|
35
|
+
gsub(CONTRIBUTOR_REGEXP, '\1[@\2][]\3')
|
36
|
+
end
|
37
|
+
|
38
|
+
# The following regexp ensure that the issue or contributor is
|
39
|
+
# not wrapped between brackets (aka: is a link)
|
40
|
+
ISSUE_NUMBER_REGEXP = /(^|[^\[])#(\d+)($|[^\]])/
|
41
|
+
CONTRIBUTOR_REGEXP = /(^|[^\[])@(\w+)($|[^\]])/
|
42
|
+
|
43
|
+
# @param [Array] issues An array of issue numbers
|
44
|
+
# @param [Array] contributors An array of contributors github ids
|
45
|
+
#
|
46
|
+
# @return [String] A list of link definitions
|
47
|
+
def links_definitions(issues, contributors)
|
48
|
+
return '' if issues.empty? && contributors.empty?
|
49
|
+
|
50
|
+
issues_list = issues.map do |issue|
|
51
|
+
"[##{issue}]: https://github.com/#{user}/#{project}/issues/#{issue}"
|
52
|
+
end
|
53
|
+
|
54
|
+
contributors_list = contributors.map do |contributor|
|
55
|
+
"[@#{contributor}]: https://github.com/#{contributor}"
|
56
|
+
end
|
57
|
+
|
58
|
+
([SEPARATOR] + issues_list + contributors_list).join("\n")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "pimpmychangelog/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "pimpmychangelog"
|
7
|
+
s.version = PimpMyChangelog::VERSION
|
8
|
+
s.authors = ["Philippe Creux"]
|
9
|
+
s.email = ["pcreux@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/pcreux/pimpmychangelog"
|
11
|
+
s.summary = %q{Pimp your CHANGELOG.md}
|
12
|
+
s.description = %q{Linkify issue numbers (#123) and github users (@gregbell) in markdown changelogs.}
|
13
|
+
|
14
|
+
s.default_executable = %q{pimpmychangelog}
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency "rspec"
|
22
|
+
s.add_development_dependency "guard-rspec"
|
23
|
+
end
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Parser do
|
4
|
+
|
5
|
+
describe "#initialize" do
|
6
|
+
it "should take a changelog" do
|
7
|
+
p = Parser.new('CHANGELOG')
|
8
|
+
p.changelog.should == 'CHANGELOG'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#content" do
|
13
|
+
context "when the changelog has link definitions" do
|
14
|
+
let(:changelog) { <<-EOS
|
15
|
+
# My Awesome ChangeLog
|
16
|
+
|
17
|
+
This my awesome changelog.
|
18
|
+
|
19
|
+
<!--- The following link definition list is generated by PimpMyChangelog --->
|
20
|
+
#123: https://whatever
|
21
|
+
@pcreux: https://github.com/pcreux
|
22
|
+
EOS
|
23
|
+
}
|
24
|
+
|
25
|
+
it "should return the ChangeLog without the link definitions" do
|
26
|
+
Parser.new(changelog).content.should == <<-EOS
|
27
|
+
# My Awesome ChangeLog
|
28
|
+
|
29
|
+
This my awesome changelog.
|
30
|
+
|
31
|
+
EOS
|
32
|
+
end
|
33
|
+
end # context "when the changelog has link definitions"
|
34
|
+
|
35
|
+
context "when the changelog does not have link definitions" do
|
36
|
+
let(:changelog) { "# My Awesome ChangeLog" }
|
37
|
+
|
38
|
+
it "should return the ChangeLog without the link definitions" do
|
39
|
+
Parser.new(changelog).content.should == changelog
|
40
|
+
end
|
41
|
+
end # context "when the changelog has link definitions"
|
42
|
+
end # describe "#content"
|
43
|
+
|
44
|
+
describe "#issues" do
|
45
|
+
it "should return a sorted list of unique issue numbers" do
|
46
|
+
Parser.new("#20 #100 #300 #20").issues.should == ['20', '100', '300']
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#contributors" do
|
51
|
+
it "should return a sorted list of unique contributors" do
|
52
|
+
Parser.new("@samvincent @pcreux @gregbell @pcreux").contributors.
|
53
|
+
should == ['gregbell', 'pcreux', 'samvincent']
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/spec/pimper_spec.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Pimper do
|
4
|
+
describe "#initialize" do
|
5
|
+
it "should take a github user, a github project and a changelog" do
|
6
|
+
g = Pimper.new('gregbell', 'activeadmin', 'ChangeLog')
|
7
|
+
g.user.should == 'gregbell'
|
8
|
+
g.project.should == 'activeadmin'
|
9
|
+
g.changelog.should == 'ChangeLog'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#better_changelog" do
|
14
|
+
let(:user) { 'gregbell' }
|
15
|
+
let(:project) { 'activeadmin' }
|
16
|
+
|
17
|
+
let(:better_changelog) { Pimper.new(user, project, changelog).better_changelog }
|
18
|
+
|
19
|
+
subject { better_changelog }
|
20
|
+
|
21
|
+
context "when the changelog does not contain any reference to issues or users" do
|
22
|
+
let(:changelog) { 'ChangeLog' }
|
23
|
+
|
24
|
+
it "should return the original changelog" do
|
25
|
+
better_changelog.should == changelog
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when the changelog contains an issue number" do
|
30
|
+
let(:changelog) { 'Pull Request #123: Add I18n.' }
|
31
|
+
|
32
|
+
it "should wrap the issue number to make a link" do
|
33
|
+
better_changelog.should include("[#123][]")
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should append the link definition at the end of the changelog" do
|
37
|
+
better_changelog.split("\n").last.should == "[#123]: https://github.com/gregbell/activeadmin/issues/123"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when the changelog contains a contributor" do
|
42
|
+
let(:changelog) { 'New feature by @pcreux' }
|
43
|
+
|
44
|
+
it "should wrap the issue number to make a link" do
|
45
|
+
better_changelog.should include("[@pcreux][]")
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should append the link definition at the end of the changelog" do
|
49
|
+
better_changelog.split("\n").last.should == "[@pcreux]: https://github.com/pcreux"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when the changelog contains issue numbers or contributors which are links" do
|
54
|
+
let(:changelog) { '[@pcreux][] closes [#123][]' }
|
55
|
+
|
56
|
+
it "should leave them alone" do
|
57
|
+
better_changelog.should include("[@pcreux][] closes [#123][]")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when the changelog already contains issue numbers, link definitions and custom links" do
|
62
|
+
let(:changelog) { <<-EOS
|
63
|
+
# New entry
|
64
|
+
You know what? @pcreux closed issue #300!
|
65
|
+
|
66
|
+
# Previous entries
|
67
|
+
You know what? [@pcreux][] closed issue [#123][].
|
68
|
+
And this is my link, don't touch it: [Adequate][http://adequatehq.com]
|
69
|
+
|
70
|
+
<!--- The following link definitions are generated by PimpMyChangelog --->
|
71
|
+
[#123]: https://github.com/gregbell/activeadmin/issues/123
|
72
|
+
[@pcreux]: https://github.com/pcreux
|
73
|
+
EOS
|
74
|
+
}
|
75
|
+
|
76
|
+
let(:better_changelog) { Pimper.new('gregbell', 'activeadmin', changelog).better_changelog }
|
77
|
+
|
78
|
+
it "should regenerate the link definition but leave the existing links alone" do
|
79
|
+
(better_changelog + "\n").should == <<-EOS
|
80
|
+
# New entry
|
81
|
+
You know what? [@pcreux][] closed issue [#300][]!
|
82
|
+
|
83
|
+
# Previous entries
|
84
|
+
You know what? [@pcreux][] closed issue [#123][].
|
85
|
+
And this is my link, don't touch it: [Adequate][http://adequatehq.com]
|
86
|
+
|
87
|
+
<!--- The following link definitions are generated by PimpMyChangelog --->
|
88
|
+
[#123]: https://github.com/gregbell/activeadmin/issues/123
|
89
|
+
[#300]: https://github.com/gregbell/activeadmin/issues/300
|
90
|
+
[@pcreux]: https://github.com/pcreux
|
91
|
+
EOS
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pimpmychangelog
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Philippe Creux
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-08-25 00:00:00 -07:00
|
19
|
+
default_executable: pimpmychangelog
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: guard-rspec
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
description: Linkify issue numbers (#123) and github users (@gregbell) in markdown changelogs.
|
50
|
+
email:
|
51
|
+
- pcreux@gmail.com
|
52
|
+
executables:
|
53
|
+
- pimpmychangelog
|
54
|
+
extensions: []
|
55
|
+
|
56
|
+
extra_rdoc_files: []
|
57
|
+
|
58
|
+
files:
|
59
|
+
- .gitignore
|
60
|
+
- Gemfile
|
61
|
+
- Guardfile
|
62
|
+
- Rakefile
|
63
|
+
- bin/pimpmychangelog
|
64
|
+
- lib/pimpmychangelog.rb
|
65
|
+
- lib/pimpmychangelog/cli.rb
|
66
|
+
- lib/pimpmychangelog/parser.rb
|
67
|
+
- lib/pimpmychangelog/pimper.rb
|
68
|
+
- lib/pimpmychangelog/version.rb
|
69
|
+
- pimpmychangelog.gemspec
|
70
|
+
- spec/parser_spec.rb
|
71
|
+
- spec/pimper_spec.rb
|
72
|
+
- spec/spec_helper.rb
|
73
|
+
has_rdoc: true
|
74
|
+
homepage: https://github.com/pcreux/pimpmychangelog
|
75
|
+
licenses: []
|
76
|
+
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
hash: 3
|
97
|
+
segments:
|
98
|
+
- 0
|
99
|
+
version: "0"
|
100
|
+
requirements: []
|
101
|
+
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 1.3.7
|
104
|
+
signing_key:
|
105
|
+
specification_version: 3
|
106
|
+
summary: Pimp your CHANGELOG.md
|
107
|
+
test_files: []
|
108
|
+
|