class GemHadar

Constants

VERSION

GemHadar version

Public Class Methods

new(&block) click to toggle source
# File lib/gem_hadar.rb, line 43
def initialize(&block)
  @dependencies = []
  @development_dependencies = []
  block and instance_eval(&block)
end
start_simplecov() click to toggle source
# File lib/gem_hadar.rb, line 492
def self.start_simplecov
  defined? SimpleCov or return
  filter = "#{File.basename(File.dirname(caller.first))}/"
  SimpleCov.start do
    add_filter filter
  end
end

Public Instance Methods

ask?(prompt, pattern) click to toggle source
# File lib/gem_hadar.rb, line 753
def ask?(prompt, pattern)
  STDOUT.print prompt
  answer = STDIN.gets.chomp
  if answer =~ pattern
    $~
  end
end
build_task() click to toggle source
# File lib/gem_hadar.rb, line 211
def build_task
  desc 'Build task (builds all packages for a release)'
  task :build => build_task_dependencies
end
clean(*args) click to toggle source
# File lib/gem_hadar.rb, line 223
def clean(*args)
  if args.empty?
    CLEAN
  else
    CLEAN.include(*args)
  end
end
clobber(*args) click to toggle source
# File lib/gem_hadar.rb, line 231
def clobber(*args)
  if args.empty?
    CLOBBER
  else
    CLOBBER.include(*args)
  end
end
compile_task() click to toggle source
# File lib/gem_hadar.rb, line 691
def compile_task
  for file in extensions
    dir = File.dirname(file)
    clean File.join(dir, 'Makefile'), File.join(dir, '*.{bundle,o,so}')
  end
  desc "Compile extensions: #{extensions * ', '}"
  task :compile do
    for file in extensions
      dir, file = File.split(file)
      cd dir do
        ruby file
        sh make
      end
    end
  end
end
create_all_tasks() click to toggle source
# File lib/gem_hadar.rb, line 761
def create_all_tasks
  default_task
  build_task
  rvm_task
  version_task
  version_show_task
  version_diff_task
  gem_hadar_update_task
  gemspec_task
  gems_install_task
  doc_task
  if test_dir
    test_task
    rcov_task
  end
  spec_task
  package_task
  yard_task
  install_library_task
  version_bump_task
  version_tag_task
  push_task
  write_ignore_file
  write_gemfile
  if extensions.full?
    compile_task
    task :prepare_install => :compile
  else
    task :prepare_install
  end
  self
end
default_task() click to toggle source
# File lib/gem_hadar.rb, line 204
def default_task
  desc 'Default task'
  task :default => default_task_dependencies
end
dependency(*args) click to toggle source
# File lib/gem_hadar.rb, line 255
def dependency(*args)
  @dependencies << args
end
development_dependency(*args) click to toggle source
# File lib/gem_hadar.rb, line 259
def development_dependency(*args)
  @development_dependencies << args
end
doc_task() click to toggle source
# File lib/gem_hadar.rb, line 435
def doc_task
  clean 'doc'
  desc "Creating documentation"
  task :doc do
    sh 'yard doc'
    cmd = 'yardoc'
    if readme
      cmd << " --readme '#{readme}'"
    end
    cmd << ' - ' << doc_files * ' '
    sh cmd
  end
end
gem_files() click to toggle source
# File lib/gem_hadar.rb, line 271
def gem_files
  (files.to_a - package_ignore_files.to_a)
