scout-gear 1.1.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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