scout-essentials 1.6.14 → 1.7.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0586199497442010ccb5ea02066de21a220968857261f64799769e2af2233434'
4
- data.tar.gz: c6d0e58c2a419e9a5afa1a0f6483ed5c6f816ceddb2deefd84c2b64f6fa694c5
3
+ metadata.gz: b525f579cb1dfea91f74e339b0cefcc9713567e0555da3e8943cbf5e05a3a8fa
4
+ data.tar.gz: 75ebc6504a1aa544134f6cd83f472f4cc056d86f093eb96eea450d96e3220603
5
5
  SHA512:
6
- metadata.gz: 4a1ca8a38e73ece435c2b2bc43fe2e35791ecc2015e5059e3ea571cfdd78f2c9fd98c816d03c7856b732fa9e3c74f21634bdc4b0962c422c9448b97aa396d65c
7
- data.tar.gz: 4a11339327cb65af5f3d79491b51ac24b83ca2ebffbfd075738d9c6c77e1dc2627b78418f3742e14230b3c2eadf0380ccc30b6c5ca684405f3109c40a0e2ac70
6
+ metadata.gz: e21bc777bae26f177ecad2aa4bcee2cd2d4b3b715b9d5fa509def84ed17ab007ff63b1f09734f506242b31d350e47f8600cbcc1a0dd544fd9932331c53572c3f
7
+ data.tar.gz: 3caf9cce8f443aaf892815e9ef0930490956ef53c26800b49dd12175a59ac01c34fd77bc82a492e6e64b17f6acb3e633bd95a4cf4b9ca11575b3851baf8e6169
data/.vimproject CHANGED
@@ -22,6 +22,7 @@ scout-essentials=/$PWD filter="*.rb *.txt *.md *.conf *.yaml" {
22
22
  system.rb
23
23
  math.rb
24
24
  hook.rb
25
+ matching.rb
25
26
  }
26
27
  named_array.rb
27
28
  indiferent_hash.rb
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.6.14
1
+ 1.7.1
@@ -52,6 +52,10 @@ module Annotation
52
52
  new.remove_instance_variable(:@annotation_types)
53
53
  end
54
54
 
55
+ if new.instance_variables.include?(:@container)
56
+ new.remove_instance_variable(:@container)
57
+ end
58
+
55
59
  new
56
60
  end
57
61
 
@@ -93,10 +93,10 @@ module IndiferentHash
93
93
  }.compact * "#"
94
94
  end
95
95
 
96
- def self.string2hash(string)
96
+ def self.string2hash(string, sep="#")
97
97
  options = {}
98
98
 
99
- string.split('#').each do |str|
99
+ string.split(sep).each do |str|
100
100
  key, _, value = str.partition "="
101
101
 
102
102
  key = key[1..-1].to_sym if key[0] == ":"
@@ -114,4 +114,61 @@ module IndiferentHash
114
114
 
115
115
  IndiferentHash.setup(options)
116
116
  end
