Class: Neurogami::Rhesus::Core

Inherits:
Object
  • Object
show all
Includes:
Common
Defined in:
lib/rhesus/core.rb

Constant Summary collapse

ERB_RE =
{
  :ruby_erb => /(<%=)\s*(\S+)\s*(%>)/,
  :rhemazar => /(<\|=\s*)(\S+)(\s*\|>)/

}
@@m =
Module.new do
  class << self
    public :binding
    def meta
      class << self; self; end
    end
  end
   class << meta
    public :define_method
  end
 end
@@re =
Regexp.new "(#{@@re})$"

Class Method Summary collapse

Methods included from Common

included

Class Method Details

.add_user_haz_vars(haz_vars) ⇒ Object



178
179
180
181
182
# File 'lib/rhesus/core.rb', line 178

def self.add_user_haz_vars haz_vars
  if File.exist?(File.expand_path( user_template_directory + '/haz_vars.txt'))
    IO.readlines(File.expand_path( user_template_directory + '/haz_vars.txt')).each { |x| haz_vars  << x.strip  unless x.strip.empty? }
  end
end

.create_methods_from_hash(variables_hash) ⇒ Object



47
48
49
50
51
# File 'lib/rhesus/core.rb', line 47

def self.create_methods_from_hash variables_hash
  variables_hash.each do |name, value|
    @@m.meta.define_method(name) { value }
  end
end

.get_project_template_filesObject



170
171
172
# File 'lib/rhesus/core.rb', line 170

def self.get_project_template_files
  Dir.glob user_template_directory + '/*'
end

.get_projects_directoriesObject

Isolate any methods that touch the file system so we can test more easily



166
167
168
# File 'lib/rhesus/core.rb', line 166

def self.get_projects_directories
  Dir.glob user_template_directory + '/*'
end

.ignore(path, ignore_filters) ⇒ Object



249
250
251
252
253
254
255
# File 'lib/rhesus/core.rb', line 249

def self.ignore path, ignore_filters 
  return false if ignore_filters.nil?  || ignore_filters.empty?
  ignore_filters.each do |patt|
    return true if path =~ patt
  end
  false
end

.language_appropriate_renaming(path, template_var, given_value) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/rhesus/core.rb', line 185

def self.language_appropriate_renaming path, template_var, given_value
  # Hack to see what might work:
  renaming_map = {
    /\.rb$/ => :to_snake_case
  }
  renaming_map.each do |file_pattern, renaming_method|
    if path =~ file_pattern
      return path.gsub( template_var, given_value.send(renaming_method) )
    end
  end
  path.gsub( template_var, given_value )
end

.load_options(template_name) ⇒ Object



264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/rhesus/core.rb', line 264

def self.load_options template_name
  full_path = user_template_directory + '/' + template_name 

  @@options ||= if File.exist? full_path+ '/.options.yaml'
                  o = YAML.load(IO.read( full_path + '/.options.yaml'))
    o['noparse'] ||= []
    o['noparse'].map!{ |patt| Regexp.new(Regexp.escape(patt)) }
    o['ignore'] ||= []
    o['ignore'] << '.options.yaml'
    o['ignore'].map!{ |patt| Regexp.new(Regexp.escape(patt)) }
    o
                else
                  {}
                end


end

.no_parse(path, no_parse_filters = []) ⇒ Object



256
257
258
259
260
261
262
# File 'lib/rhesus/core.rb', line 256

def self.no_parse path,  no_parse_filters = []
  return false if no_parse_filters.nil? or no_parse_filters.empty?
  no_parse_filters.each do |patt|
    return true if path =~ patt
  end
  false
end

.process(template_name, var_set, location, path) ⇒ Object

How can this be tested? This method is more or less the core of the tool (other key method: extracting the set of vars from the templates) The trouble is that the code works by creating a side effect; the return value is nothing.

This method does multiple things: computes file paths; alters file path basedon variable values; calls out to read in file text, alter it with variable subsition, and write it out; do direct file copies.



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/rhesus/core.rb', line 208

def self.process template_name, var_set, location, path
  relative_path  = path.sub user_template_directory , ''
  short_path = path.sub user_template_directory, ''
  real_path = short_path.sub(template_name + '/', '')

  return if ignore(path, @@options['ignore'])

  var_set.each { |key, value| real_path = language_appropriate_renaming( real_path, key, value ) }

  write_to = location + real_path 
  destination_dir = File.expand_path(File.dirname(write_to))
  FileUtils.mkdir_p destination_dir
  file_to_write_to  = File.expand_path write_to
  rename( file_to_write_to ) if File.exist? file_to_write_to 


  # Do a straight file copy unless this file might be using Erb

  if path =~ @@re && !no_parse( path, @@options['noparse']   )

    source_text = IO.readlines path
    # A shame we read each file twice FIXME
    top_line = source_text.first

    erb = :ruby_erb 
    if top_line =~ /RHEMAZAR/  
      erb = :rhemazar
      source_text.shift
    end

    text = process_template source_text.join, var_set, erb
    warn "Create #{file_to_write_to}"

    File.open(file_to_write_to, "w"){|f| f.puts text }
  else
    warn "Copy #{path} to #{file_to_write_to}"
    FileUtils.cp path, file_to_write_to
  end
