add opposites feature to cut down on repetition

This commit is contained in:
John Bintz 2012-09-14 10:44:44 -04:00
parent 832ec8f30c
commit a1e9874b30
5 changed files with 93 additions and 7 deletions

View File

@ -107,6 +107,22 @@ ensuring that hooks are always installed when `penchant gemfile` is executed, an
that lets you pass in the username of the repo to reference that repo: that lets you pass in the username of the repo to reference that repo:
`gem 'penchant', :github => 'johnbintz'`. `gem 'penchant', :github => 'johnbintz'`.
### Stupid-simple local/remote setup
Use `opposites :local, :remote` and environment settings for local/remote gems will be set accordingly depending
on environment:
``` ruby
defaults_for env(:local), :path => '../%s'
opposites :local, :remote
env :remote do
gem 'my-gem', :git => 'git://github.com/johnbintz/my-gem.git'
end
```
In `remote`, the Git repo version is used. In `local`, the path is used. Only one gem definition needed!
### Deployment mode ### Deployment mode
Use `no_deployment` blocks to indicate gems that shouldn't even appear in `Gemfiles` destined for Use `no_deployment` blocks to indicate gems that shouldn't even appear in `Gemfiles` destined for

View File

@ -62,7 +62,6 @@ Feature: CLI
When I run "bin/penchant gemfile remote" in the "tmp" directory When I run "bin/penchant gemfile remote" in the "tmp" directory
Then the output should not include "git hooks not installed" Then the output should not include "git hooks not installed"
@wip
Scenario: Install Penchant into a directory with no Gemfile Scenario: Install Penchant into a directory with no Gemfile
Given I have the directory "tmp" Given I have the directory "tmp"
When I run "bin/penchant install" in the "tmp" directory When I run "bin/penchant install" in the "tmp" directory

View File

@ -263,6 +263,65 @@ Feature: Gemfiles
gem "two", {:require=>nil} gem "two", {:require=>nil}
""" """
Scenario: Set the opposite environment in the environment defaults
Given I have the file "Gemfile.penchant" with the content:
"""
defaults_for env(:local), :path => '../%s', :opposite => :remote
defaults_for env(:remote), :opposite => :local
property(:github) { |name| { :git => "git://github.com/#{name}/%s.git" } }
env :remote do
gem 'one', :github => 'johnbintz', :require => nil
end
env :local do
gem 'two', :path => '../%s', :require => nil
end
"""
When I rebuild the Gemfile for "local" mode
Then the file "Gemfile" should have the following content:
"""
# generated by penchant, environment: local
gem "one", {:path=>"../one", :require=>nil}
gem "two", {:path=>"../two", :require=>nil}
"""
When I rebuild the Gemfile for "remote" mode
Then the file "Gemfile" should have the following content:
"""
# generated by penchant, environment: remote
gem "one", {:git=>"git://github.com/johnbintz/one.git", :require=>nil}
gem "two", {:require=>nil}
"""
Scenario: Define a pair of opposites
Given I have the file "Gemfile.penchant" with the content:
"""
defaults_for env(:local), :path => '../%s'
opposites :local, :remote
property(:github) { |name| { :git => "git://github.com/#{name}/%s.git" } }
env :remote do
gem 'one', :github => 'johnbintz', :require => nil
end
env :local do
gem 'two', :path => '../%s', :require => nil
end
"""
When I rebuild the Gemfile for "local" mode
Then the file "Gemfile" should have the following content:
"""
# generated by penchant, environment: local
gem "one", {:path=>"../one", :require=>nil}
gem "two", {:path=>"../two", :require=>nil}
"""
When I rebuild the Gemfile for "remote" mode
Then the file "Gemfile" should have the following content:
"""
# generated by penchant, environment: remote
gem "one", {:git=>"git://github.com/johnbintz/one.git", :require=>nil}
gem "two", {:require=>nil}
"""
Scenario: Override defaults for an environment Scenario: Override defaults for an environment
Given I have the file "Gemfile.penchant" with the content: Given I have the file "Gemfile.penchant" with the content:
""" """

View File

@ -143,15 +143,17 @@ module Penchant
@available_environments += args @available_environments += args
requested_env_defaults = _defaults_for(Env.new(environment))
if block_given? if block_given?
if for_environment?(args) if for_environment?(args)
@_current_env_defaults = _defaults_for(Env.new(environment)) @_current_env_defaults = requested_env_defaults
yield yield
@_current_env_defaults = {} @_current_env_defaults = {}
else else
if options[:opposite] if opposite_environment = (options[:opposite] or requested_env_defaults[:opposite])
if for_environment?([ options[:opposite] ].flatten) if for_environment?([ environment, args, opposite_environment ].flatten.uniq)
@_current_env_defaults = _defaults_for(Env.new(environment)) @_current_env_defaults = requested_env_defaults
@_strip_pathing_options = true @_strip_pathing_options = true
yield yield
@_strip_pathing_options = false @_strip_pathing_options = false
@ -160,7 +162,7 @@ module Penchant
end end
end end
else else
Penchant::Gemfile::Env.new(args.shift) Env.new(args.shift)
end end
end end
@ -168,6 +170,14 @@ module Penchant
@properties[name] = hash || block @properties[name] = hash || block
end end
def opposites(left, right)
@defaults[Env.new(left).to_s] ||= {}
@defaults[Env.new(left).to_s][:opposite] = right
@defaults[Env.new(right).to_s] ||= {}
@defaults[Env.new(right).to_s][:opposite] = left
end
def for_environment?(envs) def for_environment?(envs)
envs.include?(environment) || environment == ANY_ENVIRONMENT envs.include?(environment) || environment == ANY_ENVIRONMENT
end end
@ -226,6 +236,8 @@ module Penchant
properties = process_option_stack(gem_name, _defaults_for(gem_name).to_a).merge(original_properties) properties = process_option_stack(gem_name, _defaults_for(gem_name).to_a).merge(original_properties)
properties.delete(:opposite)
Hash[properties.sort] Hash[properties.sort]
end end

View File

@ -1,3 +1,3 @@
module Penchant module Penchant
VERSION = "0.2.22" VERSION = "0.2.23"
end end