scout-gear 1.1.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -81,7 +81,6 @@ module Log
81
81
 
82
82
  def self.with_bar(max, options = {})
83
83
  bar = new_bar(max, options)
84
- res = nil
85
84
  begin
86
85
  error = false
87
86
  keep = false
data/lib/scout/log.rb CHANGED
@@ -35,7 +35,7 @@ module Log
35
35
  def self.last_caller(stack)
36
36
  line = nil
37
37
  pos ||= 0
38
- while line.nil? or line =~ /scout\/helper\/log\.rb/ and stack.any?
38
+ while line.nil? or line =~ /scout\/log\.rb/ and stack.any?
39
39
  line = stack.shift
40
40
  end
41
41
  line ||= caller.first
@@ -13,9 +13,23 @@ module MetaExtension
13
13
 
14
14
  meta.define_method(:setup) do |obj,*rest|
15
15
  obj.extend base
16
- self.class_variable_get("@@extension_attrs").zip(rest).each do |name,value|
16
+ attrs = self.class_variable_get("@@extension_attrs")
17
+
18
+ return if attrs.nil? || attrs.empty?
19
+
20
+ if rest.length == 1 && Hash === (rlast = rest.last) &&
21
+ ! (rlkey = rlast.keys.first).nil? &&
22
+ attrs.include?(rlkey.to_sym)
23
+
24
+ pairs = rlast
25
+ else
26
+ pairs = attrs.zip(rest)
27
+ end
28
+
29
+ pairs.each do |name,value|
17
30
  obj.instance_variable_set("@#{name}", value)
18
31
  end
32
+
19
33
  obj
20
34
  end
21
35
 
