Class: Bake::Gem::Helper
- Inherits:
-
Object
- Object
- Bake::Gem::Helper
- Includes:
- Shell
- Defined in:
- lib/bake/gem/helper.rb
Overview
Helper class for performing gem-related operations like building, installing, and publishing gems.
Instance Attribute Summary collapse
-
#gemspec ⇒ Object
readonly
Returns the value of attribute gemspec.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
- #The root directory of the gem project.(rootdirectoryofthegemproject.) ⇒ Object readonly
Instance Method Summary collapse
- #build_gem(root: "pkg", signing_key: nil) ⇒ Object
-
#build_gem_in_worktree(root: "pkg", signing_key: nil) ⇒ Object
Build the gem in a clean worktree for better isolation.
-
#commit_version_changes(message: "Bump version.") ⇒ Object
Commit version changes to the current branch.
-
#create_release_branch(version_path, message: "Bump version.") ⇒ Object
Create a release branch, add the version file, and commit the changes.
-
#create_release_tag(tag: true, version:) ⇒ Object
Fetch remote tags and create a release tag for the specified version.
-
#current_branch ⇒ Object
Figure out if there is a current branch, if not, return ‘nil`.
-
#delete_git_tag(tag_name) ⇒ Object
Delete a git tag.
-
#find_gemspec(glob = "*.gemspec") ⇒ Object
Find a gemspec file in the root directory.
-
#guard_clean ⇒ Object
Verify that the repository has no uncommitted changes.
-
#guard_last_commit_not_version_bump ⇒ Object
Verify that the last commit was not a version bump.
-
#initialize(root = Dir.pwd, gemspec: nil) ⇒ Helper
constructor
Initialize a new helper with the specified root directory and optional gemspec.
-
#install_gem(*arguments, path: @gemspec.file_name) ⇒ Object
Install the gem using the ‘gem install` command.
-
#push_gem(*arguments, path: @gemspec.file_name) ⇒ Object
Push the gem to a gem repository using the ‘gem push` command.
-
#push_release(current_branch: nil) ⇒ Object
Push changes and tags to the remote repository.
- #The gemspec for the gem.=(gemspec) ⇒ Object
-
#uncommitted_changes ⇒ Object
Get the list of uncommitted changes in the repository.
-
#update_version(bump, version_path = self.version_path) ⇒ Object
Update the version number in the version file according to the bump specification.
-
#version_path ⇒ Object
Find the path to the version.rb file in the gem.
Methods included from Shell
Constructor Details
Instance Attribute Details
#gemspec ⇒ Object (readonly)
Returns the value of attribute gemspec.
100 101 102 |
# File 'lib/bake/gem/helper.rb', line 100 def gemspec @gemspec end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
97 98 99 |
# File 'lib/bake/gem/helper.rb', line 97 def root @root end |
#The root directory of the gem project.(rootdirectoryofthegemproject.) ⇒ Object (readonly)
97 |
# File 'lib/bake/gem/helper.rb', line 97 attr :root |
Instance Method Details
#build_gem(root: "pkg", signing_key: nil) ⇒ Object
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/bake/gem/helper.rb', line 195 def build_gem(root: "pkg", signing_key: nil) # Ensure the output directory exists: FileUtils.mkdir_p(root) output_path = File.join(root, @gemspec.file_name) if signing_key == false @gemspec.signing_key = nil elsif signing_key.is_a?(String) @gemspec.signing_key = signing_key elsif signing_key == true and @gemspec.signing_key.nil? raise ArgumentError, "Signing key is required for signing the gem, but none was specified by the gemspec." end ::Gem::Package.build(@gemspec, false, false, output_path) end |
#build_gem_in_worktree(root: "pkg", signing_key: nil) ⇒ Object
Build the gem in a clean worktree for better isolation
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/bake/gem/helper.rb', line 230 def build_gem_in_worktree(root: "pkg", signing_key: nil) original_pkg_path = File.join(@root, root) # Create a unique temporary path for the worktree = Time.now.strftime("%Y%m%d-%H%M%S-%N") worktree_path = File.join(Dir.tmpdir, "bake-gem-build-#{}") begin # Create worktree from current HEAD unless system("git", "worktree", "add", worktree_path, "HEAD", chdir: @root) raise "Failed to create git worktree. Make sure you have at least one commit in the repository." end # Create helper for the worktree worktree_helper = self.class.new(worktree_path) # Build gem directly into the target pkg directory output_path = worktree_helper.build_gem(root: original_pkg_path, signing_key: signing_key) output_path ensure # Clean up the worktree system("git", "worktree", "remove", worktree_path, "--force", chdir: @root) end end |
#commit_version_changes(message: "Bump version.") ⇒ Object
Commit version changes to the current branch.
272 273 274 275 |
# File 'lib/bake/gem/helper.rb', line 272 def commit_version_changes(message: "Bump version.") system("git", "add", "--all", chdir: @root) system("git", "commit", "-m", , chdir: @root) end |
#create_release_branch(version_path, message: "Bump version.") ⇒ Object
Create a release branch, add the version file, and commit the changes.
260 261 262 263 264 265 266 267 268 |
# File 'lib/bake/gem/helper.rb', line 260 def create_release_branch(version_path, message: "Bump version.") branch_name = "release-v#{@gemspec.version}" system("git", "checkout", "-b", branch_name, chdir: @root) system("git", "add", version_path, chdir: @root) system("git", "commit", "-m", , chdir: @root) return branch_name end |
#create_release_tag(tag: true, version:) ⇒ Object
Fetch remote tags and create a release tag for the specified version.
281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/bake/gem/helper.rb', line 281 def create_release_tag(tag: true, version:) tag_name = nil if tag tag_name = "v#{version}" system("git", "fetch", "--all", "--tags", chdir: @root) system("git", "tag", tag_name, chdir: @root) end return tag_name end |
#current_branch ⇒ Object
Figure out if there is a current branch, if not, return ‘nil`.
312 313 314 315 316 317 318 319 |
# File 'lib/bake/gem/helper.rb', line 312 def current_branch # We originally used this but it is not supported by older versions of git. # readlines("git", "branch", "--show-current").first&.chomp readlines("git", "symbolic-ref", "--short", "--quiet", "HEAD", chdir: @root).first&.chomp rescue CommandExecutionError nil end |
#delete_git_tag(tag_name) ⇒ Object
Delete a git tag.
295 296 297 |
# File 'lib/bake/gem/helper.rb', line 295 def delete_git_tag(tag_name) system("git", "tag", "--delete", tag_name, chdir: @root) end |
#find_gemspec(glob = "*.gemspec") ⇒ Object
Find a gemspec file in the root directory.
325 326 327 328 329 330 331 332 333 334 335 |
# File 'lib/bake/gem/helper.rb', line 325 def find_gemspec(glob = "*.gemspec") paths = Dir.glob(glob, base: @root).sort if paths.size > 1 raise "Multiple gemspecs found: #{paths}, please specify one!" end if path = paths.first return ::Gem::Specification.load(File.(path, @root)) end end |
#guard_clean ⇒ Object
Verify that the repository has no uncommitted changes.
153 154 155 156 157 158 159 160 161 |
# File 'lib/bake/gem/helper.rb', line 153 def guard_clean lines = uncommitted_changes if lines.any? raise "Repository has uncommited changes!\n#{lines.join('')}" end return true end |
#guard_last_commit_not_version_bump ⇒ Object
Verify that the last commit was not a version bump.
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/bake/gem/helper.rb', line 172 def guard_last_commit_not_version_bump # Get the last commit message: begin = readlines("git", "log", "-1", "--pretty=format:%s", chdir: @root).first&.strip rescue CommandExecutionError => error # If git log fails (e.g., no commits yet), skip the check: if error.exit_code == 128 return true else raise end end if && .match?(/^Bump (patch|minor|major|version)( version)?\.?$/i) raise "Last commit appears to be a version bump: #{.inspect}. Cannot bump version consecutively." end return true end |
#install_gem(*arguments, path: @gemspec.file_name) ⇒ Object
Install the gem using the ‘gem install` command.
215 216 217 |
# File 'lib/bake/gem/helper.rb', line 215 def install_gem(*arguments, path: @gemspec.file_name) system("gem", "install", path, *arguments) end |
#push_gem(*arguments, path: @gemspec.file_name) ⇒ Object
Push the gem to a gem repository using the ‘gem push` command.
222 223 224 |
# File 'lib/bake/gem/helper.rb', line 222 def push_gem(*arguments, path: @gemspec.file_name) system("gem", "push", path, *arguments) end |
#push_release(current_branch: nil) ⇒ Object
Push changes and tags to the remote repository.
301 302 303 304 305 306 307 308 |
# File 'lib/bake/gem/helper.rb', line 301 def push_release(current_branch: nil) # If we are on a branch, push, otherwise just push the tags (assuming shallow checkout): if current_branch system("git", "push", chdir: @root) end system("git", "push", "--tags", chdir: @root) end |
#The gemspec for the gem.=(gemspec) ⇒ Object
100 |
# File 'lib/bake/gem/helper.rb', line 100 attr :gemspec |
#uncommitted_changes ⇒ Object
Get the list of uncommitted changes in the repository.
165 166 167 |
# File 'lib/bake/gem/helper.rb', line 165 def uncommitted_changes readlines("git", "status", "--porcelain", chdir: @root) end |
#update_version(bump, version_path = self.version_path) ⇒ Object
Update the version number in the version file according to the bump specification.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/bake/gem/helper.rb', line 124 def update_version(bump, version_path = self.version_path) return false unless version_path # Guard against consecutive version bumps guard_last_commit_not_version_bump lines = File.readlines(version_path) new_version = nil lines.each do |line| Version.update_version(line) do |version| new_version = version.increment(bump) end end if new_version File.write(version_path, lines.join) if block_given? yield new_version end return version_path end end |
#version_path ⇒ Object
Find the path to the version.rb file in the gem.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/bake/gem/helper.rb', line 104 def version_path if @gemspec candidates = @gemspec.files.grep(/lib(.*?)\/version.rb/) # If only one version file exists, use it: return candidates.first if candidates.size == 1 # Try to match the gem name convention (e.g., "protocol-rack" -> "lib/protocol/rack/version.rb"): expected_path = "lib/#{@gemspec.name.gsub('-', '/')}/version.rb" return expected_path if candidates.include?(expected_path) # Fall back to the shortest path (most likely to be the main gem version): return candidates.min_by(&:length) end end |