Skip to content

Commit

Permalink
Merge pull request #192 from hawx/templates
Browse files Browse the repository at this point in the history
Add the ability to load user defined templates.
  • Loading branch information
thibaudgg committed Dec 25, 2011
2 parents 2614b44 + 4910828 commit cc4c972
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 6 deletions.
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -218,6 +218,13 @@ In addition, the `init` task can be used to append a supplied Guard template fro
$ guard init <guard-name>
```

You can also define your own templates in `~/.guard/templates/` which can be appended in the same way to your existing
`Guardfile`:

```bash
$ guard init <template-name>
```

### Start

Just launch Guard inside your Ruby or Rails project with:
Expand Down
33 changes: 27 additions & 6 deletions lib/guard.rb
Expand Up @@ -17,6 +17,8 @@ module Guard

# The Guardfile template for `guard init`
GUARDFILE_TEMPLATE = File.expand_path('../guard/templates/Guardfile', __FILE__)
# The location of user defined templates
HOME_TEMPLATES = File.expand_path('~/.guard/templates')

class << self
attr_accessor :options, :interactor, :listener, :lock
Expand All @@ -26,7 +28,7 @@ class << self
#
# @see Guard::Guard.init
#
# @param [String] guard_name the name of the Guard to initialize
# @param [String] guard_name the name of the Guard or template to initialize
#
def initialize_template(guard_name = nil)
if !File.exist?('Guardfile')
Expand All @@ -38,8 +40,24 @@ def initialize_template(guard_name = nil)
end

if guard_name
guard_class = ::Guard.get_guard_class(guard_name)
guard_class.init(guard_name)
guard_class = ::Guard.get_guard_class(guard_name, true)
if guard_class
guard_class.init(guard_name)
elsif File.exist?(File.join(HOME_TEMPLATES, guard_name))
content = File.read('Guardfile')
template = File.read(File.join(HOME_TEMPLATES, guard_name))

File.open('Guardfile', 'wb') do |f|
f.puts(content)
f.puts("")
f.puts(template)
end

::Guard::UI.info "#{ guard_name } template added to Guardfile, feel free to edit it"
else
const_name = guard_name.downcase.gsub('-', '')
UI.error "Could not load 'guard/#{ guard_name.downcase }' or '~/.guard/templates/#{ guard_name.downcase }' or find class Guard::#{ const_name.capitalize }"
end
end
end

Expand Down Expand Up @@ -432,9 +450,10 @@ def add_group(name, options = {})
# * `rspec` will find a class `Guard::RSpec`
#
# @param [String] name the name of the Guard
# @param [Boolean] fail_gracefully whether error messages should not be printed
# @return [Class, nil] the loaded class
#
def get_guard_class(name)
def get_guard_class(name, fail_gracefully=false)
name = name.to_s
try_require = false
const_name = name.gsub(/\/(.?)/) { "::#{ $1.upcase }" }.gsub(/(?:^|[_-])(.)/) { $1.upcase }
Expand All @@ -449,8 +468,10 @@ def get_guard_class(name)
UI.error "Could not find class Guard::#{ const_name.capitalize }"
end
rescue LoadError => loadError
UI.error "Could not load 'guard/#{ name.downcase }' or find class Guard::#{ const_name.capitalize }"
UI.error loadError.to_s
unless fail_gracefully
UI.error "Could not load 'guard/#{ name.downcase }' or find class Guard::#{ const_name.capitalize }"
UI.error loadError.to_s
end
end
end

Expand Down
26 changes: 26 additions & 0 deletions spec/guard_spec.rb
Expand Up @@ -33,6 +33,25 @@ class Guard::Foo < Guard::Guard
Guard.initialize_template('foo')
end
end

context "with a user defined template" do
let(:template) { File.join(Guard::HOME_TEMPLATES, '/bar') }

before {
File.should_receive(:exist?).with('Guardfile').and_return false
File.should_receive(:exist?).with(template).and_return true
}

it "copies the Guardfile template and initializes the Guard" do
FileUtils.should_receive(:cp).with(an_instance_of(String), 'Guardfile')
File.should_receive(:read).with('Guardfile').and_return 'Guardfile content'
File.should_receive(:read).with(template).and_return 'Template content'
io = StringIO.new
File.should_receive(:open).with('Guardfile', 'wb').and_yield io
Guard.initialize_template('bar')
io.string.should eql "Guardfile content\n\nTemplate content\n"
end
end
end

context "without a Guard name" do
Expand Down Expand Up @@ -495,6 +514,13 @@ class Inline < Guard
Guard.get_guard_class('inline').should == Guard::Inline
end
end

context 'when set to fail gracefully' do
it 'does not print error messages on fail' do
::Guard::UI.should_not_receive(:error)
Guard.get_guard_class('notAGuardClass', true).should be_nil
end
end
end

describe ".locate_guard" do
Expand Down

0 comments on commit cc4c972

Please sign in to comment.