@@ -0,0 +1,227 @@
1
+ module Misc
2
+ COLOR_LIST = %w(#BC80BD #CCEBC5 #FFED6F #8DD3C7 #FFFFB3 #BEBADA #FB8072 #80B1D3 #FDB462 #B3DE69 #FCCDE5 #D9D9D9)
3
+
4
+ def self.colors_for(list)
5
+ unused = COLOR_LIST.dup
6
+
7
+ used = {}
8
+ colors = list.collect do |elem|
9
+ if used.include? elem
10
+ used[elem]
11
+ else
12
+ color = unused.shift
13
+ used[elem]=color
14
+ color
15
+ end
16
+ end
17
+
18
+ [colors, used]
19
+ end
20
+
21
+ def self.format_seconds(time, extended = false)
22
+ seconds = time.to_i
23
+ str = [seconds/3600, seconds/60 % 60, seconds % 60].map{|t| "%02i" % t }.join(':')
24
+ str << ".%02i" % ((time - seconds) * 100) if extended
25
+ str
26
+ end
27
+
28
+ def self.format_paragraph(text, size = 80, indent = 0, offset = 0)
29
+ i = 0
30
+ size = size + offset + indent
31
+ re = /((?:\n\s*\n\s*)|(?:\n\s*(?=\*)))/
32
+ text.split(re).collect do |paragraph|
33
+ i += 1
34
+ str = if i % 2 == 1
35
+ words = paragraph.gsub(/\s+/, "\s").split(" ")
36
+ lines = []
37
+ line = " "*offset
38
+ word = words.shift
39
+ while word
40
+ word = word[0..size-indent-offset-4] + '...' if word.length >= size - indent - offset
41
+ while word and Log.uncolor(line).length + Log.uncolor(word).length <= size - indent
42
+ line << word << " "
43
+ word = words.shift
44
+ end
45
+ offset = 0
46
+ lines << ((" " * indent) << line[0..-2])
47
+ line = ""
48
+ end
49
+ (lines * "\n")
50
+ else
51
+ paragraph
52
+ end
53
+ offset = 0
54
+ str
55
+ end*""
56
+ end
57
+
58
+ def self.format_definition_list_item(dt, dd, size = 80, indent = 20, color = :yellow)
59
+ dd = "" if dd.nil?
60
+ dt = Log.color color, dt if color
61
+ dt = dt.to_s unless dd.empty?
62
+ len = Log.uncolor(dt).length
63
+
64
+ if indent < 0
65
+ text = format_paragraph(dd, size, indent.abs-1, 0)
66
+ text = dt << "\n" << text
67
+ else
68
+ offset = len - indent
69
+ offset = 0 if offset < 0
70
+ text = format_paragraph(dd, size, indent.abs+1, offset)
71
+ text[0..len-1] = dt
72
+ end
73
+ text
74
+ end
75
+
76
+ def self.format_definition_list(defs, size = 80, indent = 20, color = :yellow, sep = "\n\n")
77
+ entries = []
78
+ defs.each do |dt,dd|
79
+ text = format_definition_list_item(dt,dd,size,indent,color)
80
+ entries << text
81
+ end
82
+ entries * sep
83
+ end
84
+
85
+ def self.camel_case(string)
86
+ return string if string !~ /_/ && string =~ /[A-Z]+.*/
87
+ string.split(/_|(\d+)/).map{|e|
88
+ (e =~ /^[A-Z]{2,}$/ ? e : e.capitalize)
89
+ }.join
90
+ end
91
+
92
+ def self.camel_case_lower(string)
93
+ string.split('_').inject([]){ |buffer,e|
94
+ buffer.push(buffer.empty? ? e.downcase : (e =~ /^[A-Z]{2,}$/ ? e : e.capitalize))
95
+ }.join
96
+ end
97
+
98
+ def self.snake_case(string)
99
+ return nil if string.nil?
100
+ string = string.to_s if Symbol === string
101
+ string.
102
+ gsub(/([A-Z]{2,})([A-Z][a-z])/,'\1_\2').
103
+ gsub(/([a-z])([A-Z])/,'\1_\2').
104
+ gsub(/\s/,'_').gsub(/[^\w_]/, '').
105
+ split("_").collect{|p| p.match(/[A-Z]{2,}/) ? p : p.downcase } * "_"
106
+ end
107
+
108
+ # source: https://gist.github.com/ekdevdes/2450285
109
+ # author: Ethan Kramer (https://github.com/ekdevdes)
110
+ def self.humanize(value, options = {})
111
+ if options.empty?
112
+ options[:format] = :sentence
113
+ end
114
+
115
+ values = value.to_s.split('_')
116
+ values.each_index do |index|
117
+ # lower case each item in array
118
+ # Miguel Vazquez edit: Except for acronyms
119
+ values[index].downcase! unless values[index].match(/[a-zA-Z][A-Z]/)
120
+ end
121
+ if options[:format] == :allcaps
122
+ values.each do |value|
123
+ value.capitalize!
124
+ end
125
+
126
+ if options.empty?
127
+ options[:seperator] = " "
128
+ end
129
+
130
+ return values.join " "
131
+ end
132
+
133
+ if options[:format] == :class
134
+ values.each do |value|
135
+ value.capitalize!
136
+ end
137
+
138
+ return values.join ""
139
+ end
140
+
141
+ if options[:format] == :sentence
142
+ values[0].capitalize! unless values[0].match(/[a-zA-Z][A-Z]/)
143
+
144
+ return values.join " "
145
+ end
146
+
147
+ if options[:format] == :nocaps
148
+ return values.join " "
149
+ end
150
+ end
151
+
152
+ def self.fixascii(string)
153
+ if string.respond_to?(:encode)
154
+ self.fixutf8(string).encode("ASCII-8BIT")
155
+ else
156
+ string
157
+ end
158
+ end
159
+
160
+ def self.to_utf8(string)
161
+ string.encode("UTF-16BE", :invalid => :replace, :undef => :replace, :replace => "?").encode('UTF-8')
162
+ end
163
+
164
+ def self.fixutf8(string)
165
+ return nil if string.nil?
166
+ return string if string.respond_to?(:encoding) && string.encoding.to_s == "UTF-8" && (string.respond_to?(:valid_encoding?) && string.valid_encoding?) ||
167
+ (string.respond_to?(:valid_encoding) && string.valid_encoding)
168
+
169
+ if string.respond_to?(:encode)
170
+ string.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
171
+ else
172
+ require 'iconv'
173
+ @@ic ||= Iconv.new('UTF-8//IGNORE', 'UTF-8')
174
+ @@ic.iconv(string)
175
+ end
176
+ end
177
+
178
+ def self.humanize_list(list)
179
+ return "" if list.empty?
180
+ if list.length == 1
181
+ list.first
182
+ else
183
+ list[0..-2].collect{|e| e.to_s} * ", " << " and " << list[-1].to_s
184
+ end
185
+ end
186
+
187
+ def self.parse_sql_values(txt)
188
+ io = StringIO.new txt.strip
189
+
190
+ values = []
191
+ fields = []
192
+ current = nil
193
+ quoted = false
194
+ while c = io.getc
195
+ if quoted
196
+ if c == "'"
197
+ quoted = false
198
+ else
199
+ current << c
200
+ end
201
+ else
202
+ case c
203
+ when "("
204
+ current = ""
205
+ when ")"
206
+ fields << current
207
+ values << fields
208
+ fields = []
209
+ current = nil
210
+ when ','
211
+ if not current.nil?
212
+ fields << current
213
+ current = ""
214
+ end
215
+ when "'"
216
+ quoted = true
217
+ when ";"
218
+ break
219
+ else
220
+ current << c
221
+ end
222
+ end
223
+ end
224
+ values
225
+ end
226
+
227
+ end
data/lib/scout/misc.rb ADDED
@@ -0,0 +1,14 @@
1
+ require_relative 'misc/format'
2
+ module Misc
3
+ def self.in_dir(dir)
4
+ old_pwd = FileUtils.pwd
5
+ begin
6
+ FileUtils.mkdir_p dir unless File.exist?(dir)
7
+ FileUtils.cd dir
8
+ yield
9
+ ensure
10
+ FileUtils.cd old_pwd
11
+ end
12
+ end
13
+
14
+ end
@@ -1,65 +1,120 @@
1
+ require_relative '../indiferent_hash'
1
2
  module Path
3
+
2
4
  def _parts
3
5
  @_parts ||= self.split("/")
4
6
  end
5
7
 
6
8
  def _subpath
7
- @subpath ||= _parts.length > 1 ? _parts[1..-1] * "/" : _parts[0]
9
+ @subpath ||= _parts.length > 1 ? _parts[1..-1] * "/" : _parts[0] || ""
8
10
  end
9
11
 
10
12
  def _toplevel
11
- @toplevel ||= _parts.length > 1 ? _parts[0] : nil
13
+ @toplevel ||= _parts.length > 1 ? _parts[0] : ""
12
14
  end
13
15
 
14
16
  def self.follow(path, map)
15
- map.sub('{PKGDIR}', path.pkgdir).
16
- sub('{RESOURCE}', path.to_s).
17
+ map.sub('{PKGDIR}', path.pkgdir.respond_to?(:subdir) ? path.pkgdir.pkgdir : path.pkgdir || Path.default_pkgdir).
18
+ sub('{RESOURCE}', path.pkgdir.to_s).
17
19
  sub('{PWD}', FileUtils.pwd).
18
20
  sub('{TOPLEVEL}', path._toplevel).
19
21
  sub('{SUBPATH}', path._subpath).
20
22
  sub('{BASENAME}', File.basename(path)).
21
23
  sub('{PATH}', path).
22
- sub('{LIBDIR}', path.libdir).
24
+ sub('{LIBDIR}', path.libdir || (path.pkgdir.respond_to?(:libdir) && path.pkgdir.libdir) || Path.caller_lib_dir).
23
25
  sub('{REMOVE}/', '').
24
26
  sub('{REMOVE}', '').gsub(/\/+/,'/')
25
27
  end
26
28
 
27
- PATH_MAPS = IndiferentHash.setup({
28
- :current => File.join("{PWD}", "{TOPLEVEL}", "{SUBPATH}"),
29
- :user => File.join(ENV['HOME'], ".{PKGDIR}", "{TOPLEVEL}", "{SUBPATH}"),
30
- :global => File.join('/', "{TOPLEVEL}", "{PKGDIR}", "{SUBPATH}"),
31
- :usr => File.join('/usr/', "{TOPLEVEL}", "{PKGDIR}", "{SUBPATH}"),
32
- :local => File.join('/usr/local', "{TOPLEVEL}", "{PKGDIR}", "{SUBPATH}"),
33
- :fast => File.join('/fast', "{TOPLEVEL}", "{PKGDIR}", "{SUBPATH}"),
34
- :cache => File.join('/cache', "{TOPLEVEL}", "{PKGDIR}", "{SUBPATH}"),
35
- :bulk => File.join('/bulk', "{TOPLEVEL}", "{PKGDIR}", "{SUBPATH}"),
36
- :lib => File.join('{LIBDIR}', "{TOPLEVEL}", "{SUBPATH}"),
37
- :base => File.join(Path.caller_lib_dir(__FILE__), "{TOPLEVEL}", "{SUBPATH}"),
38
- :default => :user
39
- })
40
-
41
- MAP_SEARCH = %w(current workflow user local global lib fast cache bulk)
42
-
43
- def _follow(map_name)
44
- map = PATH_MAPS[map_name]
29
+ def self.path_maps
30
+ @@path_maps ||= IndiferentHash.setup({
31
+ :current => File.join("{PWD}", "{TOPLEVEL}", "{SUBPATH}"),
32
+ :user => File.join(ENV['HOME'], ".{PKGDIR}", "{TOPLEVEL}", "{SUBPATH}"),
33
+ :global => File.join('/', "{TOPLEVEL}", "{PKGDIR}", "{SUBPATH}"),
34
+ :usr => File.join('/usr/', "{TOPLEVEL}", "{PKGDIR}", "{SUBPATH}"),
35
+ :local => File.join('/usr/local', "{TOPLEVEL}", "{PKGDIR}", "{SUBPATH}"),
36
+ :fast => File.join('/fast', "{TOPLEVEL}", "{PKGDIR}", "{SUBPATH}"),
37
+ :cache => File.join('/cache', "{TOPLEVEL}", "{PKGDIR}", "{SUBPATH}"),
38
+ :bulk => File.join('/bulk', "{TOPLEVEL}", "{PKGDIR}", "{SUBPATH}"),
39
+ :lib => File.join('{LIBDIR}', "{TOPLEVEL}", "{SUBPATH}"),
40
+ :base => File.join(Path.caller_lib_dir(__FILE__), "{TOPLEVEL}", "{SUBPATH}"),
41
+ :default => :user
42
+ })
43
+ end
44
+
45
+ def self.map_search
46
+ @@map_search ||= %w(current workflow user local global lib fast cache bulk)
47
+ end
48
+
49
+ def self.search_order
50
+ @@search_order ||= (path_maps.keys & map_search) + (path_maps.keys - map_search)
51
+ end
52
+
53
+ def self.add_path(name, map)
54
+ @@path_maps[name] = map
55
+ @@search_order = nil
56
+ end
57
+
58
+ SLASH = "/"[0]
59
+ DOT = "."[0]
60
+ def located?
61
+ # OPEN RESOURCE
62
+ self.slice(0,1) == SLASH || (self.slice(0,1) == DOT && self.slice(1,2) == SLASH) # || (resource != Rbbt && (Open.remote?(self) || Open.ssh?(self)))
63
+ end
64
+
65
+ def annotate_found_where(found, where)
66
+ self.annotate(found).tap{|p|
67
+ p.instance_variable_set("@where", where)
68
+ p.instance_variable_set("@original", self.dup)
69
+ }
70
+ end
71
+
72
+ def where
73
+ @where
74
+ end
75
+
76
+ def original
77
+ @original
78
+ end
79
+
80
+ def follow(map_name = :default, annotate = true)
81
+ map = Path.path_maps[map_name]
45
82
  while Symbol === map
46
- map = PATH_MAPS[map]
83
+ map_name = map
84
+ map = Path.path_maps[map_name]
47
85
  end
48
- Path.follow(self, map)
86
+ found = Path.follow(self, map)
87
+
88
+ annotate_found_where(found, map_name) if annotate
89
+
90
+ found
49
91
  end
50
92
 
51
93
  def find(where = nil)
52
- return _follow(where) if where
94
+ return self if located?
95
+ return find_all if where == 'all' || where == :all
96
+ return follow(where) if where
53
97
 
54
- all_maps = PATH_MAPS.keys
55
- search_order = MAP_SEARCH & all_maps + (all_maps - MAP_SEARCH)
98
+ Path.search_order.each do |map_name|
99
+ found = follow(map_name, false)
56
100
 
57
- search_order.each do |name|
58
- map = PATH_MAPS[name]
59
- real_path = _follow(map)
60
- return real_path if File.exists?(real_path)
101
+ return annotate_found_where(found, map_name) if File.exist?(found) || File.directory?(found)
61
102
  end
62
103
 
63
- return _follow(:default)
104
+ return follow(:default)
105
+ end
106
+
107
+ def exist?
108
+ # OPEN
109
+ found = self.find
110
+ File.exist?(found) || File.directory?(found)
111
+ end
112
+
113
+ alias exists? exist?
114
+
115
+ def find_all(caller_lib = nil, search_paths = nil)
116
+ Path.search_order
117
+ .collect{|where| find(where) }
118
+ .select{|file| file.exist? }.uniq
64
119
  end
65
120
  end
@@ -0,0 +1,51 @@
1
+ module Path
2
+ def directory?
3
+ return nil unless self.exist?
4
+ File.directory?(self.find)
5
+ end
6
+
7
+ def dirname
8
+ self.annotate(File.dirname(self))
9
+ end
10
+
11
+ def basename
12
+ self.annotate(File.basename(self))
13
+ end
14
+
15
+
16
+ def glob(pattern = '*')
17
+ if self.include? "*"
18
+ self.glob_all
19
+ else
20
+ return [] unless self.exist?
21
+ found = self.find
22
+ exp = File.join(found, pattern)
23
+ paths = Dir.glob(exp).collect{|f| self.annotate(f) }
24
+
25
+ paths.each do |p|
26
+ p.original = File.join(found.original, p.sub(/^#{found}/, ''))
27
+ end if found.original
28
+
29
+ paths
30
+ end
31
+ end
32
+
33
+ def glob_all(pattern = nil, caller_lib = nil, search_paths = nil)
34
+ search_paths ||= Path.path_maps
35
+ search_paths = search_paths.dup
36
+
37
+ search_paths.keys.collect do |where|
38
+ found = find(where)
39
+ paths = pattern ? Dir.glob(File.join(found, pattern)) : Dir.glob(found)
40
+
41
+ paths = paths.collect{|p| self.annotate p }
42
+
43
+ paths = paths.each do |p|
44
+ p.original = File.join(found.original, p.sub(/^#{found}/, ''))
45
+ p.where = where
46
+ end if found.original and pattern
47
+
48
+ paths
49
+ end.flatten.uniq
50
+ end
51
+ end
data/lib/scout/path.rb CHANGED
@@ -1,17 +1,20 @@
1
1
  require_relative 'meta_extension'
2
+ require_relative 'path/find'
3
+ require_relative 'path/util'
2
4
 
3
5
  module Path
4
6
  extend MetaExtension
5
- extension_attr :pkgdir, :libdir
7
+ extension_attr :pkgdir, :libdir, :path_maps
6
8
 
7
9
  def self.caller_lib_dir(file = nil, relative_to = ['lib', 'bin'])
8
10
 
9
11
  if file.nil?
10
12
  caller_dup = caller.dup
11
13
  while file = caller_dup.shift
12
- break unless file =~ /scout\/(?:resource\.rb|workflow\.rb)/ or
13
- file =~ /scout\/path\.rb/ or
14
- file =~ /scout\/persist.rb/
14
+ break unless file =~ /(?:scout|rbbt)\/(?:resource\.rb|workflow\.rb)/ or
15
+ file =~ /(?:scout|rbbt)\/(?:.*\/)?path\.rb/ or
16
+ file =~ /(?:scout|rbbt)\/(?:.*\/)?path\/(?:find|refactor|util)\.rb/ or
17
+ file =~ /(?:scout|rbbt)\/persist.rb/
15
18
  end
16
19
  file = file.sub(/\.rb[^\w].*/,'.rb')
17
20
  end
@@ -31,11 +34,21 @@ module Path
31
34
  return nil
32
35
  end
33
36
 
34
- def self.setup(path, pkgdir = 'scout', libdir = nil)
35
- path.extend Path
36
- path.pkgdir = pkgdir
37
- path.libdir = libdir || Path.caller_lib_dir
38
- path
37
+ def self.default_pkgdir
38
+ @@default_pkgdir ||= 'scout'
39
+ end
40
+
41
+ def self.default_pkgdir=(pkgdir)
42
+ @@default_pkgdir = pkgdir
43
+ end
44
+
45
+
46
+ def pkgdir
47
+ @pkgdir ||= Path.default_pkgdir
48
+ end
49
+
50
+ def libdir
51
+ @libdir
39
52
  end
40
53
 
41
54
  def join(subpath, prevpath = nil)
@@ -43,7 +56,7 @@ module Path
43
56
  prevpath = prevpath.to_s if Symbol === prevpath
44
57
 
45
58
  subpath = File.join(prevpath.to_s, subpath) if prevpath
46
- new = File.join(self, subpath)
59
+ new = self.empty? ? subpath : File.join(self, subpath)
47
60
  self.annotate(new)
48
61
  new
49
62
  end
@@ -0,0 +1,54 @@
1
+ module SOPT
2
+ class << self
3
+ attr_accessor :inputs, :input_shortcuts, :input_types, :input_descriptions, :input_defaults
4
+ end
5
+
6
+ def self.all
7
+ @all ||= {}
8
+ end
9
+
10
+ def self.shortcuts
11
+ @shortcuts ||= {}
12
+ end
13
+
14
+ def self.inputs
15
+ @inputs ||= []
16
+ end
17
+
18
+ def self.input_shortcuts
19
+ @input_shortcuts ||= {}
20
+ end
21
+
22
+ def self.input_types
23
+ @input_types ||= {}
24
+ end
25
+
26
+ def self.input_descriptions
27
+ @input_descriptions ||= {}
28
+ end
29
+
30
+ def self.input_defaults
31
+ @input_defaults ||= {}
32
+ end
33
+
34
+ def self.reset
35
+ @shortcuts = {}
36
+ @all = {}
37
+ end
38
+
39
+ def self.delete_inputs(inputs)
40
+ inputs.each do |input|
41
+ input = input.to_s
42
+ self.shortcuts.delete self.input_shortcuts.delete(input)
43
+ self.inputs.delete input
44
+ self.input_types.delete input
45
+ self.input_defaults.delete input
46
+ self.input_descriptions.delete input
47
+ end
48
+ end
49
+
50
+ def self.usage
51
+ puts SOPT.doc
52
+ exit 0
53
+ end
54
+ end