Module: Path

Extended by:
MetaExtension
Defined in:
lib/scout/path.rb,
lib/scout/path/find.rb,
lib/scout/path/util.rb,
lib/scout/persist/path.rb,
lib/scout/resource/path.rb

Constant Summary collapse

SLASH =
DOT =

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MetaExtension

extended, is_extended?, purge

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, prev = nil, *args, &block) ⇒ Object



43
44
45
46
47
48
49
# File 'lib/scout/path.rb', line 43

def method_missing(name, prev = nil, *args, &block)
  if block_given? || name.to_s.start_with?('to_')
    super name, prev, *args, &block
  else
    join(name, prev)
  end
end

Class Method Details

.add_path(name, map) ⇒ Object



86
87
88
89
# File 'lib/scout/path/find.rb', line 86

def self.add_path(name, map)
  @@path_maps[name] = map
  @@map_order = nil
end

.basic_map_orderObject



78
79
80
# File 'lib/scout/path/find.rb', line 78

def self.basic_map_order
  @@basic_map_order ||= %w(current workflow user local global lib fast cache bulk)
end

.caller_lib_dir(file = nil, relative_to = ['lib', 'bin']) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/scout/path/find.rb', line 4

def self.caller_lib_dir(file = nil, relative_to = ['lib', 'bin'])

  if file.nil?
    caller_dup = caller.dup
    while file = caller_dup.shift
      break unless file =~ /(?:scout|rbbt)\/(?:resource\.rb|workflow\.rb)/ or
        file =~ /(?:scout|rbbt)\/(?:.*\/)?path\.rb/ or
        file =~ /(?:scout|rbbt)\/(?:.*\/)?path\/(?:find|refactor|util)\.rb/ or
        file =~ /(?:scout|rbbt)\/persist.rb/ or
        file =~ /scout\/resource\/produce.rb/ or
        file =~ /modules\/rbbt-util/
    end
    return nil if file.nil?
    file = file.sub(/\.rb[^\w].*/,'.rb')
  end

  relative_to = [relative_to] unless Array === relative_to
  file = File.expand_path(file)
  return Path.setup(file) if relative_to.select{|d| File.exist? File.join(file, d)}.any?

  while file != '/'
    dir = File.dirname file

    return dir if relative_to.select{|d| File.exist? File.join(dir, d)}.any?

    file = File.dirname file
  end

  return nil
end

.default_pkgdirObject



10
11
12
# File 'lib/scout/path.rb', line 10

def self.default_pkgdir
  @@default_pkgdir ||= 'scout'
end

.default_pkgdir=(pkgdir) ⇒ Object



14
15
16
# File 'lib/scout/path.rb', line 14

def self.default_pkgdir=(pkgdir)
  @@default_pkgdir = pkgdir
end

.exists_file_or_alternatives(file) ⇒ Object



147
148
149
150
151
152
153
154
# File 'lib/scout/path/find.rb', line 147

def self.exists_file_or_alternatives(file)
  return file if File.exist?(file) or File.directory?(file)
  %w(gz bgz zip).each do |extension|
    alt_file = file + '.' + extension
    return alt_file if File.exist?(alt_file) or File.directory?(alt_file)
  end
  nil
end

.follow(path, map, map_name = nil) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/scout/path/find.rb', line 35