117
+
118
+ def self.parse_options(str)
119
+ options = {}
120
+ # Match key=value pairs, supporting quoted values with spaces
121
+ str.scan(/(\w+)=("[^"]*"|[^\s"]+)/) do |key, raw_value|
122
+ value = raw_value.strip
123
+
124
+ # Remove surrounding quotes if present
125
+ if value.start_with?('"') && value.end_with?('"')
126
+ value = value[1..-2]
127
+ end
128
+
129
+ # Split by commas, but preserve quoted substrings as single elements
130
+ if value.include?(',')
131
+ # This regex splits on commas not inside quotes
132
+ parts = value.scan(/"[^"]*"|[^,]+/).map do |v|
133
+ v = v.strip
134
+ v = v[1..-2] if v.start_with?('"') && v.end_with?('"')
135
+ v
136
+ end
137
+ value = parts
138
+ options[key] = value
139
+ next
140
+ end
141
+
142
+ options[key] = true and next if value.empty?
143
+ options[key] = value[1..-1].to_sym and next if value[0] == ":"
144
+ options[key] = Regexp.new(/#{value[1..-2]}/) and next if value[0] == "/" and value[-1] == "/"
145
+ options[key] = value[1..-2] and next if value =~ /^['"].*['"]$/
146
+ options[key] = value.to_i and next if value =~ /^\d+$/
147
+ options[key] = value.to_f and next if value =~ /^\d*\.\d+$/
148
+ options[key] = true and next if value == "true"
149
+ options[key] = false and next if value == "false"
150
+ options[key] = value
151
+ end
152
+
153
+ IndiferentHash.setup(options)
154
+ end
155
+
156
+ def self.print_options(options)
157
+ options.map do |key, value|
158
+ if value.is_a?(Array)
159
+ vals = value.map do |v|
160
+ if v.to_s.empty? || v.to_s.include?(' ')
161
+ "\"#{v}\""
162
+ else
163
+ v.to_s
164
+ end
165
+ end
166
+ "#{key}=#{vals.join(',')}"
167
+ else
168
+ val = value.to_s
169
+ val = "\"#{val}\"" if val.empty? || val.include?(' ')
170
+ "#{key}=#{val}"
171
+ end
172
+ end.join(' ')
173
+ end
117
174
  end
@@ -33,7 +33,7 @@ module Misc
33
33
  end
34
34
  end
35
35
 
36
- def self.tarize(source_dir, archive_path)
36
+ def self.tarize(source_dir, archive_path = nil)
37
37
  require 'rubygems/package'
38
38
  require 'zlib'
39
39
  require 'stringio'
@@ -57,10 +57,18 @@ module Misc
57
57
 
58
58
  tar_io.rewind
59
59
 
60
- File.open(archive_path, 'wb') do |f|
61
- gz = Zlib::GzipWriter.new(f)
62
- gz.write(tar_io.string)
63
- gz.close
60
+ if archive_path
61
+ File.open(archive_path, 'wb') do |f|
62
+ gz = Zlib::GzipWriter.new(f)
63
+ gz.write(tar_io.string)
64
+ gz.close
65
+ end
66
+ else
67
+ Open.open_pipe do |f|
68
+ gz = Zlib::GzipWriter.new(f)
69
+ gz.write(tar_io.string)
70
+ gz.close
71
+ end
64
72
  end
65
73
  end
66
74
 
@@ -2,7 +2,7 @@ module Misc
2
2
  def self._convert_match_condition(condition)
3
3
  return true if condition == 'true'
4
4
  return false if condition == 'false'
5
- return condition.to_regexp if condition[0] == "/"
5
+ return Regexp.new(condition[1..-2]) if condition[0] == "/"
6
6
  return [:cmp, $1, $2.to_f] if condition =~ /^([<>]=?)(.*)/
7
7
  return [:invert, _convert_match_condition(condition[1..-1].strip)] if condition[0] == "!"
8
8
  #return {$1 => $2.to_f} if condition =~ /^([<>]=?)(.*)/
@@ -13,6 +13,9 @@ module Misc
13
13
  def self.match_value(value, condition)
14
14
  condition = _convert_match_condition(condition.strip) if String === condition
15
15
 
16
+ return true if value.nil? && condition.nil?
17
+ return false if value.nil?
18
+
16
19
  case condition
17
20
  when Regexp
18
21
  !! value.match(condition)
@@ -8,7 +8,7 @@ module Open
8
8
  return Open.ssh(file, options) if Open.ssh?(file)
9
9
  return Open.wget(file, options) if Open.remote?(file)
10
10
 
11
- File.open(file, mode)
11
+ File.open(File.expand_path(file), mode)
12
12
  end
13
13
 
14
14
  def self.file_write(file, content, mode = 'w')
@@ -89,6 +89,8 @@ module Open
89
89
  end
90
90
 
91
91
  def self.touch(file)
92
+ file = file.find if Path === file
93
+ Open.mkdir File.dirname(file)
92
94
  FileUtils.touch(file)
93
95
  end
94
96
 
@@ -115,7 +117,7 @@ module Open
115
117
 
116
118
  def self.exists?(file)
117
119
  file = file.find if Path === file
118
- File.exist?(file)
120
+ File.exist?(File.expand_path(file))
119
121
  end
120
122
 
121
123
  def self.ctime(file)
@@ -197,4 +199,8 @@ module Open
197
199
  FileUtils.cp_lr(source, target)
198
200
  end
199
201
 
202
+ def self.same_file(file1, file2)
203
+ File.identical?(file1, file2)
204
+ end
205
+
200
206
  end
@@ -1,8 +1,7 @@
1
1
  require_relative '../indiferent_hash'
2
2
  module Path
3
3
 
4
- def self.caller_lib_dir(file = nil, relative_to = ['lib', 'bin'])
5
-
4
+ def self.caller_file(file = nil)
6
5
  if file.nil?
7
6
  caller_dup = caller.dup
8
7
  while file = caller_dup.shift
@@ -16,10 +15,24 @@ module Path
16
15
  return nil if file.nil?
17
16
  file = file.sub(/\.rb[^\w].*/,'.rb')
18
17
  end
18
+ file
19
+ end
20
+
21
+ def self.caller_lib_dir(file = nil, relative_to = ['lib', 'bin'])
22
+
23
+ file = caller_file(file)
24
+
25
+ return nil if file.nil?
19
26
 
20
- relative_to = [relative_to] unless Array === relative_to
21
27
  file = File.expand_path(file)
22
- return Path.setup(file) if relative_to.select{|d| File.exist? File.join(file, d)}.any?
28
+
29
+ return File.dirname(file) if not relative_to
30
+
31
+ relative_to = [relative_to] unless Array === relative_to
32
+
33
+ if relative_to.select{|d| File.exist? File.join(file, d)}.any?
34
+ return Path.setup(file)
35
+ end
23
36
 
24
37
  while file != '/'
25
38
  dir = File.dirname file
@@ -75,18 +88,28 @@ module Path
75
88
  :cache => '/cache/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
76
89
  :bulk => '/bulk/{TOPLEVEL}/{PKGDIR}/{SUBPATH}',
77
90
  :lib => '{LIBDIR}/{TOPLEVEL}/{SUBPATH}',
78
- :scout_essentials => File.join(Path.caller_lib_dir(__FILE__), "{TOPLEVEL}/{SUBPATH}"),
91
+ :scout_essentials_lib => File.join(Path.caller_lib_dir(__FILE__), "{TOPLEVEL}/{SUBPATH}"),
79
92
  :tmp => '/tmp/{PKGDIR}/{TOPLEVEL}/{SUBPATH}',
80
93
  :default => :user
81
94
  })
