xftp 0.1.0.pre.alpha

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4fadf37a688351959fd702257a6e2efb8e9600a8
4
+ data.tar.gz: 0459bf1922cabbcc204bba768700a9148f483a3a
5
+ SHA512:
6
+ metadata.gz: 3a758097ffcd936285221424b9bedf7c5c4906b97e3ad2f90073a7ad20963990053ab1b3065f2e8dd30d6ded38f0c94c96793cfcbb12e806ac963dae5904226f
7
+ data.tar.gz: e48ed2864845c10837de4ae37999b765cee5ab9957eca157888267616bab73e1e9cec2ea77189d03e53b5026d79034c0fcc41824d5103f81ccfc0c95f27ddc80
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.overcommit.yml ADDED
@@ -0,0 +1,42 @@
1
+ # Use this file to configure the Overcommit hooks you wish to use. This will
2
+ # extend the default configuration defined in:
3
+ # https://github.com/brigade/overcommit/blob/master/config/default.yml
4
+ #
5
+ # At the topmost level of this YAML file is a key representing type of hook
6
+ # being run (e.g. pre-commit, commit-msg, etc.). Within each type you can
7
+ # customize each hook, such as whether to only run it on certain files (via
8
+ # `include`), whether to only display output if it fails (via `quiet`), etc.
9
+ #
10
+ # For a complete list of hooks, see:
11
+ # https://github.com/brigade/overcommit/tree/master/lib/overcommit/hook
12
+ #
13
+ # For a complete list of options that you can use to customize hooks, see:
14
+ # https://github.com/brigade/overcommit#configuration
15
+ #
16
+ # Uncomment the following lines to make the configuration take effect.
17
+
18
+ CommitMsg:
19
+ HardTabs:
20
+ enabled: true
21
+
22
+ PreCommit:
23
+ Rubocop:
24
+ enabled: true
25
+ on_warn: fail
26
+ HardTabs:
27
+ enabled: true
28
+ Reek:
29
+ enabled: true
30
+ LocalPathsInGemfile:
31
+ enabled: true
32
+ TrailingWhitespace:
33
+ enabled: true
34
+ BundleCheck:
35
+ enabled: true
36
+
37
+ PostCheckout:
38
+ SubmoduleStatus:
39
+ enabled: true
40
+ GitGuilt:
41
+ enabled: true
42
+
data/.reek ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ PrimaDonnaMethod:
3
+ enabled: false
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,2 @@
1
+ Metrics/LineLength:
2
+ Max: 120
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.5
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.1
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development, :test do
6
+ gem 'pry-byebug'
7
+ end
8
+
9
+ group :development do
10
+ gem 'reek', require: false
11
+ gem 'brakeman', require: false
12
+ gem 'rubocop', require: false
13
+ gem 'overcommit'
14
+ end
15
+
16
+ group :test do
17
+ gem 'mutant'
18
+ gem 'mutant-rspec'
19
+ end
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # xftp
2
+
3
+ Unified interface for ftp/sftp.
4
+ Protocol is selected by url scheme.
5
+
6
+ ## Installation
7
+
8
+ ```ruby
9
+ gem 'xftp'
10
+ ```
11
+
12
+ or
13
+
14
+ ```
15
+ $ gem install xftp
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ```ruby
21
+ XFTP.start('ftps://hostname', login: 'login', password: 'pass') do |x|
22
+ x.chdir 'remote-src-path'
23
+ x.mkdir 'new-remote-dir'
24
+ x.rmdir 'dir-to-remove'
25
+
26
+ x.glob '**/*.{xls,xlsx}' do |io|
27
+ # process entry
28
+ end
29
+
30
+ x.download '**/*.{xls,xlsx}', to: 'local-dst-path' do |file|
31
+ # process file
32
+ x.move file, to: 'remote-archive-path'
33
+ end
34
+ end
35
+ ```
36
+
37
+ ## Development
38
+
39
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
40
+
41
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
42
+
43
+ ## Contributing
44
+
45
+ 1. Fork it ( https://github.com/[my-github-username]/xftp/fork )
46
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
47
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
48
+ 4. Push to the branch (`git push origin my-new-feature`)
49
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "xftp"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/rspec ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'rspec')
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,61 @@
1
+ require 'net/ftp'
2
+ require 'net/ssh'
3
+
4
+ require 'active_support/configurable'
5
+
6
+ module XFTP
7
+ # Provides a way to store and retrive configuration options
8
+ class Configuration
9
+ include ActiveSupport::Configurable
10
+
11
+ class << self
12
+ # HACK: This is required to smooth a future transition to activesupport 4.x
13
+ # Since 3-2's config_accessor doesn't take a block or provide an option to set the default value of a config.
14
+ alias_method :old_config_accessor, :config_accessor
15
+
16
+ def config_accessor(*names)
17
+ old_config_accessor(*names)
18
+ return unless block_given?
19
+
20
+ names.each do |name|
21
+ send("#{name}=", yield)
22
+ end
23
+ end
24
+ end
25
+
26
+ config_accessor :logging do
27
+ default_logger = lambda do
28
+ logger = Logger.new(STDERR)
29
+ logger.level = Logger::ERROR
30
+ end
31
+
32
+ rails_logger = -> { Rails.logger || default_logger.call }
33
+ logger = defined?(Rails) ? rails_logger.call : default_logger.call
34
+
35
+ {
36
+ logger: logger,
37
+ verbose: false,
38
+ colorize: true
39
+ }
40
+ end
41
+
42
+ config_accessor :ftp do
43
+ {
44
+ binary: true,
45
+ passive: true,
46
+ debug_mode: false,
47
+ open_timeout: nil,
48
+ resume: false
49
+ }
50
+ end
51
+
52
+ config_accessor :ssh do
53
+ {
54
+ keepalive: true,
55
+ keepalive_interval: 30,
56
+ forward_agent: true,
57
+ verbose: :error
58
+ }
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,10 @@
1
+ require 'i18n'
2
+
3
+ locale_paths = File.join(File.dirname(__FILE__), '..', 'xftp', 'locale', '*.yml')
4
+
5
+ Dir[locale_paths].each { |path| I18n.load_path << path }
6
+ I18n.backend.load_translations unless defined?(Rails)
7
+
8
+ I18n.config.enforce_available_locales = true
9
+ I18n.default_locale = :en
10
+ I18n.available_locales = [:en, :ru]
data/lib/xftp.rb ADDED
@@ -0,0 +1,67 @@
1
+ require 'active_support/core_ext/object'
2
+ require 'active_support/core_ext/hash'
3
+
4
+ require 'configuration'
5
+ require 'xftp/version'
6
+ require 'xftp/errors'
7
+ require 'xftp/validator/settings'
8
+ require 'xftp/session/ftp'
9
+ require 'xftp/session/sftp'
10
+
11
+ require_relative 'initializers/i18n'
12
+
13
+ # The XFTP entry point (facade)
14
+ module XFTP
15
+ include Errors
16
+
17
+ SCHEME_ADAPTERS = {
18
+ ftp: XFTP::Session::FTP,
19
+ ftps: XFTP::Session::SFTP
20
+ }
21
+
22
+ # Config accessor
23
+ def self.config
24
+ @configuration ||= Configuration.new
25
+ end
26
+
27
+ # For a block { |config| ... }
28
+ # @yield the (see #config)
29
+ def self.configure
30
+ yield config
31
+ end
32
+
33
+ def self.validator
34
+ @validator ||= Validator::Settings.new
35
+ end
36
+
37
+ # Initiates a new session
38
+ #
39
+ # @param [String] :url the remote host url
40
+ # @param [Hash] settings the connection settings
41
+ # @option settings [Hash<Symbol, String>] :credentials the authentication credentials
42
+ #
43
+ # @raise [URI::InvalidURIError] if url given is not a correct URI
44
+ # @raise [XFTP::MissingArgument] if some of the required settings are missing
45
+ # @raise [XFTP::NotSupportedProtocol] if protocol detected by schema is not supported
46
+ #
47
+ # @see Net::SSH
48
+ # @see Net::FTP
49
+ #
50
+ # @see XFTP::Validator::Settings
51
+ def self.start(url, settings = {}, &block)
52
+ uri = URI.parse(url)
53
+ validator.call!(uri, settings)
54
+ klass = adapter_class(uri.scheme)
55
+ session = klass.new(uri, settings.deep_dup)
56
+ session.start(&block)
57
+ end
58
+
59
+ private
60
+
61
+ # Detects a session adapter class
62
+ # @param [String, Symbol] scheme the uri scheme
63
+ # @return [Class] session adapter class
64
+ def self.adapter_class(scheme)
65
+ SCHEME_ADAPTERS[scheme.to_sym] || not_supported_protocol!(scheme)
66
+ end
67
+ end
@@ -0,0 +1,18 @@
1
+ module XFTP
2
+ # Contains helper classes and modules to simplify building a DSL
3
+ module DSL
4
+ # Gives the target class an ability to expose both DSL design patterns.
5
+ # It yields self as a block argument if arity of the given block takes exactly 1 argument, otherwise
6
+ # it simply evaluates the given block of the target class instance (see BasicObject#instance_eval)
7
+ module BlockEvaluator
8
+ def evaluate(&callback)
9
+ return unless block_given?
10
+ if callback.arity == 1
11
+ yield self
12
+ else
13
+ instance_eval(&callback)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ module XFTP
2
+ # Raises when the given argument does not match required format
3
+ class InvalidArgument < ArgumentError; end
4
+ # Raises when required argument is missing or blank
5
+ class MissingArgument < ArgumentError; end
6
+ # Raise when the given protocol is not supported
7
+ class NotSupportedProtocol < ArgumentError; end
8
+
9
+ # Shortcut method to fail
10
+ # with a localized error message
11
+ module Errors
12
+ def missing_setting!(setting)
13
+ fail MissingArgument, I18n.t('errors.missing_setting', key: setting)
14
+ end
15
+
16
+ def not_supported_protocol!(protocol)
17
+ fail NotSupportedProtocol, I18n.t('errors.not_supported_protocol', protocol: protocol)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ ---
2
+ en:
3
+ errors:
4
+ missing_setting: 'missing setting %{key}'
5
+ not_supported_protocol: 'protocol %{protocol} is not supported'
@@ -0,0 +1,5 @@
1
+ ---
2
+ ru:
3
+ errors:
4
+ missed_config_option: 'не указан параметр подключения %{key}'
5
+ not_supported_protocol: 'протокол %{protocol} не поддерживается'
@@ -0,0 +1,23 @@
1
+ module XFTP
2
+ module Operations
3
+ module FTP
4
+ # @api private
5
+ class Glob
6
+ def initialize(ftp)
7
+ @ftp = ftp
8
+ end
9
+
10
+ # Expands pattern and returns the results
11
+ # as matches or as arguments given to the block
12
+ # @param [String] pattern the search pattern
13
+ # @param [Proc] callback
14
+ # :reek:UnusedParameters
15
+ # rubocop:disable Lint/UnusedMethodArgument
16
+ def call(pattern, &callback)
17
+ fail NotImplementedError
18
+ end
19
+ # rubocop:enable Lint/UnusedMethodArgument
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ require 'xftp/dsl/block_evaluator'
2
+
3
+ module XFTP
4
+ module Session
5
+ # @abstract Base class for xftp session adapters
6
+ # @api private
7
+ class Base
8
+ include DSL::BlockEvaluator
9
+
10
+ attr_reader :uri, :credentials, :settings
11
+
12
+ # Creates a session adapter instance
13
+ # @param [URI] uri the remote uri
14
+ # @param [Hash] settings the adapter connection settings
15
+ def initialize(uri, settings = {})
16
+ @uri = uri
17
+ @credentials = settings.delete(:credentials) || {}
18
+ @settings = settings
19
+ end
20
+
21
+ # Opens a new connection, evaluates the given block and closes the connection
22
+ # @param [Proc] callback the callback to operate on a connection session
23
+ def start(&callback)
24
+ open
25
+ evaluate(&callback)
26
+ close
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,54 @@
1
+ require 'active_support/core_ext/hash/deep_merge'
2
+ require 'forwardable'
3
+ require 'net/ftp'
4
+
5
+ require 'xftp/session/base'
6
+
7
+ module XFTP
8
+ module Session
9
+ # FTP session adapter
10
+ # @api private
11
+ class FTP < Base
12
+ extend Forwardable
13
+
14
+ # Delegate methods which have the same method signature
15
+ # directly to Net::FTP session
16
+ def_delegators :@ftp, :chdir, :mkdir, :rmdir, :close
17
+
18
+ # Creates an FTP session adapter instance
19
+ # @param [URI] uri the remote uri
20
+ # @param [Hash] settings the adapter connection settings
21
+ def initialize(uri, settings = {})
22
+ super
23
+
24
+ @ftp = Net::FTP.new
25
+ @port = uri.port || settings.delete(:port) || Net::FTP::FTP_PORT
26
+ @credentials[:login] ||= 'anonymous'
27
+
28
+ options = XFTP.config.ftp.deep_merge(@settings)
29
+ options.each { |key, val| @ftp.public_send("#{key}=", val) }
30
+ end
31
+
32
+ # Renames (moves) a file on the server
33
+ # @param [String] from the path to move from
34
+ # @param [String] to the new path to move to
35
+ def move(from, to:)
36
+ @ftp.rename(from, to)
37
+ end
38
+
39
+ # @see XFTP::Operations::FTP::Glob
40
+ def glob(pattern, &callback)
41
+ Operations::Glob.new(@ftp).call(pattern, &callback)
42
+ end
43
+
44
+ protected
45
+
46
+ # Opens a new FTP connection and
47
+ # authenticates on the remote server
48
+ def open
49
+ @ftp.connect(@uri.host, @port)
50
+ @ftp.login(@credentials[:login], @credentials[:password])
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,97 @@
1
+ require 'net/ssh'
2
+ require 'net/sftp'
3
+
4
+ require 'xftp/session/base'
5
+
6
+ module XFTP
7
+ module Session
8
+ # SFTP session adapter
9
+ # @api private
10
+ class SFTP < Base
11
+ # Default flags for rename operation
12
+ RENAME_OPERATION_FLAGS = 0x0004
13
+ # Default flags for glob operation
14
+ GLOB_OPERATION_FLAGS = File::FNM_EXTGLOB
15
+
16
+ # Creates an SFTP session adapter instance
17
+ # @param [URI] uri the remote uri
18
+ # @param [Hash] settings the adapter connection settings
19
+ def initialize(uri, settings = {})
20
+ super
21
+ @path = Pathname '.'
22
+ @settings.merge!(password: @credentials[:password])
23
+ @options = XFTP.config.sftp.deep_merge(@settings)
24
+ end
25
+
26
+ # Changes the current (remote) working directory
27
+ # @param [String] path the relative (remote) path
28
+ def chdir(path)
29
+ @path /= path
30
+ end
31
+
32
+ # Creates a remote directory
33
+ # @param [String] dirname the name of new directory
34
+ # relative to the current (remote) working directory
35
+ # @param [Hash] attrs the attributes of new directory
36
+ # supported by the the version of SFTP protocol in use
37
+ def mkdir(dirname, attrs = {})
38
+ @sftp.mkdir! pathname(dirname), attrs
39
+ end
40
+
41
+ # Removes the remote directory
42
+ # @param [String] dirname the name of directory to be removed
43
+ def rmdir(dirname)
44
+ @sftp.rmdir! pathname(dirname)
45
+ end
46
+
47
+ # Renames (moves) a file on the server
48
+ # @param [String] from the path to move from
49
+ # @param [String] to the path to move to
50
+ def move(from, to:, flags: RENAME_OPERATION_FLAGS)
51
+ @sftp.rename(from, to, flags)
52
+ end
53
+
54
+ # For more info (see Dir#glob), it's almost of the same nature
55
+ # @param [String] pattern the search pattern relative
56
+ # the the current working directory
57
+ # @param [Integer] (see File.fnmatch) for the meaning of the flags parameter.
58
+ # Default value is `File::FNM_EXTGLOB`
59
+ def glob(pattern, flags: GLOB_OPERATION_FLAGS)
60
+ @sftp.dir.glob(@path.to_s, pattern, flags)
61
+ end
62
+
63
+ protected
64
+
65
+ # Opens a new SFTP connection
66
+ def open
67
+ connect
68
+ rescue Object => anything
69
+ begin
70
+ @ssh.shutdown!
71
+ rescue ::Exception # rubocop:disable Lint/HandleExceptions, Lint/RescueException
72
+ # swallow exceptions that occur while trying to shutdown
73
+ end
74
+
75
+ raise anything
76
+ end
77
+
78
+ # Closes SFTP (SSH) connection
79
+ def close
80
+ @ssh.close
81
+ end
82
+
83
+ private
84
+
85
+ def connect
86
+ @ssh = Net::SSH.start(@uri.host, @credentials[:login], @options)
87
+ @sftp = Net::SFTP::Session.new @ssh
88
+ @sftp.connect!
89
+ end
90
+
91
+ # @return [String] a path name relative to the current working directory
92
+ def pathname(relative)
93
+ (@path / relative).to_s
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,25 @@
1
+ module XFTP
2
+ module Validator
3
+ # Connection settings validator
4
+ # @api private
5
+ class Settings
6
+ include Errors
7
+
8
+ # Validates the given connection settings
9
+ # @param [URI] uri the remote uri
10
+ # @param [Hash] settings the session connection settings
11
+ # @raise [XFTP::MissingArgument] if some of the required settings are missing
12
+ def call!(uri, settings)
13
+ validate_credentials!(settings[:credentials]) if uri.scheme == 'ftps'
14
+ end
15
+
16
+ private
17
+
18
+ def validate_credentials!(credentials)
19
+ missing_setting!(:credentials) unless credentials.present?
20
+ missing_setting!(:login) unless credentials[:login].present?
21
+ missing_setting!(:password) unless credentials[:password].present?
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ module XFTP
2
+ # Gem version builder module
3
+ module VERSION
4
+ MAJOR = 0
5
+ MINOR = 1
6
+ PATCH = 0
7
+ SUFFIX = 'alpha'
8
+
9
+ NUMBER = [MAJOR, MINOR, PATCH].compact.join('.')
10
+ STRING = "#{NUMBER}-#{SUFFIX}"
11
+ end
12
+ end
data/xftp.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'xftp/version'
5
+
6
+ TEST_FILES = %r{^(test|spec|features)/}
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'xftp'
10
+ spec.version = XFTP::VERSION::STRING
11
+ spec.authors = ['Vasiliy Yorkin']
12
+ spec.email = ['vasiliy.yorkin@gmail.com']
13
+
14
+ spec.summary = 'Unified interface for ftp/sftp'
15
+ spec.description = spec.summary
16
+ spec.homepage = 'https://github.com/vyorkin/xftp'
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match TEST_FILES }
19
+ spec.bindir = 'bin'
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(TEST_FILES)
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.8'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'yard', '~> 0.8.7'
27
+ spec.add_development_dependency 'yard-rspec', '~> 0.1'
28
+ spec.add_development_dependency 'rspec', '~> 3.2.0'
29
+ spec.add_development_dependency 'simplecov', '~> 0.9.2'
30
+ spec.add_development_dependency 'fake_ftp', '~> 0.1.1'
31
+
32
+ spec.add_runtime_dependency 'i18n', '~> 0.6.0'
33
+ spec.add_runtime_dependency 'net-sftp', '~> 2.1.2'
34
+ spec.add_runtime_dependency 'activesupport', '~> 3.2.21'
35
+ end
metadata ADDED
@@ -0,0 +1,214 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xftp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.pre.alpha
5
+ platform: ruby
6
+ authors:
7
+ - Vasiliy Yorkin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.8'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: yard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.8.7
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.8.7
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 3.2.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 3.2.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.9.2
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.9.2
97
+ - !ruby/object:Gem::Dependency
98
+ name: fake_ftp
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.1.1
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.1.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: i18n
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.6.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.6.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: net-sftp
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 2.1.2
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 2.1.2
139
+ - !ruby/object:Gem::Dependency
140
+ name: activesupport
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 3.2.21
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 3.2.21
153
+ description: Unified interface for ftp/sftp
154
+ email:
155
+ - vasiliy.yorkin@gmail.com
156
+ executables:
157
+ - console
158
+ - rspec
159
+ - setup
160
+ extensions: []
161
+ extra_rdoc_files: []
162
+ files:
163
+ - ".gitignore"
164
+ - ".overcommit.yml"
165
+ - ".reek"
166
+ - ".rspec"
167
+ - ".rubocop.yml"
168
+ - ".ruby-version"
169
+ - ".travis.yml"
170
+ - Gemfile
171
+ - README.md
172
+ - Rakefile
173
+ - bin/console
174
+ - bin/rspec
175
+ - bin/setup
176
+ - lib/configuration.rb
177
+ - lib/initializers/i18n.rb
178
+ - lib/xftp.rb
179
+ - lib/xftp/dsl/block_evaluator.rb
180
+ - lib/xftp/errors.rb
181
+ - lib/xftp/locale/en.yml
182
+ - lib/xftp/locale/ru.yml
183
+ - lib/xftp/operations/ftp/glob.rb
184
+ - lib/xftp/session/base.rb
185
+ - lib/xftp/session/ftp.rb
186
+ - lib/xftp/session/sftp.rb
187
+ - lib/xftp/validator/settings.rb
188
+ - lib/xftp/version.rb
189
+ - xftp.gemspec
190
+ homepage: https://github.com/vyorkin/xftp
191
+ licenses: []
192
+ metadata: {}
193
+ post_install_message:
194
+ rdoc_options: []
195
+ require_paths:
196
+ - lib
197
+ required_ruby_version: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ required_rubygems_version: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - ">"
205
+ - !ruby/object:Gem::Version
206
+ version: 1.3.1
207
+ requirements: []
208
+ rubyforge_project:
209
+ rubygems_version: 2.2.2
210
+ signing_key:
211
+ specification_version: 4
212
+ summary: Unified interface for ftp/sftp
213
+ test_files: []
214
+ has_rdoc: