Neurogami-rhesus 0.3.1 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -1,6 +1,8 @@
1
1
  lib/rhesus.rb
2
2
  lib/rhesus/core.rb
3
3
  lib/rhesus/utils.rb
4
+ lib/rhesus/common.rb
5
+ lib/rhesus/rhezamar.rb
4
6
  lib/templates/splash_screen
5
7
  lib/templates/basic/basic_view.rb
6
8
  lib/templates/basic/basic_ui.rb
data/README.md CHANGED
@@ -127,6 +127,28 @@ Rhesus starts with some assumptions about what files might be using Erb. You ca
127
127
 
128
128
  By default, the file-end patterns are: `rb txt rhtml ini yml yaml Rakefile gemspec`.
129
129
 
130
+
131
+ NOTE: A recent addition, and still evolving, is the use of a `.options.yaml` file in the root of a template folder.
132
+
133
+ The problem is that you may have a large set files that do not need any template processing.
134
+
135
+ Worse, some files may be actual templates (or contain Erb markup) that should be copied over as-is, but would otherwise get preprocessed.
136
+
137
+ a `.options.yaml` file can contain a hash of file patterns, like this
138
+
139
+
140
+ noparse:
141
+ - /gems/gems/rack
142
+ - .git/
143
+
144
+ ignore:
145
+ - .git/
146
+
147
+ This tells `rhesus` that any file whose template path matches on any of the items listed un `noparse` should not be parsed for tempalte variables, and simply copied over as-is.
148
+
149
+ The array under `ignore` means to ignore any files or directories that match on that substring. No parsing, no copying.
150
+
151
+
130
152
  When you select a template set, Rhesus scans these files for Erb variables. It then prompts
131
153
  you to provide values. If you use any of these variable names in file or path names then Rhesus
132
154
  will apply those values to the names and paths when applying the template.
@@ -138,6 +160,7 @@ will have the same value used in both.
138
160
  If a file in a template set is not among the file types that may have Erb (e.g., jar, dll, gif)
139
161
  then it will be copied over as-is.
140
162
 
163
+
141
164
 
142
165
  For example:
143
166
 
@@ -209,6 +232,17 @@ Note: Some of the code for auto-mangling file and path names is changing. Init
209
232
  But these other things have different conventions; code to apply appropriate conventions is being added.
210
233
 
211
234
 
235
+ NOTE: Another recent evolving features is the use of "rhamaze" templating.
236
+
237
+ Suppose you have a Ramaze project template set, with some `.xhtml` files that contain Erb markup. You do not want Rhesus to preprocess this as Erb, but you *do* want to have some interpolated variables.
238
+
239
+ So, you need to add a leading line that contains the string `RHEMAZAR` and do your rhesus variables using this syntax:
240
+
241
+ <|= my_variable |>
242
+
243
+ That leading line will be skipped when processing the file.
244
+
245
+
212
246
  REQUIREMENTS
213
247
  -------------
214
248
 
data/Rakefile CHANGED
@@ -23,8 +23,9 @@ PROJ.authors = 'James Britt / Neurogami'
23
23
  PROJ.email = 'james@neurogami.com'
24
24
  PROJ.url = 'http://code.neurogami.com'
25
25
  PROJ.version = Neurogami::Rhesus::VERSION
26
- PROJ.readme_file = 'README.md'
27
26
  PROJ.summary = "Really simple, practical code generator."
27
+ PROJ.readme_file = 'README.md'
28
+
28
29
 
29
30
 
30
31
  desc "Bacon specs"
data/bin/rhesus CHANGED
@@ -29,6 +29,7 @@ def process_template template_name
29
29
  puts " - Using template #{template_name.inspect}"
30
30
 
31
31
  var_set = {}
32
+ Neurogami::Rhesus::Core.load_options template_name
32
33
 
33
34
  Neurogami::Rhesus::Core.required_vars_for_template_set(template_name).each do |var|
34
35
  print "Value for #{var}: "
@@ -121,7 +122,9 @@ def generate_from_template filter = /.*/
121
122
 
122
123
  end
123
124
  end
125
+
124
126
  #-------------------------------------------------
127
+
125
128
  if ARGV.empty?
126
129
  help
127
130
  else
@@ -139,6 +142,9 @@ else
139
142
 
140
143
  when '--setup'
141
144
  setup
145
+
146
+ when '--install' || '-i'
147
+ install_template_from_repo
142
148
  else
143
149
  #puts "Nothing known about #{ARGV[0]}"
144
150
  # Treat the same as gen, but use the argument as a pattern filter to reduce the number of items show
@@ -0,0 +1,27 @@
1
+ module Neurogami
2
+ module Rhesus
3
+
4
+ module Common
5
+
6
+ module ClassMethods
7
+
8
+ def user_dir_exists?
9
+ File.exists? user_template_directory
10
+ end
11
+
12
+ def user_template_directory
13
+ File.expand_path "~/.rhesus"
14
+ end
15
+ end
16
+
17
+
18
+
19
+ def self.included(base)
20
+ base.extend(ClassMethods)
21
+ end
22
+
23
+ end
24
+
25
+
26
+ end
27
+ end
data/lib/rhesus/core.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'pp'
2
2
  require 'erb'
3
3
 
4
+
4
5
  class String
5
6
  def to_snake_case
6
7
  snake_case self
@@ -20,6 +21,14 @@ module Neurogami
20
21
 
21
22
  class Core
22
23
 
24
+ include Neurogami::Rhesus::Common
25
+
26
+
27
+ ERB_RE = {
28
+ :ruby_erb => /(<%=)\s*(\S+)\s*(%>)/,
29
+ :rhemazar => /(<\|=\s*)(\S+)(\s*\|>)/
30
+
31
+ }
23
32
  # http://refactormycode.com/codes/281-given-a-hash-of-variables-render-an-erb-template
24
33
  @@m = Module.new do
25
34
  class << self
@@ -41,10 +50,27 @@ module Neurogami
41
50
  end
42
51
  end
43
52
 
44
- def self.process_template template_text, variables_hash
53
+ # Can something be added so that if this is actual Erb content it
54
+ # is processed using not-Erb?
55
+ def self.process_template template_text, variables_hash, erb = :ruby_erb
56
+ if variables_hash.empty?
57
+ return template_text
58
+ end
59
+
60
+ # :rhemazar : :ruby_erb
45
61
  create_methods_from_hash variables_hash
46
- t = ERB.new(template_text, 0, "%<>")
47
- t.result @@m.binding
62
+ case erb
63
+ when :eruby_erb
64
+ t = ERB.new(template_text, 0, "%<>")
65
+ t.result @@m.binding
66
+ when :rhemazar
67
+ t = Neurogami::Rhesus::Rhezamar.new template_text
68
+ t.result variables_hash
69
+ else
70
+ t = ERB.new(template_text, 0, "%<>")
71
+ t.result @@m.binding
72
+ end
73
+
48
74
  end
49
75
 
50
76
  def self.projects
@@ -59,19 +85,48 @@ module Neurogami
59
85
  end
60
86
 
61
87
 
88
+ # Trouble: Suppose your template set includes a file, index.xhtml, and
89
+ # that file is meant to be an Erb template. The <%= foo %> stuff inside
90
+ # is exactly what should be copied over; it should *not* be preprocessed.
91
+ #
92
+ # How can Rhesus be told to not preprocess some file? It's tricky, if you want,
93
+ # for example, to have a file that has Rhesus-substitution AND do-not-touch Erb.
94
+ # One option could be to have certain file types use a different Rhesus-magic
95
+ # variable syntax:
96
+ #
97
+ # <?r= ?> in place of <%= %>
62
98
  #
99
+ # Perhaps files that need special treatment can have some magic comment up top?
100
+ # Too fugly?
101
+ #
102
+ # Thu Sep 10 23:01:43 MST 2009
103
+ # Using a modifued version of Ezamar engine.
104
+ # Still need a nice way to indicate when this is to be used;
105
+ # current approach has RHEMAZAR in the first line of the file, which
106
+ # should get striped
63
107
  def self.required_vars_for_template_set template_name
64
- #template_name.identifier_to_path!
108
+
65
109
  vars = []
66
110
 
67
111
  selected_template_files(template_name).map do |path|
68
112
  next unless File.file? path
69
113
  next unless path =~ @@re
114
+ next if ignore(path, @@options['ignore'])
115
+
116
+ next if path =~ /\.git$/
117
+ load_options template_name
118
+ next if no_parse( path, @@options['noparse'] )
119
+ next if ignore(path, @@options['ignore'])
120
+
70
121
  file_lines = IO.readlines path
71
- vars.concat(required_vars(file_lines))
72
- #file_lines.each do |v|
73
- # vars[v] = v
74
- #end
122
+ top_line = file_lines.first
123
+
124
+ erb = :ruby_erb
125
+ if top_line =~ /RHEMAZAR/
126
+ file_lines.shift
127
+ erb = :rhemazar
128
+ end
129
+ vars.concat required_vars(file_lines, erb)
75
130
  end
76
131
  vars.uniq!
77
132
  vars.sort
@@ -85,13 +140,21 @@ module Neurogami
85
140
  end
86
141
  end
87
142
 
88
- def self.required_vars file_lines
143
+ def self.required_vars file_lines, erb_style = :ruby_erb
144
+
145
+ if erb_style == :rhemazar
146
+ end
89
147
  vars = []
90
148
  file_lines.each do |l|
91
- vars.concat l.scan(/(<%=)\s*(\S+)\s*(%>)/).map{ |m| m[1].strip.split('.').first}
92
- #variables.each do |v|
93
- # vars[v] = v
94
- #end
149
+ # XXX
150
+ re = ERB_RE[erb_style]
151
+ _v = l.scan( ERB_RE[erb_style] ).map do |m|
152
+ m[1].strip.split('.').first
153
+ end
154
+
155
+ unless _v.to_s.strip.empty?
156
+ vars.concat _v
157
+ end
95
158
  end
96
159
  vars.uniq
97
160
  end
@@ -118,25 +181,18 @@ module Neurogami
118
181
  end
119
182
  end
120
183
 
121
- def self.user_dir_exists?
122
- File.exists? user_template_directory
123
- end
124
-
125
- def self.user_template_directory
126
- File.expand_path "~/.rhesus"
127
- end
128
184
 
129
185
  def self.language_appropriate_renaming path, template_var, given_value
130
186
  # Hack to see what might work:
131
187
  renaming_map = {
132
188
  /\.rb$/ => :to_snake_case
133
189
  }
134
- renaming_map.each do |file_pattern, renaming_method|
135
- if path =~ file_pattern
136
- return path.gsub( template_var, given_value.send(renaming_method) )
137
- end
190
+ renaming_map.each do |file_pattern, renaming_method|
191
+ if path =~ file_pattern
192
+ return path.gsub( template_var, given_value.send(renaming_method) )
138
193
  end
139
- path.gsub( template_var, given_value )
194
+ end
195
+ path.gsub( template_var, given_value )
140
196
  end
141
197
 
142
198
  # How can this be tested? This method is more or less the core of the
@@ -154,30 +210,87 @@ module Neurogami
154
210
  short_path = path.sub user_template_directory, ''
155
211
  real_path = short_path.sub(template_name + '/', '')
156
212
 
213
+ return if ignore(path, @@options['ignore'])
214
+
157
215
  var_set.each { |key, value| real_path = language_appropriate_renaming( real_path, key, value ) }
158
-
216
+
159
217
  write_to = location + real_path
160
218
  destination_dir = File.expand_path(File.dirname(write_to))
161
219
  FileUtils.mkdir_p destination_dir
162
220
  file_to_write_to = File.expand_path write_to
163
221
  rename( file_to_write_to ) if File.exist? file_to_write_to
222
+
223
+
164
224
  # Do a straight file copy unless this file might be using Erb
165
- if path =~ @@re
166
- source_text = IO.read path
167
- text = process_template source_text, var_set
225
+
226
+ if path =~ @@re && !no_parse( path, @@options['noparse'] )
227
+
228
+ source_text = IO.readlines path
229
+ # A shame we read each file twice FIXME
230
+ top_line = source_text.first
231
+
232
+ erb = :ruby_erb
233
+ if top_line =~ /RHEMAZAR/
234
+ erb = :rhemazar
235
+ source_text.shift
236
+ end
237
+
238
+ text = process_template source_text.join, var_set, erb
239
+ warn "Create #{file_to_write_to}"
240
+
168
241
  File.open(file_to_write_to, "w"){|f| f.puts text }
169
242
  else
243
+ warn "Copy #{path} to #{file_to_write_to}"
170
244
  FileUtils.cp path, file_to_write_to
171
245
  end
172
246
  end
173
247
 
174
248
 
249
+ def self.ignore path, ignore_filters
250
+ return false if ignore_filters.nil? || ignore_filters.empty?
251
+ ignore_filters.each do |patt|
252
+ return true if path =~ patt
253
+ end
254
+ false
255
+ end
256
+ def self.no_parse path, no_parse_filters = []
257
+ return false if no_parse_filters.nil? or no_parse_filters.empty?
258
+ no_parse_filters.each do |patt|
259
+ return true if path =~ patt
260
+ end
261
+ false
262
+ end
263
+
264
+ def self.load_options template_name
265
+ full_path = user_template_directory + '/' + template_name
266
+
267
+ @@options ||= if File.exist? full_path+ '/.options.yaml'
268
+ o = YAML.load(IO.read( full_path + '/.options.yaml'))
269
+ o['noparse'] ||= []
270
+ o['noparse'].map!{ |patt| Regexp.new(Regexp.escape(patt)) }
271
+ o['ignore'] ||= []
272
+ o['ignore'] << '.options.yaml'
273
+ o['ignore'].map!{ |patt| Regexp.new(Regexp.escape(patt)) }
274
+ o
275
+ else
276
+ {}
277
+ end
278
+
279
+
280
+ end
281
+
282
+
175
283
  def self.rename full_file_path
176
284
  ts = Time.now.to_i.to_s
177
285
  FileUtils.mv full_file_path, full_file_path + '.' + ts
178
286
  end
179
287
 
180
288
 
289
+
290
+
291
+
292
+
293
+
181
294
  # Hacky :( FIXME Add a better way to define what files get slurped for parsing
182
295
  haz_vars = %w{ rb txt rhtml ini yml yaml Rakefile rake gemspec feature}
183
296
  add_user_haz_vars haz_vars
@@ -185,5 +298,7 @@ module Neurogami
185
298
  @@re = Regexp.new "(#{@@re})$"
186
299
 
187
300
  end
301
+
302
+
188
303
  end
189
304
  end
