erector 0.2.61 → 0.2.83
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/bin/erect +2 -26
- data/lib/erector.rb +1 -0
- data/lib/erector/erect.rb +146 -0
- data/lib/erector/extensions/action_view_template_handler.rb +13 -1
- data/lib/erector/rhtml.treetop +9 -1
- data/spec/erect/erect_spec.rb +145 -0
- data/spec/{convert → erect}/erected_spec.rb +0 -0
- data/spec/{convert → erect}/rhtml_parser_spec.rb +4 -0
- metadata +7 -5
data/bin/erect
CHANGED
@@ -2,30 +2,6 @@
|
|
2
2
|
dir = File.expand_path(File.dirname(__FILE__))
|
3
3
|
$LOAD_PATH.unshift("#{dir}/../lib")
|
4
4
|
require "erector"
|
5
|
-
require "erector/
|
6
|
-
require "rake"
|
5
|
+
require "erector/erect"
|
7
6
|
|
8
|
-
|
9
|
-
# --add_to_svn
|
10
|
-
# --delete_original
|
11
|
-
|
12
|
-
files = FileList.new
|
13
|
-
ARGV.each do |file|
|
14
|
-
if File.directory?(file)
|
15
|
-
files.add(FileList["#{file}/**/*.rhtml", "#{file}/**/*.html", "#{file}/**/*.html.erb"])
|
16
|
-
else
|
17
|
-
files.add(file)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
files.each do |file|
|
22
|
-
print "Erecting #{file}... "
|
23
|
-
begin
|
24
|
-
e = Erector::Erected.new(file)
|
25
|
-
e.convert
|
26
|
-
puts " --> #{e.filename}"
|
27
|
-
rescue => e
|
28
|
-
puts e
|
29
|
-
puts
|
30
|
-
end
|
31
|
-
end
|
7
|
+
Erector::Erect.new(ARGV).run
|
data/lib/erector.rb
CHANGED
@@ -0,0 +1,146 @@
|
|
1
|
+
require "optparse"
|
2
|
+
require "rake"
|
3
|
+
require "erector/erected" # pull this out so we don't recreate the grammar every time
|
4
|
+
|
5
|
+
module Erector
|
6
|
+
class Erect
|
7
|
+
attr_reader :files, :verbose, :mode, :output_dir
|
8
|
+
def initialize(args)
|
9
|
+
@verbose = true
|
10
|
+
@mode = :to_erector
|
11
|
+
@output_dir = nil
|
12
|
+
|
13
|
+
opts = OptionParser.new do |opts|
|
14
|
+
opts.banner = "Usage: erect [options] [file|dir]*"
|
15
|
+
|
16
|
+
opts.separator "Converts from html/rhtml files to erector widgets, or from erector widgets to html files"
|
17
|
+
opts.separator ""
|
18
|
+
opts.separator "Options:"
|
19
|
+
|
20
|
+
opts.on("-q", "--quiet",
|
21
|
+
"Operate silently except in case of error") do |quiet|
|
22
|
+
@verbose = !quiet
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on("--to-erector", "(default) Convert from html/rhtml to erector classes") do
|
26
|
+
@mode = :to_erector
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on("--to-html", "Convert from erector to html") do
|
30
|
+
@mode = :to_html
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on("-o", "--output-dir DIRECTORY", "Output files to DIRECTORY (default: output files go next to input files)") do |dir|
|
34
|
+
@output_dir = dir
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
38
|
+
@mode = :help
|
39
|
+
puts opts
|
40
|
+
exit
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on_tail("-v", "--version", "Show version") do
|
44
|
+
puts Erector::VERSION
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
opts.parse!(args)
|
50
|
+
@files = args
|
51
|
+
explode_dirs
|
52
|
+
end
|
53
|
+
|
54
|
+
def say(msg)
|
55
|
+
print msg if verbose
|
56
|
+
end
|
57
|
+
|
58
|
+
#todo: unit test
|
59
|
+
def explode_dirs
|
60
|
+
exploded_files = FileList.new
|
61
|
+
files.each do |file|
|
62
|
+
if File.directory?(file)
|
63
|
+
exploded_files.add(explode(file))
|
64
|
+
else
|
65
|
+
exploded_files.add(file)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
@files = exploded_files
|
69
|
+
end
|
70
|
+
|
71
|
+
def explode(dir)
|
72
|
+
case mode
|
73
|
+
when :to_erector
|
74
|
+
FileList["#{dir}/**/*.rhtml", "#{dir}/**/*.html", "#{dir}/**/*.html.erb"]
|
75
|
+
when :to_html
|
76
|
+
FileList["#{dir}/**/*.rb"]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def run
|
81
|
+
self.send(mode)
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_erector
|
85
|
+
files.each do |file|
|
86
|
+
say "Erecting #{file}... "
|
87
|
+
begin
|
88
|
+
e = Erector::Erected.new(file)
|
89
|
+
e.convert
|
90
|
+
say " --> #{e.filename}\n"
|
91
|
+
rescue => e
|
92
|
+
puts e
|
93
|
+
puts
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def to_html
|
99
|
+
files.each do |file|
|
100
|
+
say "Erecting #{file}... "
|
101
|
+
#todo: move this into Erected with better tests for the naming methods
|
102
|
+
begin
|
103
|
+
#todo: fail if file isn't a .rb file
|
104
|
+
require file
|
105
|
+
#todo: understand modulized widgets (e.g. class Foo::Bar::Baz < Erector::Widget in baz.rb)
|
106
|
+
filename = file.split('/').last.gsub(/\.rb$/, '')
|
107
|
+
widget_name = camelize(filename)
|
108
|
+
widget_class = constantize(widget_name)
|
109
|
+
|
110
|
+
if widget_class < Erector::Widget
|
111
|
+
widget = widget_class.new
|
112
|
+
dir = output_dir || File.dirname(file)
|
113
|
+
FileUtils.mkdir_p(dir)
|
114
|
+
output_file = "#{dir}/#{filename}.html"
|
115
|
+
File.open(output_file, "w") do |f|
|
116
|
+
f.puts widget.to_s
|
117
|
+
end
|
118
|
+
say " --> #{output_file}\n"
|
119
|
+
else
|
120
|
+
say " -- not a widget, skipping\n"
|
121
|
+
end
|
122
|
+
rescue => e
|
123
|
+
puts e
|
124
|
+
puts
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# stolen from activesuppport/lib/inflector.rb
|
130
|
+
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
131
|
+
if first_letter_in_uppercase
|
132
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
133
|
+
else
|
134
|
+
lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
|
135
|
+
end
|
136
|
+
end
|
137
|
+
def constantize(camel_cased_word)
|
138
|
+
unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
|
139
|
+
raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
|
140
|
+
end
|
141
|
+
Object.module_eval("::#{$1}", __FILE__, __LINE__)
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
@@ -6,8 +6,20 @@ module ActionView
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def render(template, local_assigns)
|
9
|
-
|
9
|
+
banana = @view.first_render
|
10
|
+
paths = banana.split('/')
|
10
11
|
dot_rb = /\.rb$/
|
12
|
+
file_path = "#{RAILS_ROOT}/app/views/#{banana}.rb"
|
13
|
+
if File.exists?(file_path)
|
14
|
+
require_dependency file_path
|
15
|
+
else
|
16
|
+
partial_file_path = file_path.gsub(/\/([^\/]*)$/, '/_\1')
|
17
|
+
if File.exists?(partial_file_path)
|
18
|
+
require_dependency partial_file_path
|
19
|
+
else
|
20
|
+
return
|
21
|
+
end
|
22
|
+
end
|
11
23
|
widget_class = paths.inject(Views) do |current_module, node|
|
12
24
|
current_module.const_get(node.gsub(dot_rb, '').camelize)
|
13
25
|
end
|
data/lib/erector/rhtml.treetop
CHANGED
@@ -13,7 +13,7 @@ grammar Rhtml
|
|
13
13
|
end
|
14
14
|
|
15
15
|
rule node
|
16
|
-
hprintlet / printlet / scriptlet / doctype / self_closing_tag / closetag / opentag / text
|
16
|
+
hprintlet / printlet / scriptlet / doctype / self_closing_tag / imgtag / closetag / opentag / text
|
17
17
|
end
|
18
18
|
|
19
19
|
rule scriptlet
|
@@ -85,6 +85,14 @@ grammar Rhtml
|
|
85
85
|
}
|
86
86
|
end
|
87
87
|
|
88
|
+
rule imgtag
|
89
|
+
'<' tag_name:'img' attrs:attributes? space '>' <Erector::Indenting> {
|
90
|
+
def convert
|
91
|
+
line "#{tag_name.text_value}#{attrs.blank? ? "" : attrs.convert}"
|
92
|
+
end
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
88
96
|
rule closetag
|
89
97
|
'</' tag_name:tagname '>' <Erector::Indenting> {
|
90
98
|
def convert
|
@@ -0,0 +1,145 @@
|
|
1
|
+
dir = File.dirname(__FILE__)
|
2
|
+
require "#{dir}/../spec_helper"
|
3
|
+
require "#{dir}/../../lib/erector/erect"
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
module Erector
|
7
|
+
describe Erect do
|
8
|
+
it "parses an empty command line" do
|
9
|
+
erect = Erect.new([])
|
10
|
+
erect.files.should == []
|
11
|
+
end
|
12
|
+
|
13
|
+
it "parses a command line with one filename on it" do
|
14
|
+
erect = Erect.new(["foo.html"])
|
15
|
+
erect.files.should == ["foo.html"]
|
16
|
+
end
|
17
|
+
|
18
|
+
it "parses a command line with several filenames on it" do
|
19
|
+
erect = Erect.new(["foo.html", "bar/baz.html"])
|
20
|
+
erect.files.should == ["foo.html", "bar/baz.html"]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "is verbose by default, but quiet when told" do
|
24
|
+
Erect.new([]).verbose.should be_true
|
25
|
+
Erect.new(["-q"]).verbose.should be_false
|
26
|
+
end
|
27
|
+
|
28
|
+
it "parses a command line with several filenames and an option on it" do
|
29
|
+
erect = Erect.new(["-q", "foo.html", "bar/baz.html"])
|
30
|
+
erect.files.should == ["foo.html", "bar/baz.html"]
|
31
|
+
end
|
32
|
+
|
33
|
+
def capture
|
34
|
+
output = StringIO.new
|
35
|
+
$stdout = output
|
36
|
+
yield
|
37
|
+
output.string
|
38
|
+
ensure
|
39
|
+
$stdout = STDOUT
|
40
|
+
end
|
41
|
+
|
42
|
+
it "exits immediately from help" do
|
43
|
+
output = capture do
|
44
|
+
lambda {
|
45
|
+
erect = Erect.new(["-h"])
|
46
|
+
}.should raise_error(SystemExit)
|
47
|
+
end
|
48
|
+
output.should =~ /^Usage/
|
49
|
+
end
|
50
|
+
|
51
|
+
it "exits immediately from --version" do
|
52
|
+
output = capture do
|
53
|
+
lambda {
|
54
|
+
erect = Erect.new(["--version"])
|
55
|
+
}.should raise_error(SystemExit)
|
56
|
+
end
|
57
|
+
output.should == Erector::VERSION + "\n"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "changes to html output" do
|
61
|
+
erect = Erect.new(["--to-html"])
|
62
|
+
erect.mode.should == :to_html
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "Erect functionally" do
|
68
|
+
|
69
|
+
attr_reader :dir, :fred_html, :wilma_rhtml, :barney_html_erb, :fred_rb
|
70
|
+
|
71
|
+
def create(file, body="hi")
|
72
|
+
File.open(file, "w") do |f|
|
73
|
+
f.puts(body)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
before :all do
|
78
|
+
@dir = Dir.tmpdir + "/#{Time.now.to_i}" + "/explode"
|
79
|
+
@fred_html = "#{dir}/fred.html"
|
80
|
+
@wilma_rhtml = "#{dir}/wilma.rhtml"
|
81
|
+
@barney_html_erb = "#{dir}/barney.html.erb"
|
82
|
+
@fred_rb = "#{dir}/fred.rb"
|
83
|
+
|
84
|
+
FileUtils.mkdir_p(dir)
|
85
|
+
create(fred_html)
|
86
|
+
create(wilma_rhtml)
|
87
|
+
create(barney_html_erb)
|
88
|
+
create(fred_rb, "class Fred < Erector::Widget\ndef render\ndiv 'dino'\nend\nend")
|
89
|
+
end
|
90
|
+
|
91
|
+
it "explodes dirs into .html etc. files when in to-rb mode" do
|
92
|
+
erect = Erect.new(["--to-erector", dir])
|
93
|
+
erect.files.sort.should == [barney_html_erb, fred_html, wilma_rhtml]
|
94
|
+
end
|
95
|
+
|
96
|
+
it "explodes dirs into .rb files when in to-html mode" do
|
97
|
+
erect = Erect.new(["--to-html", dir])
|
98
|
+
erect.files.should == [fred_rb]
|
99
|
+
end
|
100
|
+
|
101
|
+
it "outputs .rb files in the same directory as the input .html files" do
|
102
|
+
erect = Erect.new(["--to-erector", "-q", fred_html])
|
103
|
+
erect.run
|
104
|
+
File.exist?(fred_rb).should be_true
|
105
|
+
File.read(fred_rb).should include("text 'hi'")
|
106
|
+
end
|
107
|
+
|
108
|
+
it "outputs .html files in the same directory as the input .rb files" do
|
109
|
+
betty_rb = "#{dir}/betty.rb"
|
110
|
+
betty_html = "#{dir}/betty.html"
|
111
|
+
create(betty_rb, "class Betty < Erector::Widget\ndef render\ndiv 'bam bam'\nend\nend")
|
112
|
+
|
113
|
+
erect = Erect.new(["--to-html", "-q", betty_rb])
|
114
|
+
erect.run
|
115
|
+
File.exist?(betty_html).should be_true
|
116
|
+
File.read(betty_html).should == "<div>bam bam</div>\n"
|
117
|
+
end
|
118
|
+
|
119
|
+
it "outputs .html files in the given directory" do
|
120
|
+
create(fred_rb, "class Fred < Erector::Widget\ndef render\ndiv 'dino'\nend\nend")
|
121
|
+
|
122
|
+
|
123
|
+
out_dir = "#{dir}/out"
|
124
|
+
out_file = "#{out_dir}/fred.html"
|
125
|
+
Erect.new([]).output_dir.should be_nil
|
126
|
+
erect = Erect.new(["--to-html", "-o", "#{out_dir}", "-q", fred_rb])
|
127
|
+
erect.output_dir.should == out_dir
|
128
|
+
erect.run
|
129
|
+
File.exist?(out_file).should be_true
|
130
|
+
File.read(out_file).should == "<div>dino</div>\n"
|
131
|
+
end
|
132
|
+
|
133
|
+
it "supports the --add-to-svn option"
|
134
|
+
it "supports the --delete-original option"
|
135
|
+
|
136
|
+
it "skips rendering classes that aren't widgets" do
|
137
|
+
mr_slate_rb = "#{dir}/mr_slate.rb"
|
138
|
+
mr_slate_html = "#{dir}/mr_slate.html"
|
139
|
+
create(mr_slate_rb, "class MrSlate\nend")
|
140
|
+
erect = Erect.new(["--to-html", mr_slate_rb])
|
141
|
+
erect.run
|
142
|
+
File.exist?(mr_slate_html).should be_false
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
File without changes
|
@@ -84,6 +84,10 @@ describe RhtmlParser do
|
|
84
84
|
it "converts open, text, close" do
|
85
85
|
parse("<div>hello</div>").convert.should == "div do\n text 'hello'\nend\n"
|
86
86
|
end
|
87
|
+
|
88
|
+
it "autocloses an img tag" do
|
89
|
+
parse("<img src='foo'>").convert.should == "img :src => 'foo'\n"
|
90
|
+
end
|
87
91
|
|
88
92
|
it "converts a scriptlet" do
|
89
93
|
parse("<% foo %>").convert.should == "foo\n"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: erector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.83
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pivotal Labs
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-04-
|
12
|
+
date: 2008-04-23 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -49,9 +49,10 @@ extensions: []
|
|
49
49
|
extra_rdoc_files:
|
50
50
|
- README.txt
|
51
51
|
files:
|
52
|
-
- spec/
|
53
|
-
- spec/
|
54
|
-
- spec/
|
52
|
+
- spec/erect
|
53
|
+
- spec/erect/erect_spec.rb
|
54
|
+
- spec/erect/erected_spec.rb
|
55
|
+
- spec/erect/rhtml_parser_spec.rb
|
55
56
|
- spec/erector
|
56
57
|
- spec/erector/extensions
|
57
58
|
- spec/erector/extensions/render_widget_spec.rb
|
@@ -62,6 +63,7 @@ files:
|
|
62
63
|
- spec/spec_suite.rb
|
63
64
|
- spec/view_caching.rb
|
64
65
|
- lib/erector
|
66
|
+
- lib/erector/erect.rb
|
65
67
|
- lib/erector/erected.rb
|
66
68
|
- lib/erector/extensions
|
67
69
|
- lib/erector/extensions/action_controller.rb
|