82
95
  end
83
96
 
84
97
  def self.basic_map_order
85
- @@basic_map_order ||= %w(current workflow user local global lib fast cache bulk)
98
+ @@basic_map_order ||= %w(current workflow user local global usr lib fast cache bulk).collect{|m| m.to_sym }
86
99
  end
87
100
 
88
101
  def self.map_order
89
- @@map_order ||= (path_maps.keys & basic_map_order) + (path_maps.keys - basic_map_order)
102
+ @@map_order ||=
103
+ begin
104
+ all_maps = path_maps.keys.collect{|m| m.to_s }.reverse
105
+ basic_map_order = self.basic_map_order.collect{|m| m.to_s }
106
+
107
+ lib_maps = all_maps.select{|m| m.end_with?('_lib') }
108
+ basic_map_order[basic_map_order.index 'lib'] = lib_maps + ['lib']
109
+ basic_map_order.flatten!
110
+
111
+ (basic_map_order & all_maps) + (all_maps - basic_map_order)
112
+ end.collect{|m| m.to_sym }
90
113
  end
91
114
 
92
115
  def self.add_path(name, map)
@@ -104,6 +127,21 @@ module Path
104
127
  map_order.push(name.to_sym)
105
128
  end
106
129
 
130
+ def map_order
131
+ @map_order ||=
132
+ begin
133
+ all_maps = path_maps.keys.collect{|m| m.to_s }.reverse
134
+ basic_map_order = Path.map_order.collect{|m| m.to_s }
135
+
136
+ (basic_map_order & all_maps) + (all_maps - basic_map_order)
137
+ end.collect{|m| m.to_sym }
138
+ end
139
+
140
+ def add_path(name, map)
141
+ path_maps[name] = map
142
+ @map_order = nil
143
+ end
144
+
107
145
  def prepend_path(name, map)
108
146
  path_maps[name] = map
109
147
  map_order.unshift(name.to_sym)
@@ -143,11 +181,14 @@ module Path
143
181
  @toplevel ||= _parts[0]
144
182
  end
145
183
 
184
+ HOME = "~"[0]
146
185
  SLASH = "/"[0]
147
186
  DOT = "."[0]
148
187
  def self.located?(path)
149
188
  # OPEN RESOURCE
150
- path.slice(0,1) == SLASH || (path.slice(0,1) == DOT && path.slice(1,2) == SLASH)
189
+ path.slice(0,1) == SLASH ||
190
+ (path.slice(0,1) == HOME && path.slice(1,1) == SLASH) ||
191
+ (path.slice(0,1) == DOT && path.slice(1,1) == SLASH)
151
192
  end
152
193
 
153
194
  def located?
@@ -199,14 +240,14 @@ module Path
199
240
 
200
241
  def find(where = nil)
201
242
  if located?
202
- if File.exist?(self)
203
- return self if located?
243
+ if File.exist?(File.expand_path(self))
244
+ return self.annotate(File.expand_path(self))
204
245
  else
205
246
  found = Path.exists_file_or_alternatives(self)
206
247
  if found
207
248
  return self.annotate(found)
