xftp 0.1.0.pre.alpha

Sign up to get free protection for your applications and to get access to all the features.
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: