Class: RVC::FS

Inherits:
Object
  • Object
show all
Defined in:
lib/rvc/fs.rb

Constant Summary collapse

MARK_PATTERN =
/^~(?:([\d\w]*|~|@))$/
REGEX_PATTERN =
/^%/
GLOB_PATTERN =
/\*/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root) ⇒ FS

Returns a new instance of FS.



30
31
32
33
34
35
# File 'lib/rvc/fs.rb', line 30

def initialize root
  fail unless root.is_a? RVC::InventoryObject
  @root = root
  @cur = root
  @marks = {}
end

Instance Attribute Details

#curObject (readonly)

Returns the value of attribute cur.



24
25
26
# File 'lib/rvc/fs.rb', line 24

def cur
  @cur
end

#marksObject (readonly)

Returns the value of attribute marks.



24
25
26
# File 'lib/rvc/fs.rb', line 24

def marks
  @marks
end

#rootObject (readonly)

Returns the value of attribute root.



24
25
26
# File 'lib/rvc/fs.rb', line 24

def root
  @root
end

Instance Method Details

#cd(dst) ⇒ Object



41
42
43
44
45
# File 'lib/rvc/fs.rb', line 41

def cd dst
  fail unless dst.is_a? RVC::InventoryObject
  @marks['~'] = [@cur]
  @cur = dst
end

#delete_numeric_marksObject



100
101
102
# File 'lib/rvc/fs.rb', line 100

def delete_numeric_marks
  @marks.reject! { |k,v| k =~ /^\d+$/ }
end

#display_pathObject



37
38
39
# File 'lib/rvc/fs.rb', line 37

def display_path
  @cur.rvc_path.map { |arc,obj| arc } * '/'
end

#lookup(path) ⇒ Object



47
48
49
50
51
# File 'lib/rvc/fs.rb', line 47

def lookup path
  arcs, absolute, trailing_slash = Path.parse path
  base = absolute ? @root : @cur
  traverse(base, arcs)
end

#lookup!(path, types) ⇒ Object



113
114
115
116
117
118
119
120
# File 'lib/rvc/fs.rb', line 113

def lookup! path, types
  types = [types] unless types.is_a? Enumerable
  lookup(path).tap do |objs|
    objs.each do |obj|
      Util.err "Expected #{types*'/'} but got #{obj.class} at #{path.inspect}" unless types.any? { |type| obj.is_a? type }
    end
  end
end

#lookup_single(path) ⇒ Object

Utility methods



106
107
108
109
110
111
# File 'lib/rvc/fs.rb', line 106

def lookup_single path
  objs = lookup path
  Util.err "Not found: #{path.inspect}" if objs.empty?
  Util.err "More than one match for #{path.inspect}" if objs.size > 1
  objs.first
end

#lookup_single!(path, type) ⇒ Object



122
123
124
125
126
127
# File 'lib/rvc/fs.rb', line 122

def lookup_single! path, type
  objs = lookup!(path, type)
  Util.err "Not found: #{path.inspect}" if objs.empty?
  Util.err "More than one match for #{path.inspect}" if objs.size > 1
  objs.first
end

#traverse(base, arcs) ⇒ Object

Starting from base, traverse each path element in arcs. Since the path may contain wildcards, this function returns a list of matches.



55
56
57
58
59
60
61
62
# File 'lib/rvc/fs.rb', line 55

def traverse base, arcs
  objs = [base]
  arcs.each_with_index do |arc,i|
    objs.map! { |obj| traverse_one obj, arc, i==0 }
    objs.flatten!
  end
  objs
end

#traverse_one(cur, arc, first) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/rvc/fs.rb', line 64

def traverse_one cur, arc, first
  case arc
  when '.'
    [cur]
  when '..'
    [cur.rvc_parent ? cur.rvc_parent : cur]
  when '...'
    # XXX shouldnt be nil
    [(cur.respond_to?(:parent) && cur.parent) ? cur.parent : (cur.rvc_parent || cur)]
  when MARK_PATTERN
    if first and objs = @marks[$1]
      objs
    else
      []
    end
  when REGEX_PATTERN
    regex = Regexp.new($')
    cur.children.select { |k,v| k =~ regex }.map { |k,v| v.rvc_link(cur, k); v }
  when GLOB_PATTERN
    regex = glob_to_regex arc
    cur.children.select { |k,v| k =~ regex }.map { |k,v| v.rvc_link(cur, k); v }
  else
    # XXX check for ambiguous child
    if first and arc =~ /^\d+$/ and objs = @marks[arc]
      objs
    else
      if child = cur.traverse_one(arc)
        child.rvc_link cur, arc
        [child]
      else
        []
      end
    end
  end
end