Skip to content
Browse files

task-y gem helpers, wip specs

  • Loading branch information...
1 parent 9300347 commit a3c2fd87150a9cce7dac4d60846f00ec5ab8dcf3 @indirect indirect committed
Showing with 101 additions and 162 deletions.
  1. +77 −130 lib/bundler/gem_helper.rb
  2. +9 −0 lib/bundler/gem_tasks.rb
  3. +1 −0 lib/bundler/ui.rb
  4. +14 −32 spec/bundler/gem_helper_spec.rb
View
207 lib/bundler/gem_helper.rb
@@ -1,170 +1,117 @@
-$:.unshift File.expand_path('../vendor', __FILE__)
-require 'thor'
+require 'bundler/ui'
require 'bundler'
module Bundler
class GemHelper
include Rake::DSL if defined? Rake::DSL
- class << self
- # set when install'd.
- attr_accessor :instance
-
- def install_tasks(opts = {})
- new(opts[:dir], opts[:name]).install
- end
+ def self.install_tasks(opts = {})
+ Bundler.ui ||= UI::Shell.new(options)
+ helper = self.new(opts[:dir], opts[:name])
+ @last_gemspec = helper.gemspec
+ helper.install
+ end
- def gemspec(&block)
- gemspec = instance.gemspec
- block.call(gemspec) if block
- gemspec
- end
+ def self.gemspec
+ Bundler.ui.warn "Bundler::GemHelper.gemspec is deprecated. Please use " \
+ "Bundler::GemHelper.new yourself. See bundler/gem_tasks.rb for more."
+ yield @last_gemspec if block_given?
+ @last_gemspec
end
- attr_reader :spec_path, :base, :gemspec
+ attr_reader :base, :gemspec, :gem_path, :spec_path
def initialize(base = nil, name = nil)
- Bundler.ui = UI::Shell.new
- @base = (base ||= Dir.pwd)
- gemspecs = name ? [File.join(base, "#{name}.gemspec")] : Dir[File.join(base, "{,*}.gemspec")]
- raise "Unable to determine name from existing gemspec. Use :name => 'gemname' in #install_tasks to manually set it." unless gemspecs.size == 1
- @spec_path = gemspecs.first
- @gemspec = Bundler.load_gemspec(@spec_path)
+ @base = base || Dir.pwd
+ @spec_path = find_gemspec(@base, name)
+ @gemspec = Bundler.load_gemspec(spec_path)
+ @gem_path = "#{@gemspec.name}-#{@gemspec.version}.gem"
end
- def install
- built_gem_path = nil
-
- desc "Build #{name}-#{version}.gem into the pkg directory."
- task 'build' do
- built_gem_path = build_gem
- end
-
- desc "Build and install #{name}-#{version}.gem into system gems."
- task 'install' => 'build' do
- install_gem(built_gem_path)
+ def find_gemspec(base, name)
+ if name
+ gemspecs = [File.join(base, "#{name}.gemspec")]
+ else
+ gemspecs = Dir[File.join(base, "{,*}.gemspec")]
end
- desc "Create tag #{version_tag} and build and push #{name}-#{version}.gem to Rubygems"
- task 'release' => 'build' do
- release_gem(built_gem_path)
+ if gemspecs.size != 1
+ raise "Unable to determine name from existing gemspec. Use :name => " \
+ "'gemname' in #install_tasks to manually set it."
end
- GemHelper.instance = self
- end
-
- def build_gem
- file_name = nil
- sh("gem build -V '#{spec_path}'") { |out, code|
- file_name = File.basename(built_gem_path)
- FileUtils.mkdir_p(File.join(base, 'pkg'))
- FileUtils.mv(built_gem_path, 'pkg')
- Bundler.ui.confirm "#{name} #{version} built to pkg/#{file_name}."
- }
- File.join(base, 'pkg', file_name)
- end
-
- def install_gem(built_gem_path=nil)
- built_gem_path ||= build_gem
- out, _ = sh_with_code("gem install '#{built_gem_path}' --local")
- raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output" unless out[/Successfully installed/]
- Bundler.ui.confirm "#{name} (#{version}) installed."
+ gemspecs.first
end
- def release_gem(built_gem_path=nil)
- guard_clean
- built_gem_path ||= build_gem
- tag_version { git_push } unless already_tagged?
- rubygem_push(built_gem_path) if gem_push?
- end
-
- protected
- def rubygem_push(path)
- if Pathname.new("~/.gem/credentials").expand_path.exist?
- sh("gem push '#{path}'")
- Bundler.ui.confirm "Pushed #{name} #{version} to rubygems.org."
- else
- raise "Your rubygems.org credentials aren't set. Run `gem push` to set them."
- end
+ def name
+ gemspec.name
end
- def built_gem_path
- Dir[File.join(base, "#{name}-*.gem")].sort_by{|f| File.mtime(f)}.last
+ def version
+ gemspec.version
end
- def git_push
- perform_git_push
- perform_git_push ' --tags'
- Bundler.ui.confirm "Pushed git commits and tags."
+ def no_gem_push?
+ %w(n no nil false off 0).include?(ENV['gem_push'].to_s.downcase)
end
- def perform_git_push(options = '')
- cmd = "git push #{options}"
- out, code = sh_with_code(cmd)
- raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n" unless code == 0
- end
+ def install
+ directory "pkg"
- def already_tagged?
- if sh('git tag').split(/\n/).include?(version_tag)
- Bundler.ui.confirm "Tag #{version_tag} has already been created."
- true
+ desc "Build #{gem_path} into the pkg directory."
+ task :build => "pkg" do
+ sh "gem build -V '#{spec_path}'"
+ mv gem_path, "pkg/#{gem_path}"
+ Bundler.ui.confirm "#{name} #{version} built to pkg/#{gem_path}."
end
- end
- def guard_clean
- clean? && committed? or raise("There are files that need to be committed first.")
- end
-
- def clean?
- sh_with_code("git diff --exit-code")[1] == 0
- end
+ desc "Build and install #{gem_path} into system gems."
+ task :install => :build do
+ Dir.chdir "pkg" do
+ sh "gem install '#{gem_path}'"
+ end
+ end
- def committed?
- sh_with_code("git diff-index --quiet --cached HEAD")[1] == 0
- end
+ desc "Create tag v#{version} and build and push #{gem_path} to Rubygems"
+ task :release => [:tag, :git_push, :build, :push]
- def tag_version
- sh "git tag -a -m \"Version #{version}\" #{version_tag}"
- Bundler.ui.confirm "Tagged #{version_tag}."
- yield if block_given?
- rescue
- Bundler.ui.error "Untagging #{version_tag} due to error."
- sh_with_code "git tag -d #{version_tag}"
- raise
- end
+ task :tag => :check_committed do
+ if %x(git tag).split(/\n/).include?("v#{version}")
+ Bundler.ui.confirm "Tag v#{version} has already been created."
+ else
+ sh "git tag -am 'Version #{version}' v#{version}"
+ Bundler.ui.confirm "Tagged v#{version}."
+ end
+ end
- def version
- gemspec.version
- end
+ task :git_push do
+ sh "git push"
+ sh "git push --tags"
+ Bundler.ui.confirm "Pushed git commits and tags."
+ end
- def version_tag
- "v#{version}"
- end
+ task :push do
+ return if no_gem_push?
- def name
- gemspec.name
- end
+ if !Pathname.new("~/.gem/credentials").expand_path.exist?
+ Bundler.ui.error "Your rubygems.org credentials aren't set. " \
+ "Run `gem push` at least once to set them first." && exit(1)
+ end
- def sh(cmd, &block)
- out, code = sh_with_code(cmd, &block)
- code == 0 ? out : raise(out.empty? ? "Running `#{cmd}' failed. Run this command directly for more detailed output." : out)
- end
+ sh "gem push 'pkg/#{gem_path}'"
+ Bundler.ui.confirm "Pushed #{name} #{version} to rubygems.org."
+ end
- def sh_with_code(cmd, &block)
- cmd << " 2>&1"
- outbuf = ''
- Bundler.ui.debug(cmd)
- Dir.chdir(base) {
- outbuf = `#{cmd}`
- if $? == 0
- block.call(outbuf) if block
+ task :check_committed do
+ # Unfortunately --porcelain depends on git 1.7 :(
+ # sh('test -z "$(git status --porcelain)"') do |ok|
+ sh('git diff --quiet && git diff --cached --quiet') do |ok|
+ ok || ( Bundler.ui.error("You have uncommitted changes, " \
+ "please commit them first.") && exit(1) )
end
- }
- [outbuf, $?]
- end
+ end
- def gem_push?
- ! %w{n no nil false off 0}.include?(ENV['gem_push'].to_s.downcase)
end
+
end
end
View
9 lib/bundler/gem_tasks.rb
@@ -1,2 +1,11 @@
require 'bundler/gem_helper'
Bundler::GemHelper.install_tasks
+
+# If you would like to build your own gem tasks and helpers, use this as a
+# starting point, and customize as needed:
+# require 'bundler/gem_helper'
+# namespace :subgem do
+# gem_helper = Bundler::GemHelper.new(gem_dir)
+# gem_helper.install
+# gem_helper.gemspec
+# end
View
1 lib/bundler/ui.rb
@@ -1,3 +1,4 @@
+require 'bundler/vendored_thor'
require 'rubygems/user_interaction'
module Bundler
View
46 spec/bundler/gem_helper_spec.rb
@@ -50,44 +50,26 @@ def mock_build_message
mock_confirm_message "test 0.0.1 built to pkg/test-0.0.1.gem."
end
- before(:each) do
- bundle 'gem test'
- @app = bundled_app("test")
- @gemspec = File.read("#{@app.to_s}/test.gemspec")
- File.open("#{@app.to_s}/test.gemspec", 'w'){|f| f << @gemspec.gsub('TODO: ', '') }
- @helper = Bundler::GemHelper.new(@app.to_s)
- end
-
- it "uses a shell UI for output" do
- expect(Bundler.ui).to be_a(Bundler::UI::Shell)
+ around do |it|
+ Dir.chdir(bundled_app){ bundle 'gem test' }
+ gemspec_path = bundled_app("test/test.gemspec")
+ working_spec = gemspec_path.read.gsub('TODO: ', '')
+ gemspec_path.open('w'){|f| f << working_spec }
+
+ old, Rake.application = Rake.application, Rake::Application.new
+ Bundler::GemHelper.install_tasks(:dir => bundled_app("test"), :name => 'test')
+ it.run
+ Rake.application = old
end
describe 'install_tasks' do
- before(:each) do
- @saved, Rake.application = Rake.application, Rake::Application.new
- end
-
- after(:each) do
- Rake.application = @saved
- end
-
it "defines Rake tasks" do
- names = %w[build install release]
-
- names.each { |name|
- expect { Rake.application[name] }.to raise_error(/Don't know how to build task/)
- }
-
- @helper.install
-
- names.each { |name|
- expect { Rake.application[name] }.not_to raise_error
- expect(Rake.application[name]).to be_instance_of Rake::Task
- }
+ %w[build install release].each do |task|
+ expect(Rake.application[task]).to be_a(Rake::Task)
+ end
end
it "provides a way to access the gemspec object" do
- @helper.install
expect(Bundler::GemHelper.gemspec.name).to eq('test')
end
end
@@ -95,7 +77,7 @@ def mock_build_message
describe 'build' do
it "builds" do
mock_build_message
- @helper.build_gem
+ Rake.application[:build].execute
expect(bundled_app('test/pkg/test-0.0.1.gem')).to exist
end

0 comments on commit a3c2fd8

Please sign in to comment.
Something went wrong with that request. Please try again.