yeah it's all consolidated now
This commit is contained in:
parent
033ba8a54c
commit
1a5f0142df
47
README.md
47
README.md
@ -3,7 +3,7 @@
|
||||
I like to do these things in all my projects:
|
||||
|
||||
* Have all my tests run before committing. I don't like buying ice cream for the team on test failures.
|
||||
* If I'm developing gems alongside this project, I use a `Gemfile.erb` to get around the "one gem, one source" issue in
|
||||
* If I'm developing gems alongside this project, I use a `Gemfile.penchant` to get around the "one gem, one source" issue in
|
||||
current versions of Bundler.
|
||||
* If I'm moving to different machines or (heaven forbid!) having other developers work on the project, I want to make
|
||||
getting all those local gems as easy as possible.
|
||||
@ -14,27 +14,36 @@ This gem makes that easier!
|
||||
|
||||
Installs a bunch of scripts into the `scripts` directory of your project:
|
||||
|
||||
* `gemfile` which switches between `Gemfile.erb` environments
|
||||
* `gemfile` which switches between `Gemfile.penchant` environments
|
||||
* `install-git-hooks` which will do just what it says
|
||||
* `hooks`, several git hooks that the prior script symlinks into .git/hooks for you
|
||||
* `initialize-environment`, which bootstraps your local environment so you can get up and running
|
||||
|
||||
## Gemfile.erb?!
|
||||
## Gemfile.penchant?!
|
||||
|
||||
Yeah, it's a `Gemfile` with ERB in it:
|
||||
Yeah, it's a `Gemfile` with some extras:
|
||||
|
||||
``` erb
|
||||
<% env :local do %>
|
||||
gem 'guard', :path => '../guard'
|
||||
<% end %>
|
||||
``` ruby
|
||||
source :rubygems
|
||||
|
||||
<% env :remote do %>
|
||||
gem 'guard', :git => 'git://github.com/johnbintz/guard.git'
|
||||
<% end %>
|
||||
gem 'rails', '3.2.3'
|
||||
gems 'rake', 'nokogiri', 'rack-rewrite'
|
||||
|
||||
<% no_deployment do %>
|
||||
gem 'os-specific-things'
|
||||
<% end %>
|
||||
no_deployment do
|
||||
group :development, :test do
|
||||
gem 'rspec', '~> 2.6.0'
|
||||
|
||||
dev_gems = %w{flowerbox guard-flowerbox}
|
||||
|
||||
env :local do
|
||||
gems dev_gems, :path => '../%s'
|
||||
end
|
||||
|
||||
env :remote do
|
||||
gems dev_gems, :git => 'git://github.com/johnbintz/%s.git'
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Use `script/gemfile local` to get at the local ones, and `script/gemfile remote` to get at the remote ones.
|
||||
@ -49,8 +58,8 @@ remote servers. *Very* helpful when you have OS-specific gems and are developing
|
||||
and deploying on another, or if you don't want to deal with the dependencies for your testing
|
||||
frameworks:
|
||||
|
||||
``` erb
|
||||
<% no_deployment do %>
|
||||
``` ruby
|
||||
no_deployment do
|
||||
require 'rbconfig'
|
||||
case RbConfig::CONFIG['host_os']
|
||||
when /darwin/
|
||||
@ -64,7 +73,7 @@ frameworks:
|
||||
group :test do
|
||||
# ... all your testing libraries you won't need on the deployed end ...
|
||||
end
|
||||
<% end %>
|
||||
end
|
||||
```
|
||||
|
||||
Run `penchant gemfile ENV --deployment` to get this behavior. This is run by default when the
|
||||
@ -74,8 +83,8 @@ pre-commit git hook runs, but only after the default Rake task passes.
|
||||
|
||||
Get new developers up to speed fast! `script/initialize-environment` does the following when run:
|
||||
|
||||
* Check out any remote repos found in `Gemfile.erb` to the same directory where your current project lives.
|
||||
That way, you can have your `Gemfile.erb` set up as above and everything works cleanly.
|
||||
* Check out any remote repos found in `Gemfile.penchant` to the same directory where your current project lives.
|
||||
That way, you can have your `Gemfile.penchant` set up as above and everything works cleanly.
|
||||
* Runs `script/gemfile remote` to set your project to using remote repositories.
|
||||
* Runs `rake bootstrap` for the project if it exists.
|
||||
|
||||
|
@ -30,7 +30,7 @@ class PenchantCLI < Thor
|
||||
method_options :dir => 'script'
|
||||
def convert
|
||||
install
|
||||
FileUtils.mv 'Gemfile', 'Gemfile.erb'
|
||||
FileUtils.mv 'Gemfile', 'Gemfile.penchant'
|
||||
gemfile(:remote)
|
||||
end
|
||||
|
||||
@ -52,7 +52,7 @@ class PenchantCLI < Thor
|
||||
|
||||
gemfile = Penchant::Gemfile.new
|
||||
if !gemfile.has_gemfile?
|
||||
puts "No Gemfile or Gemfile.erb, exiting."
|
||||
puts "No Gemfile or Gemfile.penchant, exiting."
|
||||
exit 1
|
||||
end
|
||||
system %{bundle}
|
||||
|
@ -49,7 +49,7 @@ Feature: Gemfiles
|
||||
Scenario: Use a gem list for an operation
|
||||
Given I have the file "Gemfile.erb" with the content:
|
||||
"""
|
||||
<% with_gem_list 'test' do %>
|
||||
<% gems 'test' do %>
|
||||
<% env :local, :path => '../%s' do %>
|
||||
<%= gem %>
|
||||
<% end %>
|
||||
@ -65,7 +65,7 @@ Feature: Gemfiles
|
||||
Scenario: Let gem get additional info
|
||||
Given I have the file "Gemfile.erb" with the content:
|
||||
"""
|
||||
<% with_gem_list 'test' do %>
|
||||
<% gems 'test' do %>
|
||||
<%= gem :path => '../%s' %>
|
||||
<% end %>
|
||||
"""
|
||||
@ -74,38 +74,24 @@ Feature: Gemfiles
|
||||
"""
|
||||
# generated by penchant, environment: local
|
||||
|
||||
|
||||
gem 'test', :path => %{../test}
|
||||
gem 'test', {:path=>"../test"}
|
||||
|
||||
"""
|
||||
|
||||
Scenario: Use a gem list without a block
|
||||
Given I have the file "Gemfile.erb" with the content:
|
||||
"""
|
||||
<% with_gem_list 'test', :path => '../%s' %>
|
||||
<% gems 'test', :path => '../%s' %>
|
||||
"""
|
||||
When I rebuild the Gemfile for "local" mode
|
||||
Then the file "Gemfile" should have the following content:
|
||||
"""
|
||||
# generated by penchant, environment: local
|
||||
gem 'test', :path => %{../test}
|
||||
gem 'test', {:path=>"../test"}
|
||||
|
||||
"""
|
||||
|
||||
Scenario: Use a gem list with an array
|
||||
Given I have the file "Gemfile.erb" with the content:
|
||||
"""
|
||||
<% with_gem_list [ 'test' ], :path => '../%s' %>
|
||||
"""
|
||||
When I rebuild the Gemfile for "local" mode
|
||||
Then the file "Gemfile" should have the following content:
|
||||
"""
|
||||
# generated by penchant, environment: local
|
||||
gem 'test', :path => %{../test}
|
||||
|
||||
"""
|
||||
|
||||
Scenario: Use another gem list with an array
|
||||
Given I have the file "Gemfile.erb" with the content:
|
||||
"""
|
||||
<% gems [ 'test' ], :path => '../%s' %>
|
||||
@ -114,7 +100,7 @@ Feature: Gemfiles
|
||||
Then the file "Gemfile" should have the following content:
|
||||
"""
|
||||
# generated by penchant, environment: local
|
||||
gem 'test', :path => %{../test}
|
||||
gem 'test', {:path=>"../test"}
|
||||
|
||||
"""
|
||||
|
||||
|
@ -49,7 +49,6 @@ Feature: Gemfiles
|
||||
gem "three", {:path=>"../three"}
|
||||
"""
|
||||
|
||||
@wip
|
||||
Scenario: Use an env block
|
||||
Given I have the file "Gemfile.penchant" with the content:
|
||||
"""
|
||||
|
@ -74,31 +74,128 @@ module Penchant
|
||||
gemfile_header['deployment mode'] != nil
|
||||
end
|
||||
|
||||
class ERBFile
|
||||
end
|
||||
class FileProcessor
|
||||
attr_reader :environment, :is_deployment
|
||||
|
||||
class PenchantFile
|
||||
def self.result(data, *args)
|
||||
new(data).result(*args)
|
||||
end
|
||||
|
||||
def self.handle_result(&block)
|
||||
if block
|
||||
@handle_result = block
|
||||
else
|
||||
@handle_result
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
|
||||
attr_reader :environment, :is_deployment
|
||||
|
||||
def result(_env, _is_deployment)
|
||||
@environment = _env.to_s.to_sym
|
||||
@is_deployment = _is_deployment
|
||||
|
||||
@output = []
|
||||
|
||||
instance_eval(@data)
|
||||
handle_result(@data)
|
||||
|
||||
@output.join("\n")
|
||||
end
|
||||
|
||||
def env(*args)
|
||||
yield if args.include?(environment)
|
||||
end
|
||||
|
||||
def no_deployment
|
||||
yield if !is_deployment
|
||||
end
|
||||
|
||||
protected
|
||||
def args_to_string(args)
|
||||
args.inspect[1..-2]
|
||||
end
|
||||
|
||||
def split_args(args)
|
||||
template = {}
|
||||
|
||||
while args.last.instance_of?(Hash)
|
||||
template.merge!(args.pop)
|
||||
end
|
||||
|
||||
[ args, template ]
|
||||
end
|
||||
|
||||
def call_and_indent_output(block)
|
||||
index = @output.length
|
||||
block.call
|
||||
index.upto(@output.length - 1) do |i|
|
||||
@output[i] = " " + @output[i]
|
||||
end
|
||||
end
|
||||
|
||||
def process_options(gem_name, template = {})
|
||||
Hash[
|
||||
template.collect { |key, value|
|
||||
value = value % gem_name if value.respond_to?(:%)
|
||||
|
||||
[ key, value ]
|
||||
}.sort
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
class ERBFile < FileProcessor
|
||||
def handle_result(data)
|
||||
@output << ERB.new(data, nil, nil, '@_erbout').result(binding)
|
||||
end
|
||||
|
||||
def env(check, template = {}, &block)
|
||||
if check.to_s == @env.to_s
|
||||
original_erbout = @_erbout.dup
|
||||
|
||||
output = instance_eval(&block).lines.to_a
|
||||
|
||||
output.each do |line|
|
||||
if gem_name = line[%r{gem ['"]([^'"]+)['"]}, 1]
|
||||
line.replace(line.rstrip + process_options(gem_name, template) + "\n")
|
||||
end
|
||||
end
|
||||
|
||||
@_erbout = original_erbout + output.join
|
||||
end
|
||||
end
|
||||
|
||||
def gems(*gems)
|
||||
template = {}
|
||||
template = gems.pop if gems.last.instance_of?(Hash)
|
||||
|
||||
gems.flatten.each do |gem|
|
||||
@_current_gem = gem
|
||||
if block_given?
|
||||
yield
|
||||
else
|
||||
@_erbout += gem(template) + "\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def gem(template = {})
|
||||
output = "gem '#{@_current_gem}'"
|
||||
options = process_options(@_current_gem, template)
|
||||
if !options.empty?
|
||||
output += ", #{options.inspect}"
|
||||
end
|
||||
output
|
||||
end
|
||||
end
|
||||
|
||||
class PenchantFile < FileProcessor
|
||||
def handle_result(data)
|
||||
instance_eval(data)
|
||||
end
|
||||
|
||||
def gem(*args)
|
||||
gem_name, template = split_args(args)
|
||||
|
||||
@ -135,47 +232,6 @@ module Penchant
|
||||
def source(*args)
|
||||
@output << %{source #{args_to_string(args)}}
|
||||
end
|
||||
|
||||
def env(*args)
|
||||
yield if args.include?(environment)
|
||||
end
|
||||
|
||||
def no_deployment
|
||||
yield if !is_deployment
|
||||
end
|
||||
|
||||
private
|
||||
def args_to_string(args)
|
||||
args.inspect[1..-2]
|
||||
end
|
||||
|
||||
def split_args(args)
|
||||
template = {}
|
||||
|
||||
while args.last.instance_of?(Hash)
|
||||
template.merge!(args.pop)
|
||||
end
|
||||
|
||||
[ args, template ]
|
||||
end
|
||||
|
||||
def call_and_indent_output(block)
|
||||
index = @output.length
|
||||
block.call
|
||||
index.upto(@output.length - 1) do |i|
|
||||
@output[i] = " " + @output[i]
|
||||
end
|
||||
end
|
||||
|
||||
def process_options(gem_name, template = {})
|
||||
Hash[
|
||||
template.collect { |key, value|
|
||||
value = value % gem_name if value.respond_to?(:%)
|
||||
|
||||
[ key, value ]
|
||||
}.sort
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
def switch_to!(gemfile_env = nil, deployment = false)
|
||||
@ -214,64 +270,20 @@ module Penchant
|
||||
end
|
||||
|
||||
def process(template)
|
||||
case File.extname(processable_gemfile_path)
|
||||
builder = case File.extname(processable_gemfile_path)
|
||||
when '.penchant'
|
||||
PenchantFile.result(template, @env, @is_deployment)
|
||||
PenchantFile
|
||||
when '.erb'
|
||||
ERB.new(template, nil, nil, '@_erbout').result(binding).lines.to_a
|
||||
ERBFile
|
||||
end
|
||||
|
||||
builder.result(template, @env, @is_deployment)
|
||||
end
|
||||
|
||||
def template
|
||||
File.read(processable_gemfile_path)
|
||||
end
|
||||
|
||||
def env(check, template = {}, &block)
|
||||
if check.to_s == @env.to_s
|
||||
original_erbout = @_erbout.dup
|
||||
|
||||
output = instance_eval(&block).lines.to_a
|
||||
|
||||
output.each do |line|
|
||||
if gem_name = line[%r{gem ['"]([^'"]+)['"]}, 1]
|
||||
line.replace(line.rstrip + options_to_string(gem_name, template) + "\n")
|
||||
end
|
||||
end
|
||||
|
||||
@_erbout = original_erbout + output.join
|
||||
end
|
||||
end
|
||||
|
||||
def with_gem_list(*gems)
|
||||
template = {}
|
||||
template = gems.pop if gems.last.instance_of?(Hash)
|
||||
|
||||
gems.flatten.each do |gem|
|
||||
@_current_gem = gem
|
||||
if block_given?
|
||||
yield
|
||||
else
|
||||
@_erbout += gem(template) + "\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
alias :gems :with_gem_list
|
||||
|
||||
def gem(template = {})
|
||||
"gem '#{@_current_gem}'" + options_to_string(@_current_gem, template)
|
||||
end
|
||||
|
||||
def options_to_string(gem_name, template = {})
|
||||
template.collect do |key, value|
|
||||
", #{key.inspect} => %{#{value % gem_name}}"
|
||||
end.join
|
||||
end
|
||||
|
||||
def no_deployment(&block)
|
||||
instance_eval(&block) if !@is_deployment
|
||||
end
|
||||
|
||||
def gemfile_header
|
||||
(has_gemfile? and File.readlines(gemfile_path).first) or ""
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user