Skip to content

Commit 8dab12c

Browse files
committed
+ Added Hoe::Git plugin, forked from jbarnette/hoe-git + halostatue/hoe-git2
+ Bumped ruby version to 3.2+. + Clarified dependency on rake to ~> 13.0. [git-p4: depot-paths = "//src/hoe/dev/": change = 14804]
1 parent 1598d84 commit 8dab12c

4 files changed

Lines changed: 190 additions & 2 deletions

File tree

Manifest.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ lib/hoe/flay.rb
1515
lib/hoe/flog.rb
1616
lib/hoe/gem_prelude_sucks.rb
1717
lib/hoe/gemcutter.rb
18+
lib/hoe/git.rb
1819
lib/hoe/inline.rb
1920
lib/hoe/newb.rb
2021
lib/hoe/package.rb

README.rdoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ Again, this must be done before the Hoe spec, or it won't be useful.
167167
* Hoe::Flog
168168
* Hoe::GemPreludeSucks
169169
* Hoe::Gemcutter
170+
* Hoe::Git
170171
* Hoe::Inline
171172
* Hoe::Newb
172173
* Hoe::Package

Rakefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ Hoe.spec "hoe" do
1919

2020
pluggable!
2121
require_rubygems_version ">= 3.0"
22-
require_ruby_version [">= 2.7", "< 4"]
22+
require_ruby_version ">= 3.2"
2323

24-
dependency "rake", [">= 0.8", "< 15.0"] # FIX: to force it to exist pre-isolate
24+
dependency "rake", "~> 13.0" # FIX: to force it to exist pre-isolate
2525
end
2626

2727
task :plugins do

lib/hoe/git.rb

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
class Hoe # :nodoc:
2+
3+
##
4+
# This module is a Hoe plugin. You can set its attributes in your
5+
# Rakefile Hoe spec, like this:
6+
#
7+
# Hoe.plugin :git
8+
#
9+
# Hoe.spec "myproj" do
10+
# self.git_release_tag_prefix = "REL_"
11+
# self.git_remotes << "myremote"
12+
# end
13+
#
14+
#
15+
# === Tasks
16+
#
17+
# git:changelog:: Print the current changelog.
18+
# git:manifest:: Update the manifest with Git's file list.
19+
# git:tag:: Create and push a tag.
20+
21+
module Git
22+
23+
##
24+
# What do you want at the front of your release tags?
25+
# [default: <tt>"v"</tt>]
26+
27+
attr_accessor :git_release_tag_prefix
28+
29+
##
30+
# Which remotes do you want to push tags, etc. to?
31+
# [default: <tt>%w[ origin ]</tt>]
32+
33+
attr_accessor :git_remotes
34+
35+
attr_accessor :git_changes # :nodoc:
36+
37+
def initialize_git # :nodoc:
38+
self.git_release_tag_prefix = "v"
39+
self.git_remotes = %w[ origin ]
40+
end
41+
42+
def define_git_tasks # :nodoc:
43+
return unless File.exist? ".git"
44+
45+
desc "Print the current changelog."
46+
task "git:changelog" do
47+
tag = ENV["FROM"] || git_tags.last
48+
range = [tag, "HEAD"].compact.join ".."
49+
50+
changes = `git log #{range} --format="tformat:%B|||%aN|||%aE|||"`
51+
.split("|||")
52+
.each_slice(3)
53+
.map { |msg, author, email|
54+
msg.lines(chomp: true).reject(&:empty?)
55+
}
56+
.flatten
57+
58+
next if changes.empty?
59+
60+
self.git_changes = Hash.new { |h, k| h[k] = [] }
61+
62+
codes = {
63+
"!" => :major,
64+
"+" => :minor,
65+
"*" => :minor,
66+
"-" => :bug,
67+
"?" => :unknown,
68+
}
69+
70+
codes_re = Regexp.escape codes.keys.join
71+
72+
changes.each do |change|
73+
if change =~ /^\s*([#{codes_re}])\s*(.*)/ then
74+
code, line = codes[$1], $2
75+
else
76+
code, line = codes["?"], change.chomp
77+
end
78+
79+
git_changes[code] << line
80+
end
81+
82+
now = Time.new.strftime "%Y-%m-%d"
83+
84+
puts "=== #{ENV["VERSION"] || "NEXT"} / #{now}"
85+
puts
86+
changelog_section :major
87+
changelog_section :minor
88+
changelog_section :bug
89+
changelog_section :unknown
90+
puts
91+
end
92+
93+
desc "Update the manifest with Git's file list. Use Hoe's excludes."
94+
task "git:manifest" do
95+
with_config do |config, _|
96+
files = `git ls-files`
97+
.lines(chomp:true)
98+
.grep_v(config["exclude"])
99+
100+
File.write "Manifest.txt", files.sort.join("\n")
101+
end
102+
end
103+
104+
desc "Create and push a TAG " +
105+
"(default #{git_release_tag_prefix}#{version})."
106+
107+
task "git:tag" do
108+
tag = ENV["TAG"]
109+
ver = ENV["VERSION"] || version
110+
pre = ENV["PRERELEASE"] || ENV["PRE"]
111+
ver += ".#{pre}" if pre
112+
tag ||= "#{git_release_tag_prefix}#{ver}"
113+
114+
git_tag_and_push tag
115+
end
116+
117+
task "git:tags" do
118+
p git_tags
119+
end
120+
121+
task :release_sanity do
122+
unless ENV["DIRTY"] or `git status --porcelain`.empty?
123+
abort "Won't release: Dirty index or untracked files present!"
124+
end
125+
end
126+
127+
task :release_to => "git:tag"
128+
end
129+
130+
##
131+
# Generate a tag and push it to all remotes.
132+
133+
def git_tag_and_push tag
134+
msg = "Tagging #{tag}."
135+
136+
flags = " -s" unless `git config --get user.signingkey`.empty?
137+
138+
sh %Q(git tag#{flags} -f #{tag} -m "#{msg}")
139+
git_remotes.each { |remote| sh "git push -f #{remote} tag #{tag}" }
140+
end
141+
142+
##
143+
# Return all git tags massaged down to readable versions.
144+
145+
def git_tags
146+
flags = %w[--date-order
147+
--reverse
148+
--simplify-by-decoration
149+
--pretty=format:%H].join " "
150+
shas = `git log #{flags}`.lines(chomp: true)
151+
152+
`git name-rev --tags #{shas.join " "}`
153+
.lines
154+
.map { |s| s[/tags\/(#{git_release_tag_prefix}.+)/, 1] }
155+
.compact
156+
.map { |s| s.sub(/\^0$/, "") } # v1.2.3^0 -> v1.2.3 (why?)
157+
.grep(%r{^#{git_release_tag_prefix}}) # TODO: remove?
158+
end
159+
160+
##
161+
# Generate and print a changelog section based on the +code+.
162+
163+
def changelog_section code
164+
name = +{
165+
:major => "major enhancement",
166+
:minor => "minor enhancement",
167+
:bug => "bug fix",
168+
:unknown => "unknown",
169+
}[code]
170+
171+
changes = git_changes[code]
172+
count = changes.size
173+
name += "s" if count > 1
174+
name.sub!(/fixs/, "fixes")
175+
176+
return if count < 1
177+
178+
puts "* #{count} #{name}:"
179+
puts
180+
changes.sort.each do |line|
181+
puts " * #{line}"
182+
end
183+
puts
184+
end
185+
end
186+
end

0 commit comments

Comments
 (0)