module Gemika::Env

Version switches to write code that works with different versions of Ruby and gem dependencies.

Constants

VERSION_PATTERN

Public Instance Methods

gem?(*args) click to toggle source

Check if the given gem was activated by the current gemfile. It might or might not have been `require`d yet.

@example

Gemika::Env.gem?('activerecord')
Gemika::Env.gem?('activerecord', '= 5.0.0')
Gemika::Env.gem?('activerecord', '~> 4.2.0')
# File lib/gemika/env.rb, line 64
def gem?(*args)
  options = args.last.is_a?(Hash) ? args.pop : {}
  name, requirement_string = args
  if options[:gemfile] && !process_gemfile?(options[:gemfile])
    gem_in_gemfile?(options[:gemfile], name, requirement_string)
  else
    gem_activated?(name, requirement_string)
  end
end
gemfile() click to toggle source

Returns the path to the gemfile for the current Ruby process.

# File lib/gemika/env.rb, line 16
def gemfile
  if @gemfile_changed
    @process_gemfile
  else
    ENV['BUNDLE_GEMFILE']
  end
end
github?() click to toggle source

Return whether this process is running within a Github Actions build.

# File lib/gemika/env.rb, line 100
def github?
  ENV.key?('GITHUB_WORKFLOW')
end
new_ordered_hash() click to toggle source

Creates an hash that enumerates entries in order of insertion.

@!visibility private

# File lib/gemika/env.rb, line 109
def new_ordered_hash
  # We use it when ActiveSupport is activated
  if ruby?('>= 1.9')
    {}
  elsif gem?('activesupport')
    require 'active_support/ordered_hash'
    ActiveSupport::OrderedHash.new
  else
    # We give up
    {}
  end
end
ruby() click to toggle source

Returns the current version of Ruby.

# File lib/gemika/env.rb, line 77
def ruby
  RUBY_VERSION
end
ruby?(requirement) click to toggle source

Check if the current version of Ruby satisfies the given requirements.

@example

Gemika::Env.ruby?('>= 2.1.0')
# File lib/gemika/env.rb, line 87
def ruby?(requirement)
  requirement_satisfied?(requirement, ruby)
end
travis?() click to toggle source

Returns whether this process is running within a TravisCI build.

# File lib/gemika/env.rb, line 94
def travis?
  !!ENV['TRAVIS']
end
with_gemfile(path, *args, &block) click to toggle source

Changes the gemfile to the given `path`, runs the given `block`, then resets the gemfile to its original path.

@example

Gemika::Env.with_gemfile('gemfiles/Gemfile.rails3') do
  system('rspec spec') or raise 'RSpec failed'
end
# File lib/gemika/env.rb, line 33
def with_gemfile(path, *args, &block)
  # Make sure that if block calls  #gemfile we still return the gemfile for this
  # process, regardless of what's in ENV temporarily
  @gemfile_changed = true
  @process_gemfile = ENV['BUNDLE_GEMFILE']

  # .with_clean_env is deprecated since Bundler ~> 2.
  bundler_method = if Gemika::Env.gem?('bundler', '< 2')
    :with_clean_env
  else
    :with_unbundled_env
  end

  Bundler.send(bundler_method) do
    ENV['BUNDLE_GEMFILE'] = path
    block.call(*args)
  end
ensure
  @gemfile_changed = false
  ENV['BUNDLE_GEMFILE'] = @process_gemfile
end

Private Instance Methods

bundler?() click to toggle source
# File lib/gemika/env.rb, line 124
def bundler?
  !gemfile.nil? && gemfile != ''
end
gem_activated?(name, requirement) click to toggle source
# File lib/gemika/env.rb, line 132
def gem_activated?(name, requirement)
  gem = Gem.loaded_specs[name]
  if gem
    if requirement
      version = gem.version
      requirement_satisfied?(requirement, version)
    else
      true
    end
  else
    false
  end
end
gem_in_gemfile?(gemfile, name, requirement = nil) click to toggle source
# File lib/gemika/env.rb, line 146
def gem_in_gemfile?(gemfile, name, requirement = nil)
  lockfile = lockfile_contents(gemfile)
  if lockfile =~ /\b#{Regexp.escape(name)}\s*\((#{VERSION_PATTERN})\)/
    version = $1
    if requirement
      requirement_satisfied?(requirement, version)
    else
      true
    end
  else
    false
  end
end
lockfile_contents(gemfile) click to toggle source
# File lib/gemika/env.rb, line 171
def lockfile_contents(gemfile)
  lockfile = "#{gemfile}.lock"
  File.exists?(lockfile) or raise MissingLockfile, "Lockfile not found: #{lockfile}"
  File.read(lockfile)
end
process_gemfile?(given_gemfile) click to toggle source
# File lib/gemika/env.rb, line 128
def process_gemfile?(given_gemfile)
  bundler? && File.expand_path(gemfile) == File.expand_path(given_gemfile)
end
requirement_satisfied?(requirement, version) click to toggle source
# File lib/gemika/env.rb, line 160
def requirement_satisfied?(requirement, version)
  requirement = Gem::Requirement.new(requirement) if requirement.is_a?(String)
  version = Gem::Version.new(version) if version.is_a?(String)
  if requirement.respond_to?(:satisfied_by?) # Ruby 1.9.3+
    requirement.satisfied_by?(version)
  else
    ops = Gem::Requirement::OPS
    requirement.requirements.all? { |op, rv| (ops[op] || ops["="]).call version, rv }
  end
end