ftpsync 0.0.4 → 0.0.5
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 +5 -5
- data/.rubocop.yml +16 -0
- data/Gemfile +10 -0
- data/README.md +65 -5
- data/Rakefile +18 -6
- data/bin/console +4 -3
- data/ftpsync.gemspec +25 -19
- data/lib/ftpsync/version.rb +3 -1
- data/lib/ftpsync.rb +77 -51
- metadata +18 -47
- data/.travis.yml +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 0ffec10f36bb727a2bf78b5f132b52c9e9ecf37b0f6e93e6af3fc0666135c4a1
|
|
4
|
+
data.tar.gz: 135414d933aa32bd53aab2326f07adbf91003a02687bb33e3e3b554c11448232
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1e4d8864990232bd31db836e22f8afa6deacecac19a548d8575ea5d4e326cbd39c5a215df63889643f0ffc616daed52c968334a5de0ed9215e0d26df4a99de47
|
|
7
|
+
data.tar.gz: b8f91ae8839dab6182e94441096589f12ecc9341a1dd1e62ad9d5e23971bb9acead7d5b2da364e5170e6dc6feec3f08515c030ac35096293aab0e00f193e9d29
|
data/.rubocop.yml
ADDED
data/Gemfile
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
source 'https://rubygems.org'
|
|
2
4
|
|
|
3
5
|
# Specify your gem's dependencies in ftpsync.gemspec
|
|
4
6
|
gemspec
|
|
7
|
+
|
|
8
|
+
group :development, :test do
|
|
9
|
+
gem 'minitest', '~> 5.0'
|
|
10
|
+
gem 'rake', '~> 13.0'
|
|
11
|
+
gem 'rubocop', '~> 1.0'
|
|
12
|
+
gem 'rubocop-minitest', '~> 0.40'
|
|
13
|
+
gem 'rubocop-rake', '~> 0.7'
|
|
14
|
+
end
|
data/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# FtpSync
|
|
2
2
|
|
|
3
|
+
[](https://github.com/Quintasan/ftpsync/actions/workflows/ci.yml)
|
|
4
|
+
|
|
3
5
|
A simple library for synchronizing from/to FTP servers.
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
@@ -25,22 +27,80 @@ example = FtpSync::Simple.new "ftp.example.com", "username", "password"
|
|
|
25
27
|
example.pull_dir('remotepath', 'localpath')
|
|
26
28
|
```
|
|
27
29
|
|
|
30
|
+
### Options
|
|
31
|
+
|
|
32
|
+
`FtpSync::Simple#new` accepts an options hash:
|
|
33
|
+
|
|
34
|
+
| Option | Default | Description |
|
|
35
|
+
|------------|---------|------------------------------------|
|
|
36
|
+
| `:port` | `21` | FTP port to connect to |
|
|
37
|
+
| `:passive` | `false` | Use passive mode |
|
|
38
|
+
| `:verbose` | `false` | Log progress to stderr |
|
|
39
|
+
|
|
40
|
+
`FtpSync::Simple#pull_dir` accepts an options hash:
|
|
41
|
+
|
|
42
|
+
| Option | Description |
|
|
43
|
+
|----------------|------------------------------------------------------------|
|
|
44
|
+
| `:since` | Skip files that already exist locally and are up to date |
|
|
45
|
+
| `:skip_errors` | Rescue `Net::FTPPermError` and continue instead of raising |
|
|
46
|
+
|
|
47
|
+
> **Note:** `:since` compares size and the mtime reported by the server's
|
|
48
|
+
> `LIST` output, which usually has minute precision. A remote file of the
|
|
49
|
+
> same size that was modified within the same minute as the local copy may
|
|
50
|
+
> therefore be skipped.
|
|
51
|
+
|
|
52
|
+
Passing a block to `pull_dir` invokes it with the local path of each
|
|
53
|
+
downloaded file:
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
example.pull_dir('remotepath', 'localpath', since: true) do |file|
|
|
57
|
+
process(file)
|
|
58
|
+
end
|
|
59
|
+
```
|
|
60
|
+
|
|
28
61
|
## Development
|
|
29
62
|
|
|
30
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake
|
|
63
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake` to run the tests and RuboCop (or `rake test` / `rake rubocop` individually). You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
31
64
|
|
|
32
|
-
|
|
65
|
+
### Integration tests (requires Docker)
|
|
33
66
|
|
|
34
|
-
|
|
67
|
+
The integration suite runs against a real FTP server
|
|
68
|
+
([garethflowers/ftp-server](https://garethflowers.dev/docker-ftp-server/),
|
|
69
|
+
vsftpd) in a Docker container:
|
|
70
|
+
|
|
71
|
+
$ rake test:integration
|
|
72
|
+
|
|
73
|
+
The container listens on `127.0.0.1:2121` (control) and
|
|
74
|
+
`127.0.0.1:40000-40009` (passive data). The tests are skipped automatically
|
|
75
|
+
if Docker is not available, and the container is created and removed for
|
|
76
|
+
each run. Override the credentials and control port with the
|
|
77
|
+
`FTPSYNC_TEST_USER`, `FTPSYNC_TEST_PASS` and `FTPSYNC_TEST_FTP_PORT`
|
|
78
|
+
environment variables.
|
|
79
|
+
|
|
80
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
81
|
+
|
|
82
|
+
### Releasing
|
|
35
83
|
|
|
36
|
-
|
|
84
|
+
Releases are published to [rubygems.org](https://rubygems.org) with
|
|
85
|
+
[trusted publishing](https://guides.rubygems.org/trusted-publishing/),
|
|
86
|
+
so no API key is needed. The `.github/workflows/publish.yml` workflow runs
|
|
87
|
+
the tests and RuboCop, builds the gem, and pushes it whenever you push a
|
|
88
|
+
`v*` tag.
|
|
37
89
|
|
|
90
|
+
1. Bump the version in `lib/ftpsync/version.rb` and commit it.
|
|
91
|
+
2. Create and push a tag:
|
|
92
|
+
|
|
93
|
+
$ git tag v0.1.0
|
|
94
|
+
$ git push --tags
|
|
95
|
+
|
|
96
|
+
## Contributing
|
|
97
|
+
|
|
98
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/quintasan/ftpsync. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](https://www.contributor-covenant.org) code of conduct.
|
|
38
99
|
|
|
39
100
|
## License
|
|
40
101
|
|
|
41
102
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
42
103
|
|
|
43
|
-
|
|
44
104
|
## Credits
|
|
45
105
|
|
|
46
106
|
This gem is a basically stripped down version of [orlando/ftp_sync](https://github.com/orlando/ftp_sync) which I couldn't get to work.
|
data/Rakefile
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rake/testtask'
|
|
5
|
+
require 'rubocop/rake_task'
|
|
3
6
|
|
|
4
7
|
Rake::TestTask.new(:test) do |t|
|
|
5
|
-
t.libs <<
|
|
6
|
-
t.libs <<
|
|
7
|
-
t.test_files = FileList['test
|
|
8
|
+
t.libs << 'test'
|
|
9
|
+
t.libs << 'lib'
|
|
10
|
+
t.test_files = FileList['test/*_test.rb']
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
desc 'Run integration tests against a Dockerized FTP server'
|
|
14
|
+
Rake::TestTask.new(:'test:integration') do |t|
|
|
15
|
+
t.libs << 'test'
|
|
16
|
+
t.libs << 'lib'
|
|
17
|
+
t.test_files = FileList['test/integration/**/*_test.rb']
|
|
8
18
|
end
|
|
9
19
|
|
|
10
|
-
|
|
20
|
+
RuboCop::RakeTask.new
|
|
21
|
+
|
|
22
|
+
task default: %i[test rubocop]
|
data/bin/console
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'ftpsync'
|
|
5
6
|
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
|
@@ -10,5 +11,5 @@ require "ftpsync"
|
|
|
10
11
|
# require "pry"
|
|
11
12
|
# Pry.start
|
|
12
13
|
|
|
13
|
-
require
|
|
14
|
+
require 'irb'
|
|
14
15
|
IRB.start
|
data/ftpsync.gemspec
CHANGED
|
@@ -1,26 +1,32 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
require 'ftpsync/version'
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/ftpsync/version'
|
|
5
4
|
|
|
6
5
|
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name
|
|
8
|
-
spec.version
|
|
9
|
-
spec.authors
|
|
10
|
-
spec.email
|
|
6
|
+
spec.name = 'ftpsync'
|
|
7
|
+
spec.version = FtpSync::VERSION
|
|
8
|
+
spec.authors = ['Michał Zając']
|
|
9
|
+
spec.email = ['rubygems.org@quintasan.pl']
|
|
11
10
|
|
|
12
|
-
spec.summary
|
|
13
|
-
spec.
|
|
14
|
-
|
|
11
|
+
spec.summary = 'A simple library for synchronizing from/to FTP servers.'
|
|
12
|
+
spec.description = 'Recursively pull directory trees from FTP servers, with support ' \
|
|
13
|
+
'for incremental syncs and per-file callbacks.'
|
|
14
|
+
spec.homepage = 'https://github.com/Quintasan/ftpsync'
|
|
15
|
+
spec.license = 'MIT'
|
|
16
|
+
spec.required_ruby_version = '>= 2.6.0'
|
|
15
17
|
|
|
16
|
-
spec.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
spec.metadata = {
|
|
19
|
+
'source_code_uri' => spec.homepage,
|
|
20
|
+
'rubygems_mfa_required' => 'true'
|
|
21
|
+
}
|
|
20
22
|
|
|
21
|
-
spec.
|
|
23
|
+
spec.files = Dir.chdir(__dir__) do
|
|
24
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
25
|
+
f.match?(%r{^(test|spec|features)/|^\.github/}) || !File.file?(f)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
spec.require_paths = ['lib']
|
|
22
29
|
|
|
23
|
-
spec.
|
|
24
|
-
spec.
|
|
25
|
-
spec.add_development_dependency "minitest"
|
|
30
|
+
spec.add_dependency 'net-ftp'
|
|
31
|
+
spec.add_dependency 'net-ftp-list', '>= 3.2.8'
|
|
26
32
|
end
|
data/lib/ftpsync/version.rb
CHANGED
data/lib/ftpsync.rb
CHANGED
|
@@ -1,96 +1,122 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require "net/ftp/list"
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
4
3
|
require 'fileutils'
|
|
4
|
+
require 'ftpsync/version'
|
|
5
|
+
require 'net/ftp'
|
|
6
|
+
require 'net/ftp/list'
|
|
5
7
|
|
|
6
8
|
module FtpSync
|
|
9
|
+
# Synchronizes directories against an FTP server.
|
|
7
10
|
class Simple
|
|
8
11
|
attr_accessor :server, :port, :username, :password, :passive
|
|
9
12
|
|
|
10
13
|
def initialize(server, username, password, options = {})
|
|
11
14
|
@server = server
|
|
12
|
-
@port = options
|
|
15
|
+
@port = options.fetch(:port, 21)
|
|
13
16
|
@username = username
|
|
14
17
|
@password = password
|
|
15
|
-
@passive = options
|
|
16
|
-
@verbose = options
|
|
18
|
+
@passive = options.fetch(:passive, false)
|
|
19
|
+
@verbose = options.fetch(:verbose, false)
|
|
17
20
|
|
|
18
21
|
@connection = nil
|
|
19
22
|
@level = 0
|
|
20
23
|
end
|
|
21
24
|
|
|
25
|
+
# Recursively pulls +remotepath+ into +localpath+.
|
|
26
|
+
#
|
|
27
|
+
# Options:
|
|
28
|
+
# :since skip files that already exist locally and are up to date
|
|
29
|
+
# :skip_errors rescue Net::FTPPermError and keep going
|
|
30
|
+
#
|
|
31
|
+
# If a block is given, it is invoked with the local path of each
|
|
32
|
+
# downloaded file.
|
|
22
33
|
def pull_dir(remotepath, localpath, options = {}, &block)
|
|
23
|
-
|
|
34
|
+
ensure_local_directory(localpath)
|
|
24
35
|
connect! unless @connection
|
|
25
36
|
@level += 1
|
|
26
37
|
|
|
27
|
-
|
|
28
|
-
directories = []
|
|
29
|
-
files = []
|
|
30
|
-
|
|
31
|
-
@connection.list(remotepath) do |e|
|
|
32
|
-
entry = Net::FTP::List.parse(e)
|
|
33
|
-
|
|
34
|
-
paths = [ "#{remotepath}/#{entry.basename}".gsub(/\/+/, '/'), File.join(localpath, entry.basename)]
|
|
38
|
+
directories, files = scan_directory(remotepath, localpath, options)
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
next
|
|
39
|
-
else
|
|
40
|
-
directories << paths
|
|
41
|
-
end
|
|
42
|
-
elsif entry.file?
|
|
43
|
-
if options[:since]
|
|
44
|
-
files << paths unless File.exist?(paths[1]) and entry.mtime < File.mtime(paths[1]) and entry.filesize == File.size(paths[1])
|
|
45
|
-
else
|
|
46
|
-
files << paths
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
todelete.delete paths[1]
|
|
40
|
+
directories.each do |remote_dir, local_dir|
|
|
41
|
+
pull_dir(remote_dir, local_dir, options, &block)
|
|
50
42
|
end
|
|
51
43
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
pull_dir(remotedir, localdir, options, &block)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
files.each do |paths|
|
|
58
|
-
remotefile, localfile = paths
|
|
59
|
-
begin
|
|
60
|
-
log "#{remotefile} => #{localfile}"
|
|
61
|
-
@connection.get(remotefile, localfile)
|
|
62
|
-
if block_given?
|
|
63
|
-
log "Executing block"
|
|
64
|
-
yield(localfile)
|
|
65
|
-
end
|
|
66
|
-
rescue Net::FTPPermError
|
|
67
|
-
log "Error when reading #{remotefile}"
|
|
68
|
-
raise Net::FTPPermError unless options[:skip_errors]
|
|
69
|
-
end
|
|
44
|
+
files.each do |remote_file, local_file|
|
|
45
|
+
download(remote_file, local_file, options, &block)
|
|
70
46
|
end
|
|
71
47
|
|
|
72
48
|
@level -= 1
|
|
73
|
-
close! if @level
|
|
49
|
+
close! if @level.zero?
|
|
74
50
|
end
|
|
75
51
|
|
|
76
52
|
def connect!
|
|
77
53
|
@connection = Net::FTP.new
|
|
78
|
-
log "Connecting to #{@server}:#{@port} in #{@passive ?
|
|
54
|
+
log "Connecting to #{@server}:#{@port} in #{@passive ? 'passive' : 'active'} mode"
|
|
79
55
|
@connection.connect(@server, @port)
|
|
80
56
|
@connection.passive = @passive
|
|
81
|
-
log "Logging in as #{@username}
|
|
57
|
+
log "Logging in as #{@username}"
|
|
82
58
|
@connection.login(@username, @password)
|
|
83
59
|
log "Successfully opened connection to #{@server}:#{@port}"
|
|
84
60
|
end
|
|
85
61
|
|
|
86
62
|
def close!
|
|
87
63
|
@connection.close
|
|
64
|
+
@connection = nil
|
|
88
65
|
log "Closed connection to #{@server}:#{@port}"
|
|
89
66
|
end
|
|
90
67
|
|
|
91
68
|
def log(message)
|
|
92
|
-
|
|
69
|
+
warn message if @verbose
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def ensure_local_directory(localpath)
|
|
75
|
+
return if File.directory?(localpath)
|
|
76
|
+
|
|
77
|
+
FileUtils.mkpath(localpath)
|
|
78
|
+
log "Creating #{localpath} directory"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def scan_directory(remotepath, localpath, options)
|
|
82
|
+
directories = []
|
|
83
|
+
files = []
|
|
84
|
+
|
|
85
|
+
@connection.list(remotepath) do |line|
|
|
86
|
+
entry = Net::FTP::List.parse(line)
|
|
87
|
+
next if %w[. ..].include?(entry.name)
|
|
88
|
+
|
|
89
|
+
remote_child = join_remote(remotepath, entry.basename)
|
|
90
|
+
local_child = File.join(localpath, entry.basename)
|
|
91
|
+
|
|
92
|
+
if entry.dir?
|
|
93
|
+
directories << [remote_child, local_child]
|
|
94
|
+
elsif entry.file?
|
|
95
|
+
files << [remote_child, local_child] unless skip_file?(local_child, entry, options)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
[directories, files]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def skip_file?(local_path, entry, options)
|
|
103
|
+
return false unless options[:since]
|
|
104
|
+
return false unless File.file?(local_path)
|
|
105
|
+
|
|
106
|
+
entry.mtime < File.mtime(local_path) && entry.filesize == File.size(local_path)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def download(remote_file, local_file, options)
|
|
110
|
+
log "#{remote_file} => #{local_file}"
|
|
111
|
+
@connection.get(remote_file, local_file)
|
|
112
|
+
yield(local_file) if block_given?
|
|
113
|
+
rescue Net::FTPPermError => e
|
|
114
|
+
log "Error when reading #{remote_file}"
|
|
115
|
+
raise e unless options[:skip_errors]
|
|
93
116
|
end
|
|
94
117
|
|
|
118
|
+
def join_remote(remote_dir, basename)
|
|
119
|
+
"#{remote_dir}/#{basename}".gsub(%r{/+}, '/')
|
|
120
|
+
end
|
|
95
121
|
end
|
|
96
122
|
end
|
metadata
CHANGED
|
@@ -1,72 +1,44 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ftpsync
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michał Zając
|
|
8
|
-
|
|
9
|
-
bindir: exe
|
|
8
|
+
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: net-ftp
|
|
13
|
+
name: net-ftp
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
18
|
+
version: '0'
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: bundler
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - "~>"
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '1.10'
|
|
34
|
-
type: :development
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - "~>"
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '1.10'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: rake
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - "~>"
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '10.0'
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - "~>"
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '10.0'
|
|
25
|
+
version: '0'
|
|
55
26
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
27
|
+
name: net-ftp-list
|
|
57
28
|
requirement: !ruby/object:Gem::Requirement
|
|
58
29
|
requirements:
|
|
59
30
|
- - ">="
|
|
60
31
|
- !ruby/object:Gem::Version
|
|
61
|
-
version:
|
|
62
|
-
type: :
|
|
32
|
+
version: 3.2.8
|
|
33
|
+
type: :runtime
|
|
63
34
|
prerelease: false
|
|
64
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
36
|
requirements:
|
|
66
37
|
- - ">="
|
|
67
38
|
- !ruby/object:Gem::Version
|
|
68
|
-
version:
|
|
69
|
-
description:
|
|
39
|
+
version: 3.2.8
|
|
40
|
+
description: Recursively pull directory trees from FTP servers, with support for incremental
|
|
41
|
+
syncs and per-file callbacks.
|
|
70
42
|
email:
|
|
71
43
|
- rubygems.org@quintasan.pl
|
|
72
44
|
executables: []
|
|
@@ -74,7 +46,7 @@ extensions: []
|
|
|
74
46
|
extra_rdoc_files: []
|
|
75
47
|
files:
|
|
76
48
|
- ".gitignore"
|
|
77
|
-
- ".
|
|
49
|
+
- ".rubocop.yml"
|
|
78
50
|
- CODE_OF_CONDUCT.md
|
|
79
51
|
- Gemfile
|
|
80
52
|
- LICENSE.txt
|
|
@@ -88,8 +60,9 @@ files:
|
|
|
88
60
|
homepage: https://github.com/Quintasan/ftpsync
|
|
89
61
|
licenses:
|
|
90
62
|
- MIT
|
|
91
|
-
metadata:
|
|
92
|
-
|
|
63
|
+
metadata:
|
|
64
|
+
source_code_uri: https://github.com/Quintasan/ftpsync
|
|
65
|
+
rubygems_mfa_required: 'true'
|
|
93
66
|
rdoc_options: []
|
|
94
67
|
require_paths:
|
|
95
68
|
- lib
|
|
@@ -97,16 +70,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
97
70
|
requirements:
|
|
98
71
|
- - ">="
|
|
99
72
|
- !ruby/object:Gem::Version
|
|
100
|
-
version:
|
|
73
|
+
version: 2.6.0
|
|
101
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
75
|
requirements:
|
|
103
76
|
- - ">="
|
|
104
77
|
- !ruby/object:Gem::Version
|
|
105
78
|
version: '0'
|
|
106
79
|
requirements: []
|
|
107
|
-
|
|
108
|
-
rubygems_version: 2.4.6
|
|
109
|
-
signing_key:
|
|
80
|
+
rubygems_version: 4.0.16
|
|
110
81
|
specification_version: 4
|
|
111
82
|
summary: A simple library for synchronizing from/to FTP servers.
|
|
112
83
|
test_files: []
|
data/.travis.yml
DELETED