Class: Tap::Root

Inherits:
Object
  • Object
show all
Defined in:
lib/tap/root.rb

Constant Summary collapse

WIN_ROOT_PATTERN =

Regexp to match a windows-style root path.

/\A[A-z]:\//

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path = Dir.pwd, dir = Dir.pwd) ⇒ Root

Returns a new instance of Root.



35
36
37
# File 'lib/tap/root.rb', line 35

def initialize(path=Dir.pwd, dir=Dir.pwd)
  @path_root = File.expand_path(path.to_s, dir.to_s)
end

Class Method Details

.empty?(dir) ⇒ Boolean

Empty returns true when dir is an existing directory that has no files.

Returns:

  • (Boolean)


27
28
29
# File 'lib/tap/root.rb', line 27

def empty?(dir)
  File.directory?(dir) && (Dir.entries(dir) - ['.', '..']).empty?
end

.trivial?(path) ⇒ Boolean

Trivial indicates when a path does not have content to load. Returns true if the file at path is empty, non-existant, a directory, or nil.

Returns:

  • (Boolean)


22
23
24
# File 'lib/tap/root.rb', line 22

def trivial?(path)
  path == nil || !File.file?(path) || File.size(path) == 0
end

.typeObject

The path root type indicating windows, *nix, or some unknown style of paths (:win, :nix, :unknown).



8
9
10
11
12
13
14
15
16
17
18
# File 'lib/tap/root.rb', line 8

def type
  @path_root_type ||= begin
    pwd = File.expand_path('.')
    
    case
    when pwd =~ WIN_ROOT_PATTERN then :win 
    when pwd[0] == ?/ then :nix
    else :unknown
    end
  end
end

Instance Method Details

#chdir(dir, mkdir = false, &block) ⇒ Object

Changes to the specified directory using Dir.chdir, keeping the same block semantics as that method. The directory will be created if necessary and mkdir is specified. Raises an error for non-existant directories, as well as non-directory inputs.



131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/tap/root.rb', line 131

def chdir(dir, mkdir=false, &block)
  dir = expand(dir)

  unless File.directory?(dir)
    if !File.exists?(dir) && mkdir
      FileUtils.mkdir_p(dir)
    else
      raise ArgumentError, "not a directory: #{dir}"
    end
  end

  Dir.chdir(dir, &block)
end

#exchange(path, extname) ⇒ Object Also known as: ex

Returns the expanded path, exchanging the extension with extname. Extname may optionally omit the leading period.

root = Root.new("/root")
root.exchange('path/to/file.txt', '.html')  # => '/root/path/to/file.html'
root.exchange('path/to/file.txt', 'rb')     # => '/root/path/to/file.rb'


96
97
98
99
# File 'lib/tap/root.rb', line 96

def exchange(path, extname)
  path = expand(path)
  "#{path.chomp(File.extname(path))}#{extname[0] == ?. ? '' : '.'}#{extname}"
end

#expand(path) ⇒ Object

Stringifies and expands the path relative to self. Paths are turned into strings using to_s.



41
42
43
# File 'lib/tap/root.rb', line 41

def expand(path)
  File.expand_path(path.to_s, @path_root)
end

#glob(*patterns) ⇒ Object

Globs for unique paths matching the input patterns expanded relative to self. If no patterns are specified, glob returns all paths matching ‘./*/’.



121
122
123
124
125
# File 'lib/tap/root.rb', line 121

def glob(*patterns)
  patterns << "**/*" if patterns.empty?
  patterns.collect! {|pattern| expand(pattern) }
  Dir[*patterns].uniq
end

#mkdir(*path) ⇒ Object

Makes the specified directory and parent directories (as required).



146
147
148
149
150
# File 'lib/tap/root.rb', line 146

def mkdir(*path)
  path = self.path(*path)
  FileUtils.mkdir_p(path) unless File.directory?(path)
  path
end

#open(path, mode = 'r', &block) ⇒ Object

Opens the path in the specified mode, using the same semantics as File.open.



154
155
156
157
# File 'lib/tap/root.rb', line 154

def open(path, mode='r', &block)
  path = expand(path)
  File.open(path, mode, &block)
end

#parentObject

Returns a new Root for the parent directory for self.



85
86
87
# File 'lib/tap/root.rb', line 85

def parent
  root File.dirname(@path_root)
end

#path(*segments) ⇒ Object

Joins and expands the path segments relative to self. Segments are turned to strings using to_s.



47
48
49
50
# File 'lib/tap/root.rb', line 47

def path(*segments)
  segments.collect! {|seg| seg.to_s }
  expand(File.join(*segments))
end

#prepare(*path) ⇒ Object

Prepares a file at the path by making paths’s parent directory. The file is opened in the mode and passed to the block, if given. The mode is ignored if no block is given.

Returns path.



164
165
166
167
168
169
170
# File 'lib/tap/root.rb', line 164

def prepare(*path)
  path = self.path(*path)
  dirname = File.dirname(path)
  FileUtils.mkdir_p(dirname) unless File.exists?(dirname)
  File.open(path, 'w') {|io| yield(io) } if block_given?
  path
end

#relative?(path) ⇒ Boolean

Returns true if the expanded path is relative to self.

Returns:

  • (Boolean)


53
54
55
# File 'lib/tap/root.rb', line 53

def relative?(path)
  expand(path).rindex(@path_root, 0) == 0
end

#relative_path(path) ⇒ Object Also known as: rp

Returns the part of the expanded path relative to self, or nil if the path is not relative to self.



59
60
61
62
63
64
65
66
# File 'lib/tap/root.rb', line 59

def relative_path(path)
  path = expand(path)
  return nil unless relative?(path)
  
  # if path_root_length > path.length then the first arg
  # returns nil, and an empty string is returned
  path[path_root_length, path.length - path_root_length] || ""
end

#root(path) ⇒ Object

Returns a new Root for the path, relative to self.



70
71
72
# File 'lib/tap/root.rb', line 70

def root(path)
  Root.new(path, self)
end

#sub(path) ⇒ Object

Returns a new Root for the path, relative to self. Same as root but raises an error if the path is not relative to self.



76
77
78
79
80
81
82
# File 'lib/tap/root.rb', line 76

def sub(path)
  sub = root(path)
  unless relative?(sub)
    raise ArgumentError, "not a sub path: #{sub} (#{self})"
  end
  sub
end

#to_sObject

Returns path.



173
174
175
# File 'lib/tap/root.rb', line 173

def to_s
  @path_root
end

#translate(path, source, target) ⇒ Object Also known as: tr

Generates a path translated from the source to the target. Raises an error if path is not relative to the source.



104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/tap/root.rb', line 104

def translate(path, source, target)
  path = expand(path)
  source = root(source)
  target = root(target)
  
  rp = source.relative_path(path)
  if rp.nil?
    raise ArgumentError, "\n#{path}\nis not relative to:\n#{source}"
  end
  
  target.path(rp)
end