Class: Shojiku::TemplateRoot
- Inherits:
-
Object
- Object
- Shojiku::TemplateRoot
- Defined in:
- lib/shojiku/template_root.rb
Overview
Resolving a template NAME to the sources behind it.
A name is an identifier, never a path. A bundle format will take this
lookup over later, so nothing outside this class may assume a directory is
how names resolve — callers ask for "receipt_ja" and get sources back.
The rejection rules are the union across platforms, not the host's.
Windows is a first-class target (it is what the .NET SDK's market runs
on), so a backslash is a separator, C:name is drive-relative,
\\host\share is a UNC path and CON/NUL are reserved devices —
every one of them refused on EVERY platform. A template name that is
valid on one machine is valid on all of them, which is the only way the
same application deploys to both.
Defined Under Namespace
Classes: Rejected
Constant Summary collapse
- DEVICES =
Reserved DOS device names. Windows resolves these no matter what directory you are in and no matter what extension you append.
(%w[CON PRN AUX NUL] + (1..9).flat_map { |n| ["COM#{n}", "LPT#{n}"] }).freeze
- SEPARATORS =
A name is ONE segment. Refusing both separators outright subsumes traversal, absolute paths and nested lookups in a single rule — the simplest thing six other SDKs can mirror without drifting.
%r{[/\\]}- DRIVE_RELATIVE =
/\A[A-Za-z]:/- CONTROL =
/[\x00-\x1f\x7f]/- TEMPLATE_FILE =
"templates.yml"- DEFINITIONS_FILE =
"definitions.yml"- RULES =
Each rule, and what a caller is told when it fires. The keys are the predicate names below, so adding a rule is one entry plus one method.
{ "separator" => "a name is one segment, so `/` and `\\` are never part of it " \ "(which is also what makes `..` traversal impossible)", "control" => "it contains a control character", "drive_relative" => "it is drive-relative, which Windows resolves against " \ "that drive's current directory", "device" => "it is a reserved device name on Windows" }.freeze
Instance Attribute Summary collapse
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Instance Method Summary collapse
-
#initialize(path) ⇒ TemplateRoot
constructor
A new instance of TemplateRoot.
-
#resolve(name) ⇒ Object
Resolves
name, or raises Rejected naming why it will not.
Constructor Details
#initialize(path) ⇒ TemplateRoot
Returns a new instance of TemplateRoot.
46 47 48 |
# File 'lib/shojiku/template_root.rb', line 46 def initialize(path) @path = path end |
Instance Attribute Details
#path ⇒ Object (readonly)
Returns the value of attribute path.
44 45 46 |
# File 'lib/shojiku/template_root.rb', line 44 def path @path end |
Instance Method Details
#resolve(name) ⇒ Object
Resolves name, or raises Rejected naming why it will not.
Rejection is an exception INSIDE this class and a failed Result outside it (see Client#generate) — a hostile template name is a fact about the request, not a bug in the calling program.
55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/shojiku/template_root.rb', line 55 def resolve(name) identifier!(name) reject!(name) dir = File.join(@path, name) real = contained!(dir) Sources.new( template: read!(File.join(real, TEMPLATE_FILE)), definitions: optional(File.join(real, DEFINITIONS_FILE)), assets_dir: real ) end |