diff options
author | Andre Arko <andre@arko.net> | 2013-03-27 18:05:33 -0700 |
---|---|---|
committer | Andre Arko <andre@arko.net> | 2013-03-27 18:05:33 -0700 |
commit | a3c2fd87150a9cce7dac4d60846f00ec5ab8dcf3 (patch) | |
tree | 07ec15a6e439a60dc9f45352cd1c170f8ecae4a5 | |
parent | 93003471ce5af70979301e87a37b35aada4d158f (diff) | |
download | bundler-gem_tasks.tar.gz |
task-y gem helpers, wip specsgem_tasks
-rw-r--r-- | lib/bundler/gem_helper.rb | 207 | ||||
-rw-r--r-- | lib/bundler/gem_tasks.rb | 9 | ||||
-rw-r--r-- | lib/bundler/ui.rb | 1 | ||||
-rw-r--r-- | spec/bundler/gem_helper_spec.rb | 46 |
4 files changed, 101 insertions, 162 deletions
diff --git a/lib/bundler/gem_helper.rb b/lib/bundler/gem_helper.rb index dc9897beb6..667f571ebb 100644 --- a/lib/bundler/gem_helper.rb +++ b/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 diff --git a/lib/bundler/gem_tasks.rb b/lib/bundler/gem_tasks.rb index bc7590886f..a6747fd390 100644 --- a/lib/bundler/gem_tasks.rb +++ b/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 diff --git a/lib/bundler/ui.rb b/lib/bundler/ui.rb index 01b6c6eae8..9b6bc906ec 100644 --- a/lib/bundler/ui.rb +++ b/lib/bundler/ui.rb @@ -1,3 +1,4 @@ +require 'bundler/vendored_thor' require 'rubygems/user_interaction' module Bundler diff --git a/spec/bundler/gem_helper_spec.rb b/spec/bundler/gem_helper_spec.rb index 134fc87099..ea0ca2b283 100644 --- a/spec/bundler/gem_helper_spec.rb +++ b/spec/bundler/gem_helper_spec.rb @@ -50,44 +50,26 @@ describe "Bundler::GemHelper tasks" do 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 @@ describe "Bundler::GemHelper tasks" do 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 |