end

.process_template(template_text, variables_hash, erb = :ruby_erb) ⇒ Object

Can something be added so that if this is actual Erb content it is processed using not-Erb?



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/rhesus/core.rb', line 55

def self.process_template template_text, variables_hash, erb  = :ruby_erb
  if variables_hash.empty?
    return template_text
  end

  # :rhemazar : :ruby_erb
  create_methods_from_hash variables_hash
  case erb
  when :eruby_erb
    t = ERB.new(template_text, 0, "%<>")
    t.result @@m.binding
  when :rhemazar 
    t = Neurogami::Rhesus::Rhezamar.new template_text
    t.result variables_hash
  else
    t = ERB.new(template_text, 0, "%<>")
    t.result @@m.binding
  end

end

.projectsObject



76
77
78
79
80
81
# File 'lib/rhesus/core.rb', line 76

def self.projects
  get_projects_directories.map { |path|
    path.sub! user_template_directory + '/', ''
    path
  }
end

.rename(full_file_path) ⇒ Object



283
284
285
286
# File 'lib/rhesus/core.rb', line 283

def self.rename full_file_path
  ts = Time.now.to_i.to_s
  FileUtils.mv full_file_path, full_file_path + '.' + ts 
end

.required_vars(file_lines, erb_style = :ruby_erb) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/rhesus/core.rb', line 143

def self.required_vars file_lines, erb_style = :ruby_erb

  if erb_style == :rhemazar
  end
  vars = []
  file_lines.each do |l|
    # XXX
    re = ERB_RE[erb_style]
    _v = l.scan( ERB_RE[erb_style] ).map do |m| 
      m[1].strip.split('.').first
    end

    unless _v.to_s.strip.empty?
      vars.concat  _v
    end
  end
  vars.uniq
end

.required_vars_for_template_set(template_name) ⇒ Object

Trouble: Suppose your template set includes a file, index.xhtml, and that file is meant to be an Erb template. The <%= foo %> stuff inside is exactly what should be copied over; it should not be preprocessed.

How can Rhesus be told to not preprocess some file? It’s tricky, if you want, for example, to have a file that has Rhesus-substitution AND do-not-touch Erb. One option could be to have certain file types use a different Rhesus-magic variable syntax:

<?r=   ?>  in place of <%= %>

Perhaps files that need special treatment can have some magic comment up top? Too fugly?

Thu Sep 10 23:01:43 MST 2009

Using a modifued version of Ezamar engine.

Still need a nice way to indicate when this is to be used; current approach has RHEMAZAR in the first line of the file, which should get striped



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/rhesus/core.rb', line 107

def self.required_vars_for_template_set template_name

  vars = []

  selected_template_files(template_name).map do |path|
    next unless File.file? path
    next unless path =~ @@re
    next if  ignore(path, @@options['ignore'])

    next if path =~ /\.git$/
    load_options template_name
    next  if no_parse( path, @@options['noparse']   ) 
    next if  ignore(path, @@options['ignore'])

    file_lines = IO.readlines path
    top_line = file_lines.first

    erb = :ruby_erb 
    if top_line =~ /RHEMAZAR/  
      file_lines.shift
      erb = :rhemazar
    end
    vars.concat required_vars(file_lines, erb)
  end
  vars.uniq!
  vars.sort
end

.selected_template_files(template_name) ⇒ Object



174
175
176
# File 'lib/rhesus/core.rb', line 174

def self.selected_template_files template_name
  Dir.glob( user_template_directory + '/' + template_name + '/**/*', File::FNM_DOTMATCH).select { |f| f !~ /\.$/ }
end

.templatesObject



135
136
137
138
139
140
141
# File 'lib/rhesus/core.rb', line 135

def self.templates
  get_project_template_files.map do |path|
    # Remove the base path
    path.sub! user_template_directory + '/', ''
    path
  end
end

.tuple_base_name_pair(name) ⇒ Object



83
84
85
# File 'lib/rhesus/core.rb', line 83

def self.tuple_base_name_pair name
  [snake_case(name), camelize(name)]
end