Skip to content

Commit

Permalink
Adding ability to build a gem for every gemset (dependencies change b…
Browse files Browse the repository at this point in the history
…ased on gemset definition)
  • Loading branch information
winton committed Jan 1, 2011
1 parent 3bcd4eb commit b3f7765
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 49 deletions.
51 changes: 33 additions & 18 deletions Rakefile
Expand Up @@ -3,7 +3,6 @@ require File.dirname(__FILE__) + '/lib/gem_template/gems'
GemTemplate::Gems.activate %w(rake rspec)

require 'rake'
require 'rake/gempackagetask'
require 'spec/rake/spectask'

def gemspec
Expand All @@ -13,13 +12,6 @@ def gemspec
end
end

if defined?(Rake::GemPackageTask)
Rake::GemPackageTask.new(gemspec) do |pkg|
pkg.gem_spec = gemspec
end
task :gem => :gemspec
end

if defined?(Spec::Rake::SpecTask)
desc "Run specs"
Spec::Rake::SpecTask.new do |t|
Expand All @@ -28,10 +20,41 @@ if defined?(Spec::Rake::SpecTask)
t.warning = true
end
task :spec
task :default => :spec
end

desc "Build gem(s)"
task :gem do
old_gemset = ENV['GEMSET']
pkg = "#{File.dirname(__FILE__)}/pkg"
system "rm -Rf #{pkg}"
(GemTemplate::Gems.gemspecs.keys + %w(default nodep)).each do |gemset|
ENV['GEMSET'] = gemset
system "mkdir -p #{pkg} && cd #{pkg} && gem build ../gem_template.gemspec"
end
ENV['GEMSET'] = old_gemset
end

namespace :gem do
desc "Install gem(s)"
task :install do
Rake::Task['gem'].invoke
Dir["#{File.dirname(__FILE__)}/pkg/*.gem"].each do |pkg|
system "gem install #{pkg} --no-ri --no-rdoc"
end
end

desc "Push gem(s)"
task :push do
Rake::Task['gem'].invoke
Dir["#{File.dirname(__FILE__)}/pkg/*.gem"].each do |pkg|
system "gem push #{pkg}"
end
end
end

namespace :gems do
desc "Install gems (DEV=0 DOCS=0 GEMSPEC=default SUDO=0)"
desc "Install gem dependencies (DEV=0 DOCS=0 GEMSPEC=default SUDO=0)"
task :install do
dev = ENV['DEV'] == '1'
docs = ENV['DOCS'] == '1' ? '' : '--no-ri --no-rdoc'
Expand Down Expand Up @@ -62,12 +85,4 @@ end
desc "Validate the gemspec"
task :gemspec do
gemspec.validate
end

