scout-essentials 1.6.9 → 1.6.11

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: a3c6a3bfa03c83171a83558fa73b4a23c5bffffb02fa036c36f4ad6417abbee9
4
- data.tar.gz: 605d88dc63abe624432c9ece462ac19c33e243252667d5aa8b27a541e38582f6
3
+ metadata.gz: ca46feecfdca0f796ad76e9e0e8f3dcf33eb169e41605708cf2042507c968207
4
+ data.tar.gz: 93b589d483250fdca27ed5e888887d2135b81f253b7ad30afb97adcb8a3382f2
5
5
  SHA512:
6
- metadata.gz: 9528eea7eccc93c0640f1530ecba2eeb874fd3f4bb211789f8bd830e127ff52c880cee2fb4621f92db7f855fb0d4f7d12098ace50726f76f14f27c5cd8ffb8f7
7
- data.tar.gz: beaf0a93070745d6102d766931557369a74d5ada67182c7b13cde60eb5d14a8d8e71f29e8f80356910bac97fef1022e9bb21028d2a687515a04bb781dd7d61fb
6
+ metadata.gz: 95d450e003292a7507116cd39bc74822e12820119cea0ddfeabd8aa5a86979f17d4a8aefdf76db5f526026c7795422b8bf7a91c5ae2833a75feb48cf08c5a17b
7
+ data.tar.gz: 2bdaa762c5899135b5d5aadc054017b597244bf000bb5525894da4b9f9e893053221d3049c5df821726cb999cb5c3fc53e486535395b7fb54513b6a9a339d21c
data/.vimproject CHANGED
@@ -66,6 +66,7 @@ scout-essentials=/$PWD filter="*.rb *.txt *.md *.conf *.yaml" {
66
66
  remote.rb
67
67
  stream.rb
68
68
  util.rb
69
+ sync.rb
69
70
  bgzf.rb
70
71
  }
71
72
  tmpfile.rb
@@ -76,6 +77,7 @@ scout-essentials=/$PWD filter="*.rb *.txt *.md *.conf *.yaml" {
76
77
  produce.rb
77
78
  scout.rb
78
79
  software.rb
80
+ sync.rb
79
81
  util.rb
80
82
  }
81
83
  config.rb
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.6.9
1
+ 1.6.11
@@ -1,8 +1,10 @@
1
+ require 'scout/log'
1
2
  module Annotation
2
3
  module AnnotationModule
3
4
  def annotation(*attrs)
4
5
  annotations = self.instance_variable_get("@annotations")
5
- annotations.concat attrs - annotations
6
+ attrs -= annotations
7
+ annotations.concat attrs
6
8
  attrs.each do |a|
7
9
  self.attr_accessor a
8
10
  end
@@ -13,8 +15,11 @@ module Annotation
13
15
  end
14
16
 
15
17
  def included(mod)
18
+ attrs = self.instance_variable_get("@annotations")
16
19
  mod.instance_variable_set(:@annotations, []) unless mod.instance_variables.include?(:@annotations)
17
- mod.instance_variable_get(:@annotations).concat self.instance_variable_get(:@annotations)
20
+ annotations = mod.instance_variable_get(:@annotations)
21
+ attrs -= annotations
22
+ annotations.concat attrs
18
23
  end
19
24
 
20
25
  def extended(obj)
@@ -24,6 +29,7 @@ module Annotation
24
29
  obj.annotation_types << self
25
30
 
26
31
  annotations = obj.instance_variable_get(:@annotations)
32
+ attrs -= annotations
27
33
  annotations.concat attrs
28
34
  end
29
35
 
data/lib/scout/cmd.rb CHANGED
@@ -92,7 +92,7 @@ module CMD
92
92
  end
93
93
 
94
94
  def self.bash(cmd)