def self.follow(path, map, map_name = nil)
  file = map.sub('{PKGDIR}', path.pkgdir.respond_to?(:pkgdir) ? path.pkgdir.pkgdir || Path.default_pkgdir : path.pkgdir || Path.default_pkgdir).
    sub('{HOME}', ENV["HOME"]).
    sub('{RESOURCE}', path.pkgdir.to_s).
    sub('{PWD}', FileUtils.pwd).
    sub('{TOPLEVEL}', path._toplevel).
    sub('{SUBPATH}', path._subpath).
    sub('{BASENAME}', File.basename(path)).
    sub('{PATH}', path).
    sub('{LIBDIR}'){ path.libdir || (path.pkgdir.respond_to?(:libdir) && path.pkgdir.libdir) || Path.caller_lib_dir || "NOLIBDIR" }.
    sub('{MAPNAME}', map_name.to_s).
    sub('{REMOVE}/', '').
    sub('{REMOVE}', '').gsub(/\/+/,'/')

  while true
    file.gsub!(/\{(.+)(?<!\\)\/(.+)(?<!\\)\/(.+)\}/) do |m|
      key, orig, replace = m.split(/(?<!\\)\//).collect{|p| p.gsub('\/','/') }
      key_text = follow(path, "#{key}}", map_name)
      key_text[orig] = replace[0..-2] if key_text.include?(orig)
      key_text
    end || break
  end

  file
end

.is_filename?(string, need_to_exists = true) ⇒ Boolean

Returns:

  • (Boolean)


8
9
10
11
12
13
# File 'lib/scout/path/util.rb', line 8

def self.is_filename?(string, need_to_exists = true)
  return false if string.nil?
  return true if Path === string
  return true if String === string and ! string.include?("\n") and string.split("/").select{|p| p.length > 265 }.empty? and (! need_to_exists || File.exist?(string))
  return false
end

.map_orderObject



82
83
84
# File 'lib/scout/path/find.rb', line 82

def self.map_order
  @@map_order ||= (path_maps.keys & basic_map_order) + (path_maps.keys - basic_map_order)
end

.newer?(path, file, by_link = false) ⇒ Boolean

Is ‘file’ newer than ‘path’? return non-true if path is newer than file

Returns:

  • (Boolean)


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/scout/path/util.rb', line 115

def self.newer?(path, file, by_link = false)
  return true if not Open.exists?(file)
  path = path.find if Path === path
  file = file.find if Path === file
  if by_link
    patht = File.exist?(path) ? File.lstat(path).mtime : nil
    filet = File.exist?(file) ? File.lstat(file).mtime : nil
  else
    patht = Open.mtime(path)
    filet = Open.mtime(file)
  end
  return true if patht.nil? || filet.nil?
  diff = patht - filet
  return diff if diff < 0
  return false
end

.path_mapsObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/scout/path/find.rb', line 61

def self.path_maps
  @@path_maps ||= IndiferentHash.setup({
    :current => "{PWD}/{TOPLEVEL}/{SUBPATH}",
    :user    => "{HOME}/.{PKGDIR}/{TOPLEVEL}/{SUBPATH}",
    :global  => '/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
    :usr     => '/usr/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
    :local   => '/usr/local/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
    :fast    => '/fast/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
    :cache   => '/cache/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
    :bulk    => '/bulk/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
    :lib     => '{LIBDIR}/{TOPLEVEL}/{SUBPATH}',
    :scout_gear => File.join(Path.caller_lib_dir(__FILE__), "{TOPLEVEL}/{SUBPATH}"),
    :tmp     => '/tmp/{PKGDIR}/{TOPLEVEL}/{SUBPATH}',
    :default => :user
  })
end

.sanitize_filename(filename, length = 254) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/scout/path/util.rb', line 15

def self.sanitize_filename(filename, length = 254)
  if filename.length > length
    if filename =~ /(\..{2,9})$/
      extension = $1
    else
      extension = ''
    end

    post_fix = "--#{filename.length}@#{length}_#{Misc.digest(filename)[0..4]}" + extension

    filename = filename[0..(length - post_fix.length - 1)] << post_fix
  else
    filename
  end
  filename
end

Instance Method Details

#_partsObject



91
92
93
# File 'lib/scout/path/find.rb', line 91

def _parts
  @_parts ||= self.split("/")
end

#_subpathObject



95
96
97
# File 'lib/scout/path/find.rb', line 95

def _subpath
  @subpath ||= _parts.length > 1 ? _parts[1..-1] * "/" : _parts[0] || ""
end

#_toplevelObject



99
100
101
# File 'lib/scout/path/find.rb', line 99

def _toplevel
  @toplevel ||= _parts.length > 1 ? _parts[0] : ""
end

#annotate_found_where(found, where) ⇒ Object



110
111
112
113
114
115
# File 'lib/scout/path/find.rb', line 110

def annotate_found_where(found, where)
  self.annotate(found).tap{|p| 
    p.instance_variable_set("@where", where) 
    p.instance_variable_set("@original", self.dup) 
  }
end

#basenameObject



45
46
47
# File 'lib/scout/path/util.rb', line 45

def basename
  self.annotate(File.basename(self))
end

#directory?Boolean

Returns:

  • (Boolean)


32
33
34
35
# File 'lib/scout/path/util.rb', line 32

def directory?
  return nil unless self.exist?
  File.directory?(self.find)
end

#dirnameObject



41
42
43
# File 'lib/scout/path/util.rb', line 41

def dirname
  self.annotate(File.dirname(self))
end

#exist?Boolean Also known as: exists?

Returns:

  • (Boolean)


184
185
186
187
188
# File 'lib/scout/path/find.rb', line 184

def exist?
  # OPEN
  found = self.find
  File.exist?(found) || File.directory?(found)
end

#find(where = nil) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/scout/path/find.rb', line 156

def find(where = nil)
  if located?
    if File.exist?(self)
      return self if located?
    else
      found = Path.exists_file_or_alternatives(self)
      if found
        return self.annotate(found)
      else
        return self if located?
      end
    end
  end

  return find_all if where == 'all' || where == :all

  return follow(where) if where

  map_order.each do |map_name|
    found = follow(map_name, false)

    found = Path.exists_file_or_alternatives(found)
    return annotate_found_where(found, map_name) if found
  end

  return follow(:default)
end

#find_all(caller_lib = nil, search_paths = nil) ⇒ Object



192
193
194
195
196
# File 'lib/scout/path/find.rb', line 192

def find_all(caller_lib = nil, search_paths = nil)
  map_order
    .collect{|where| find(where) }
    .select{|file| file.exist? }.uniq
end

#find_with_extension(extension, *args) ⇒ Object



198
199
200
201
202
203
# File 'lib/scout/path/find.rb', line 198

def find_with_extension(extension, *args)
  found = self.find(*args)
  return found if found.exists?
  found_with_extension = self.set_extension(extension).find
  found_with_extension.exists? ? found_with_extension : found
end

#follow(map_name = :default, annotate = true) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/scout/path/find.rb', line 129

def follow(map_name = :default, annotate = true)
  IndiferentHash.setup(path_maps)
  map = path_maps[map_name] || Path.path_maps[map_name]
  if map.nil? && String === map_name
    map = File.join(map_name, '{TOPLEVEL}/{SUBPATH}')
  end
  raise "Map not found #{Log.fingerprint map_name} not in #{Log.fingerprint path_maps.keys}" if map.nil?
  while Symbol === map
    map_name = map
    map = path_maps[map_name]
  end
  found = Path.follow(self, map, map_name)

  annotate_found_where(found, map_name)  if annotate

  found
end

#glob(pattern = '*') ⇒ Object



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

def glob(pattern = '*')
  if self.include? "*"
    self.glob_all
  else
    return [] unless self.exist? 
    found = self.find
    exp = File.join(found, pattern)
    paths = Dir.glob(exp).collect{|f| self.annotate(f) }

    paths.each do |p|
      p.original = File.join(found.original, p.sub(/^#{found}/, ''))
    end if found.original

    paths
  end
end

#glob_all(pattern = nil, caller_lib = nil, search_paths = nil) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/scout/path/util.rb', line 66

def glob_all(pattern = nil, caller_lib = nil, search_paths = nil)
  search_paths ||= Path.path_maps
  search_paths = search_paths.dup

  search_paths.keys.collect do |where| 
    found = find(where)
    paths = pattern ? Dir.glob(File.join(found, pattern)) : Dir.glob(found) 

    paths = paths.collect{|p| self.annotate p }

    paths = paths.each do |p|
      p.original = File.join(found.original, p.sub(/^#{found}/, ''))
      p.where = where
    end if found.original and pattern

    paths
  end.flatten.uniq
end

#identifyObject



53
54
55
# File 'lib/scout/resource/path.rb', line 53

def identify
  Resource.identify(self)
end

#join(subpath, prevpath = nil) ⇒ Object Also known as: [], /



30
31
32
33
34
35
36
37
38
# File 'lib/scout/path.rb', line 30

def join(subpath, prevpath = nil)
  subpath = subpath.to_s if Symbol === subpath
  prevpath = prevpath.to_s if Symbol === prevpath

  subpath = File.join(prevpath.to_s, subpath) if prevpath
  new = self.empty? ? subpath.dup : File.join(self, subpath)
  self.annotate(new)
  new
end

#json(*rest, &block) ⇒ Object



8
9
10
# File 'lib/scout/persist/path.rb', line 8

def json(*rest, &block)
  Open.json(self, *rest, &block)
end

#libdirObject



22
23
24
# File 'lib/scout/path.rb', line 22

def libdir
  @libdir || Path.caller_lib_dir
end

#listObject



71
72
73
74
# File 'lib/scout/resource/path.rb', line 71

def list
  found = produce_and_find('list')
  Open.list(found)
end

#located?Boolean

Returns:

  • (Boolean)


105
106
107
108
# File 'lib/scout/path/find.rb', line 105

def located?
  # OPEN RESOURCE
  self.slice(0,1) == SLASH || (self.slice(0,1) == DOT && self.slice(1,2) == SLASH) # || (resource != Rbbt && (Open.remote?(self) || Open.ssh?(self)))
end

#map_orderObject



125
126
127
# File 'lib/scout/path/find.rb', line 125

def map_order
  @map_order ||= (path_maps.keys & Path.basic_map_order) + (path_maps.keys - Path.basic_map_order)
end

#marshal(*rest, &block) ⇒ Object



12
13
14
# File 'lib/scout/persist/path.rb', line 12

def marshal(*rest, &block)
  Open.marshal(self, *rest, &block)
end

#no_method_missingObject



2
3
4
5
6
# File 'lib/scout/path/util.rb', line 2

def no_method_missing
  class << self
    undef_method :method_missing
  end
end

#open(*args, &block) ⇒ Object



57
58
59
60
# File 'lib/scout/resource/path.rb', line 57

def open(*args, &block)
  produce
  Open.open(self, *args, &block)
end

#originalObject



121
122
123
# File 'lib/scout/path/find.rb', line 121

def original
  @original
end

#path_mapsObject



26
27
28
# File 'lib/scout/path.rb', line 26

def path_maps
  @path_maps ||= Path.path_maps.dup
end

#pkgdirObject



18
19
20
# File 'lib/scout/path.rb', line 18

def pkgdir
  @pkgdir ||= Path.default_pkgdir
end

#produce(force = false) ⇒ Object



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/scout/resource/path.rb', line 2

def produce(force = false)
  return self if ! force && (Open.exist?(self) || @produced)
  begin
    if Resource === self.pkgdir
      self.pkgdir.produce self, force
    else
      false
    end
  rescue ResourceNotFound
    false
  rescue
    message = $!.message
    message = "No exception message" if message.nil? || message.empty?
    Log.warn "Error producing #{self}: #{message}"
    raise $!
  ensure
    @produced = true
  end
end

#produce_and_find(extension = nil, *args) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/scout/resource/path.rb', line 35

def produce_and_find(extension = nil, *args)
  found = if extension
            found = find_with_extension(extension, *args)
            found.exists? ? found : produce_with_extension(extension, *args)
          else
            found = find
            found.exists? ? found : produce(*args)
          end
  raise "Not found: #{self}" unless found

  found
end

#produce_with_extension(extension, *args) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/scout/resource/path.rb', line 22

def produce_with_extension(extension, *args)
  begin
    self.produce(*args)
  rescue Exception
    exception = $!
    begin
      self.set_extension(extension).produce(*args)
    rescue Exception
      raise exception
    end
  end
end

#readObject



62
63
64
65
# File 'lib/scout/resource/path.rb', line 62

def read
  produce
  Open.read(self)
end

#relocateObject



48
49
50
51
# File 'lib/scout/resource/path.rb', line 48

def relocate
  return self if Open.exists?(self)
  Resource.relocate(self)
end

#remove_extension(extension = nil) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/scout/path/util.rb', line 93

def remove_extension(extension = nil)
  if extension.nil?
    unset_extension
  else
    self.annotate(self.sub(/\.#{extension}$/,''))
  end
end

#replace_extension(new_extension = nil, multiple = false) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/scout/path/util.rb', line 101

def replace_extension(new_extension = nil, multiple = false)
  if String === multiple
    new_path = self.sub(/(\.[^\.\/]{1,5})(.#{multiple})?$/,'')
  elsif multiple
    new_path = self.sub(/(\.[^\.\/]{1,5})+$/,'')
  else
    new_path = self.sub(/\.[^\.\/]{1,5}$/,'')
  end
  new_path = new_path + "." + new_extension.to_s
  self.annotate(new_path)
end

#set_extension(extension) ⇒ Object



85
86
87
# File 'lib/scout/path/util.rb', line 85

def set_extension(extension)
  self.annotate(self + ".#{extension}")
end

#sub(*args) ⇒ Object



37
38
39
# File 'lib/scout/path/util.rb', line 37

def sub(*args)
  self.annotate super(*args)
end

#unset_extensionObject



89
90
91
# File 'lib/scout/path/util.rb', line 89

def unset_extension
  self.annotate(self.split(".")[0..-2] * ".")
end

#whereObject



117
118
119
# File 'lib/scout/path/find.rb', line 117

def where
  @where
end

#write(*args, &block) ⇒ Object



67
68
69
# File 'lib/scout/resource/path.rb', line 67

def write(*args, &block)
  Open.write(self.find, *args, &block)
end

#yaml(*rest, &block) ⇒ Object



4
5
6
# File 'lib/scout/persist/path.rb', line 4

def yaml(*rest, &block)
  Open.yaml(self, *rest, &block)
end