class Rake::Release::Task

Public Class Methods

new(spec = nil, **kwargs, &block) click to toggle source
# File lib/rake/release/task.rb, line 17
def initialize(spec = nil, **kwargs, &block)
  @spec = spec || Rake::Release::Spec.new(spec, **kwargs, &block)

  if @spec.namespace
    send(:namespace, @spec.namespace) { setup }
  else
    setup
  end
end

Protected Class Methods

load_all(dir = pwd, &block) click to toggle source
# File lib/rake/release/task.rb, line 206
def load_all(dir = pwd, &block)
  specs = Spec.scan dir.join('**/*.gemspec')

  specs.each {|spec| spec.namespace = spec.name } if specs.size > 1

  specs.each(&block) if block

  if specs.uniq {|s| s.namespace.to_s.strip }.size != specs.size
    raise 'Non distinct release task namespaces'
  end

  specs.each {|spec| Task.new spec }
end
pwd() click to toggle source
# File lib/rake/release/task.rb, line 220
def pwd
  @pwd ||= Pathname.new Bundler::SharedHelpers.pwd
end
ui() click to toggle source
# File lib/rake/release/task.rb, line 224
def ui
  @ui ||= Bundler::UI::Shell.new
end

Protected Instance Methods

already_tagged?() click to toggle source
# File lib/rake/release/task.rb, line 151
def already_tagged?
  out, = sh 'git', 'tag'

  return false unless out.split(/\n/).include? @spec.version_tag

  Task.ui.confirm "Tag #{@spec.version_tag} has already been created."

  true
end
build() click to toggle source
# File lib/rake/release/task.rb, line 81
def build
  @spec.pkg_path.mkpath

  sh! 'gem', 'build', '-V', @spec.gemspec_path

  @spec.pkg_path.mkpath
  FileUtils.mv @spec.pkg_file_name,
    @spec.pkg_path.join(@spec.pkg_file_name)

  Task.ui.confirm \
    "#{@spec.name} #{@spec.version} built to #{@spec.pkg_path}."
end
clean?() click to toggle source
# File lib/rake/release/task.rb, line 120
def clean?
  _, ret = sh 'git', 'diff', '--exit-code'

  ret.zero?
end
committed?() click to toggle source
# File lib/rake/release/task.rb, line 126
def committed?
  _, ret = sh 'git', 'diff-index', '--quiet', '--cached', 'HEAD'

  ret.zero?
end
git_clean() click to toggle source
# File lib/rake/release/task.rb, line 115
def git_clean
  clean? && committed? ||
    raise('There are files that need to be committed first.')
end
git_push(remote) click to toggle source
# File lib/rake/release/task.rb, line 161
def git_push(remote)
  cmd = %w[git push --quiet]

  cmd << remote unless remote.to_s.empty?

  sh!(*cmd)
  sh!(*cmd, '--tags')

  Task.ui.confirm 'Pushed git commits and tags.'
end
guard_clean() click to toggle source
# File lib/rake/release/task.rb, line 66
def guard_clean
  return if clean? && committed?

  raise 'There are files that need to be committed first.'
end
guard_tag() click to toggle source
# File lib/rake/release/task.rb, line 72
def guard_tag
  out, = sh! 'git', 'tag', '--points-at', 'HEAD'

  return if out.split("\n").include? @spec.version_tag

  raise "Tag #{@spec.version_tag} does not point to current HEAD. " \
        'Will no release wrong code.'
end
install(local: false) click to toggle source
# File lib/rake/release/task.rb, line 94
def install(local: false)
  cmd = %w[gem install] + [@spec.pkg_file_path]
  cmd << '--local' if local

  sh!(*cmd)

  Task.ui.confirm "#{@spec.name} (#{@spec.version}) installed."
end
publish() click to toggle source
# File lib/rake/release/task.rb, line 103
def publish
  cmd = %w[gem push]
  cmd << @spec.pkg_file_path << '--host' << @spec.push_host

  pid = ::Kernel.spawn(*cmd.flatten.map(&:to_s))
  _, status = ::Process.wait2(pid)

  ::Kernel.exit(1) unless status.success?

  Task.ui.confirm "Pushed #{@spec.pkg_file_name} to #{@spec.push_host}"
end
publish?() click to toggle source
# File lib/rake/release/task.rb, line 172
def publish?
  !%w[n no nil false off 0].include?(ENV['gem_push'].to_s.downcase)
end
setup() click to toggle source
# File lib/rake/release/task.rb, line 29
def setup
  desc "Build #{@spec.pkg_file_name}.gem into the pkg directory."
  task(:build) { build }

  desc "Build and install #{@spec.pkg_file_name} into system gems."
  task(install: [:build]) { install }

  desc "Build and install #{@spec.pkg_file_name} into " \
       'system gems without network access.'
  task('install:local' => [:build]) { install local: true }

  if @spec.sign_tag
    desc "Create, sign and push tag #{@spec.version_tag}, " \
         "build gem and publish to #{@spec.push_host_name}."
  else
    desc "Create and push tag #{@spec.version_tag}, " \
         "build gem and publish to #{@spec.push_host_name}."
  end
  task :release, [:remote] => %w[build release:push release:publish]

  task 'release:guard:clean' do
    guard_clean
  end

  task 'release:guard:tag' do
    guard_tag
  end

  task 'release:push', [:remote] => %w[release:guard:clean] do |_, args|
    tag_version { git_push(args[:remote]) } unless already_tagged?
  end

  task 'release:publish' => %w[release:guard:tag] do
    publish if publish?
  end
end
sh(*cmd, chdir: @spec.base) click to toggle source
# File lib/rake/release/task.rb, line 191
def sh(*cmd, chdir: @spec.base)
  cmd = cmd.flatten.map(&:to_s)

  Task.ui.debug cmd

  Open3.popen2(*cmd, chdir: chdir) do |stdin, out, t|
    stdin.close

    status = t.value

    [out.read, status.exitstatus]
  end
end
sh!(*cmd, **kwargs, &block) click to toggle source
# File lib/rake/release/task.rb, line 176
      def sh!(*cmd, **kwargs, &block)
        cmd = cmd.flatten.map(&:to_s)

        out, ret = sh(*cmd, **kwargs, &block)

        if ret != 0
          raise <<~ERROR
            Running `#{cmd}` failed, exit code: #{ret}
              #{out.strip.gsub(/\n/, "\n  ")}
          ERROR
        end

        [out, ret]
      end
tag_version() { || ... } click to toggle source
# File lib/rake/release/task.rb, line 132
def tag_version
  cmd = %w[git tag --annotate]
  cmd << '--sign' if @spec.sign_tag
  cmd << '--message' << "Version #{@spec.version}"
  cmd << @spec.version_tag

  sh!(*cmd)

  Task.ui.confirm "Tagged #{@spec.version_tag}."

  yield if block_given?
rescue StandardError
  Task.ui.error "Untagging #{@spec.version_tag} due to error."

  sh! 'git', 'tag', '-d', @spec.version_tag

  raise
end