95
- cmd = %Q(bash <<EOF\n#{cmd}\nEOF\n)
95
+ cmd = %Q(bash -l <<EOF\n#{cmd}\nEOF\n)
96
96
  CMD.cmd(cmd, :autojoin => true)
97
97
  end
98
98
 
@@ -115,10 +115,27 @@ module IndiferentHash
115
115
  def keys_to_sym!
116
116
  string_keys = keys.select{|k| String === k}
117
117
  string_keys.each do |key|
118
- self[key.to_sym] = self.delete(key)
118
+ begin
119
+ self[key.to_sym] = self.delete(key)
120
+ rescue
121
+ next
122
+ end
119
123
  end
120
124
  end
121
125
 
126
+ def keys_to_sym
127
+ new = IndiferentHash.setup({})
128
+ self.keys.each do |key|
129
+ begin
130
+ skey = key.is_a?(String) ? key.to_sym : key
131
+ rescue
132
+ skey = key
133
+ end
134
+ new[skey] = self[key]
135
+ end
136
+ new
137
+ end
138
+
122
139
  def prety_print
123
140
  Misc.format_definition_list(self, sep: "\n")
124
141
  end
@@ -140,4 +140,56 @@ module Open
140
140
  nil
141
141
  end
142
142
  end
143
+
144
+ def self.ln_s(source, target, options = {})
145
+ source = source.find if Path === source
146
+ target = target.find if Path === target
147
+
148
+ target = File.join(target, File.basename(source)) if File.directory? target
149
+ FileUtils.mkdir_p File.dirname(target) unless File.exist?(File.dirname(target))
150
+ FileUtils.rm target if File.exist?(target)
151
+ FileUtils.rm target if File.symlink?(target)
152
+ FileUtils.ln_s source, target
153
+ end
154
+
155
+ def self.ln(source, target, options = {})
156
+ source = source.find if Path === source
157
+ target = target.find if Path === target
158
+ source = File.realpath(source) if File.symlink?(source)
159
+
160
+ FileUtils.mkdir_p File.dirname(target) unless File.exist?(File.dirname(target))
161
+ FileUtils.rm target if File.exist?(target)
162
+ FileUtils.rm target if File.symlink?(target)
163
+ FileUtils.ln source, target
164
+ end
165
+
166
+ def self.ln_h(source, target, options = {})
167
+ source = source.find if Path === source
168
+ target = target.find if Path === target
169
+
170
+ FileUtils.mkdir_p File.dirname(target) unless File.exist?(File.dirname(target))
171
+ FileUtils.rm target if File.exist?(target)
172
+ begin
173
+ CMD.cmd("ln -L '#{ source }' '#{ target }'")
174
+ rescue ProcessFailed
175
+ Log.debug "Could not hard link #{source} and #{target}: #{$!.message.gsub("\n", '. ')}"
176
+ CMD.cmd("cp -L '#{ source }' '#{ target }'")
177
+ end
178
+ end
179
+
180
+ def self.link(source, target, options = {})
181
+ begin
182
+ Open.ln(source, target, options)
183
+ rescue
184
+ Log.debug "Could not make regular link, trying symbolic: #{Misc.fingerprint(source)} -> #{Misc.fingerprint(target)}"
185
+ Open.ln_s(source, target, options)
186
+ end
187
+ nil
188
+ end
189
+
190
+ def self.link_dir(source, target)
191
+ Log.debug "Copy with hard-links #{Log.fingerprint source}->#{Log.fingerprint target}"
192
+ FileUtils.cp_lr(source, target)
193
+ end
194
+
143
195
  end
@@ -0,0 +1,85 @@
1
+ module Open
2
+
3
+ def self.rsync(source, target, options = {})
4
+ excludes, files, hard_link, test, print, delete, source_server, target_server, other = IndiferentHash.process_options options,
5
+ :excludes, :files, :hard_link, :test, :print, :delete, :source, :target, :other
6
+
7
+ excludes ||= %w(.save .crap .source tmp filecache open-remote)
8
+ excludes = excludes.split(/,\s*/) if excludes.is_a?(String) and not excludes.include?("--exclude")
9
+
10
+ if File.directory?(source) || source.end_with?("/")
11
+ source += "/" unless source.end_with? '/'
12
+ target += "/" unless target.end_with? '/'
13
+ end
14
+
15
+ if source == target && ! (source_server || target_server)
16
+ Log.warn "Asking to rsync local file with itself"
17
+ return
18
+ end
19
+
20
+ if target_server
21
+ target_uri = [target_server, "'" + target + "'"] * ":"
22
+ else
23
+ target_uri = "'" + target + "'"
24
+ end
25
+
26
+ if source_server
27
+ source_uri = [source_server, "'" + source + "'"] * ":"
28
+ else
29
+ source_uri = "'" + source + "'"
30
+ end
31
+
32
+
33
+ if target_server
34
+ CMD.cmd("ssh #{target_server} mkdir -p '#{File.dirname(target)}'")
35
+ else
36
+ Open.mkdir File.dirname(target)
37
+ end
38
+
39
+
40
+ Log.low "Migrating #{source} #{files.length} files to #{target} - #{Misc.fingerprint(files)}}" if files
41
+
42
+
43
+ rsync_args = %w(-avztHP --copy-unsafe-links --omit-dir-times)
44
+ rsync_args << "--link-dest '#{source}'" if hard_link && ! source_server
45
+ rsync_args << excludes.collect{|s| "--exclude '#{s}'" } if excludes and excludes.any?
46
+ rsync_args << "-nv" if test
47
+ if files
48
+ tmp_files = TmpFile.tmp_file 'rsync_files-'
49
+ Open.write(tmp_files, files * "\n")
50
+ rsync_args << "--files-from='#{tmp_files}'"
51
+ end
52
+
53
+ cmd = "rsync #{rsync_args * " "} #{source_uri} #{target_uri}"
54
+ case other
55
+ when String
56
+ cmd << " " << other
57
+ when Array
58
+ cmd << " " << other * " "
59
+ end
60
+ cmd << " && rm -Rf #{source}" if delete && ! files
61
+
62
+ if print
63
+ cmd
64
+ else
65
+ CMD.cmd_log(cmd, :log => Log::HIGH)
66
+
67
+ if delete && files
68
+ remove_files = files.collect{|f| File.join(source, f) }
69
+ dirs = remove_files.select{|f| File.directory? f }
70
+ remove_files.each do |file|
71
+ next if dirs.include? file
72
+ Open.rm file
73
+ end
74
+
75
+ dirs.each do |dir|
76
+ FileUtils.rmdir dir if Dir.glob(dir).empty?
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ def self.sync(...)
83
+ rsync(...)
84
+ end
85
+ end
@@ -125,57 +125,6 @@ module Open
125
125
  Pathname.new(File.expand_path(file)).realpath.to_s
126
126
  end
127
127
 
128
- def self.ln_s(source, target, options = {})
129
- source = source.find if Path === source
130
- target = target.find if Path === target
131
-
132
- target = File.join(target, File.basename(source)) if File.directory? target
133
- FileUtils.mkdir_p File.dirname(target) unless File.exist?(File.dirname(target))
134
- FileUtils.rm target if File.exist?(target)
135
- FileUtils.rm target if File.symlink?(target)
136
- FileUtils.ln_s source, target
137
- end
138
-
139
- def self.ln(source, target, options = {})
140
- source = source.find if Path === source
141
- target = target.find if Path === target
142
- source = File.realpath(source) if File.symlink?(source)
143
-
144
- FileUtils.mkdir_p File.dirname(target) unless File.exist?(File.dirname(target))
145
- FileUtils.rm target if File.exist?(target)
146
- FileUtils.rm target if File.symlink?(target)
147
- FileUtils.ln source, target
148
- end
149
-
150
- def self.ln_h(source, target, options = {})
151
- source = source.find if Path === source
152
- target = target.find if Path === target
153
-
154
- FileUtils.mkdir_p File.dirname(target) unless File.exist?(File.dirname(target))
155
- FileUtils.rm target if File.exist?(target)
156
- begin
157
- CMD.cmd("ln -L '#{ source }' '#{ target }'")
158
- rescue ProcessFailed
159
- Log.debug "Could not hard link #{source} and #{target}: #{$!.message.gsub("\n", '. ')}"
160
- CMD.cmd("cp -L '#{ source }' '#{ target }'")
161
- end
162
- end
163
-
164
- def self.link(source, target, options = {})
165
- begin
166
- Open.ln(source, target, options)
167
- rescue
168
- Log.debug "Could not make regular link, trying symbolic: #{Misc.fingerprint(source)} -> #{Misc.fingerprint(target)}"
169
- Open.ln_s(source, target, options)
170
- end
171
- nil
172
- end
173
-
174
- def self.link_dir(source, target)
175
- Log.debug "Copy with hard-links #{Log.fingerprint source}->#{Log.fingerprint target}"
176
- FileUtils.cp_lr(source, target)
177
- end
178
-
179
128
  def self.list(file)
180
129
  file = file.produce_and_find if Path === file
181
130
  Open.read(file).split("\n")
data/lib/scout/open.rb CHANGED
@@ -6,6 +6,7 @@ require_relative 'open/stream'
6
6
  require_relative 'open/util'
7
7
  require_relative 'open/remote'
8
8
  require_relative 'open/lock'
9
+ require_relative 'open/sync'
9
10
 
10
11
  module Open
11
12
  module NamedStream
@@ -141,9 +141,13 @@ module Path
141
141
 
142
142
  SLASH = "/"[0]
143
143
  DOT = "."[0]
144
- def located?
144
+ def self.located?(path)
145
145
  # OPEN RESOURCE
146
- self.slice(0,1) == SLASH || (self.slice(0,1) == DOT && self.slice(1,2) == SLASH) # || (resource != Rbbt && (Open.remote?(self) || Open.ssh?(self)))
146
+ path.slice(0,1) == SLASH || (path.slice(0,1) == DOT && path.slice(1,2) == SLASH)
147
+ end
148
+
149
+ def located?
150
+ Path.located?(self)
147
151
  end
148
152
 
149
153
  def annotate_found_where(found, where)
@@ -0,0 +1,24 @@
1
+ require 'scout/open/sync'
2
+ module Resource
3
+ def self.sync(path, map = nil, options = {})
4
+ resource = IndiferentHash.process_options options,
5
+ :resource
6
+
7
+ map = 'user' if map.nil?
8
+ resource = path.pkgdir if resource.nil? and path.is_a?(Path) and path.pkgdir.is_a?(Resource)
9
+ resource = Resource.default_resource if resource.nil?
10
+
11
+ target = resource.identify(path).find(map)
12
+
13
+ if File.exist?(path)
14
+ real_paths = [path]
15
+ else
16
+ path = Path.setup(path, pkgdir: resource) unless path.is_a?(Path)
17
+ real_paths = path.directory? ? path.find_all : path.glob_all
18
+ end
19
+
20
+ real_paths.each do |source|
21
+ Open.sync(source, target, options)
22
+ end
23
+ end
24
+ end
@@ -1,9 +1,9 @@
1
1
  module Resource
2
2
  def identify(path)
3
- return path unless path.start_with?("/")
3
+ return path unless Path.located?(path)
4
4
  path_maps = path.path_maps if Path === path
5
5
  path_maps ||= self.path_maps || Path.path_maps
6
- path = File.expand_path(path)
6
+ path = File.expand_path(path) if path.start_with?("/")
7
7
  path += "/" if File.directory?(path)
8
8
 
9
9
  map_order ||= (path_maps.keys & Path.basic_map_order) + (path_maps.keys - Path.basic_map_order)
@@ -30,7 +30,7 @@ module Resource
30
30
  m.named_captures.include?(c) ? m[c] : nil
31
31
  }.compact * "/"
32
32
 
33
- unlocated.gsub!(/\/+/,'/')
33
+ #unlocated.gsub!(/\/+/,'/')
34
34
 
35
35
  if self.subdir && ! self.subdir.empty?
36
36
  subdir = self.subdir
@@ -5,6 +5,7 @@ require_relative 'resource/path'
5
5
  require_relative 'resource/open'
6
6
  require_relative 'resource/util'
7
7
  require_relative 'resource/software'
8
+ require_relative 'resource/sync'
8
9
 
9
10
  module Resource
10
11
  extend Annotation
@@ -14,7 +15,7 @@ module Resource
14
15
  attr_accessor :default_resource
15
16
 
16
17
  def default_resource
17
- @default_resource ||= Scout
18
+ @default_resource
18
19
  end
19
20
  end
20
21
 
@@ -41,7 +41,7 @@ module SOPT
41
41
  IndiferentHash.setup @@current_options
42
42
  GOT_OPTIONS.merge! @@current_options
43
43
 
44
- @@current_options
44
+ @@current_options.keys_to_sym
45
45
  end
46
46
 
47
47
  def self.get(opt_str)
@@ -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.9 ruby lib
5
+ # stub: scout-essentials 1.6.11 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "scout-essentials".freeze
9
- s.version = "1.6.9".freeze
9
+ s.version = "1.6.11".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 = "2025-03-25"
14
+ s.date = "2025-04-10"
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 = [
@@ -64,6 +64,7 @@ Gem::Specification.new do |s|
64
64
  "lib/scout/open/lock/lockfile.rb",
65
65
  "lib/scout/open/remote.rb",
66
66
  "lib/scout/open/stream.rb",
67
+ "lib/scout/open/sync.rb",
67
68
  "lib/scout/open/util.rb",
68
69
  "lib/scout/path.rb",
69
70
  "lib/scout/path/digest.rb",
@@ -81,6 +82,7 @@ Gem::Specification.new do |s|
81
82
  "lib/scout/resource/produce/rake.rb",
82
83
  "lib/scout/resource/scout.rb",
83
84
  "lib/scout/resource/software.rb",
85
+ "lib/scout/resource/sync.rb",
84
86
  "lib/scout/resource/util.rb",
85
87
  "lib/scout/simple_opt.rb",
86
88
  "lib/scout/simple_opt/accessor.rb",
@@ -110,6 +112,7 @@ Gem::Specification.new do |s|
110
112
  "test/scout/open/test_lock.rb",
111
113
  "test/scout/open/test_remote.rb",
112
114
  "test/scout/open/test_stream.rb",
115
+ "test/scout/open/test_sync.rb",
113
116
  "test/scout/open/test_util.rb",
114
117
  "test/scout/path/test_digest.rb",
115
118
  "test/scout/path/test_find.rb",
@@ -120,6 +123,7 @@ Gem::Specification.new do |s|
120
123
  "test/scout/resource/test_path.rb",
121
124
  "test/scout/resource/test_produce.rb",
122
125
  "test/scout/resource/test_software.rb",
126
+ "test/scout/resource/test_sync.rb",
123
127
  "test/scout/resource/test_util.rb",
124
128
  "test/scout/simple_opt/test_doc.rb",
125
129
  "test/scout/simple_opt/test_get.rb",
@@ -0,0 +1,55 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ class TestOpenSync < Test::Unit::TestCase
5
+ def test_rsync_basic
6
+ TmpFile.with_file do |source|
7
+ TmpFile.with_file do |target|
8
+ Open.write(source, 'payload')
9
+ Open.rsync(source, target)
10
+ assert_equal 'payload', Open.read(target)
11
+ end
12
+ end
13
+ end
14
+
15
+ def test_rsync_dir
16
+ TmpFile.with_path do |source|
17
+ TmpFile.with_path do |target|
18
+ Open.write(source.file, 'payload')
19
+ Open.rsync(source, target)
20
+ assert_equal 'payload', Open.read(target.file)
21
+ end
22
+ end
23
+ end
24
+
25
+ def test_rsync_excludes
26
+ TmpFile.with_path do |source|
27
+ TmpFile.with_path do |target|
28
+ Open.write(source.file, 'payload')
29
+ Open.write(source.tmp_dir.tmp_file, 'decoy')
30
+ Open.rsync(source, target, excludes: 'tmp_dir')
31
+ assert_equal 'payload', Open.read(target.file)
32
+ refute Open.exist?(target.tmp_dir.tmp_file)
33
+ end
34
+ end
35
+ end
36
+
37
+ def test_rsync_remote
38
+ TmpFile.with_path do |source|
39
+ Open.write(source.file, 'payload')
40
+ cmd = Open.rsync(source, 'remote:target', print: true)
41
+ assert cmd.end_with?('remote:target/\'')
42
+ end
43
+ end
44
+
45
+ def test_sync_alias
46
+ TmpFile.with_path do |source|
47
+ TmpFile.with_path do |target|
48
+ Open.write(source.file, 'payload')
49
+ Open.sync(source, target)
50
+ assert_equal 'payload', Open.read(target.file)
51
+ end
52
+ end
53
+ end
54
+ end
55
+
@@ -0,0 +1,32 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ require 'scout'
5
+ class TestResourceSync < Test::Unit::TestCase
6
+ def test_sync_file
7
+ TmpFile.with_path do |source|
8
+ TmpFile.with_path do |target|
9
+ Open.write(source.file, 'payload')
10
+ Misc.in_dir target.find do
11
+ Resource.sync(source.file, :current)
12
+ end
13
+
14
+ assert_equal 'payload', Open.read(target[Resource.identify(source)].file)
15
+ end
16
+ end
17
+ end
18
+
19
+ def test_sync_dir
20
+ TmpFile.with_path do |source|
21
+ TmpFile.with_path do |target|
22
+ Open.write(source.file, 'payload')
23
+ Misc.in_dir target.find do
24
+ Resource.sync(source, :current)
25
+ end
26
+
27
+ assert_equal 'payload', Open.read(target[Resource.identify(source)].file)
28
+ end
29
+ end
30
+ end
31
+ end
32
+
@@ -10,6 +10,11 @@ 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_dir
14
+ path = Path.setup('share/data/somedir/').find
15
+ assert_equal 'share/data/somedir', Scout.identify(path)
16
+ end
17
+
13
18
  def test_identify_with_subdir
14
19
  m = Module.new
15
20
  m.extend Resource
@@ -35,5 +40,14 @@ class TestResourceUtil < Test::Unit::TestCase
35
40
  assert_equal path2, Resource.relocate(path1)
36
41
  end
37
42
  end
43
+
44
+ def ___test_s3
45
+ require 'scout-camp'
46
+ require 'scout/aws/s3'
47
+ p = Path.setup("s3://bucket/var/jobs/workflow/task/job.txt")
48
+ p.path_maps = {:bucket => 's3://bucket/{TOPLEVEL}/{SUBPATH}'}
49
+
50
+ assert_equal 'var/jobs/workflow/task/job.txt', Resource.identify(p)
51
+ end
38
52
  end
39
53
 
@@ -1,6 +1,7 @@
1
1
  require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
2
  require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
3
 
4
+ require 'scout'
4
5
  require 'scout/resource/scout'
5
6
  class TestResourceUnit < Test::Unit::TestCase
6
7
  module TestResource
@@ -22,5 +23,6 @@ class TestResourceUnit < Test::Unit::TestCase
22
23
  assert_equal 'share/databases/DATABASE/FILE', Resource.identify('/usr/local/share/scout/databases/DATABASE/FILE')
23
24
  assert_equal 'share/databases/DATABASE/FILE', Resource.identify(File.join(ENV["HOME"], '.scout/share/databases/DATABASE/FILE'))
24
25
  assert_equal 'share/databases/DATABASE/FILE', Resource.identify('/usr/local/share/scout/databases/DATABASE/FILE')
26
+ assert_equal 'share/databases/DATABASE/FILE', Resource.identify('/usr/local/share/scout/databases/DATABASE/FILE/')
25
27
  end
26
28
  end
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.9
4
+ version: 1.6.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-25 00:00:00.000000000 Z
10
+ date: 2025-04-10 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: shoulda
@@ -174,6 +174,7 @@ files:
174
174
  - lib/scout/open/lock/lockfile.rb
175
175
  - lib/scout/open/remote.rb
176
176
  - lib/scout/open/stream.rb
177
+ - lib/scout/open/sync.rb
177
178
  - lib/scout/open/util.rb
178
179
  - lib/scout/path.rb
179
180
  - lib/scout/path/digest.rb
@@ -191,6 +192,7 @@ files:
191
192
  - lib/scout/resource/produce/rake.rb
192
193
  - lib/scout/resource/scout.rb
193
194
  - lib/scout/resource/software.rb
195
+ - lib/scout/resource/sync.rb
194
196
  - lib/scout/resource/util.rb
195
197
  - lib/scout/simple_opt.rb
196
198
  - lib/scout/simple_opt/accessor.rb
@@ -220,6 +222,7 @@ files:
220
222
  - test/scout/open/test_lock.rb
221
223
  - test/scout/open/test_remote.rb
222
224
  - test/scout/open/test_stream.rb
225
+ - test/scout/open/test_sync.rb
223
226
  - test/scout/open/test_util.rb
224
227
  - test/scout/path/test_digest.rb
225
228
  - test/scout/path/test_find.rb
@@ -230,6 +233,7 @@ files:
230
233
  - test/scout/resource/test_path.rb
231
234
  - test/scout/resource/test_produce.rb
232
235
  - test/scout/resource/test_software.rb
236
+ - test/scout/resource/test_sync.rb
233
237
  - test/scout/resource/test_util.rb
234
238
  - test/scout/simple_opt/test_doc.rb
235
239
  - test/scout/simple_opt/test_get.rb