templater 0.4.5 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +1 -0
- data/README +1 -1
- data/ROADMAP +35 -0
- data/Rakefile +5 -5
- data/lib/templater.rb +2 -1
- data/lib/templater/actions/evaluation.rb +21 -0
- data/lib/templater/cli/generator.rb +7 -7
- data/lib/templater/description.rb +13 -15
- data/lib/templater/generator.rb +19 -0
- data/spec/actions/custom_action_spec.rb +18 -0
- data/spec/actions/evaluation_spec.rb +40 -0
- data/spec/options_parser_spec.rb +4 -4
- metadata +8 -5
- data/TODO +0 -3
data/LICENSE
CHANGED
data/README
CHANGED
@@ -68,7 +68,7 @@ This is how to create a very simple system for generating things:
|
|
68
68
|
|
69
69
|
The generator classes override the source_root method to specify where templates will be located. All subclasses of Templater::Generator that have any actions must do this. The +template+ and +file+ methods add actions to the generator. In the first case, a template that is rendered with ERB and then put in its destination location, in the other case a file that is copied. +empty_directory+ action creates empty directory under destination root.
|
70
70
|
|
71
|
-
Neither manifolds or generators actually do anything by themselves, they are just abstract
|
71
|
+
Neither manifolds or generators actually do anything by themselves, they are just abstract representations. The last line invokes the command-line-interface, which fetches the desired generator, tells it to render its templates and checks with the user if there are any problems. The generators can easily be used without the command-line-interface, so it is easy to construct an alternative interface.
|
72
72
|
|
73
73
|
== Invoking other generators
|
74
74
|
|
data/ROADMAP
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
Roadmap:
|
2
|
+
|
3
|
+
0.5:
|
4
|
+
|
5
|
+
* Custom actions (ex.: append/prepend to existing files).
|
6
|
+
|
7
|
+
0.6:
|
8
|
+
|
9
|
+
* Internals overview.
|
10
|
+
* Plugins development guide.
|
11
|
+
* Overall improvements in documentation.
|
12
|
+
|
13
|
+
0.7:
|
14
|
+
|
15
|
+
* Haml support.
|
16
|
+
|
17
|
+
0.8:
|
18
|
+
|
19
|
+
* Interactive UI.
|
20
|
+
|
21
|
+
0.9:
|
22
|
+
|
23
|
+
* Built-in generators generator.
|
24
|
+
* Executable to run the generator above.
|
25
|
+
* Clean up as much as possible before stabilization period.
|
26
|
+
|
27
|
+
1.0:
|
28
|
+
|
29
|
+
* Redundant spec coverage.
|
30
|
+
* Generators in natural languages with Treetop. We can write generators using
|
31
|
+
plain text and use Cucumber-like steps to process actions.
|
32
|
+
|
33
|
+
1.x:
|
34
|
+
|
35
|
+
* Add magic template names for files.
|
data/Rakefile
CHANGED
@@ -8,8 +8,8 @@ require File.join(File.dirname(__FILE__), 'lib', 'templater')
|
|
8
8
|
|
9
9
|
PLUGIN = "templater"
|
10
10
|
NAME = "templater"
|
11
|
-
AUTHOR = "Jonas Nicklas"
|
12
|
-
EMAIL = "jonas.nicklas@gmail.com"
|
11
|
+
AUTHOR = "Jonas Nicklas, Michael Klishin"
|
12
|
+
EMAIL = "jonas.nicklas@gmail.com, michael.s.klishin@gmail.com"
|
13
13
|
HOMEPAGE = "http://templater.rubyforge.org/"
|
14
14
|
SUMMARY = "File generation system"
|
15
15
|
|
@@ -36,7 +36,7 @@ spec = Gem::Specification.new do |s|
|
|
36
36
|
s.version = Templater::VERSION
|
37
37
|
s.platform = Gem::Platform::RUBY
|
38
38
|
s.has_rdoc = true
|
39
|
-
s.extra_rdoc_files = ["README", "LICENSE", '
|
39
|
+
s.extra_rdoc_files = ["README", "LICENSE", 'ROADMAP']
|
40
40
|
s.summary = SUMMARY
|
41
41
|
s.description = s.summary
|
42
42
|
s.author = AUTHOR
|
@@ -44,7 +44,7 @@ spec = Gem::Specification.new do |s|
|
|
44
44
|
s.homepage = HOMEPAGE
|
45
45
|
s.require_path = 'lib'
|
46
46
|
s.autorequire = PLUGIN
|
47
|
-
s.files = %w(LICENSE README Rakefile
|
47
|
+
s.files = %w(LICENSE README Rakefile ROADMAP) + Dir.glob("{lib,spec}/**/*")
|
48
48
|
|
49
49
|
s.add_dependency "highline", ">= 1.4.0"
|
50
50
|
s.add_dependency "diff-lcs", ">= 1.1.2"
|
@@ -140,4 +140,4 @@ namespace :spec do
|
|
140
140
|
end
|
141
141
|
|
142
142
|
desc 'Default: run unit tests.'
|
143
|
-
task :default => 'spec'
|
143
|
+
task :default => 'spec'
|
data/lib/templater.rb
CHANGED
@@ -14,6 +14,7 @@ require path + 'actions/template'
|
|
14
14
|
require path + 'actions/file'
|
15
15
|
require path + 'actions/directory'
|
16
16
|
require path + 'actions/empty_directory'
|
17
|
+
require path + 'actions/evaluation'
|
17
18
|
require path + 'description'
|
18
19
|
require path + 'generator'
|
19
20
|
require path + 'manifold'
|
@@ -44,6 +45,6 @@ module Templater
|
|
44
45
|
class MalformattedArgumentError < ArgumentError #:nodoc:
|
45
46
|
end
|
46
47
|
|
47
|
-
VERSION = '0.
|
48
|
+
VERSION = '0.5.0'
|
48
49
|
|
49
50
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Templater
|
2
|
+
module Actions
|
3
|
+
class Evaluation < Action
|
4
|
+
attr_reader :generaor, :name, :options, :operation
|
5
|
+
|
6
|
+
def initialize(generator, name, options = {}, &operation)
|
7
|
+
@generator, @name = generator, name
|
8
|
+
@options = options
|
9
|
+
@operation = operation
|
10
|
+
end
|
11
|
+
|
12
|
+
def render
|
13
|
+
self.generator.instance_eval(&operation) || ''
|
14
|
+
end
|
15
|
+
|
16
|
+
def identical?
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -5,11 +5,11 @@ module Templater
|
|
5
5
|
class Generator
|
6
6
|
|
7
7
|
def initialize(generator_name, generator_class, destination_root, name, version)
|
8
|
-
@generator_name
|
8
|
+
@generator_name = generator_name
|
9
9
|
@destination_root = destination_root
|
10
|
-
@generator_class
|
11
|
-
@name
|
12
|
-
@version
|
10
|
+
@generator_class = generator_class
|
11
|
+
@name = name
|
12
|
+
@version = version
|
13
13
|
end
|
14
14
|
|
15
15
|
def version
|
@@ -20,11 +20,11 @@ module Templater
|
|
20
20
|
# outputs a helpful message and quits
|
21
21
|
def help
|
22
22
|
puts "Usage: #{@name} #{@generator_name} [options] [args]"
|
23
|
-
puts
|
23
|
+
puts
|
24
24
|
puts @generator_class.desc
|
25
|
-
puts
|
25
|
+
puts
|
26
26
|
puts @options[:opts]
|
27
|
-
puts
|
27
|
+
puts
|
28
28
|
exit
|
29
29
|
end
|
30
30
|
|
@@ -1,25 +1,23 @@
|
|
1
1
|
module Templater
|
2
|
-
|
2
|
+
|
3
3
|
class Description
|
4
4
|
attr_accessor :name, :options, :block
|
5
|
-
|
5
|
+
|
6
6
|
def initialize(name, options={}, &block)
|
7
7
|
@name = name
|
8
8
|
@options = options
|
9
9
|
@block = block
|
10
|
-
end
|
10
|
+
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
class ActionDescription < Description
|
14
|
-
|
15
14
|
def compile(generator)
|
16
15
|
@block.call(generator)
|
17
16
|
end
|
18
|
-
|
19
17
|
end
|
20
|
-
|
18
|
+
|
21
19
|
class ArgumentDescription < Description
|
22
|
-
|
20
|
+
|
23
21
|
# Checks if the given argument is valid according to this description
|
24
22
|
#
|
25
23
|
# === Parameters
|
@@ -35,7 +33,7 @@ module Templater
|
|
35
33
|
elsif options[:as] == :array and not argument.is_a?(Array)
|
36
34
|
raise Templater::MalformattedArgumentError, "Expected the argument to be an Array, but was '#{argument.inspect}'"
|
37
35
|
end
|
38
|
-
|
36
|
+
|
39
37
|
invalid = catch :invalid do
|
40
38
|
block.call(argument) if block
|
41
39
|
throw :invalid, :not_invalid
|
@@ -43,7 +41,7 @@ module Templater
|
|
43
41
|
raise Templater::ArgumentError, invalid unless invalid == :not_invalid
|
44
42
|
end
|
45
43
|
end
|
46
|
-
|
44
|
+
|
47
45
|
def extract(argument)
|
48
46
|
case options[:as]
|
49
47
|
when :hash
|
@@ -60,11 +58,11 @@ module Templater
|
|
60
58
|
end
|
61
59
|
return argument
|
62
60
|
end
|
63
|
-
|
61
|
+
|
64
62
|
end
|
65
|
-
|
63
|
+
|
66
64
|
class InvocationDescription < Description
|
67
|
-
|
65
|
+
|
68
66
|
def get(generator)
|
69
67
|
klass = generator.class.manifold.generator(name)
|
70
68
|
if klass and block
|
@@ -73,6 +71,6 @@ module Templater
|
|
73
71
|
klass.new(generator.destination_root, generator.options, *generator.arguments)
|
74
72
|
end
|
75
73
|
end
|
76
|
-
|
74
|
+
|
77
75
|
end
|
78
|
-
end
|
76
|
+
end
|
data/lib/templater/generator.rb
CHANGED
@@ -308,6 +308,25 @@ module Templater
|
|
308
308
|
end
|
309
309
|
end
|
310
310
|
|
311
|
+
# Evaluates given block in the scope of generator. Useful for modification
|
312
|
+
# of existing files, for instance, Merb generators may update routing
|
313
|
+
# file or something.
|
314
|
+
#
|
315
|
+
# === Parameters
|
316
|
+
# name<Symbol>:: The name of this custom action
|
317
|
+
# options<Hash>:: Options for this custom action
|
318
|
+
# &block<Proc>:: A block to execute when the generator is instantiated
|
319
|
+
#
|
320
|
+
# === Options
|
321
|
+
# :before<Symbol>:: Name of a method to execute before this template is invoked
|
322
|
+
# :after<Symbol>:: Name of a method to execute after this template is invoked
|
323
|
+
def custom_action(name, *args, &block)
|
324
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
325
|
+
actions[name] = ActionDescription.new(name, options) do |generator|
|
326
|
+
Actions::Evaluation.new(generator, name, options, &block)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
311
330
|
# An easy way to add many templates to a generator, each item in the list is added as a
|
312
331
|
# template. The provided list can be either an array of Strings or a Here-Doc with templates
|
313
332
|
# on individual lines.
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Templater::Generator, ".custom_action" do
|
4
|
+
before do
|
5
|
+
@generator_class = Templater::Generator
|
6
|
+
@generator_class.stub!(:source_root).and_return('/tmp/source')
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'evaluates given block in context of generator' do
|
10
|
+
$custom_action_evaluation_result = "not called yet"
|
11
|
+
@generator_class.custom_action :update_routes_rb do
|
12
|
+
$custom_action_evaluation_result = source_root
|
13
|
+
end
|
14
|
+
|
15
|
+
@generator_class.new("/tmp/destination").render!
|
16
|
+
$custom_action_evaluation_result.should == "/tmp/source"
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Templater::Actions::Evaluation do
|
4
|
+
before do
|
5
|
+
@generator = mock('a generator')
|
6
|
+
@generator.stub!(:source_root).and_return('/tmp/source')
|
7
|
+
@generator.stub!(:destination_root).and_return('/tmp/destination')
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#render' do
|
11
|
+
it "returns result of block evaluation" do
|
12
|
+
evaluation = Templater::Actions::Evaluation.new(@generator, :monkey) do
|
13
|
+
"noop"
|
14
|
+
end
|
15
|
+
evaluation.render.should == "noop"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns empty string when block returned nil" do
|
19
|
+
evaluation = Templater::Actions::Evaluation.new(@generator, :monkey) do
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
evaluation.render.should == ""
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#identical?" do
|
27
|
+
it "always returns false" do
|
28
|
+
noop_evaluation = Templater::Actions::Evaluation.new(@generator, :monkey) do
|
29
|
+
"noop"
|
30
|
+
end
|
31
|
+
|
32
|
+
another_evaluation = Templater::Actions::Evaluation.new(@generator, :monkey) do
|
33
|
+
"noop"
|
34
|
+
end
|
35
|
+
|
36
|
+
noop_evaluation.should_not be_identical
|
37
|
+
another_evaluation.should_not be_identical
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/spec/options_parser_spec.rb
CHANGED
@@ -2,17 +2,17 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
2
2
|
require "tempfile"
|
3
3
|
|
4
4
|
describe Templater::CLI::Parser do
|
5
|
-
describe "given unknown option" do
|
5
|
+
describe "given unknown option" do
|
6
6
|
it "outputs a meaninful error message instead of just blowing up" do
|
7
7
|
lambda do
|
8
8
|
Templater::CLI::Parser.parse(["--this-option-is-unknown", "--second-unknown-option"])
|
9
9
|
end.should_not raise_error
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it "lists unknown options" do
|
13
|
-
e = OptionParser::InvalidOption.new("--this-option-is-unknown", "--second-unknown-option")
|
13
|
+
e = OptionParser::InvalidOption.new("--this-option-is-unknown", "--second-unknown-option")
|
14
14
|
output = Templater::CLI::Parser.error_message(e)
|
15
|
-
|
15
|
+
|
16
16
|
output.should =~ /--this-option-is-unknown/
|
17
17
|
output.should =~ /--second-unknown-option/
|
18
18
|
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: templater
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Jonas Nicklas
|
7
|
+
- Jonas Nicklas, Michael Klishin
|
8
8
|
autorequire: templater
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 0.9.5
|
44
44
|
version:
|
45
45
|
description: File generation system
|
46
|
-
email: jonas.nicklas@gmail.com
|
46
|
+
email: jonas.nicklas@gmail.com, michael.s.klishin@gmail.com
|
47
47
|
executables: []
|
48
48
|
|
49
49
|
extensions: []
|
@@ -51,17 +51,18 @@ extensions: []
|
|
51
51
|
extra_rdoc_files:
|
52
52
|
- README
|
53
53
|
- LICENSE
|
54
|
-
-
|
54
|
+
- ROADMAP
|
55
55
|
files:
|
56
56
|
- LICENSE
|
57
57
|
- README
|
58
58
|
- Rakefile
|
59
|
-
-
|
59
|
+
- ROADMAP
|
60
60
|
- lib/templater
|
61
61
|
- lib/templater/actions
|
62
62
|
- lib/templater/actions/action.rb
|
63
63
|
- lib/templater/actions/directory.rb
|
64
64
|
- lib/templater/actions/empty_directory.rb
|
65
|
+
- lib/templater/actions/evaluation.rb
|
65
66
|
- lib/templater/actions/file.rb
|
66
67
|
- lib/templater/actions/template.rb
|
67
68
|
- lib/templater/capture_helpers.rb
|
@@ -80,8 +81,10 @@ files:
|
|
80
81
|
- lib/templater/spec/helpers.rb
|
81
82
|
- lib/templater.rb
|
82
83
|
- spec/actions
|
84
|
+
- spec/actions/custom_action_spec.rb
|
83
85
|
- spec/actions/directory_spec.rb
|
84
86
|
- spec/actions/empty_directory_spec.rb
|
87
|
+
- spec/actions/evaluation_spec.rb
|
85
88
|
- spec/actions/file_spec.rb
|
86
89
|
- spec/actions/template_spec.rb
|
87
90
|
- spec/core_ext
|