end
gem_hadar_update_task() click to toggle source
# File lib/gem_hadar.rb, line 386
def gem_hadar_update_task
  namespace :gem_hadar do
    desc 'Update gem_hadar a different version'
    task :update do
      answer = ask?("Which gem_hadar version? ", /^((?:\d+.){2}(?:\d+))$/)
      unless answer
        warn "Invalid version specification!"
        exit 1
      end
      gem_hadar_version = answer[0]
      filename = "#{name}.gemspec"
      old_data = File.read(filename)
      new_data = old_data.gsub(
        /(add_(?:development_)?dependency\(%q<gem_hadar>, \["~> )([\d.]+)("\])/
      ) { "#$1#{gem_hadar_version}#$3" }
      if old_data == new_data
        warn "#{filename.inspect} already depends on gem_hadar "\
          "#{gem_hadar_version} => Do nothing."
      else
        warn "Upgrading #{filename.inspect} to #{gem_hadar_version}."
        secure_write(filename) do |spec|
          spec.write new_data
        end
      end
    end
  end
end
gem_push_task() click to toggle source
# File lib/gem_hadar.rb, line 637
def gem_push_task
  namespace :gem do
    path = "pkg/#{name_version}.gem"
    desc "Push gem file #{File.basename(path)} to rubygems"
    if developing
      task :push => :build do
        puts "Skipping push to rubygems while developing mode is enabled."
      end
    else
      task :push => :build do
        if File.exist?(path)
          if ask?("Do you really want to push #{path.inspect} to rubygems? "\
              "(yes/NO) ", /\Ayes\z/i)
            then
            key = ENV['GEM_API_KEY'].full? { |k| "--key #{k} " }
            sh "gem push #{key}#{path}"
          else
            exit 1
          end
        else
          warn "Cannot push gem to rubygems: #{path.inspect} doesn't exist."
          exit 1
        end
      end
    end
  end
end
gems_install_task(&block) click to toggle source
# File lib/gem_hadar.rb, line 263
def gems_install_task(&block)
  block ||= proc {  sh 'bundle install' }
  desc 'Install all gems from the Gemfile'
  namespace :gems do
    task :install => :gemspec , &block
  end
end
gemspec() click to toggle source
# File lib/gem_hadar.rb, line 275
def gemspec
  Gem::Specification.new do |s|
    s.name        = name
    s.version     = ::Gem::Version.new(version)
    s.author      = author
    s.email       = email
    s.homepage    = assert_valid_link(:homepage, homepage)
    s.summary     = summary
    s.description = description

    gem_files.full? { |f| s.files = Array(f) }
    test_files.full? { |t| s.test_files = Array(t) }
    extensions.full? { |e| s.extensions = Array(e) }
    bindir.full? { |b| s.bindir = b }
    executables.full? { |e| s.executables = Array(e) }
    licenses.full? { |l| s.licenses = Array(licenses) }
    post_install_message.full? { |m| s.post_install_message = m }

    required_ruby_version.full? { |v| s.required_ruby_version = v }
    s.add_development_dependency('gem_hadar', "~> #{VERSION[/\A\d+\.\d+/, 0]}")
    for d in @development_dependencies
      s.add_development_dependency(*d)
    end
    for d in @dependencies
      if s.respond_to?(:add_runtime_dependency)
        s.add_runtime_dependency(*d)
      else
        s.add_dependency(*d)
      end
    end

    require_paths.full? { |r| s.require_paths = Array(r) }

    if title
      s.rdoc_options << '--title' << title
    else
      s.rdoc_options << '--title' << "#{name.camelize} - #{summary}"
    end
    if readme
      s.rdoc_options << '--main' << readme
      s.extra_rdoc_files << readme
    end
    doc_files.full? { |df| s.extra_rdoc_files.concat Array(df) }
  end
end
gemspec_task() click to toggle source
# File lib/gem_hadar.rb, line 414
def gemspec_task
  desc 'Create a gemspec file'
  task :gemspec => :version do
    filename = "#{name}.gemspec"
    warn "Writing to #{filename.inspect} for #{version}"
    secure_write(filename, gemspec.to_ruby)
  end
end
git_remote() click to toggle source
# File lib/gem_hadar.rb, line 578
def git_remote
  ENV.fetch('GIT_REMOTE', 'origin').split(/\s+/).first
end
git_remotes() click to toggle source
# File lib/gem_hadar.rb, line 582
def git_remotes
  remotes = ENV['GIT_REMOTE'].full?(:split, /\s+/)
  remotes or remotes = `git remote`.lines.map(&:chomp)
  remotes
end
git_remotes_task() click to toggle source
# File lib/gem_hadar.rb, line 665
def git_remotes_task
  task :git_remotes do
    puts git_remotes.map { |r|
      url = `git remote get-url #{r.inspect}`.chomp
      "#{r} #{url}"
    }
  end
end
has_to_be_set(name) click to toggle source
# File lib/gem_hadar.rb, line 49
def has_to_be_set(name)
  fail "#{self.class}: #{name} has to be set for gem"
end
ignore(*args) click to toggle source
# File lib/gem_hadar.rb, line 239
def ignore(*args)
  if args.empty?
    ignore_files
  else
    args.each { |a| ignore_files << a }
  end
end
install_library(&block) click to toggle source
# File lib/gem_hadar.rb, line 216
def install_library(&block)
  @install_library_block = lambda do
    desc 'Install executable/library into site_ruby directories'
    task :install => :prepare_install, &block
  end
end
install_library_task() click to toggle source
# File lib/gem_hadar.rb, line 431
def install_library_task
  @install_library_block.full?(:call)
end
master_prepare_task() click to toggle source
# File lib/gem_hadar.rb, line 588
def master_prepare_task
  namespace :master do
    desc "Prepare a remote git repository for this project"
    task :prepare do
      puts "Create a new remote git repository for #{name.inspect}"
      remote_name = ask?('Name (default: origin) ? ', /^.+$/).
        full?(:[], 0) || 'origin'
      dir         = ask?("Directory (default: /git/#{name}.git)? ", /^.+$/).
        full?(:[], 0) || "/git/#{name}.git"
      ssh_account = ask?('SSH account (format: login@host)? ', /^[^@]+@[^@]+/).
        full?(:[], 0) || exit(1)
      sh "ssh #{ssh_account} 'git init --bare #{dir}'"
      sh "git remote add -m master #{remote_name} #{ssh_account}:#{dir}"
    end
  end
end
master_push_task() click to toggle source
# File lib/gem_hadar.rb, line 621
def master_push_task
  namespace :master do
    git_remotes.each do |gr|
      namespace gr.to_sym do
        desc "Push master to git remote #{gr}"
        task :push do
          sh "git push #{gr} master"
        end
      end
    end

    desc "Push master #{version} to all git remotes: #{git_remotes * ' '}"
    task :push => git_remotes.map { |gr| :"master:#{gr}:push" }
  end
end
package_ignore(*args) click to toggle source
# File lib/gem_hadar.rb, line 247
def package_ignore(*args)
  if args.empty?
    package_ignore_files
  else
    args.each { |a| package_ignore_files << a }
  end
end
package_task() click to toggle source
# File lib/gem_hadar.rb, line 423
def package_task
  clean 'pkg'
  Gem::PackageTask.new(gemspec) do |pkg|
    pkg.need_tar      = true
    pkg.package_files += gem_files
  end
end
push_task() click to toggle source
# File lib/gem_hadar.rb, line 674
def push_task
  master_prepare_task
  version_push_task
  master_push_task
  gem_push_task
  git_remotes_task
  task :modified do
    changed_files = `git status --porcelain`.gsub(/^\s*\S\s+/, '').lines
    unless changed_files.empty?
      warn "There are still modified files:\n#{changed_files * ''}"
      exit 1
    end
  end
  desc "Push master and version #{version} all git remotes: #{git_remotes * ' '}"
  task :push => %i[ modified build master:push version:push gem:push ]
end
rcov_task() click to toggle source
# File lib/gem_hadar.rb, line 471
def rcov_task
  if defined?(::Rcov)
    rt = ::Rcov::RcovTask.new(:run_rcov) do |t|
      t.libs << test_dir
      t.libs.concat require_paths.to_a
      t.libs.uniq!
      t.test_files = test_files
      t.verbose    = true
      t.rcov_opts  = %W[-x '\\b#{test_dir}\/' -x '\\bgems\/']
    end
    desc 'Run the rcov code coverage tests'
    task :rcov => [ (:compile if extensions.full?), rt.name ].compact
    clobber 'coverage'
  else
    desc 'Run the rcov code coverage tests'
    task :rcov do
      warn "rcov doesn't work for some reason, have you tried 'gem install rcov'?"
    end
  end
end
require_path(path = nil) click to toggle source
# File lib/gem_hadar.rb, line 99
def require_path(path = nil)
  if path
    self.require_paths = Set[path]
  else
    require_paths.first
  end
end
rvm(&block) click to toggle source
# File lib/gem_hadar.rb, line 193
def rvm(&block)
  if block
    @rvm = RvmConfig.new(&block)
  elsif !@rvm
    @rvm = RvmConfig.new { }
  end
  @rvm
end
rvm_task() click to toggle source
# File lib/gem_hadar.rb, line 708
  def rvm_task
    desc 'Create .rvmrc file'
    task :rvm do
      secure_write('.rvmrc') do |output|
        output.write <<EOT
rvm use #{rvm.use}
rvm gemset create #{rvm.gemset}
rvm gemset use #{rvm.gemset}
EOT
      end
    end
  end
spec_task() click to toggle source
# File lib/gem_hadar.rb, line 460
def spec_task
  defined? ::RSpec::Core::RakeTask or return
  st =  RSpec::Core::RakeTask.new(:run_specs) do |t|
    t.ruby_opts ||= ''
    t.ruby_opts << ' -I' << ([ spec_dir ] + require_paths.to_a).uniq * ':'
    t.pattern = spec_pattern
    t.verbose = true
  end
  task :spec => [ (:compile if extensions.full?), st.name ].compact
end
test_task() click to toggle source
# File lib/gem_hadar.rb, line 449
def test_task
  tt =  Rake::TestTask.new(:run_tests) do |t|
    t.libs << test_dir
    t.libs.concat require_paths.to_a
    t.test_files = test_files
    t.verbose    = true
  end
  desc 'Run the tests'
  task :test => [ (:compile if extensions.full?), tt.name ].compact
end
version_bump_task() click to toggle source
# File lib/gem_hadar.rb, line 527
def version_bump_task
  namespace :version do
    namespace :bump do
      desc 'Bump major version'
      task :major do
        version = File.read('VERSION').chomp.version
        version.bump(:major)
        secure_write('VERSION') { |v| v.puts version }
      end

      desc 'Bump minor version'
      task :minor do
        version = File.read('VERSION').chomp.version
        version.bump(:minor)
        secure_write('VERSION') { |v| v.puts version }
      end

      desc 'Bump build version'
      task :build do
        version = File.read('VERSION').chomp.version
        version.bump(:build)
        secure_write('VERSION') { |v| v.puts version }
      end
    end
  end
end
version_diff_task() click to toggle source
# File lib/gem_hadar.rb, line 366
def version_diff_task
  namespace :version do
    desc "List all versions in order"
    task :list do
      system 'git fetch --tags'
      $?.success? or exit $?.exitstatus
      puts versions
    end

    desc "Displaying the diff from env var VERSION to the next version or HEAD"
    task :diff do
      arg_version = ENV.fetch('VERSION', version).dup.prepend(?v)
      my_versions = versions.map { _1.prepend(?v) } + %w[ HEAD ]
      start_version, end_version = my_versions[my_versions.index(arg_version), 2]
      puts color(172) {"Showing diff from version %s to %s:" % [ start_version, end_version ]}
      puts `git diff --color=always #{start_version}..#{end_version}`
    end
  end
end
version_push_task() click to toggle source
# File lib/gem_hadar.rb, line 605
def version_push_task
  namespace :version do
    git_remotes.each do |gr|
      namespace gr.to_sym do
        desc "Push version #{version} to git remote #{gr}"
        task :push do
          sh "git push #{gr} v#{version}"
        end
      end
    end

    desc "Push version #{version} to all git remotes: #{git_remotes * ' '}"
    task :push => git_remotes.map { |gr| :"version:#{gr}:push" }
  end
end
version_show_task() click to toggle source
# File lib/gem_hadar.rb, line 342
def version_show_task
  namespace :version do
    desc "Displaying the current version"
    task :show do
      require path_name
      dir = File.join('lib', path_name)
      version_file = File.join(dir, 'version.rb')
      m = Module.new
      m.instance_eval File.read(version_file)
      version_rb   = m.const_get(
        [ path_module, 'VERSION' ] * '::'
      )
      equal        = version == version_rb ? '==' : '!='
      puts "version.rb=#{version_rb} #{equal} VERSION=#{version}"
    end
  end
end
version_tag_task() click to toggle source
# File lib/gem_hadar.rb, line 554
def version_tag_task
  namespace :version do
    desc "Tag this commit as version #{version}"
    task :tag do
      force = ENV['FORCE'].to_i == 1
      begin
        sh "git tag -a -m 'Version #{version}' #{'-f' if force} v#{version}"
      rescue RuntimeError
        if `git diff v#{version}..HEAD`.empty?
          puts "Version #{version} is already tagged, but it's no different"
        else
          if ask?("Different version tag #{version} already exists. Overwrite with "\
              "force? (yes/NO) ", /\Ayes\z/i)
            force = true
            retry
          else
            exit 1
          end
        end
      end
    end
  end
end
version_task() click to toggle source
# File lib/gem_hadar.rb, line 321
  def version_task
    desc m = "Writing version information for #{name}-#{version}"
    task :version do
      puts m
      mkdir_p dir = File.join('lib', path_name)
      secure_write(File.join(dir, 'version.rb')) do |v|
        v.puts <<EOT
#{module_type} #{path_module}
  # #{path_module} version
  VERSION         = '#{version}'
  VERSION_ARRAY   = VERSION.split('.').map(&:to_i) # :nodoc:
  VERSION_MAJOR   = VERSION_ARRAY[0] # :nodoc:
  VERSION_MINOR   = VERSION_ARRAY[1] # :nodoc:
  VERSION_BUILD   = VERSION_ARRAY[2] # :nodoc:
end
EOT
        version_epilogue.full? { |ve| v.puts ve }
      end
    end
  end
versions() click to toggle source
# File lib/gem_hadar.rb, line 360
def versions
  `git tag`.lines.grep(/^v?\d+\.\d+\.\d+$/).map(&:chomp).map {
    _1.sub(/\Av/, '')
  }.sort_by(&:version)
end
write_gemfile() click to toggle source
# File lib/gem_hadar.rb, line 506
  def write_gemfile
     default_gemfile =<<EOT
# vim: set filetype=ruby et sw=2 ts=2:

source 'https://rubygems.org'

gemspec
EOT
    current_gemfile = File.exist?('Gemfile') && File.read('Gemfile')
    case current_gemfile
    when false
      secure_write('Gemfile') do |output|
        output.write default_gemfile
      end
    when default_gemfile
      ;;
    else
      warn "INFO: Current Gemfile differs from default Gemfile."
    end
  end
write_ignore_file() click to toggle source
# File lib/gem_hadar.rb, line 500
def write_ignore_file
  secure_write('.gitignore') do |output|
    output.puts(ignore.sort)
  end
end
yard_task() click to toggle source
# File lib/gem_hadar.rb, line 721
def yard_task
  defined? YARD or return
  namespace :yard do
    my_yard_dir = Pathname.new(yard_dir)

    desc 'Create yard documentation (including private)'
    task :private do
      sh "yardoc -o #{my_yard_dir}"
    end

    desc 'View the yard documentation'
    task :view do
      index_file = my_yard_dir + 'index.html'
      File.exist?(index_file)
      sh "open #{index_file}"
    end

    desc 'Clean the yard documentation'
    task :clean do
      rm_rf my_yard_dir
    end

    desc 'List all undocumented classes/modules/methods'
    task :'list-undoc' do
      sh "yard stats --list-undoc"
    end
  end

  desc 'Create the yard documentation and view it'
  task :yard => %i[ yard:private yard:view ]
end