Class: Metasploit::Model::Spec::Template
- Extended by:
- ActiveModel::Callbacks, ActiveSupport::Autoload
- Includes:
- ActiveModel::Validations::Callbacks
- Defined in:
- app/models/metasploit/model/spec/template.rb
Overview
Processes '.rb.erb' templates to create Module::Ancestor#contents that contain the same metadata as the Module::Ancestor, Module::Class, Module::Instance and associations for those contents. This ensures that when the Module::Ancestor#contents are loaded in metasploit-framework, the same metadata instances are derived from the contents ensuring idempotency of the contents and metadata parsing loop.
Direct Known Subclasses
Defined Under Namespace
Modules: Write
Constant Summary collapse
- BACKTRACE_FILE_REGEXP =
Regular expression to parse file from backtrace line
/(?<file>.*):\d+:in .*/
- EXPLICIT_TRIM_MODE =
Trim mode for ERB templates so that lines using <%- -%> will be trimmed of new lines
'-'
- EXTENSION =
File extension for templates.
'.rb.erb'
Instance Attribute Summary collapse
-
#destination_pathname ⇒ String
The pathname where to #write the template results.
-
#locals ⇒ Hash{Symbol => Object}
Local variables to exposed to partials.
-
#overwrite ⇒ Boolean
Whether to overwrite a pre-existing file.
-
#search_pathnames ⇒ Array<Pathname>
Pathnames to search for partials.
-
#source_relative_name ⇒ String
Name of template under #search_pathnames without EXTENSION similar to how to refer to partials.
Class Method Summary collapse
-
.root ⇒ Pathname
The root of all relative #search_pathnames.
-
.root=(root) ⇒ Pathname
Sets the Template.root pathname for all #search_pathnames, including those on subclasses.
Instance Method Summary collapse
-
#find_pathname(relative_path) ⇒ Pathname?
private
Finds relative_path under #search_pathnames.
-
#partial_pathname(partial_relative_path) ⇒ Pathname?
Converts the
partial_relative_path
to a real (absolute) pathname that can be passed to #result by finding the corresponding file in the #search_pathnames. -
#render(partial_relative_path, options = {}) ⇒ String?
Renders partial in templates.
-
#render_super ⇒ String?
Renders the super template of the current template by searching for the template of the same name under super #search_pathnames (those that have a higher index).
- #result(pathname, options = {}) ⇒ Object
-
#search_real_pathnames ⇒ void
private
Makes sure all #search_pathnames are real (absolute).
-
#source_pathname ⇒ Pathname?
Converts #source_relative_name to a real (absolute) pathname.
-
#write ⇒ void
Writes result of template to #destination_pathname.
Methods inherited from Base
Constructor Details
This class inherits a constructor from Metasploit::Model::Base
Instance Attribute Details
#destination_pathname ⇒ String
The pathname where to #write the template results.
36 37 38 |
# File 'app/models/metasploit/model/spec/template.rb', line 36 def destination_pathname @destination_pathname end |
#locals ⇒ Hash{Symbol => Object}
Local variables to exposed to partials.
42 43 44 |
# File 'app/models/metasploit/model/spec/template.rb', line 42 def locals @locals end |
#overwrite ⇒ Boolean
Whether to overwrite a pre-existing file.
48 49 50 |
# File 'app/models/metasploit/model/spec/template.rb', line 48 def overwrite @overwrite end |
#search_pathnames ⇒ Array<Pathname>
Pathnames to search for partials. First item is search first, etc.
54 55 56 |
# File 'app/models/metasploit/model/spec/template.rb', line 54 def search_pathnames @search_pathnames end |
#source_relative_name ⇒ String
Name of template under #search_pathnames without EXTENSION similar to how to refer to partials.
60 61 62 |
# File 'app/models/metasploit/model/spec/template.rb', line 60 def source_relative_name @source_relative_name end |
Class Method Details
.root ⇒ Pathname
The root of all relative #search_pathnames. By changing root you can use your own set of templates.
202 203 204 |
# File 'app/models/metasploit/model/spec/template.rb', line 202 def root @@root ||= Metasploit::Model::Engine.root.join('spec', 'support', 'templates', 'metasploit', 'model') end |
.root=(root) ⇒ Pathname
Sets the root pathname for all #search_pathnames, including those on subclasses.
210 211 212 |
# File 'app/models/metasploit/model/spec/template.rb', line 210 def root=(root) @@root = root end |
Instance Method Details
#find_pathname(relative_path) ⇒ Pathname? (private)
Finds relative_path under #search_pathnames
253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'app/models/metasploit/model/spec/template.rb', line 253 def find_pathname(relative_path) found_pathname = nil search_pathnames.each do |search_pathname| real_pathname = search_pathname.join(relative_path) if real_pathname.exist? found_pathname = real_pathname break end end found_pathname end |
#partial_pathname(partial_relative_path) ⇒ Pathname?
Converts the partial_relative_path
to a real (absolute) pathname that can be passed to #result by finding the
corresponding file in the #search_pathnames.
99 100 101 102 103 104 105 106 107 |
# File 'app/models/metasploit/model/spec/template.rb', line 99 def partial_pathname(partial_relative_path) partial_relative_pathname = Pathname.new(partial_relative_path) relative_directory = partial_relative_pathname.dirname raw_basename = partial_relative_pathname.basename partial_basename = "_#{raw_basename}#{EXTENSION}" relative_pathname = relative_directory.join(partial_basename) find_pathname(relative_pathname) end |
#render(partial_relative_path, options = {}) ⇒ String?
Renders partial in templates.
116 117 118 119 |
# File 'app/models/metasploit/model/spec/template.rb', line 116 def render(partial_relative_path, ={}) pathname = partial_pathname(partial_relative_path) result(pathname, ) end |
#render_super ⇒ String?
Renders the super template of the current template by searching for the template of the same name under super #search_pathnames (those that have a higher index).
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'app/models/metasploit/model/spec/template.rb', line 127 def render_super super_pathname = nil backtrace = caller match = BACKTRACE_FILE_REGEXP.match(backtrace[0]) if match real_path = match[:file] current_search_pathname_found = false relative_pathname = nil search_pathnames.each do |search_pathname| # find the current index unless current_search_pathname_found if real_path.starts_with?(search_pathname.to_path) current_search_pathname_found = true real_pathname = Pathname.new(real_path) relative_pathname = real_pathname.relative_path_from(search_pathname) end # then switch to finding the next (super) index else real_pathname = search_pathname.join(relative_pathname) if real_pathname.exist? super_pathname = real_pathname break end end end unless super_pathname raise IOError, "Couldn't find super template" end else raise RegexpError, "Can't parse file from backtrace to determine current search path" end result(super_pathname) end |
#result(pathname, options = {}) ⇒ Object
Must be an instance method
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'app/models/metasploit/model/spec/template.rb', line 172 def result(pathname, ={}) .assert_valid_keys(:locals) if pathname content = pathname.read safe_level = nil template = ERB.new content, safe_level, EXPLICIT_TRIM_MODE template.filename = pathname.to_path erb_binding = binding.dup locals = self.locals || {} result_locals = [:locals] || {} merged_locals = locals.merge(result_locals) merged_locals.each do |name, value| erb_binding.eval("#{name} = nil; lambda { |value| #{name} = value }").call(value) end # use current binding to allow templates to call {#render} and then use {#method_missing} to allow access to # locals template.result(erb_binding) else '' end end |
#search_real_pathnames ⇒ void (private)
This method returns an undefined value.
Makes sure all #search_pathnames are real (absolute). Relative pathnames are resolved against root.
271 272 273 274 275 276 277 278 279 |
# File 'app/models/metasploit/model/spec/template.rb', line 271 def search_real_pathnames search_pathnames.collect! { |search_pathname| if search_pathname.relative? self.class.root.join(search_pathname) else search_pathname end } end |
#source_pathname ⇒ Pathname?
Converts #source_relative_name to a real (absolute) pathname.
218 219 220 221 222 223 224 225 |
# File 'app/models/metasploit/model/spec/template.rb', line 218 def source_pathname unless instance_variable_defined? :@source_pathname relative_path = "#{source_relative_name}#{EXTENSION}" @source_pathname = find_pathname(relative_path) end @source_pathname end |
#write ⇒ void
This method returns an undefined value.
Writes result of template to #destination_pathname.
232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'app/models/metasploit/model/spec/template.rb', line 232 def write unless overwrite Metasploit::Model::Spec::PathnameCollision.check!(destination_pathname) end result = self.result(source_pathname) # make directory destination_pathname.parent.mkpath destination_pathname.open('wb') do |f| f.write(result) end end |