# frozen_string_literal: truerequire_relative"../bundler"require"shellwords"moduleBundlerclassGemHelperincludeRake::DSLifdefined?Rake::DSLclass<<self# set when install'd.attr_accessor:instancedefinstall_tasks(opts={})new(opts[:dir],opts[:name]).installenddeftag_prefix=(prefix)instance.tag_prefix=prefixenddefgemspec(&block)gemspec=instance.gemspecblock.call(gemspec)ifblockgemspecendendattr_reader:spec_path,:base,:gemspecattr_writer:tag_prefixdefinitialize(base=nil,name=nil)@base=File.expand_path(base||SharedHelpers.pwd)gemspecs=name?[File.join(@base,"#{name}.gemspec")]:Gem::Util.glob_files_in_dir("{,*}.gemspec",@base)raise"Unable to determine name from existing gemspec. Use :name => 'gemname' in #install_tasks to manually set it."unlessgemspecs.size==1@spec_path=gemspecs.first@gemspec=Bundler.load_gemspec(@spec_path)@tag_prefix=""enddefinstallbuilt_gem_path=nildesc"Build #{name}-#{version}.gem into the pkg directory."task"build"dobuilt_gem_path=build_gemenddesc"Generate SHA512 checksum if #{name}-#{version}.gem into the checksums directory."task"build:checksum"=>"build"dobuild_checksum(built_gem_path)enddesc"Build and install #{name}-#{version}.gem into system gems."task"install"=>"build"doinstall_gem(built_gem_path)enddesc"Build and install #{name}-#{version}.gem into system gems without network access."task"install:local"=>"build"doinstall_gem(built_gem_path,:local)enddesc"Create tag #{version_tag} and build and push #{name}-#{version}.gem to #{gem_push_host}\n"\"To prevent publishing in RubyGems use `gem_push=no rake release`"task"release",[:remote]=>["build","release:guard_clean","release:source_control_push","release:rubygem_push"]doendtask"release:guard_clean"doguard_cleanendtask"release:source_control_push",[:remote]do|_,args|tag_version{git_push(args[:remote])}unlessalready_tagged?endtask"release:rubygem_push"=>"build"dorubygem_push(built_gem_path)ifgem_push?endGemHelper.instance=selfenddefbuild_gemfile_name=nilsh([*gem_command,"build","-V",spec_path])dofile_name=File.basename(built_gem_path)SharedHelpers.filesystem_access(File.join(base,"pkg")){|p|FileUtils.mkdir_p(p)}FileUtils.mv(built_gem_path,"pkg")Bundler.ui.confirm"#{name}#{version} built to pkg/#{file_name}."endFile.join(base,"pkg",file_name)enddefinstall_gem(built_gem_path=nil,local=false)built_gem_path||=build_gemcmd=[*gem_command,"install",built_gem_path.to_s]cmd<<"--local"iflocalsh(cmd)Bundler.ui.confirm"#{name} (#{version}) installed."enddefbuild_checksum(built_gem_path=nil)built_gem_path||=build_gemSharedHelpers.filesystem_access(File.join(base,"checksums")){|p|FileUtils.mkdir_p(p)}file_name="#{File.basename(built_gem_path)}.sha512"require"digest/sha2"checksum=::Digest::SHA512.new.hexdigest(built_gem_path.to_s)target=File.join(base,"checksums",file_name)File.write(target,checksum)Bundler.ui.confirm"#{name}#{version} checksum written to checksums/#{file_name}."endprotecteddefrubygem_push(path)cmd=[*gem_command,"push",path]cmd<<"--key"<<gem_keyifgem_keycmd<<"--host"<<allowed_push_hostifallowed_push_hostsh_with_input(cmd)Bundler.ui.confirm"Pushed #{name}#{version} to #{gem_push_host}"enddefbuilt_gem_pathGem::Util.glob_files_in_dir("#{name}-*.gem",base).sort_by{|f|File.mtime(f)}.lastenddefgit_push(remote=nil)remote||=default_remotesh(%W[git push #{remote} refs/heads/#{current_branch}])sh(%W[git push #{remote} refs/tags/#{version_tag}])Bundler.ui.confirm"Pushed git commits and release tag."enddefdefault_remoteremote_for_branch,status=sh_with_status(%W[git config --get branch.#{current_branch}.remote])return"origin"unlessstatus.success?remote_for_branch.stripenddefcurrent_branch# We can replace this with `git branch --show-current` once we drop support for git < 2.22.0sh(%w[git rev-parse --abbrev-ref HEAD]).gsub(%r{\Aheads/},"").stripenddefallowed_push_host@gemspec.metadata["allowed_push_host"]if@gemspec.respond_to?(:metadata)enddefgem_push_hostenv_rubygems_host=ENV["RUBYGEMS_HOST"]env_rubygems_host=nilifenv_rubygems_host&&env_rubygems_host.empty?allowed_push_host||env_rubygems_host||"rubygems.org"enddefalready_tagged?returnfalseunlesssh(%w[git tag]).split(/\n/).include?(version_tag)Bundler.ui.confirm"Tag #{version_tag} has already been created."trueenddefguard_cleanclean?&&committed?||raise("There are files that need to be committed first.")enddefclean?sh_with_status(%w[git diff --exit-code])[1].success?enddefcommitted?sh_with_status(%w[git diff-index --quiet --cached HEAD])[1].success?enddeftag_versionsh%W[git tag -m Version\ #{version}#{version_tag}]Bundler.ui.confirm"Tagged #{version_tag}."yieldifblock_given?rescueRuntimeErrorBundler.ui.error"Untagging #{version_tag} due to error."sh_with_status%W[git tag -d #{version_tag}]raiseenddefversiongemspec.versionenddefversion_tag"#{@tag_prefix}v#{version}"enddefnamegemspec.nameenddefsh_with_input(cmd)Bundler.ui.debug(cmd)SharedHelpers.chdir(base)doabortunlessKernel.system(*cmd)endenddefsh(cmd,&block)out,status=sh_with_status(cmd,&block)unlessstatus.success?raise("Running `#{cmd.shelljoin}` failed with the following output:\n\n#{out}\n")endoutenddefsh_with_status(cmd,&block)Bundler.ui.debug(cmd)SharedHelpers.chdir(base)dooutbuf=IO.popen(cmd,:err=>[:child,:out],&:read)status=$?block.call(outbuf)ifstatus.success?&&block[outbuf,status]endenddefgem_keyBundler.settings["gem.push_key"].to_s.downcaseifBundler.settings["gem.push_key"]enddefgem_push?!%w[n no nil false off 0].include?(ENV["gem_push"].to_s.downcase)enddefgem_commandENV["GEM_COMMAND"]&.shellsplit||["gem"]endendend