desc "Install gem locally"
task :install => :package do
sh %{gem install pkg/#{gemspec.name}-#{gemspec.version}}
end

task :default => :spec
task :package => :gemspec
end
4 changes: 2 additions & 2 deletions config/gemsets.yml
@@ -1,3 +1,3 @@
gem_template:
rake: =0.8.7
rspec: =1.3.1
rake: >=0.8.7
rspec: <2
1 change: 1 addition & 0 deletions config/gemspec.yml
Expand Up @@ -9,4 +9,5 @@ description:
dependencies:
-
development_dependencies:
- rake
- rspec
10 changes: 6 additions & 4 deletions gem_template.gemspec
Expand Up @@ -3,20 +3,22 @@ lib = File.expand_path('../lib/', __FILE__)
$:.unshift lib unless $:.include?(lib)

require 'gem_template/gems'
GemTemplate::Gems.gemset ||= :default
GemTemplate::Gems.gemset ||= ENV['GEMSET'] || :default

Gem::Specification.new do |s|
GemTemplate::Gems.gemspec.hash.each do |key, value|
unless %w(dependencies development_dependencies).include?(key)
if key == 'name' && GemTemplate::Gems.gemset != :default
s.name = "#{value}-#{GemTemplate::Gems.gemset}"
elsif !%w(dependencies development_dependencies).include?(key)
s.send "#{key}=", value
end
end

GemTemplate::Gems.gemspec.dependencies.each do |g|
GemTemplate::Gems.dependencies.each do |g|
s.add_dependency g.to_s, GemTemplate::Gems.versions[g]
end

GemTemplate::Gems.gemspec.development_dependencies.each do |g|
GemTemplate::Gems.development_dependencies.each do |g|
s.add_development_dependency g.to_s, GemTemplate::Gems.versions[g]
end

Expand Down
53 changes: 44 additions & 9 deletions lib/gem_template/gems.rb
Expand Up @@ -6,16 +6,17 @@ module GemTemplate
module Gems
class <<self

attr_accessor :config, :gemset, :gemsets, :versions
attr_accessor :config
attr_reader :gemset, :gemsets, :versions

class SimpleStruct
attr_accessor :hash
attr_reader :hash

def initialize(hash)
@hash = hash
@hash.each do |key, value|
self.class.send(:define_method, key) { hash[key] }
self.class.send(:define_method, "#{key}=") { |v| hash[key] = v }
self.class.send(:define_method, key) { @hash[key] }
self.class.send(:define_method, "#{key}=") { |v| @hash[key] = v }
end
end
end
Expand All @@ -33,7 +34,7 @@ def activate(*gems)
puts "rubygems library could not be required" if @config.warn
end

self.gemset = :default unless defined?(@gemset) && @gemset
self.gemset ||= gemset_from_loaded_specs

gems.flatten.collect(&:to_sym).each do |name|
version = @versions[name]
Expand All @@ -45,6 +46,14 @@ def activate(*gems)
end
end

def dependencies
dependency_filter(@gemspec.dependencies, @gemset)
end

def development_dependencies
dependency_filter(@gemspec.development_dependencies, @gemset)
end

def gemset=(gemset)
if gemset
@gemset = gemset.to_sym
Expand All @@ -58,11 +67,11 @@ def gemset=(gemset)
}.inject({}) do |hash, config|
deep_merge(hash, symbolize_keys(config))
end

@versions = @gemsets[gemspec.name.to_sym].inject({}) do |hash, (key, value)|
if value.is_a?(::String)
@versions = (@gemsets[gemspec.name.to_sym] || {}).inject({}) do |hash, (key, value)|
if !value.is_a?(::Hash)
hash[key] = value
elsif value.is_a?(::Hash) && key == @gemset
elsif key == @gemset
value.each { |k, v| hash[k] = v }
end
hash
Expand Down Expand Up @@ -91,6 +100,32 @@ def deep_merge(first, second)
end
first.merge(second, &merger)
end

def dependency_filter(dependencies, match)
dependencies.inject([]) { |array, value|
if value.is_a?(::Hash)
array += value[match.to_s] if value[match.to_s]
else
array << value
end
array
}.uniq.collect(&:to_sym)
end

def gemset_from_loaded_specs
if defined?(Gem)
Gem.loaded_specs.each do |name, spec|
if name == gemspec.name
return :default
elsif name[0..gemspec.name.length] == "#{gemspec.name}-"
return name[gemspec.name.length+1..-1].to_sym
end
end
:default
else
:none
end
end

def symbolize_keys(hash)
return {} unless hash.is_a?(::Hash)
Expand Down
2 changes: 2 additions & 0 deletions spec/fixtures/gemsets.yml
@@ -1,6 +1,8 @@
name:
rake: =0.8.7
default:
mysql: =2.8.1
rspec: =1.3.1
rspec2:
mysql2: =0.2.6
rspec: =2.3.0
11 changes: 10 additions & 1 deletion spec/fixtures/gemspec.yml
Expand Up @@ -8,5 +8,14 @@ summary: Summary
description: Description
dependencies:
- rake
- default:
- mysql
- rspec2:
- mysql2
development_dependencies:
- rspec
- default:
- mysql
- rspec
- rspec2:
- mysql2
- rspec
71 changes: 57 additions & 14 deletions spec/gem_template/gems_spec.rb
Expand Up @@ -58,26 +58,29 @@
:rake => ">0.8.6",
:default => {
:externals => '=1.0.2',
:mysql => "=2.8.1",
:rspec => "=1.3.1"
},
:rspec2 => { :rspec => "=2.3.0" }
:rspec2 => {
:mysql2 => "=0.2.6",
:rspec => "=2.3.0"
}
}
}
end

