lib/tasks/changelog_task.rb in fog-1.21.0 vs lib/tasks/changelog_task.rb in fog-1.22.0
- old
+ new
@@ -6,105 +6,207 @@
class ChangelogTask < ::Rake::TaskLib
def initialize
desc "Update the changelog since the last release"
task(:changelog) do
- timestamp = Time.now.utc.strftime('%m/%d/%Y')
- sha = `git log | head -1`.split(' ').last
- changelog = ["#{Fog::VERSION} #{timestamp} #{sha}"]
- changelog << ('=' * changelog[0].length)
- changelog << ''
- github_repo_data = Fog::JSON.decode(Excon.get('https://api.github.com/repos/fog/fog', :headers => {'User-Agent' => 'geemus'}).body)
- data = github_repo_data.reject {|key, value| !['forks', 'open_issues', 'watchers'].include?(key)}
- github_collaborator_data = Fog::JSON.decode(Excon.get('https://api.github.com/repos/fog/fog/collaborators', :headers => {'User-Agent' => 'geemus'}).body)
- data['collaborators'] = github_collaborator_data.length
- rubygems_data = Fog::JSON.decode(Excon.get('https://rubygems.org/api/v1/gems/fog.json').body)
- data['downloads'] = rubygems_data['downloads']
- stats = []
- for key in data.keys.sort
- stats << "'#{key}' => #{data[key]}"
- end
- changelog << "Stats! { #{stats.join(', ')} }"
- changelog << ''
+ @changelog = []
+ @changelog << release_header
- last_sha = `cat changelog.txt | head -1`.split(' ').last
- shortlog = `git shortlog #{last_sha}..HEAD`
- changes = {}
- committers = {}
- for line in shortlog.split("\n")
- if line =~ /^\S/
- committer = line.split(' (', 2).first
- committers[committer] = 0
- elsif line =~ /^\s*((Merge.*)|(Release.*))?$/
- # skip empty lines, Merge and Release commits
- else
- unless line[-1..-1] == '.'
- line << '.'
- end
- line.lstrip!
- line.gsub!(/^\[([^\]]*)\] /, '')
- tag = $1 || 'misc'
- changes[tag] ||= []
- changes[tag] << (line << ' thanks ' << committer)
- committers[committer] += 1
- end
- end
+ process_commits
- for committer, commits in committers.to_a.sort {|x,y| y[1] <=> x[1]}
- if [
- 'Aaron Suggs',
- 'Ash Wilson',
- 'Brian Hartsock',
- 'Chris Roberts',
- 'Christopher Oliver',
- 'Daniel Reichert',
- 'Decklin Foster',
- 'Dylan Egan',
- 'Erik Michaels-Ober',
- 'geemus',
- 'Henry Addison',
- 'James Bence',
- 'Kevin Menard',
- 'Kevin Olbrich',
- 'Kyle Rames',
- 'Lincoln Stoll',
- 'Luqman Amjad',
- 'Michael Zeng',
- 'Mike Hagedorn',
- 'Mike Pountney',
- 'Nat Welch',
- 'Nick Osborn',
- 'nightshade427',
- 'Patrick Debois',
- 'Paul Thornthwaite',
- 'Rodrigo Estebanez',
- 'Rupak Ganguly',
- 'Stepan G. Fedorov',
- 'Wesley Beary'
- ].include?(committer)
- next
- end
- changelog << "MVP! #{committer}"
- changelog << ''
- break
+ @changelog << "**MVP!** #{mvp}" if mvp
+ @changelog << blank_line
+
+ add_commits_to_changelog
+ save_changelog
+ end
+ end
+
+ private
+
+ def release_header
+ <<-HEREDOC
+## #{Fog::VERSION} #{timestamp}
+*Hash* #{sha}
+
+Statistic | Value
+------------- | --------:
+Collaborators | #{collaborators}
+Downloads | #{downloads}
+Forks | #{forks}
+Open Issues | #{open_issues}
+Watchers | #{watchers}
+ HEREDOC
+ end
+
+ def save_changelog
+ old_changelog = File.read('CHANGELOG.md')
+ File.open('CHANGELOG.md', 'w') do |file|
+ file.write(@changelog.join("\n"))
+ file.write("\n\n")
+ file.write(old_changelog)
+ end
+ end
+
+ def blank_line
+ ''
+ end
+
+ def add_commits_to_changelog
+ @changes.keys.sort.each do |tag|
+ @changelog << "#### [#{tag}]"
+ @changes[tag].each do |commit|
+ @changelog << "* #{commit}"
end
+ @changelog << blank_line
+ end
+ end
- for tag in changes.keys.sort
- changelog << ('[' << tag << ']')
- for commit in changes[tag]
- changelog << (' ' << commit)
- end
- changelog << ''
+ def process_commits
+ shortlog = `git shortlog #{last_release_sha}..HEAD`
+ @changes = {}
+ @committers = {}
+ @committer = nil
+ shortlog.split("\n").each do |line|
+ @current_line = line
+ if committer_line?
+ @committer = committer_match[1]
+ add_committer
+ elsif !release_merge_line?
+ add_period_if_necessary
+ @current_line.lstrip!
+ add_commit_line
+ increment_commits
end
+ end
+ end
- old_changelog = File.read('changelog.txt')
- File.open('changelog.txt', 'w') do |file|
- file.write(changelog.join("\n"))
- file.write("\n\n")
- file.write(old_changelog)
+ def add_commit_line
+ @current_line.gsub!(/^\[([^\]]*)\] /, '')
+ tag = $1 || 'misc'
+ @changes[tag] ||= []
+ @changes[tag] << "#{@current_line} thanks #{@committer}"
+ end
+
+ def increment_commits
+ @committers[@committer] += 1
+ end
+
+ def add_committer
+ @committers[@committer] = 0
+ end
+
+ def committers_sorted_by_commits
+ committer_pairs = @committers.to_a.sort {|x,y| y[1] <=> x[1]}
+ committer_pairs.reject! {|pair| pair.last < 1 }
+ committer_pairs.collect {|pair| pair.first }
+ end
+
+ def former_mvp?(committer)
+ [
+ 'Aaron Suggs',
+ 'Ash Wilson',
+ 'Benson Kalahar',
+ 'Brian Hartsock',
+ 'Chris Roberts',
+ 'Christopher Oliver',
+ 'Daniel Reichert',
+ 'Decklin Foster',
+ 'Dylan Egan',
+ 'Erik Michaels-Ober',
+ 'geemus',
+ 'Henry Addison',
+ 'James Bence',
+ 'Kevin Menard',
+ 'Kevin Olbrich',
+ 'Kyle Rames',
+ 'Lincoln Stoll',
+ 'Luqman Amjad',
+ 'Michael Zeng',
+ 'Mike Hagedorn',
+ 'Mike Pountney',
+ 'Nat Welch',
+ 'Nick Osborn',
+ 'nightshade427',
+ 'Patrick Debois',
+ 'Paul Thornthwaite',
+ 'Rodrigo Estebanez',
+ 'Rupak Ganguly',
+ 'Stepan G. Fedorov',
+ 'Wesley Beary'
+ ].include?(committer)
+ end
+
+ def mvp
+ return @mvp if @mvp
+ committers_sorted_by_commits.each do |committer|
+ unless former_mvp?(committer)
+ @mvp = committer
+ return @mvp
end
end
+ nil
end
+
+ def add_period_if_necessary
+ @current_line << "." unless @current_line[-1] == '.'
+ end
+
+ def release_merge_line?
+ @current_line =~ /^\s*((Merge.*)|(Release.*))?$/
+ end
+
+ def committer_line?
+ committer_match != nil
+ end
+
+ def committer_match
+ @current_line.match /([\w\s]+)\s+\(\d+\)/
+ end
+
+ def last_release_sha
+ `cat changelog.md | head -2`.split(' ').last
+ end
+
+ def downloads
+ repsonse = Excon.get('https://rubygems.org/api/v1/gems/fog.json')
+ data = Fog::JSON.decode(repsonse.body)
+ data['downloads']
+ end
+
+ def collaborators
+ response = Excon.get('https://api.github.com/repos/fog/fog/collaborators', :headers => {'User-Agent' => 'geemus'})
+ data = Fog::JSON.decode(response.body)
+ data.length
+ end
+
+ def forks
+ repo_metadata['forks']
+ end
+
+ def open_issues
+ repo_metadata['open_issues']
+ end
+
+ def watchers
+ repo_metadata['watchers']
+ end
+
+ def repo_metadata
+ return @repo_metadata if @repo_metadata
+ response = Excon.get('https://api.github.com/repos/fog/fog', :headers => {'User-Agent' => 'geemus'})
+ data = Fog::JSON.decode(response.body)
+ @repo_metadata = data.select {|key, value| ['forks', 'open_issues', 'watchers'].include?(key)}
+ end
+
+ def sha
+ `git log | head -1`.split(' ').last
+ end
+
+ def timestamp
+ @time ||= Time.now.utc.strftime('%m/%d/%Y')
+ end
+
end
end
end