@@ -0,0 +1,35 @@
1
+
2
+ module Neurogami
3
+ module Rhesus
4
+
5
+ class InstallationError < Exception
6
+ end
7
+
8
+ class Installer
9
+
10
+
11
+ include Neurogami::Rhesus::Common
12
+
13
+ class << self
14
+
15
+
16
+ def install_from_repo repo_url
17
+ raise InstallationError.new("No ~/.rhesus folder") unless user_dir_exists?
18
+ begin
19
+ Dir.chdir(user_template_directory) do
20
+ git_repo_clone repo_url
21
+ end
22
+ rescue Exception
23
+ raise InstallationError.new("Error cloning repo: #{$!}")
24
+ end
25
+ end
26
+
27
+
28
+ def git_repo_clone repo_url
29
+ warn `git clone #{repo_url}`
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,18 @@
1
+ module Neurogami
2
+ module Rhesus
3
+ class Rhezamar
4
+
5
+ def initialize text
6
+ @text = text
7
+ end
8
+
9
+ def result variables_hash
10
+ t = @text.dup
11
+ variables_hash.each do |k, v|
12
+ t.gsub!( /<\|=\s*#{k}\s*\|>/m, v )
13
+ end
14
+ t
15
+ end
16
+ end
17
+ end
18
+ end
data/lib/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Neurogami
2
2
  module Rhesus
3
3
  # :stopdoc:
4
- VERSION = '0.3.1'
4
+ VERSION = '0.3.3'
5
5
 
6
6
  def self.version
7
7
  VERSION
data/test/test_rhesus.rb CHANGED
@@ -1,6 +1,17 @@
1
1
  require 'rubygems'
2
2
  require 'bacon'
3
- require 'lib/rhesus/core'
3
+
4
+ h = File.expand_path(File.dirname(__FILE__))
5
+ $:.unshift h + '/../lib/'
6
+
7
+ require 'rhesus'
8
+
9
+ #require 'lib/rhesus/core'
10
+ #require 'lib/rhesus/installer'
11
+
12
+
13
+ require 'mockfs'
14
+
4
15
 
5
16
  $here = File.expand_path(File.dirname(__FILE__))
6
17
 
@@ -54,5 +65,54 @@ describe 'The core Rhesus code' do
54
65
 
55
66
  end
56
67
 
68
+
69
+ it 'needs to know when a file with Erb is not meant to be interpolated' do
70
+
71
+ template_text = "Hey! \n<|= zoobar |> got <%= _adj1 %>, \nand I'm <%= _adj2 %> <%= _adj3 %>. And <|= goober |> mean <%= _adj2 %> <%= _adj3 %>"
72
+
73
+ vars = Neurogami::Rhesus::Core.required_vars( template_text.split( "\n"), :rhemazar )
74
+ vars.sort!
75
+ vars.should == ['goober', 'zoobar' ]
76
+
77
+ end
78
+
79
+
80
+
81
+ it 'needs to handle rhezamar templating' do
82
+
83
+ variables_hash = {'zoobar' => 'Jimbo', 'goober' => 'Goober' }
84
+ template_text = "<|= zoobar |> got <%= _adj1 %>, \nand I'm <%= _adj2 %> <%= _adj3 %>. And <|= goober |> mean <%= _adj2 %> <%= _adj3 %>"
85
+ expected = "Jimbo got <%= _adj1 %>, \nand I'm <%= _adj2 %> <%= _adj3 %>. And Goober mean <%= _adj2 %> <%= _adj3 %>"
86
+ t = Neurogami::Rhesus::Rhezamar.new template_text
87
+ results = t.result variables_hash
88
+ results.should.equal expected
89
+
90
+
91
+ end
57
92
  end
58
93
 
94
+ describe 'The Rhesus installer' do
95
+ MockFS.mock = true
96
+
97
+ it 'would be super-duper if it handled a git repo URL as a means to install a new template' do
98
+ repo_url = 'git://github.com/Neurogami/gae.ramaze.git'
99
+
100
+ lambda { Neurogami::Rhesus::Installer.install_from_repo repo_url }.should.not.raise(Neurogami::Rhesus::InstallationError)
101
+
102
+
103
+ end
104
+
105
+
106
+ # it 'knows when a repo URL is valid' do
107
+ # repo_url = 'git@github.com:Neurogami/andi.git'
108
+ # Neurogami::Rhesus::Installer.is_valid_repo_url?(repo_url).should.equal true
109
+
110
+ # end
111
+
112
+ # it 'can pull out repo URL parts' do
113
+
114
+ # end
115
+
116
+ MockFS.mock = false
117
+
118
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Neurogami-rhesus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Britt / Neurogami
@@ -41,6 +41,9 @@ files:
41
41
  - lib/rhesus.rb
42
42
  - lib/rhesus/core.rb
43
43
  - lib/rhesus/utils.rb
44
+ - lib/rhesus/installer.rb
45
+ - lib/rhesus/common.rb
46
+ - lib/rhesus/rhezamar.rb
44
47
  - lib/templates/about/about_controller.rb
45
48
  - lib/templates/about/about_model.rb
46
49
  - lib/templates/about/about_ui.rb