208
249
  else
209
- return self if located?
250
+ return self
210
251
  end
211
252
  end
212
253
  end
@@ -216,6 +257,7 @@ module Path
216
257
  return follow(where) if where
217
258
 
218
259
  map_order.each do |map_name|
260
+ next unless path_maps.include?(map_name)
219
261
  found = follow(map_name, false)
220
262
 
221
263
  found = Path.exists_file_or_alternatives(found)
@@ -23,7 +23,7 @@ module Path
23
23
  extension = ''
24
24
  end
25
25
 
26
- post_fix = "--#{filename.length}@#{length}_#{Misc.digest(filename)[0..4]}" + extension
26
+ post_fix = "--#{filename.length}--#{Misc.digest(filename)[0..4]}" + extension
27
27
 
28
28
  filename = filename[0..(length - post_fix.length - 1)] << post_fix
29
29
  else
@@ -49,16 +49,17 @@ module Path
49
49
  self.annotate(File.basename(self))
50
50
  end
51
51
 
52
- def glob(pattern = '*')
52
+ def glob(pattern = "*")
53
53
  if self.include? "*"
54
54
  if located?
55
- Dir.glob(File.join(self, pattern))
55
+ Dir.glob(self)
56
56
  else
57
57
  self.glob_all
58
58
  end
59
59
  else
60
60
  return [] unless self.exist?
61
61
  found = self.find
62
+
62
63
  exp = File.join(found, pattern)
63
64
  paths = Dir.glob(exp).collect{|f| self.annotate(f) }
64
65
 
data/lib/scout/path.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require_relative 'annotation'
2
- require_relative 'path/find'
3
2
  require_relative 'path/util'
4
3
  require_relative 'path/tmpfile'
5
4
  require_relative 'path/digest'
@@ -28,10 +27,6 @@ module Path
28
27
  @path_maps ||= Path.path_maps.dup
29
28
  end
30
29
 
31
- def map_order
32
- @map_order ||= (path_maps.keys & Path.map_order) + (path_maps.keys - Path.map_order)
33
- end
34
-
35
30
  def join(subpath = nil, prevpath = nil)
36
31
  return self if subpath.nil?
37
32
 
@@ -54,5 +49,5 @@ module Path
54
49
  join(name, prev)
55
50
  end
56
51
  end
57
-
58
52
  end
53
+ require_relative 'path/find'
@@ -4,4 +4,6 @@ module Scout
4
4
  self.pkgdir = 'scout'
5
5
  end
6
6
 
7
+ Resource.default_resource = Scout
8
+
7
9
  Path.load_path_maps(Scout.etc["path_maps"])
@@ -2,14 +2,19 @@ module Resource
2
2
  def identify(path)
3
3
  path = Path.setup path unless Path === path
4
4
  return path unless path.located?
5
+
5
6
  path_maps = path.path_maps if Path === path
6
7
  path_maps ||= self.path_maps || Path.path_maps
7
- path = File.expand_path(path) if path.start_with?("/")
8
- path += "/" if File.directory?(path)
9
8
 
10
- map_order ||= (path_maps.keys & Path.basic_map_order) + (path_maps.keys - Path.basic_map_order)
9
+ map_order = path.map_order
10
+ map_order ||= Path.map_order
11
11
  map_order -= [:current, "current"]
12
12
 
13
+ libdir = Path.caller_lib_dir
14
+
15
+ path = File.expand_path(path) if path.start_with?('/')
16
+ path += "/" if File.directory?(path) and not path.end_with?('/')
17
+
13
18
  choices = []
14
19
  map_order.uniq.each do |name|
15
20
  pattern = path_maps[name]
@@ -22,6 +27,7 @@ module Resource
22
27
  regexp = "^" + pattern
23
28
  .gsub(/{(TOPLEVEL)}/,'(?<\1>[^/]+)')
24
29
  .gsub(/\.{(PKGDIR)}/,'\.(?<\1>[^/]+)')
30
+ .gsub(/{(LIBDIR)}/, libdir)
25
31
  .gsub(/\/{([^}]+)}/,'(?:/(?<\1>[^/]+))?') +
26
32
  "(?:/(?<REST>.+))?/?$"
27
33
  if m = path.match(regexp)
@@ -7,6 +7,15 @@ require_relative 'resource/util'
7
7
  require_relative 'resource/software'
8
8
  require_relative 'resource/sync'
9
9
 
10
+ require_relative 'log'
11
+ require_relative 'path'
12
+ require_relative 'resource/produce'
13
+ require_relative 'resource/path'
14
+ require_relative 'resource/open'
15
+ require_relative 'resource/util'
16
+ require_relative 'resource/software'
17
+ require_relative 'resource/sync'
18
+
10
19
  module Resource
