github_changelog_generator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'github_changelog_generator'
4
+
5
+ ChangelogGenerator.new.compund_changelog
@@ -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: []