Class: Shoe

Inherits:
Object
  • Object
show all
Defined in:
lib/shoe.rb

Overview

Shoe defines some handy Rake tasks for your project, all built around your Gem::Specification.

Here’s how you use it in your Rakefile:

require 'shoe'
Shoe.tie('myproject', '0.1.0', "This is my project, and it's awesome!") do |spec|
  spec.add_development_dependency 'thoughtbot-shoulda'
end

Shoe comes with an executable named “shoe” that will generate a Rakefile like this (but slightly fancier) for you.

Defined Under Namespace

Classes: LocalDocManager

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, version, summary) ⇒ Shoe

Initializes a Gem::Specification with some nice conventions.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/shoe.rb', line 26

def initialize(name, version, summary)
  @spec = Gem::Specification.new do |spec|
    spec.name             = name
    spec.version          = version
    spec.summary          = summary
    spec.files            = FileList['Rakefile', '*.gemspec', '**/*.rdoc', 'bin/**/*', 'examples/**/*', 'features/**/*', 'lib/**/*', 'resources/**/*', 'shoulda_macros/**/*', 'test/**/*'].to_a
    spec.executables      = everything_in_the_bin_directory
    spec.rdoc_options     = %W(--main README.rdoc --title #{name}-#{version} --inline-source) # MAYBE include --all, so that we document private methods?
    spec.extra_rdoc_files = FileList['*.rdoc', 'shoulda_macros/**/*'].to_a
    spec.has_rdoc         = true
    spec.author           = `git config --get user.name`.chomp
    spec.email            = `git config --get user.email`.chomp
    spec.add_development_dependency 'matthewtodd-shoe'
  end

  def @spec.remove_development_dependency_on_shoe
    dependencies.delete_if { |d| d.name == 'matthewtodd-shoe' }
  end
end

Instance Attribute Details

#specObject (readonly)

The Gem::Specification for your project.



23
24
25
# File 'lib/shoe.rb', line 23

def spec
  @spec
end

Class Method Details

.remove_development_dependency_on_shoeObject



41
42
43
# File 'lib/shoe.rb', line 41

def @spec.remove_development_dependency_on_shoe
  dependencies.delete_if { |d| d.name == 'matthewtodd-shoe' }
end

.tie(name, version, summary) {|shoe.spec| ... } ⇒ Object

Here’s where you start. In your Rakefile, you’ll probably just call Shoe.tie, then add any dependencies in the block.

Yields:



16
17
18
19
20
# File 'lib/shoe.rb', line 16

def self.tie(name, version, summary)
  shoe = new(name, version, summary)
  yield shoe.spec if block_given?
  shoe.define_tasks
end

Instance Method Details

#define_tasksObject

This is where the magic happens.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/shoe.rb', line 47

def define_tasks
  if File.directory?('.git')
    desc 'Remove ignored files'
    task :clean do
      sh 'git clean -fdX'
    end
  end

  if File.directory?('lib')
    desc 'Generate documentation'
    task :rdoc do
      LocalDocManager.new(spec).generate_rdoc

      case RUBY_PLATFORM
      when /darwin/
        sh 'open rdoc/index.html'
      when /mswin|mingw/
        sh 'start rdoc\index.html'
      else
        sh 'firefox rdoc/index.html'
      end
    end
  end

  if File.file?("lib/#{spec.name}.rb")
    desc 'Run an irb console'
    task :shell do
      # MAYBE include -Iext. I think I'd like to wait until I handle C extensions in general.
      exec 'irb', '-Ilib', "-r#{spec.name}"
    end
  end

  if File.directory?('test')
    require 'rake/testtask'
    # MAYBE be a little more forgiving in test selection, using test/**/*_test.rb. Or create suites based on subdirectory?
    Rake::TestTask.new { |task| task.pattern = 'test/*_test.rb' }
    default_depends_on(:test)
  end

  if File.directory?('features')
    require 'cucumber/rake/task'
    Cucumber::Rake::Task.new('features', 'Run features')
    default_depends_on(:features)
  end

  desc 'Show latest gemspec contents'
  task :gemspec do
    puts spec.to_ruby
  end

  if there_is_no_tag_for_the_current_version && we_are_on_the_master_branch && we_have_already_pushed_the_master_branch_to_a_remote_called_origin
    desc "Release #{spec.name}-#{spec.version}"
    task :release do
      File.open("#{spec.name}.gemspec", 'w') { |f| f.write spec.to_ruby }
      sh "git add #{spec.name}.gemspec"
      sh "git commit -a -m 'Release #{spec.version}'"
      sh "git tag #{spec.version}"
      sh 'git push'
      sh 'git push --tags'
    end
  end
end