11
20
  extend Annotation
12
21
  annotation :pkgdir, :libdir, :subdir, :resources, :rake_dirs, :path_maps, :map_order, :lock_dir
@@ -24,7 +33,7 @@ module Resource
24
33
  end
25
34
 
26
35
  def path_maps
27
- @path_maps ||= Path.path_maps.dup
36
+ @path_maps ||= Path.path_maps
28
37
  end
29
38
 
30
39
  def subdir
@@ -97,7 +97,7 @@ module SOPT
97
97
 
98
98
  name = SOPT.input_format(name, type.to_sym, default, shortcut)
99
99
  Misc.format_definition_list_item(name, description)
100
- end * "\n"
100
+ end.compact * "\n"
101
101
  end
102
102
 
103
103
 
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: scout-essentials 1.6.14 ruby lib
5
+ # stub: scout-essentials 1.7.1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "scout-essentials".freeze
9
- s.version = "1.6.14".freeze
9
+ s.version = "1.7.1".freeze
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Miguel Vazquez".freeze]
14
- s.date = "1980-01-02"
14
+ s.date = "2025-06-12"
15
15
  s.description = "Things a scout can use anywhere".freeze
16
16
  s.email = "mikisvaz@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
@@ -146,7 +146,7 @@ Gem::Specification.new do |s|
146
146
  ]
147
147
  s.homepage = "http://github.com/mikisvaz/scout-essentials".freeze
148
148
  s.licenses = ["MIT".freeze]
149
- s.rubygems_version = "3.6.7".freeze
149
+ s.rubygems_version = "3.6.6".freeze
150
150
  s.summary = "Scout essential tools".freeze
151
151
 
152
152
  s.specification_version = 4
@@ -42,5 +42,10 @@ class TestOptions < Test::Unit::TestCase
42
42
  hash = {:a => /test/}
43
43
  assert_equal({}, IndiferentHash.string2hash(IndiferentHash.hash2string(hash)))
44
44
  end
45
+
46
+ def test_parse_options
47
+ assert_include IndiferentHash.parse_options('blueberries=true title="This is a title" list=one,two,"and three"'), "title"
48
+ assert_include IndiferentHash.parse_options('source="=>Alias"'), "source"
49
+ end
45
50
  end
46
51
 
@@ -110,7 +110,7 @@ class TestPathFind < Test::Unit::TestCase
110
110
  path = Path.setup("somefile")
111
111
  TmpFile.with_path do |tmpdir|
112
112
  Open.write(tmpdir.somefile, 'test')
113
- path.path_maps["tmpdir"] = tmpdir
113
+ path.add_path :tmpdir, tmpdir
114
114
  assert path.exists?
115
115
  end
116
116
  end
@@ -10,6 +10,12 @@ class TestResourceUtil < Test::Unit::TestCase
10
10
  assert_equal 'share/data/somedir/somepath', Scout.identify(path)
11
11
  end
12
12
 
13
+ def test_identify_lib
14
+ p = Scout.data.file.find(:lib)
15
+ assert p.located?
16
+ assert_equal "data/file", p.identify
17
+ end
18
+
13
19
  def test_identify_dir
14
20
  path = Path.setup('share/data/somedir/').find
15
21
  assert_equal 'share/data/somedir', Scout.identify(path)
@@ -29,8 +35,8 @@ class TestResourceUtil < Test::Unit::TestCase
29
35
  Path.setup dir
30
36
 
31
37
  path_base = Path.setup("basedir").someother.file
32
- path_base.path_maps[:subdir1] = File.join(dir, 'subdir1', '{PATH}')
33
- path_base.path_maps[:subdir2] = File.join(dir, 'subdir2', '{PATH}')
38
+ path_base.add_path :subdir1, File.join(dir, 'subdir1', '{PATH}')
39
+ path_base.add_path :subdir2, File.join(dir, 'subdir2', '{PATH}')
34
40
 
35
41
  path1 = path_base.find(:subdir1)
36
42
  path2 = path_base.find(:subdir2)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout-essentials
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.14
4
+ version: 1.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
10
+ date: 2025-06-12 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: shoulda
@@ -271,7 +271,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
271
271
  - !ruby/object:Gem::Version
272
272
  version: '0'
273
273
  requirements: []
274
- rubygems_version: 3.6.7
274
+ rubygems_version: 3.6.6
275
275
  specification_version: 4
276
276
  summary: Scout essential tools
277
277
  test_files: []