Module: Hoe::Git

Defined in:
lib/hoe/git.rb

Overview

This module is a Hoe plugin. You can set its attributes in your Rakefile Hoe spec, like this:

Hoe.plugin :git

Hoe.spec "myproj" do
 self.git_release_tag_prefix  = "REL_"
 self.git_remotes            << "myremote"
end

Tasks

git:changelog:: Print the current changelog. git:manifest:: Update the manifest with Git's file list. git:tag:: Create and push a tag.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#git_changesObject

:nodoc:



35
36
37
# File 'lib/hoe/git.rb', line 35

def git_changes
  @git_changes
end

#git_release_tag_prefixObject

What do you want at the front of your release tags? [default: "v"]



27
28
29
# File 'lib/hoe/git.rb', line 27

def git_release_tag_prefix
  @git_release_tag_prefix
end

#git_remotesObject

Which remotes do you want to push tags, etc. to? [default: %w[ origin ]]



33
34
35
# File 'lib/hoe/git.rb', line 33

def git_remotes
  @git_remotes
end

Instance Method Details

#changelog_section(code) ⇒ Object

Generate and print a changelog section based on the code.



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/hoe/git.rb', line 163

def changelog_section code
  name = +{
    :major   => "major enhancement",
    :minor   => "minor enhancement",
    :bug     => "bug fix",
    :unknown => "unknown",
  }[code]

  changes = git_changes[code]
  count = changes.size
  name += "s" if count > 1
  name.sub!(/fixs/, "fixes")

  return if count < 1

  puts "* #{count} #{name}:"
  puts
  changes.sort.each do |line|
    puts "  * #{line}"
  end
  puts
end

#define_git_tasksObject

:nodoc:



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/hoe/git.rb', line 42

def define_git_tasks # :nodoc:
  return unless File.exist? ".git"

  desc "Print the current changelog."
  task "git:changelog" do
    tag   = ENV["FROM"] || git_tags.last
    range = [tag, "HEAD"].compact.join ".."

    changes = `git log #{range} --format="tformat:%B|||%aN|||%aE|||"`
      .split("|||")
      .each_slice(3)
      .map { |msg, author, email|
        msg.lines(chomp: true).reject(&:empty?)
      }
      .flatten

    next if changes.empty?

    self.git_changes = Hash.new { |h, k| h[k] = [] }

    codes = {
      "!" => :major,
      "+" => :minor,
      "*" => :minor,
      "-" => :bug,
      "?" => :unknown,
    }

    codes_re = Regexp.escape codes.keys.join

    changes.each do |change|
      if change =~ /^\s*([#{codes_re}])\s*(.*)/ then
        code, line = codes[$1], $2
      else
        code, line = codes["?"], change.chomp
      end

      git_changes[code] << line
    end

    now = Time.new.strftime "%Y-%m-%d"

    puts "=== #{ENV["VERSION"] || "NEXT"} / #{now}"
    puts
    changelog_section :major
    changelog_section :minor
    changelog_section :bug
    changelog_section :unknown
    puts
  end

  desc "Update the manifest with Git's file list. Use Hoe's excludes."
  task "git:manifest" do
    with_config do |config, _|
      files = `git ls-files`
        .lines(chomp:true)
        .grep_v(config["exclude"])

      File.write "Manifest.txt", files.sort.join("\n")
    end
  end

  desc "Create and push a TAG " +
       "(default #{git_release_tag_prefix}#{version})."

  task "git:tag" do
    tag = ENV["TAG"]
    ver = ENV["VERSION"] || version
    pre = ENV["PRERELEASE"] || ENV["PRE"]
    ver += ".#{pre}" if pre
    tag ||= "#{git_release_tag_prefix}#{ver}"

    git_tag_and_push tag
  end

  task "git:tags" do
    p git_tags
  end

  task :release_sanity do
    unless ENV["DIRTY"] or `git status --porcelain`.empty?
      abort "Won't release: Dirty index or untracked files present!"
    end
  end

  task :release_to => "git:tag"
end

#git_tag_and_push(tag) ⇒ Object

Generate a tag and push it to all remotes.



133
134
135
136
137
138
139
140
# File 'lib/hoe/git.rb', line 133

def git_tag_and_push tag
  msg = "Tagging #{tag}."

  flags = " -s" unless `git config --get user.signingkey`.empty?

  sh %Q(git tag#{flags} -f #{tag} -m "#{msg}")
  git_remotes.each { |remote| sh "git push -f #{remote} tag #{tag}" }
end

#git_tagsObject

Return all git tags massaged down to readable versions.



145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/hoe/git.rb', line 145

def git_tags
  flags  = %w[--date-order
              --reverse
              --simplify-by-decoration
              --pretty=format:%H].join " "
  shas = `git log #{flags}`.lines(chomp: true)

  `git name-rev --tags #{shas.join " "}`
    .lines
    .map { |s| s[/tags\/(#{git_release_tag_prefix}.+)/, 1] }
    .compact
    .map { |s| s.sub(/\^0$/, "") } # v1.2.3^0 -> v1.2.3 (why?)
    .grep(%r{^#{git_release_tag_prefix}}) # TODO: remove?
end

#initialize_gitObject

:nodoc:



37
38
39
40
# File 'lib/hoe/git.rb', line 37

def initialize_git # :nodoc:
  self.git_release_tag_prefix = "v"
  self.git_remotes            = %w[ origin ]
end