bfs-scp 0.4.4 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: caf82a4458c6bd32289190f40d664108d365f70c0ec2ca78d92faf030a647ac6
4
- data.tar.gz: 8e47309534a09fdcfd2f67b5f021b32be0ef955a64376e274568118ef63fb2cb
3
+ metadata.gz: 2d2a1d8aa79faab191a46b8719628bc1b92fa2528be1e9b95d1e0c88e34e5131
4
+ data.tar.gz: 3b8ed648fc045c535b360c9541028655a18748c4421cdec5f6ac23b3ca04681a
5
5
  SHA512:
6
- metadata.gz: 4a2600a804bdd5d768e26f622b4c98bba543c1d780649f4bf32ae7ecdc180058c46d9db3ccb837b4647bf1400b5d2da440070f5ed11ea1d75c2998177c69f7ee
7
- data.tar.gz: f3f078f7e9bacf1a29bc0c17d95288aa23134d3d44dff1a5591bf3f360d445e78adede1306c9c28c4d12182586330393776d4fbcdbaf7cca682063140c2ad8c4
6
+ metadata.gz: 375ed1a9efc068961df091335dd6950e934d3f9363d7c79b6e8428c4d04febe368569189caf8b941ca74b3b1c964229cc7df6ed1399e6cdb783e16a2e71c1814
7
+ data.tar.gz: faaccfff6e02b43e0e41374596dd89f169c827916ca1902d3504de4cdbafb6fcc53594055170a68a7b76715783d82217e55200bdb233c379392446d4853888aa
data/bfs-scp.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.files = `git ls-files`.split("\n")
16
16
  s.test_files = `git ls-files -- spec/*`.split("\n")
17
17
  s.require_paths = ['lib']
18
- s.required_ruby_version = '>= 2.4.0'
18
+ s.required_ruby_version = '>= 2.5.0'
19
19
 
20
20
  s.add_dependency 'bfs', s.version
21
21
  s.add_dependency 'net-scp'
@@ -10,7 +10,7 @@ module BFS
10
10
  class CommandError < RuntimeError
11
11
  attr_reader :status
12
12
 
13
- def initialize(cmd, status, extra=nil)
13
+ def initialize(cmd, status, extra = nil)
14
14
  @status = status
15
15
  super ["Command '#{cmd}' exited with status #{status}", extra].join(': ')
16
16
  end
@@ -28,30 +28,25 @@ module BFS
28
28
  # @option opts [Integer] :keepalive_interval interval if keepalive enabled. Default: 300.
29
29
  # @option opts [Array<String>] :keys an array of file names of private keys to use for publickey and hostbased authentication.
30
30
  # @option opts [Boolean|Symbol] :verify_host_key specifying how strict host-key verification should be, either false, true, :very, or :secure.
31
- def initialize(host, opts={})
32
- opts = opts.dup
33
- opts.keys.each do |key|
34
- val = opts.delete(key)
35
- opts[key.to_sym] = val unless val.nil?
36
- end
37
- super(opts)
31
+ def initialize(host, prefix: nil, **opts)
32
+ super(**opts)
38
33
 
39
- @prefix = opts.delete(:prefix)
40
- @client = Net::SCP.start(host, nil, opts)
34
+ @prefix = prefix
35
+ @client = Net::SCP.start(host, nil, **opts)
41
36
 
42
37
  if @prefix # rubocop:disable Style/GuardClause
43
38
  @prefix = norm_path(@prefix) + '/'
44
- mkdir_p(@prefix)
39
+ mkdir_p abs_path(@prefix)
45
40
  end
46
41
  end
47
42
 
48
43
  # Lists the contents of a bucket using a glob pattern
49
- def ls(pattern='**/*', _opts={})
50
- prefix = @prefix || '.'
44
+ def ls(pattern = '**/*', **_opts)
45
+ prefix = @prefix ? abs_path(@prefix) : '/'
51
46
  Enumerator.new do |y|
52
47
  sh! 'find', prefix, '-type', 'f' do |out|
53
48
  out.each_line do |line|
54
- path = trim_prefix(line.strip)
49
+ path = trim_prefix(norm_path(line.strip))
55
50
  y << path if File.fnmatch?(pattern, path, File::FNM_PATHNAME)
56
51
  end
57
52
  end
@@ -59,24 +54,28 @@ module BFS
59
54
  end
60
55
 
61
56
  # Info returns the object info
62
- def info(path, _opts={})
57
+ def info(path, **_opts)
63
58
  full = full_path(path)
64
59
  path = norm_path(path)
65
- out = sh! 'stat', '-c', '%s;%Z', full
60
+ out = sh! 'stat', '-c', '%s;%Z;%a', full
66
61
 
67
- size, epoch = out.strip.split(';', 2).map(&:to_i)
68
- BFS::FileInfo.new(path, size, Time.at(epoch))
62
+ size, epoch, mode = out.strip.split(';', 3)
63
+ BFS::FileInfo.new(path: path, size: size.to_i, mtime: Time.at(epoch.to_i), mode: BFS.norm_mode(mode))
69
64
  rescue CommandError => e
70
65
  e.status == 1 ? raise(BFS::FileNotFound, path) : raise
71
66
  end
72
67
 
73
68
  # Creates a new file and opens it for writing
74
- def create(path, opts={}, &block)
69
+ # @option opts [String|Encoding] :encoding Custom file encoding.
70
+ # @option opts [Integer] :perm Custom file permission, default: 0600.
71
+ def create(path, encoding: nil, perm: nil, **opts, &block)
75
72
  full = full_path(path)
