summaryrefslogtreecommitdiff
path: root/importer_bundler_extensions.rb
diff options
context:
space:
mode:
Diffstat (limited to 'importer_bundler_extensions.rb')
-rw-r--r--importer_bundler_extensions.rb89
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