github_changelog_generator 0.0.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 +7 -0
- data/bin/github_changelog_generator +5 -0
- data/lib/github_changelog_generator.rb +205 -0
- data/lib/github_changelog_generator/parser.rb +55 -0
- metadata +75 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f85f1c07a9a8a62875a705a096a6defec31a8e39
|
4
|
+
data.tar.gz: 0f32a943be2acba4387df7016ac10654b1f6976e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7d10d9c8610a5ce8a27156b6c14f483965c9e4273724a989bc8af1cb6df3e3044a7af50799b2cc92ce82ad281171e6460effc887e204b47ef1f7410a60e1db71
|
7
|
+
data.tar.gz: c804a7f77d45628fe26087db70bc5694af73033c287bac402e28b69be606c82a56a37fe94063960da7636367704152700032c766b0deb531581b567e7708df07
|
@@ -0,0 +1,205 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'github_api'
|
4
|
+
require 'json'
|
5
|
+
require 'httparty'
|
6
|
+
require_relative 'github_changelog_generator/parser'
|
7
|
+
|
8
|
+
|
9
|
+
class ChangelogGenerator
|
10
|
+
|
11
|
+
attr_accessor :options, :all_tags
|
12
|
+
|
13
|
+
def initialize()
|
14
|
+
|
15
|
+
@options = Parser.parse_options
|
16
|
+
if @options[:token]
|
17
|
+
@github = Github.new oauth_token: @options[:token]
|
18
|
+
else
|
19
|
+
@github = Github.new
|
20
|
+
end
|
21
|
+
@all_tags = self.get_all_tags
|
22
|
+
@pull_requests = self.get_all_closed_pull_requests
|
23
|
+
|
24
|
+
@tag_times_hash = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def print_json(json)
|
28
|
+
puts JSON.pretty_generate(json)
|
29
|
+
end
|
30
|
+
|
31
|
+
def exec_command(cmd)
|
32
|
+
exec_cmd = "cd #{$project_path} && #{cmd}"
|
33
|
+
%x[#{exec_cmd}]
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def get_all_closed_pull_requests
|
38
|
+
|
39
|
+
|
40
|
+
issues = @github.pull_requests.list @options[:user], @options[:project], :state => 'closed'
|
41
|
+
json = issues.body
|
42
|
+
|
43
|
+
if @options[:verbose]
|
44
|
+
puts 'Receive all pull requests'
|
45
|
+
end
|
46
|
+
|
47
|
+
json
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
def compund_changelog
|
52
|
+
if @options[:verbose]
|
53
|
+
puts 'Generating changelog:'
|
54
|
+
end
|
55
|
+
|
56
|
+
log = "# Changelog\n\n"
|
57
|
+
|
58
|
+
if @options[:last]
|
59
|
+
log += self.generate_log_between_tags(self.all_tags[0], self.all_tags[1])
|
60
|
+
elsif @options[:tag1] && @options[:tag2]
|
61
|
+
|
62
|
+
tag1 = @options[:tag1]
|
63
|
+
tag2 = @options[:tag2]
|
64
|
+
tags_strings = []
|
65
|
+
self.all_tags.each { |x| tags_strings.push(x['name'])}
|
66
|
+
|
67
|
+
if tags_strings.include?(tag1)
|
68
|
+
if tags_strings.include?(tag2)
|
69
|
+
hash = Hash[tags_strings.map.with_index.to_a]
|
70
|
+
index1 = hash[tag1]
|
71
|
+
index2 = hash[tag2]
|
72
|
+
log += self.generate_log_between_tags(self.all_tags[index1], self.all_tags[index2])
|
73
|
+
else
|
74
|
+
puts "Can't find tag #{tag2} -> exit"
|
75
|
+
exit
|
76
|
+
end
|
77
|
+
else
|
78
|
+
puts "Can't find tag #{tag1} -> exit"
|
79
|
+
exit
|
80
|
+
end
|
81
|
+
else
|
82
|
+
log += self.generate_log_for_all_tags
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
if @options[:verbose]
|
87
|
+
puts log
|
88
|
+
end
|
89
|
+
|
90
|
+
output_filename = "#{@options[:project]}_changelog.md"
|
91
|
+
File.open(output_filename, 'w') { |file| file.write(log) }
|
92
|
+
|
93
|
+
puts "Done! Generated log placed in #{output_filename}"
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
def generate_log_for_all_tags
|
98
|
+
log = ''
|
99
|
+
for index in 1 ... self.all_tags.size
|
100
|
+
log += self.generate_log_between_tags(self.all_tags[index-1], self.all_tags[index])
|
101
|
+
end
|
102
|
+
|
103
|
+
log
|
104
|
+
end
|
105
|
+
|
106
|
+
def is_megred(number)
|
107
|
+
@github.pull_requests.merged? @options[:user], @options[:project], number
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_all_merged_pull_requests
|
111
|
+
json = self.get_all_closed_pull_requests
|
112
|
+
puts 'Check if the requests is merged... (it can take a while)'
|
113
|
+
|
114
|
+
json.delete_if { |req|
|
115
|
+
merged = self.is_megred(req[:number])
|
116
|
+
if @options[:verbose]
|
117
|
+
puts "##{req[:number]} #{merged ? 'merged' : 'not merged'}"
|
118
|
+
end
|
119
|
+
!merged
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
def get_all_tags
|
124
|
+
|
125
|
+
url = "https://api.github.com/repos/#{@options[:user]}/#{@options[:project]}/tags"
|
126
|
+
|
127
|
+
if @options[:verbose]
|
128
|
+
puts "Receive tags for repo #{url}"
|
129
|
+
end
|
130
|
+
|
131
|
+
response = HTTParty.get(url,
|
132
|
+
:headers => {'Authorization' => 'token 8587bb22f6bf125454768a4a19dbcc774ea68d48',
|
133
|
+
'User-Agent' => 'Changelog-Generator'})
|
134
|
+
|
135
|
+
json_parse = JSON.parse(response.body)
|
136
|
+
|
137
|
+
if @options[:verbose]
|
138
|
+
puts "Found #{json_parse.count} tags"
|
139
|
+
end
|
140
|
+
|
141
|
+
json_parse
|
142
|
+
end
|
143
|
+
|
144
|
+
def generate_log_between_tags(since_tag, till_tag)
|
145
|
+
since_tag_time = self.get_time_of_tag(since_tag)
|
146
|
+
till_tag_time = self.get_time_of_tag(till_tag)
|
147
|
+
|
148
|
+
# if we mix up tags order - lits fix it!
|
149
|
+
if since_tag_time > till_tag_time
|
150
|
+
since_tag, till_tag = till_tag, since_tag
|
151
|
+
since_tag_time, till_tag_time = till_tag_time, since_tag_time
|
152
|
+
end
|
153
|
+
|
154
|
+
till_tag_name = till_tag['name']
|
155
|
+
|
156
|
+
pull_requests = Array.new(@pull_requests)
|
157
|
+
|
158
|
+
pull_requests.delete_if { |req|
|
159
|
+
t = Time.parse(req[:closed_at]).utc
|
160
|
+
true_classor_false_class = t > since_tag_time
|
161
|
+
classor_false_class = t < till_tag_time
|
162
|
+
|
163
|
+
in_range = (true_classor_false_class) && (classor_false_class)
|
164
|
+
!in_range
|
165
|
+
}
|
166
|
+
|
167
|
+
self.create_log(pull_requests, till_tag_name, till_tag_time)
|
168
|
+
end
|
169
|
+
|
170
|
+
def create_log(pull_requests, tag_name, tag_time)
|
171
|
+
|
172
|
+
trimmed_tag = tag_name.tr('v', '')
|
173
|
+
log = "## [#{trimmed_tag}] (https://github.com/#{@options[:user]}/#{@options[:project]}/tree/#{tag_name})\n"
|
174
|
+
|
175
|
+
time_string = tag_time.strftime @options[:format]
|
176
|
+
log += "#### #{time_string}\n"
|
177
|
+
|
178
|
+
pull_requests.each { |dict|
|
179
|
+
merge = "#{dict[:title]} [\\##{dict[:number]}](https://github.com/#{@options[:user]}/#{@options[:project]}/pull/#{dict[:number]})\n\n"
|
180
|
+
log += "- #{merge}"
|
181
|
+
}
|
182
|
+
log
|
183
|
+
end
|
184
|
+
|
185
|
+
def get_time_of_tag(prev_tag)
|
186
|
+
|
187
|
+
if @tag_times_hash[prev_tag['name']]
|
188
|
+
return @tag_times_hash[prev_tag['name']]
|
189
|
+
end
|
190
|
+
|
191
|
+
if @options[:verbose]
|
192
|
+
puts "Get time for tag #{prev_tag['name']}"
|
193
|
+
end
|
194
|
+
|
195
|
+
github_git_data_commits_get = @github.git_data.commits.get @options[:user], @options[:project], prev_tag['commit']['sha']
|
196
|
+
time_string = github_git_data_commits_get['committer']['date']
|
197
|
+
Time.parse(time_string)
|
198
|
+
@tag_times_hash[prev_tag['name']] = Time.parse(time_string)
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
if __FILE__ == $0
|
204
|
+
ChangelogGenerator.new.compund_changelog
|
205
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
class Parser
|
5
|
+
def self.parse_options
|
6
|
+
options = {:tag1 => nil, :tag2 => nil, :format => '%d/%m/%y'}
|
7
|
+
|
8
|
+
parser = OptionParser.new { |opts|
|
9
|
+
opts.banner = 'Usage: changelog_generator.rb -u user_name -p project_name [-t 16-digit-GitHubToken] [options]'
|
10
|
+
opts.on('-u', '--user [USER]', 'your username on GitHub') do |last|
|
11
|
+
options[:user] = last
|
12
|
+
end
|
13
|
+
opts.on('-p', '--project [PROJECT]', 'name of project on GitHub') do |last|
|
14
|
+
options[:project] = last
|
15
|
+
end
|
16
|
+
opts.on('-t', '--token [TOKEN]', 'To make more than 50 requests this app required your OAuth token for GitHub. You can generate it on https://github.com/settings/applications') do |last|
|
17
|
+
options[:token] = last
|
18
|
+
end
|
19
|
+
opts.on('-h', '--help', 'Displays Help') do
|
20
|
+
puts opts
|
21
|
+
exit
|
22
|
+
end
|
23
|
+
opts.on('-v', '--[no-]verbose', 'Run verbosely') do |v|
|
24
|
+
options[:verbose] = v
|
25
|
+
end
|
26
|
+
opts.on('-l', '--last-changes', 'generate log between last 2 tags') do |last|
|
27
|
+
options[:last] = last
|
28
|
+
end
|
29
|
+
opts.on('-f', '--date-format [FORMAT]', 'date format. default is %d/%m/%y') do |last|
|
30
|
+
options[:format] = last
|
31
|
+
end
|
32
|
+
}
|
33
|
+
|
34
|
+
parser.parse!
|
35
|
+
|
36
|
+
#udefined case with 1 parameter:
|
37
|
+
if ARGV[0] && !ARGV[1]
|
38
|
+
puts parser.banner
|
39
|
+
exit
|
40
|
+
end
|
41
|
+
|
42
|
+
if !options[:user] || !options[:project]
|
43
|
+
puts parser.banner
|
44
|
+
exit
|
45
|
+
end
|
46
|
+
|
47
|
+
if ARGV[1]
|
48
|
+
options[:tag1] = ARGV[0]
|
49
|
+
options[:tag2] = ARGV[1]
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
options
|
54
|
+
end
|
55
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: github_changelog_generator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Petr Korolev
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: github_api
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.12'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.12'
|
41
|
+
description: Script, that automatically generate change-log from your tags and pull-requests
|
42
|
+
email: sky4winder+github_changelog_generator@gmail.com
|
43
|
+
executables:
|
44
|
+
- github_changelog_generator
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- bin/github_changelog_generator
|
49
|
+
- lib/github_changelog_generator.rb
|
50
|
+
- lib/github_changelog_generator/parser.rb
|
51
|
+
homepage: https://github.com/skywinder/Github-Changelog-Generator
|
52
|
+
licenses:
|
53
|
+
- MIT
|
54
|
+
metadata: {}
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
requirements: []
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 2.2.2
|
72
|
+
signing_key:
|
73
|
+
specification_version: 4
|
74
|
+
summary: Script, that automatically generate change-log from your tags and pull-requests.
|
75
|
+
test_files: []
|