# Copyright (c) 2012 MaxMedia and Travis Warlick # Licensed under the MIT License (see LICENSE) require 'bundler' require 'pathname' require 'pp' module Dionysus module TravisCI class GemfileGenerator def initialize(gemfile) @definition = load_definition(gemfile) @gemspec = load_gemspec(gemfile) end def generate(filename, options={}) Pathname.new(filename).dirname.mkpath File.open(filename, "w") do |f| f.puts %(source "http://rubygems.org") @definition.dependencies.each do |dep| next if dep.name == @gemspec.name next if exclude_by_group?(dep, options[:without]) f.puts dependency_line(dep) end case options[:add] when String f.puts options[:add] when Array options[:add].each {|ln| f.puts ln} else raise "Invalid :add option: %p"%[options[:add]] if options[:add] end f.puts %(gemspec :path => "../") end end private def dependency_line(dep) ln = [ %(gem "%s")%[dep.name] ] ln << %("%s")%[dep.requirement] groups = dep.groups.collect {|v| %(:#{v})}.join(", ") ln << %(:group => [%s])%[groups] if dep.autorequire == [] ln << %(:require => false) elsif dep.autorequire requires = dep.autorequire.collect {|s| %("#{s}")}.join(",") ln << %(:require => [%s])%[requires] end if dep.source and dep.source.is_a?(Bundler::Source::Git) ln << %(:git => "%s")%[dep.source.options["git"]] %w[branch ref tag].each do |key| if dep.source.options[key] ln << %(%p => "%s")%[key.to_sym, dep.source.options[key]] end end elsif dep.source and dep.source.is_a?(Bundler::Source::Path) raise "Cannot create Gemfiles for Travis-CI with :path gems" elsif dep.source raise "Unknown source type: %s"%[dep.source.class] end ln.join(", ") end def exclude_by_group?(dep, *without) return false if without.nil? or without.empty? without = without.compact.flatten !(dep.groups & without).empty? end def load_definition(gemfile) Bundler::Dsl.new.tap do |dsl| dsl.instance_eval(Bundler.read_file(gemfile), "Gemfile", 1) end end def load_gemspec(gemfile) gemspecs = Dir[ Pathname(gemfile).dirname.join("*.gemspec") ] if gemspecs.empty? raise "Gemspec not found in same directory as %p"%[gemfile] elsif gemspecs.length > 1 warn "Multiple gemspecs found, but only one is supported. Using %p."%[gemspecs.first] end Bundler.load_gemspec(gemspecs.first) end end end end