Class: Vfs::Path

Inherits:
String show all
Defined in:
lib/vfs/path.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from String

#to_dir_on, #to_entry_on, #to_file_on

Constructor Details

#initialize(path = '/', options = {}) ⇒ Path

Returns a new instance of Path.



3
4
5
6
7
8
9
10
11
12
13
14
# File 'lib/vfs/path.rb', line 3

def initialize path = '/', options = {}
  if options[:skip_normalization]
    super path
    @probably_dir = options[:probably_dir]
  else
    Path.validate! path
    path, probably_dir = Path.normalize_to_string path
    raise "invalid path '#{path}' (you are outside of the root)!" unless path
    super path
    @probably_dir = probably_dir
  end
end

Class Method Details

.absolute?(path) ⇒ Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/vfs/path.rb', line 46

def absolute? path
  path =~ /^[\/~\/]|^\.$|^\.\//
end

.normalize(path) ⇒ Object



67
68
69
70
71
72
73
74
# File 'lib/vfs/path.rb', line 67

def normalize path
  path, probably_dir = normalize_to_string path
  unless path
    nil
  else
    Path.new(path, skip_normalization: true, probably_dir: probably_dir)
  end
end

.normalize_to_string(path) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/vfs/path.rb', line 80

def normalize_to_string path
  root = path[0..0]
  result, probably_dir = [], false

  parts = path.split('/')[1..-1]
  if parts
    parts.each do |part|
      if part == '..' and (root != '.' or (root == '.' and result.size > 0))
        return nil, false unless result.size > 0
        result.pop
        probably_dir ||= true
      else
        result << part
        probably_dir &&= false
      end
    end
  end
  normalized_path = result.join('/')

  probably_dir ||= true if normalized_path.empty?

  return "#{root}#{'/' unless root == '/' or normalized_path.empty?}#{normalized_path}", probably_dir
end

.valid?(path, forbid_relative = true, &block) ⇒ Boolean

Returns:

  • (Boolean)


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/vfs/path.rb', line 50

def valid? path, forbid_relative = true, &block
  result, err = if forbid_relative and !absolute?(path)
    [false, "path must be started with '/', or '.'"]
  elsif path =~ /.+\/~$|.+\/$|\/\.$/
    [false, "path can't be ended with '/', '/~', or '/.'"]
  elsif path =~ /\/\/|\/~\/|\/\.\//
    [false, "path can't include '/./', '/~/', '//' combinations!"]
  # elsif path =~ /.+[~]|\/\.\//
  #   [false, "'~', or '.' can be present only at the begining of string"]
  else
    [true, nil]
  end

  block.call err if block and !result and err
  result
end

.validate!(path, forbid_relative = true) ⇒ Object



76
77
78
# File 'lib/vfs/path.rb', line 76

def validate! path, forbid_relative = true
  valid?(path, forbid_relative){|error| raise "invalid path '#{path}' (#{error})!"}
end

Instance Method Details

#+(path = '') ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/vfs/path.rb', line 16

def + path = ''
  path = path.to_s
  Path.validate! path, false

  if Path.absolute?(path)
    Path.normalize path
  elsif path.empty?
    self
  else
    Path.normalize "#{self}#{'/' unless self == '/'}#{path}"
  end
end

#nameObject



37
38
39
40
41
42
43
# File 'lib/vfs/path.rb', line 37

def name
  unless @name
    root = self[0..0]
    @name ||= split('/').last || root
  end
  @name
end

#parentObject



29
30
31
# File 'lib/vfs/path.rb', line 29

def parent
  self + '..'
end

#probably_dir?Boolean

Returns:

  • (Boolean)


33
34
35
# File 'lib/vfs/path.rb', line 33

def probably_dir?
  !!@probably_dir
end