diff options
author | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2014-09-01 15:01:42 +0100 |
---|---|---|
committer | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2014-09-01 15:01:42 +0100 |
commit | a1156c6cd761dd38f5e18df6505db236f95184e2 (patch) | |
tree | 488fb05982305268ade70e9c059c99c482f91f6b | |
parent | 1867c8a8b88cef240f1201f66986ec015277f38a (diff) | |
download | morph-a1156c6cd761dd38f5e18df6505db236f95184e2.tar.gz |
import: rubygems.to_chunk: use a fake Gemfile, not a real one
-rwxr-xr-x | import/rubygem.to_chunk | 86 |
1 files changed, 57 insertions, 29 deletions
diff --git a/import/rubygem.to_chunk b/import/rubygem.to_chunk index 559c7caf..7156c9d3 100755 --- a/import/rubygem.to_chunk +++ b/import/rubygem.to_chunk @@ -255,18 +255,13 @@ class RubyGemChunkMorphologyGenerator STDERR.puts(message) end - def load_local_gemspecs(source_dir_name) + def load_local_gemspecs() # Look for .gemspec files in the source repo. # # If there is no .gemspec, but you set 'name' and 'version' then # inside Bundler::Source::Path.load_spec_files this call will create a # fake gemspec matching that name and version. That's probably not useful. - # FIXME: Bundler complains that it can't find the Gemfile unless we chdir - # to the root directory of the repo first. There may be a way around this - # by overriding or fixing the Bundler::Source::Path class. - Dir.chdir(source_dir_name) - #dir = Pathname.new(source_dir_name).expand_path dir = '.' source = Bundler::Source::Path.new({ @@ -275,7 +270,7 @@ class RubyGemChunkMorphologyGenerator Log.info "Loaded #{source.specs.count} specs from source dir." source.specs.each do |spec| - Log.debug " * #{spec.inspect}" + Log.debug " * #{spec.inspect} #{spec.dependencies.inspect}" end source @@ -289,13 +284,13 @@ class RubyGemChunkMorphologyGenerator end def get_spec_for_gem(specs, gem_name) - found = 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 #{dep}, got #{found}" + "Unsure which Gem to use for #{gem_name}, got #{found}" end found[0] end @@ -344,6 +339,16 @@ class RubyGemChunkMorphologyGenerator } end + def build_deps_for_gem(spec) + deps = spec.dependencies.select do |d| + d.type == :development && BUILD_DEPENDENCY_WHITELIST.member?(d.name) + end + end + + def runtime_deps_for_gem(spec) + spec.dependencies.select {|d| d.type == :runtime} + end + def write_morph(file, morph) file.write(YAML.dump(morph)) end @@ -354,34 +359,57 @@ class RubyGemChunkMorphologyGenerator Log.info("Creating chunk morph for #{gem_name} based on " + "source code in #{source_dir_name}") - local_source = load_local_gemspecs(source_dir_name) + Dir.chdir(source_dir_name) - # already done in load_local_gemspecs() ... - #Dir.chdir(source_dir_name) + ## Find the .gemspec file in the project repo corresponding to the Gem + ## requested on the commandline. + #local_source = load_local_gemspecs + #local_specset = Bundler::SpecSet.new(local_source.local_specs) + #spec = get_spec_for_gem(local_specset, gem_name) - begin - definition = load_definition(gem_name) - rescue Bundler::GemfileNotFound - definition = Definition.new(nil, [], [], false) - end + # 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') + fake_gemfile.gemspec({:name => gem_name}) - build_specs, runtime_specs = definition.resolve_dependencies + definition = fake_gemfile.to_definition('Gemfile.lock', true) + resolved_specs = definition.resolve_remotely! - spec = get_spec_for_gem(specset, gem_name) + #build_specs, runtime_specs = definition.resolve_dependencies - #if not spec_is_from_current_source_tree(spec) - # error "Specified gem '#{spec.name}' doesn't live in the source in " + - # "'#{source_dir_name}'" - # Log.debug "SPEC: #{spec.inspect} #{spec.source}" - # rails_spec = get_spec_for_gem(specset, 'rails') - # Log.debug "Rails: #{rails_spec.inspect}" - # exit 1 - #end + spec = get_spec_for_gem(resolved_specs, gem_name) + + if not spec_is_from_current_source_tree(spec) + 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 morph = generate_chunk_morph_for_gem(spec) - deps = Hash[specset.collect { |d| [d.name, d.version.to_s] }] - morph['x-dependencies-rubygem'] = deps + # One might think that you could use the Bundler::Dependency.groups + # field to filter but it doesn't seem to be useful. Instead we go back to + # the Gem::Specification of the target Gem and use the dependencies fild + # there. We look up each dependency in the resolved_specset to find out + # what version Bundler has chosen of it. + + def format_deps_for_morphology(specset, dep_list) + info = dep_list.collect do |dep| + spec = specset[dep][0] + [spec.name, spec.version.to_s] + end + Hash[info] + end + + build_deps = format_deps_for_morphology( + resolved_specs, build_deps_for_gem(spec)) + runtime_deps = format_deps_for_morphology( + resolved_specs, runtime_deps_for_gem(spec)) + + morph['x-build-dependencies-rubygem'] = build_deps + morph['x-runtime-dependencies-rubygem'] = runtime_deps write_morph(STDOUT, morph) end |