it "should set Gems.versions" do
GemTemplate::Gems.versions.should == {
:externals => "=1.0.2",
:mysql => "=2.8.1",
:rake => ">0.8.6",
:rspec => "=1.3.1",
:externals => "=1.0.2"
:rspec => "=1.3.1"
}
end

it "should set everything to nil if gemset given nil value" do
GemTemplate::Gems.gemset = nil
GemTemplate::Gems.gemset.should == nil
GemTemplate::Gems.gemsets.should == nil
GemTemplate::Gems.versions.should == nil

it "should return proper values for Gems.dependencies" do
GemTemplate::Gems.dependencies.should == [ :rake, :mysql ]
GemTemplate::Gems.development_dependencies.should == [ :mysql, :rspec ]
end
end

Expand All @@ -96,19 +99,29 @@
:rake => ">0.8.6",
:default => {
:externals => '=1.0.2',
:mysql => "=2.8.1",
:rspec => "=1.3.1"
},
:rspec2 => { :rspec => "=2.3.0" }
:rspec2 => {
:mysql2=>"=0.2.6",
:rspec => "=2.3.0"
}
}
}
end

it "should set Gems.versions" do
GemTemplate::Gems.versions.should == {
:mysql2 => "=0.2.6",
:rake => ">0.8.6",
:rspec => "=2.3.0"
}
end

it "should return proper values for Gems.dependencies" do
GemTemplate::Gems.dependencies.should == [ :rake, :mysql2 ]
GemTemplate::Gems.development_dependencies.should == [ :mysql2, :rspec ]
end
end

describe :nil do
Expand All @@ -124,6 +137,22 @@
end
end

describe :gemset_from_loaded_specs do
before(:each) do
Gem.stub!(:loaded_specs)
end

it "should return the correct gemset for name gem" do
Gem.should_receive(:loaded_specs).and_return({ "name" => nil })
GemTemplate::Gems.send(:gemset_from_loaded_specs).should == :default
end

it "should return the correct gemset for name-rspec gem" do
Gem.should_receive(:loaded_specs).and_return({ "name-rspec2" => nil })
GemTemplate::Gems.send(:gemset_from_loaded_specs).should == :rspec2
end
end

describe :reload_gemspec do
it "should populate @gemspec" do
GemTemplate::Gems.gemspec.hash.should == {
Expand All @@ -134,8 +163,15 @@
"homepage" => "http://github.com/author/name",
"summary" => "Summary",
"description" => "Description",
"dependencies" => ["rake"],
"development_dependencies" => ["rspec"]
"dependencies" => [
"rake",
{ "default" => [ "mysql" ] },
{ "rspec2" => [ "mysql2" ] }
],
"development_dependencies" => [
{ "default" => [ "mysql", "rspec" ] },
{ "rspec2" => [ "mysql2", "rspec" ] }
]
}
end

Expand All @@ -147,8 +183,15 @@
GemTemplate::Gems.gemspec.homepage.should == "http://github.com/author/name"
GemTemplate::Gems.gemspec.summary.should == "Summary"
GemTemplate::Gems.gemspec.description.should == "Description"
GemTemplate::Gems.gemspec.dependencies.should == ["rake"]
GemTemplate::Gems.gemspec.development_dependencies.should == ["rspec"]
GemTemplate::Gems.gemspec.dependencies.should == [
"rake",
{ "default" => ["mysql"] },
{ "rspec2" => [ "mysql2" ] }
]
GemTemplate::Gems.gemspec.development_dependencies.should == [
{ "default" => [ "mysql", "rspec" ] },
{ "rspec2" => [ "mysql2", "rspec" ] }
]
end

it "should produce a valid gemspec" do
Expand Down
3 changes: 2 additions & 1 deletion spec/spec_helper.rb
@@ -1,10 +1,11 @@
require 'pp'

$root = File.expand_path('../../', __FILE__)
require "#{$root}/lib/gem_template/gems"

GemTemplate::Gems.activate :rspec

require "#{$root}/lib/gem_template"
require 'pp'

Spec::Runner.configure do |config|
end

0 comments on commit b3f7765

Please sign in to comment.