Class: Tap::Root
- Inherits:
-
Object
- Object
- Tap::Root
- Includes:
- Configurable, Utils
- Defined in:
- lib/tap/root.rb,
lib/tap/root/utils.rb,
lib/tap/root/versions.rb
Overview
Root abstracts a directory to standardize access to resources organized within variable directory structures.
# define a root directory with aliased relative paths
root = Root.new(
:root => '/root_dir',
:relative_paths => {:input => 'in', :output => 'out'})
# access aliased paths
root[:input] # => '/root_dir/in'
root[:output] # => '/root_dir/out'
root['implicit'] # => '/root_dir/implicit'
# absolute paths can also be aliased
root[:abs, true] = "/absolute/path"
root.path(:abs, "to", "file.txt") # => '/absolute/path/to/file.txt'
# expanded paths are returned unchanged
path = File.('expanded')
root[path] # => path
# work with paths
path = root.path(:input, 'path/to/file.txt') # => '/root_dir/in/path/to/file.txt'
root.relative_path(:input, path) # => 'path/to/file.txt'
root.translate(path, :input, :output) # => '/root_dir/out/path/to/file.txt'
By default, Roots are initialized to the present working directory (Dir.pwd).
Implementation Notes
Internally Root expands and stores all aliased paths in the ‘paths’ hash. Expanding paths ensures they remain constant even when the present working directory (Dir.pwd) changes.
Root keeps a separate ‘relative_paths’ hash mapping aliases to their relative paths. This hash allow reassignment if and when the root directory changes. By contrast, there is no separate data structure storing the absolute paths. An absolute path thus has an alias in ‘paths’ but not ‘relative_paths’, whereas relative paths have aliases in both.
These features may be important to note when subclassing Root:
-
root and all paths in ‘paths’ are expanded
-
relative paths are stored in ‘relative_paths’
-
absolute paths are present in ‘paths’ but not in ‘relative_paths’
Defined Under Namespace
Constant Summary
Constants included from Utils
Instance Attribute Summary collapse
-
#path_root ⇒ Object
readonly
The filesystem root, inferred from self.root (ex ‘/’ on *nix or something like ‘C:/’ on Windows).
-
#paths ⇒ Object
readonly
A hash of (alias, expanded path) pairs for expanded relative and absolute paths.
Instance Method Summary collapse
-
#[](als) ⇒ Object
Returns the expanded path for the specified alias.
-
#[]=(als, path, absolute = false) ⇒ Object
Sets an alias for the path relative to the root directory.
-
#absolute_paths ⇒ Object
Returns the absolute paths registered with self.
-
#absolute_paths=(paths) ⇒ Object
Sets the absolute paths to those provided.
-
#chdir(als, mkdir = false, &block) ⇒ Object
Changes pwd to the specified directory using Root.chdir.
-
#glob(als, *patterns) ⇒ Object
Globs for paths along the aliased path matching the input patterns.
-
#initialize(config_or_dir = Dir.pwd) ⇒ Root
constructor
Creates a new Root from the specified configurations.
-
#path(als, *paths) ⇒ Object
Resolves the specified alias, joins paths together, and expands the resulting path.
-
#prepare(als, *paths, &block) ⇒ Object
Constructs a path from the inputs and prepares it using Root.prepare.
-
#relative?(als, path) ⇒ Boolean
Returns true if the path is relative to the specified alias.
-
#relative_path(als, path) ⇒ Object
Returns the part of path relative to the specified alias.
-
#relative_paths=(paths) ⇒ Object
Sets the relative_paths to those provided.
-
#root=(path) ⇒ Object
Sets the root directory.
-
#translate(path, source_als, target_als) ⇒ Object
Generates a path translated from the aliased source to the aliased target.
-
#version_glob(als, path, *vpatterns) ⇒ Object
Lists all versions of path in the aliased dir matching the version patterns.
Methods included from Utils
chdir, empty?, exchange, expanded?, glob, path_root_type, prepare, relative?, relative_path, split, suffix_glob, translate, trivial?, version_glob
Methods included from Versions
#compare_versions, #deversion, #increment, #version, #vniq
Constructor Details
#initialize(config_or_dir = Dir.pwd) ⇒ Root
Creates a new Root from the specified configurations. A directory may be provided instead of a configuration hash; in that case no aliased relative or absolute paths are specified. By default root is the present working directory.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/tap/root.rb', line 78 def initialize(config_or_dir=Dir.pwd) # root, relative_paths, and absolute_paths are assigned manually as # an optimization (otherwise assign_paths would get called once for # each configuration) if config_or_dir.kind_of?(String) assign_paths(config_or_dir, {}, {}) config_or_dir = {} else root = config_or_dir.delete(:root) || Dir.pwd relative_paths = config_or_dir.delete(:relative_paths) || {} absolute_paths = config_or_dir.delete(:absolute_paths) || {} assign_paths(root, relative_paths, absolute_paths) end initialize_config(config_or_dir) end |
Instance Attribute Details
#path_root ⇒ Object (readonly)
The filesystem root, inferred from self.root (ex ‘/’ on *nix or something like ‘C:/’ on Windows).
72 73 74 |
# File 'lib/tap/root.rb', line 72 def path_root @path_root end |
#paths ⇒ Object (readonly)
A hash of (alias, expanded path) pairs for expanded relative and absolute paths.
68 69 70 |
# File 'lib/tap/root.rb', line 68 def paths @paths end |
Instance Method Details
#[](als) ⇒ Object
Returns the expanded path for the specified alias. If the alias has not been set, then the path is inferred to be ‘root/als’. Expanded paths are returned directly.
r = Root.new '/root_dir', :dir => 'path/to/dir'
r[:dir] # => '/root_dir/path/to/dir'
r.path_root # => '/'
r['relative/path'] # => '/root_dir/relative/path'
r['/expanded/path'] # => '/expanded/path'
188 189 190 191 192 193 194 |
# File 'lib/tap/root.rb', line 188 def [](als) path = self.paths[als] return path unless path == nil als = als.to_s (als) ? als : File.(File.join(root, als)) end |
#[]=(als, path, absolute = false) ⇒ Object
Sets an alias for the path relative to the root directory. The aliases ‘root’ and :root cannot be set with this method (use root= instead). Absolute paths can be set using the second syntax.
r = Root.new '/root_dir'
r[:dir] = 'path/to/dir'
r[:dir] # => '/root_dir/path/to/dir'
r[:abs, true] = '/abs/path/to/dir'
r[:abs] # => '/abs/path/to/dir'
– Implementation Note:
The syntax for setting an absolute path requires an odd use []=.
In fact the method receives the arguments (:dir, true, ‘/abs/path/to/dir’) rather than (:dir, ‘/abs/path/to/dir’, true) meaning that internally path and absolute are switched when setting an absolute path.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/tap/root.rb', line 156 def []=(als, path, absolute=false) raise ArgumentError, "the alias #{als.inspect} is reserved" if als.to_s == 'root' # switch the paths if absolute was provided unless absolute == false path, absolute = absolute, path end case when path.nil? @relative_paths.delete(als) @paths.delete(als) when absolute @relative_paths.delete(als) @paths[als] = File.(path) else @relative_paths[als] = path @paths[als] = File.(File.join(root, path)) end end |
#absolute_paths ⇒ Object
Returns the absolute paths registered with self.
127 128 129 130 131 132 133 134 135 |
# File 'lib/tap/root.rb', line 127 def absolute_paths abs_paths = {} paths.each do |als, path| unless relative_paths.include?(als) || als.to_s == 'root' abs_paths[als] = path end end abs_paths end |
#absolute_paths=(paths) ⇒ Object
121 122 123 124 |
# File 'lib/tap/root.rb', line 121 def absolute_paths=(paths) paths = Validation::HASH[paths] assign_paths(root, relative_paths, paths) end |
#chdir(als, mkdir = false, &block) ⇒ Object
Changes pwd to the specified directory using Root.chdir.
241 242 243 |
# File 'lib/tap/root.rb', line 241 def chdir(als, mkdir=false, &block) super(self[als], mkdir, &block) end |
#glob(als, *patterns) ⇒ Object
Globs for paths along the aliased path matching the input patterns. Patterns should join with the aliased path make valid globs for Dir.glob. If no patterns are specified, glob returns all paths matching ‘als/*/’.
227 228 229 230 231 |
# File 'lib/tap/root.rb', line 227 def glob(als, *patterns) patterns << "**/*" if patterns.empty? patterns.collect! {|pattern| path(als, pattern)} super(*patterns) end |
#path(als, *paths) ⇒ Object
Resolves the specified alias, joins paths together, and expands the resulting path.
198 199 200 |
# File 'lib/tap/root.rb', line 198 def path(als, *paths) File.(File.join(self[als], *paths)) end |
#prepare(als, *paths, &block) ⇒ Object
Constructs a path from the inputs and prepares it using Root.prepare. Returns the path.
247 248 249 |
# File 'lib/tap/root.rb', line 247 def prepare(als, *paths, &block) super(path(als, *paths), &block) end |
#relative?(als, path) ⇒ Boolean
Returns true if the path is relative to the specified alias.
203 204 205 |
# File 'lib/tap/root.rb', line 203 def relative?(als, path) super(self[als], path) end |
#relative_path(als, path) ⇒ Object
Returns the part of path relative to the specified alias.
208 209 210 |
# File 'lib/tap/root.rb', line 208 def relative_path(als, path) super(self[als], path) end |
#relative_paths=(paths) ⇒ Object
108 109 110 111 |
# File 'lib/tap/root.rb', line 108 def relative_paths=(paths) paths = Validation::HASH[paths] assign_paths(root, paths, absolute_paths) end |
#root=(path) ⇒ Object
Sets the root directory. All paths are reassigned accordingly.
96 97 98 |
# File 'lib/tap/root.rb', line 96 def root=(path) assign_paths(path, relative_paths, absolute_paths) end |
#translate(path, source_als, target_als) ⇒ Object
219 220 221 |
# File 'lib/tap/root.rb', line 219 def translate(path, source_als, target_als) super(path, self[source_als], self[target_als]) end |
#version_glob(als, path, *vpatterns) ⇒ Object
Lists all versions of path in the aliased dir matching the version patterns. If no patterns are specified, then all versions of path will be returned.
236 237 238 |
# File 'lib/tap/root.rb', line 236 def version_glob(als, path, *vpatterns) super(path(als, path), *vpatterns) end |