diff options
Diffstat (limited to 'importer_bundler_extensions.rb')
-rw-r--r-- | importer_bundler_extensions.rb | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/importer_bundler_extensions.rb b/importer_bundler_extensions.rb new file mode 100644 index 0000000..90a5ae4 --- /dev/null +++ b/importer_bundler_extensions.rb @@ -0,0 +1,89 @@ +#!/usr/bin/env ruby +# +# Extensions to Bundler library which allow using it in importers. +# +# Copyright (C) 2014 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +require 'bundler' + +class << Bundler + def default_gemfile + # This is a hack to make things not crash when there's no Gemfile + Pathname.new('.') + end +end + +module Importer + module BundlerExtensions + def create_bundler_definition_for_gemspec(gem_name) + # Using the real Gemfile doesn't get great results, because people can put + # lots of stuff in there that is handy for developers to have but + # irrelevant if you just want to produce a .gem. Also, there is only one + # Gemfile per repo, but a repo may include multiple .gemspecs that we want + # to process individually. Also, some projects don't use Bundler and may + # not have a Gemfile at all. + # + # Instead of reading the real Gemfile, invent one that simply includes the + # chosen .gemspec. If present, the Gemfile.lock will be honoured. + fake_gemfile = Bundler::Dsl.new + fake_gemfile.source('https://rubygems.org') + begin + fake_gemfile.gemspec({:name => gem_name}) + rescue Bundler::InvalidOption + error "Did not find #{gem_name}.gemspec in current directory." + exit 1 + end + + fake_gemfile.to_definition('Gemfile.lock', true) + end + + def get_spec_for_gem(specs, gem_name) + found = specs[gem_name].select {|s| Gem::Platform.match(s.platform)} + if found.empty? + raise Exception, + "No Gemspecs found matching '#{gem_name}'" + elsif found.length != 1 + raise Exception, + "Unsure which Gem to use for #{gem_name}, got #{found}" + end + found[0] + end + + def spec_is_from_current_source_tree(spec, source_dir) + Dir.chdir(source_dir) do + spec.source.instance_of? Bundler::Source::Path and + File.identical?(spec.source.path, '.') + end + end + + def validate_spec(spec, source_dir_name, expected_version) + if not spec_is_from_current_source_tree(spec, source_dir_name) + error "Specified gem '#{spec.name}' doesn't live in the source in " + + "'#{source_dir_name}'" + log.debug "SPEC: #{spec.inspect} #{spec.source}" + exit 1 + end + + if expected_version != nil && spec.version != expected_version + # This check is brought to you by Coderay, which changes its version + # number based on an environment variable. Other Gems may do this too. + error "Source in #{source_dir_name} produces #{spec.full_name}, but " + + "the expected version was #{expected_version}." + exit 1 + end + end + end +end |