76
- enc = opts.delete(:encoding) || @encoding
77
- temp = BFS::TempWriter.new(path, encoding: enc) do |temp_path|
73
+
74
+ opts[:preserve] = true if perm && !opts.key?(:preserve)
75
+ enc = encoding || @encoding
76
+ temp = BFS::TempWriter.new(path, encoding: enc, perm: perm) do |temp_path|
78
77
  mkdir_p File.dirname(full)
79
- @client.upload!(temp_path, full)
78
+ @client.upload!(temp_path, full, **opts)
80
79
  end
81
80
  return temp unless block
82
81
 
@@ -88,10 +87,10 @@ module BFS
88
87
  end
89
88
 
90
89
  # Opens an existing file for reading
91
- def open(path, opts={}, &block)
90
+ def open(path, encoding: nil, tempdir: nil, **_opts, &block)
92
91
  full = full_path(path)
93
- enc = opts.delete(:encoding) || @encoding
94
- temp = Tempfile.new(File.basename(path), encoding: enc)
92
+ enc = encoding || @encoding
93
+ temp = Tempfile.new(File.basename(path), tempdir, encoding: enc)
95
94
  temp.close
96
95
 
97
96
  @client.download!(full, temp.path)
@@ -101,7 +100,7 @@ module BFS
101
100
  end
102
101
 
103
102
  # Deletes a file.
104
- def rm(path, _opts={})
103
+ def rm(path, **_opts)
105
104
  path = full_path(path)
106
105
  sh! 'rm', '-f', path
107
106
  end
@@ -110,7 +109,7 @@ module BFS
110
109
  #
111
110
  # @param [String] src The source path.
112
111
  # @param [String] dst The destination path.
113
- def cp(src, dst, _opts={})
112
+ def cp(src, dst, **_opts)
114
113
  full_src = full_path(src)
115
114
  full_dst = full_path(dst)
116
115
 
@@ -124,7 +123,7 @@ module BFS
124
123
  #
125
124
  # @param [String] src The source path.
126
125
  # @param [String] dst The destination path.
127
- def mv(src, dst, _opts={})
126
+ def mv(src, dst, **_opts)
128
127
  full_src = full_path(src)
129
128
  full_dst = full_path(dst)
130
129
 
@@ -141,6 +140,15 @@ module BFS
141
140
 
142
141
  private
143
142
 
143
+ def abs_path(path)
144
+ path = "/#{path}" unless path.start_with?('~/', './')
145
+ path
146
+ end
147
+
148
+ def full_path(*)
149
+ abs_path(super)
150
+ end
151
+
144
152
  def mkdir_p(path)
145
153
  sh! 'mkdir', '-p', path
146
154
  end
@@ -186,5 +194,5 @@ BFS.register('scp', 'ssh') do |url|
186
194
  opts[:password] ||= CGI.unescape(url.password) if url.password
187
195
  opts[:port] ||= url.port if url.port
188
196
 
189
- BFS::Bucket::SCP.new url.host, opts
197
+ BFS::Bucket::SCP.new(url.host, **opts)
190
198
  end
@@ -13,15 +13,43 @@ run_spec = \
13
13
  end
14
14
 
15
15
  RSpec.describe BFS::Bucket::SCP, if: run_spec do
16
- subject { described_class.new sandbox[:host], sandbox[:opts].merge(prefix: SecureRandom.uuid) }
17
- after { subject.close }
16
+ context 'absolute' do
17
+ subject { described_class.new sandbox[:host], **sandbox[:opts].merge(prefix: SecureRandom.uuid) }
18
+ after { subject.close }
18
19
 
19
- it_behaves_like 'a bucket',
20
- content_type: false,
21
- metadata: false
20
+ it_behaves_like 'a bucket', content_type: false, metadata: false
21
+ end
22
+
23
+ context 'relative' do
24
+ subject { described_class.new sandbox[:host], **sandbox[:opts].merge(prefix: "~/#{SecureRandom.uuid}") }
25
+ after { subject.close }
26
+
27
+ it_behaves_like 'a bucket', content_type: false, metadata: false
28
+ end
22
29
 
23
30
  it 'should resolve from URL' do
24
31
  bucket = BFS.resolve('scp://root:root@127.0.0.1:7022')
25
32
  expect(bucket).to be_instance_of(described_class)
26
33
  end
34
+
35
+ it 'should handle absolute and relative paths' do
36
+ abs = BFS::Blob.new("scp://root:root@127.0.0.1:7022/#{SecureRandom.uuid}/file.txt")
37
+ abs.create {|w| w.write 'absolute' }
38
+
39
+ rel = BFS::Blob.new("scp://root:root@127.0.0.1:7022/~/#{SecureRandom.uuid}/file.txt")
40
+ rel.create {|w| w.write 'relative' }
41
+
42
+ expect(abs.read).to eq('absolute')
43
+ expect(rel.read).to eq('relative')
44
+
45
+ abs.close
46
+ rel.close
47
+ end
48
+
49
+ it 'should support custom perms' do
50
+ blob = BFS::Blob.new("scp://root:root@127.0.0.1:7022/#{SecureRandom.uuid}/file.txt")
51
+ blob.create(perm: 0o666) {|w| w.write 'foo' }
52
+ expect(blob.info.mode).to eq(0o666)
53
+ blob.close
54
+ end
27
55
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bfs-scp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitrij Denissenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-27 00:00:00.000000000 Z
11
+ date: 2020-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bfs
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.4.4
19
+ version: 0.6.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.4.4
26
+ version: 0.6.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: net-scp
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -60,14 +60,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - ">="
62
62
  - !ruby/object:Gem::Version
63
- version: 2.4.0
63
+ version: 2.5.0
64
64
  required_rubygems_version: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  requirements: []
70
- rubygems_version: 3.0.3
70
+ rubygems_version: 3.0.6
71
71
  signing_key:
72
72
  specification_version: 4
73
73
  summary: SCP/SSH adapter for bfs