ftpmock 0.0.0 → 0.1.0

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: 6a2714d624206cbe24807a0bcc79669622477c00e6c0940c0935b339acaced40
4
- data.tar.gz: 10063104b716fa5a937926b00d351897310d270d9fbe442854ff9b9e0b9af29c
3
+ metadata.gz: c9fcde1b94eb86b0f144b748def95e77104d92bd45a024527a3a33dd9445e5ca
4
+ data.tar.gz: ac31e623824872dd372e65233d9d4a1de3277a248beda3b18cba8442b5054bcd
5
5
  SHA512:
6
- metadata.gz: 7ef4fe9824f4ed0f195d7d511321a6e247e37ec64a85c76082125cacb63c3815ef64393cec661714a1c703b6cd8d1163d6c614c55bedeed1f1e05f3193ef7d37
7
- data.tar.gz: 8476bcb8358b326632f6fab4c634773f13b18458124625193af5dc87af1995fc242c92ef158641c264c6dbed3a6064b161b111d50993fc9417824ad83741e2ae
6
+ metadata.gz: e9fe1e4d12970f57eb15d7ed68d76fc278460360de769526f58f7ed2a093a0fe294a4f59cc69c7dff4596cf664a2a80537ae490e89b62fe4f8165e6e6fcc948b
7
+ data.tar.gz: 48d26252d595a84ab33252c223508a059397145d57a61422b47d1da45a844a191b3610bdc2feaecf16b9f2669ff5726ba69343660ae8256596d91bbcd7aacc68
data/.gitignore CHANGED
@@ -9,3 +9,6 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+
13
+ # OS
14
+ .DS_Store
data/.rubocop.yml CHANGED
@@ -9,7 +9,7 @@ AllCops:
9
9
  EnabledByDefault: false
10
10
  UseCache: true
11
11
  CacheRootDirectory: ~
12
- TargetRubyVersion: 2.6
12
+ TargetRubyVersion: 2.7
13
13
  Exclude:
14
14
  - 'a/*'
15
15
  - 'bin/*'
@@ -43,11 +43,69 @@ Naming:
43
43
  Style:
44
44
  Enabled: true
45
45
 
46
+ # Undefaulted
47
+
48
+ Style/HashEachMethods:
49
+ Enabled: true
50
+ Style/HashTransformKeys:
51
+ Enabled: true
52
+ Style/HashTransformValues:
53
+ Enabled: true
54
+
46
55
  # Custom
47
56
 
48
- Metrics/LineLength:
57
+ Layout/LineLength:
49
58
  Max: 80
59
+ Exclude:
60
+ - 'spec/ftpmock/proxies_net_ftp/integration_spec.rb'
50
61
 
51
62
  # If you think this should be true, reach out!
52
63
  Style/FrozenStringLiteralComment:
53
64
  Enabled: false
65
+
66
+ Style/Documentation:
67
+ Enabled: false
68
+
69
+ Style/GuardClause:
70
+ Enabled: false
71
+
72
+ Style/MethodMissingSuper:
73
+ Exclude:
74
+ - 'lib/ftpmock/proxies/method_missing_mixin.rb'
75
+ Style/MissingRespondToMissing:
76
+ Exclude:
77
+ - 'lib/ftpmock/proxies/method_missing_mixin.rb'
78
+
79
+ Metrics/BlockLength:
80
+ Exclude:
81
+ - 'spec/**/*.rb'
82
+
83
+ Naming/ConstantName:
84
+ Exclude:
85
+ - 'lib/ftpmock/proxies/*_proxy.rb'
86
+
87
+ Naming/MethodParameterName:
88
+ Exclude:
89
+ - 'spec/ftpmock/helpers/*.rb'
90
+
91
+ # http://c2.com/cgi/wiki?AbcMetric, https://en.wikipedia.org/wiki/ABC_Software_Metric
92
+ Metrics/AbcSize:
93
+ # Max: 15 (default)
94
+ Max: 20
95
+ Exclude:
96
+ - 'spec/ftpmock/helpers/*.rb'
97
+
98
+ # https://rubystyle.guide#short-methods
99
+ Metrics/MethodLength:
100
+ # Max: 10 (default)
101
+ Max: 15
102
+ Exclude:
103
+ - 'spec/ftpmock/helpers/*.rb'
104
+
105
+ Metrics/ClassLength:
106
+ # Max: 100 (default)
107
+ Max: 200
108
+
109
+ Metrics/CyclomaticComplexity:
110
+ Exclude:
111
+ - 'lib/ftpmock/proxies/*_proxy.rb'
data/.travis.yml CHANGED
@@ -1,7 +1,24 @@
1
1
  ---
2
2
  sudo: false
3
3
  language: ruby
4
- cache: bundler
4
+
5
5
  rvm:
6
- - 2.6.3
6
+ - 2.3
7
+ - 2.4
8
+ - 2.5
9
+ - 2.6
10
+ - 2.7
11
+ - ruby-head
12
+
7
13
  before_install: gem install bundler -v 2.0.2
14
+
15
+ cache:
16
+ - bundler
17
+ - apt
18
+
19
+ addons:
20
+ code_climate:
21
+ repo_token: e91dbff92783b09f531028ccb33b372a03b8ee2ec0b15bf8e250359c80e06838
22
+
23
+ after_success:
24
+ - bundle exec codeclimate-test-reporter
data/Gemfile CHANGED
@@ -3,4 +3,4 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in ftpmock.gemspec
4
4
  gemspec
5
5
 
6
- gem 'rubocop', '0.75.0'
6
+ gem 'rubocop', '0.80.0' # February 18, 2020
data/Gemfile.lock CHANGED
@@ -2,50 +2,69 @@ PATH
2
2
  remote: .
3
3
  specs:
4
4
  ftpmock (0.1.0)
5
+ diffy (~> 3.0)
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
8
9
  specs:
9
10
  ast (2.4.0)
11
+ codeclimate-test-reporter (1.0.9)
12
+ simplecov (<= 0.13)
10
13
  diff-lcs (1.3)
11
- jaro_winkler (1.5.3)
12
- parallel (1.18.0)
13
- parser (2.6.5.0)
14
+ diffy (3.3.0)
15
+ docile (1.1.5)
16
+ jaro_winkler (1.5.4)
17
+ json (2.3.0)
18
+ net-sftp (2.1.2)
19
+ net-ssh (>= 2.6.5)
20
+ net-ssh (5.2.0)
21
+ parallel (1.19.1)
22
+ parser (2.7.0.2)
14
23
  ast (~> 2.4.0)
15
24
  rainbow (3.0.0)
16
25
  rake (10.5.0)
26
+ rexml (3.2.4)
17
27
  rspec (3.9.0)
18
28
  rspec-core (~> 3.9.0)
19
29
  rspec-expectations (~> 3.9.0)
20
30
  rspec-mocks (~> 3.9.0)
21
- rspec-core (3.9.0)
22
- rspec-support (~> 3.9.0)
31
+ rspec-core (3.9.1)
32
+ rspec-support (~> 3.9.1)
23
33
  rspec-expectations (3.9.0)
24
34
  diff-lcs (>= 1.2.0, < 2.0)
25
35
  rspec-support (~> 3.9.0)
26
- rspec-mocks (3.9.0)
36
+ rspec-mocks (3.9.1)
27
37
  diff-lcs (>= 1.2.0, < 2.0)
28
38
  rspec-support (~> 3.9.0)
29
- rspec-support (3.9.0)
30
- rubocop (0.75.0)
39
+ rspec-support (3.9.2)
40
+ rubocop (0.80.0)
31
41
  jaro_winkler (~> 1.5.1)
32
42
  parallel (~> 1.10)
33
- parser (>= 2.6)
43
+ parser (>= 2.7.0.1)
34
44
  rainbow (>= 2.2.2, < 4.0)
45
+ rexml
35
46
  ruby-progressbar (~> 1.7)
36
47
  unicode-display_width (>= 1.4.0, < 1.7)
37
48
  ruby-progressbar (1.10.1)
38
- unicode-display_width (1.6.0)
49
+ simplecov (0.13.0)
50
+ docile (~> 1.1.0)
51
+ json (>= 1.8, < 3)
52
+ simplecov-html (~> 0.10.0)
53
+ simplecov-html (0.10.2)
54
+ unicode-display_width (1.6.1)
39
55
 
40
56
  PLATFORMS
41
57
  ruby
42
58
 
43
59
  DEPENDENCIES
44
60
  bundler (~> 2.0)
61
+ codeclimate-test-reporter
45
62
  ftpmock!
63
+ net-sftp
46
64
  rake (~> 10.0)
47
65
  rspec (~> 3.0)
48
- rubocop (= 0.75.0)
66
+ rubocop (= 0.80.0)
67
+ simplecov
49
68
 
50
69
  BUNDLED WITH
51
70
  2.0.2
data/README.md CHANGED
@@ -1,38 +1,162 @@
1
1
  # Ftpmock
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/ftpmock`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Test your FTP calls offline.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ ## Status
6
+
7
+ | Is It Working? | Is It Tested? | Code Quality | **# of Downloads** | **Get Involved!** |
8
+ |:---|:---|:---|:---|:---|
9
+ | [![Master Build Status](https://api.travis-ci.org/thejamespinto/ftpmock.svg?branch=master)](https://travis-ci.org/thejamespinto/ftpmock) | [![Test Coverage](https://api.codeclimate.com/v1/badges/25ac02fa4774e3fcb569/test_coverage)](https://codeclimate.com/github/thejamespinto/ftpmock/test_coverage) | [![Maintainability](https://api.codeclimate.com/v1/badges/25ac02fa4774e3fcb569/maintainability)](https://codeclimate.com/github/thejamespinto/ftpmock/maintainability) | [![Downloads](http://img.shields.io/gem/dt/ftpmock.svg)](https://rubygems.org/gems/ftpmock) | [![GitHub Issues](https://img.shields.io/github/issues/thejamespinto/ftpmock.svg)](https://github.com/thejamespinto/ftpmock/issues) |
10
+
11
+ ## Compatibility
12
+
13
+ | <image width=16 src='./images/ruby.png'> Ruby 2.3 | <image width=16 src='./images/ruby.png'> Ruby 2.4 | <image width=16 src='./images/ruby.png'> Ruby 2.5 | <image width=16 src='./images/ruby.png'> Ruby 2.6 | <image width=16 src='./images/ruby.png'> Ruby 2.7 |
14
+ | :--- | :--- | :--- | :--- | :--- |
6
15
 
7
16
  ## Installation
8
17
 
9
18
  Add this line to your application's Gemfile:
10
19
 
11
20
  ```ruby
12
- gem 'ftpmock'
21
+ group :test do
22
+ gem 'ftpmock'
23
+ end
13
24
  ```
14
25
 
15
- And then execute:
26
+ ## Usage
16
27
 
17
- $ bundle
28
+ If you know your way around tests
18
29
 
19
- Or install it yourself as:
30
+ ```ruby
31
+ require 'ftpmock'
32
+
33
+ RSpec.configure do |config|
34
+ config.around(:example) do |example|
35
+ Ftpmock.on! do
36
+ example.run
37
+ end
38
+ end
39
+ end
40
+ ```
20
41
 
21
- $ gem install ftpmock
42
+ If you need to see a full example
22
43
 
23
- ## Usage
44
+ ```ruby
45
+ require 'rubygems'
46
+ require 'test/unit'
47
+ require 'ftpmock'
48
+
49
+ # Optional (default values)
50
+ Ftpmock.configure do |c|
51
+ c.path = 'test/ftp_records'
52
+ c.verbose = true
53
+ end
54
+
55
+ class FtpmockTest < Test::Unit::TestCase
56
+ def test_ubuntu_mirror
57
+ Ftpmock.on! do
58
+ # Ubuntu Download - University of Pittsburgh
59
+ ftp = Net::FTP.new
60
+ assert_equal(Ftpmock::NetFtpProxy, ftp.class)
61
+ assert ftp.connect('mirror.cs.pitt.edu', 21)
62
+ assert ftp.login('', '')
63
+
64
+ t = Time.now
65
+ 3.times do |i|
66
+ list = ftp.list('/ubuntu/releases')
67
+ assert list.size.positive?
68
+
69
+ ftp.get('/ubuntu/releases/robots.txt', 'tmp/ubuntu_robots.txt')
70
+ assert File.exist?('tmp/ubuntu_robots.txt')
71
+
72
+ puts "[Take #{i+1}] #{(Time.now-t).round(3)}s"
73
+ end
74
+ end
75
+ end
76
+ end
77
+ ```
78
+
79
+ Run this test once, and Ftpmock will record the FTP requests to __test/ftp\_records/mirror-cs-pitt-edu\_21\_\_/__
80
+
81
+ Run it again, and Ftpmock will replay the responses from __mirror.cs.pitt.edu__ when the FTP request is made.
82
+
83
+ Your tests are now blazing fast because no real FTP requests are made anymore.
84
+
85
+ The test will continue to pass, even if you are offline, or if the University of Pittsburgh FTP servers are down for maintenance.
86
+
87
+ The responses will be accurate since they will contain the same list and files you get from a real request.
24
88
 
25
- TODO: Write usage instructions here
89
+ Unlike VCR, Ftpmock combines your four credentials _(address + port + username + password)_ and caches onto the exact same directory, optimizing for both storage and readability.
26
90
 
27
91
  ## Development
28
92
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
93
+ After checking out the repo, run `bin/setup` to install dependencies.
94
+
95
+ Then, run `bundle exec rake spec` to run the tests.
96
+
97
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
98
+
99
+ To install this gem onto your local machine, run `bundle exec rake install`.
100
+
101
+ ## Documentation
102
+
103
+ ![Chart](./images/ftpmock.png)
104
+
105
+ - Core
106
+ - [x] Stubber
107
+ - [x] Configuration
108
+ - [x] Cache
109
+ - [x] Helpers
110
+ - Proxies
111
+ - [x] Proxy for Ruby's native Net::FTP library
112
+ - [ ] Proxy for Jamis Buck's gem 'net-sftp'
113
+
114
+ ### Core instantiable classes & procedural modules
115
+
116
+ links: [lib/ftpmock/core](./lib/ftpmock/core)
117
+
118
+ - [x] stubber for proxies
119
+ - [x] configuration class
120
+ - [x] cache class
121
+ - [x] cache path helper
122
+ - [x] cache list helper
123
+ - [x] cache get helper
124
+ - [x] cache put helper
125
+
126
+ ### Proxy for Ruby's native Net::FTP library (Ftpmock::NetFtpProxy)
127
+
128
+ links: [lib/ftpmock/proxies/net_ftp_proxy.rb](./lib/ftpmock/proxies/net_ftp_proxy.rb) , https://apidock.com/ruby/Net/FTP & https://github.com/ruby/ruby/tree/master/lib/net
129
+
130
+ - [x] proxy class
131
+ - [x] stubbers
132
+ - [x] address & port forwarding
133
+ - [x] username & password forwarding
134
+ - [x] chdir forwarding
135
+ - [x] pwd
136
+ - [x] list
137
+ - [x] get
138
+ - [x] put
139
+ - [ ] ssl support
140
+ - [x] unit tests
141
+ - [x] integration tests
142
+
143
+ ### Proxy for Jamis Buck's gem 'net-sftp' (Ftpmock::NetSftpProxy)
144
+
145
+ links: [lib/ftpmock/proxies/net_sftp_proxy.rb](./lib/ftpmock/proxies/net_sftp_proxy.rb) , https://rubygems.org/gems/net-sftp & https://github.com/net-ssh/net-sftp
30
146
 
31
- 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`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
147
+ - [x] proxy class
148
+ - [x] stubbers
149
+ - [ ] address & port forwarding
150
+ - [ ] username & password forwarding
151
+ - [ ] list
152
+ - [ ] get
153
+ - [ ] put
154
+ - [ ] unit tests
155
+ - [ ] integration tests
32
156
 
33
157
  ## Contributing
34
158
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ftpmock.
159
+ Bug reports and pull requests are welcome on GitHub at https://github.com/thejamespinto/ftpmock.
36
160
 
37
161
  ## License
38
162
 
data/ftpmock.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ['James Pinto']
9
9
  spec.email = ['thejamespinto@gmail.com']
10
10
 
11
- spec.summary = 'Record and Replay FTP requests in Ruby tests.'
11
+ spec.summary = 'Test your FTP calls offline.'
12
12
  spec.description = 'Just like VCR and WebMock, but for FTP.'
13
13
  spec.homepage = 'https://github.com/thejamespinto/ftpmock'
14
14
  spec.license = 'MIT'
@@ -31,6 +31,11 @@ Gem::Specification.new do |spec|
31
31
  spec.require_paths = ['lib']
32
32
 
33
33
  spec.add_development_dependency 'bundler', '~> 2.0'
34
+ spec.add_development_dependency 'codeclimate-test-reporter'
35
+ spec.add_development_dependency 'net-sftp'
34
36
  spec.add_development_dependency 'rake', '~> 10.0'
35
37
  spec.add_development_dependency 'rspec', '~> 3.0'
38
+ spec.add_development_dependency 'simplecov'
39
+
40
+ spec.add_dependency 'diffy', '~> 3.0'
36
41
  end
Binary file
data/images/ruby.png ADDED
Binary file
data/lib/ftpmock.rb CHANGED
@@ -1,6 +1,24 @@
1
+ require 'pathname'
1
2
  require 'ftpmock/version'
2
3
 
4
+ Dir['lib/ftpmock/{utils,core,helpers,proxies}/*.rb'].each do |f|
5
+ load f
6
+ end
7
+
3
8
  module Ftpmock
4
9
  class Error < StandardError; end
5
- # Your code goes here...
10
+ class GetNotFetched < StandardError; end
11
+ class PutFileNotFound < Error; end
12
+ class PutLocalDiffersFromCache < Error; end
13
+
14
+ def self.on!(&block)
15
+ NetFtpProxy.on! do
16
+ NetSftpProxy.on!(&block)
17
+ end
18
+ end
19
+
20
+ def self.off!
21
+ NetFtpProxy.off!
22
+ NetSftpProxy.off!
23
+ end
6
24
  end
@@ -0,0 +1,186 @@
1
+ module Ftpmock
2
+ class Cache
3
+ attr_reader :credentials, :configuration
4
+
5
+ def initialize(configuration, credentials)
6
+ @configuration = configuration
7
+ @credentials = credentials
8
+ @chdir = nil
9
+ end
10
+
11
+ def path
12
+ @path ||= Pathname("#{configuration.path}/#{path_dir}")
13
+ end
14
+
15
+ def path_dir
16
+ StringUtils.parameterize(credentials.map(&:to_s).join('_'))
17
+ end
18
+
19
+ def _alert(tag, content, color = :green)
20
+ configuration.verbose && VerboseUtils.alert(tag, content, color)
21
+ end
22
+
23
+ def chdir(dirname = nil)
24
+ return @chdir if dirname.nil?
25
+
26
+ original = @chdir
27
+ @chdir = PathHelper.join(@chdir, dirname)
28
+
29
+ _chdir_alert(dirname, original, @chdir)
30
+ @chdir
31
+ end
32
+
33
+ def _chdir_alert(dirname, old_chdir, new_chdir)
34
+ tag = "ftpmock.cache.chdir '#{dirname}'"
35
+
36
+ _alert tag, "changed from '#{old_chdir}' to '#{new_chdir}'", :green
37
+ end
38
+
39
+ def list(*args)
40
+ key = args.join(',')
41
+ tag = _list_tag_for(key)
42
+
43
+ list = ListHelper.read(path, chdir, key)
44
+ _list_alert_hit(tag, list)
45
+ return list if list
46
+
47
+ _list_alert_miss(tag)
48
+ list = yield
49
+
50
+ _list_alert_storing(tag, list)
51
+ ListHelper.write(path, chdir, key, list)
52
+
53
+ list
54
+ end
55
+
56
+ def _list_tag_for(key)
57
+ tag = "ftpmock.cache.list '#{key}'"
58
+ tag += ", chdir: '#{chdir}'" if chdir
59
+ tag
60
+ end
61
+
62
+ def _list_alert_hit(tag, list)
63
+ list.nil? || _alert(tag, "hit! (#{list.size} lines)")
64
+ end
65
+
66
+ def _list_alert_miss(tag)
67
+ _alert tag, 'miss!', :yellow
68
+ end
69
+
70
+ def _list_alert_storing(tag, list)
71
+ _alert tag, "storing #{list.size} lines!"
72
+ end
73
+
74
+ def get(remotefile, localfile = File.basename(remotefile))
75
+ tag = _get_tag_for(remotefile)
76
+
77
+ if GetHelper.read(path, chdir, remotefile, localfile)
78
+ _get_alert_hit(tag, localfile)
79
+ return
80
+ end
81
+
82
+ _get_alert_miss(tag)
83
+ yield
84
+
85
+ if GetHelper.fetched?(localfile)
86
+ _get_alert_storing(tag, localfile)
87
+ GetHelper.write(path, chdir, remotefile, localfile)
88
+ else
89
+ _get_raise_localfile_not_fetched(remotefile, localfile)
90
+ end
91
+ end
92
+
93
+ def _get_tag_for(remotefile)
94
+ tag = "ftpmock.cache.get '#{remotefile}'"
95
+ tag += ", chdir: '#{chdir}'" if chdir
96
+ tag
97
+ end
98
+
99
+ def _get_alert_hit(tag, localfile)
100
+ _alert tag, "hit! (#{localfile})"
101
+ end
102
+
103
+ def _get_alert_miss(tag)
104
+ _alert tag, 'miss!', :yellow
105
+ end
106
+
107
+ def _get_alert_storing(tag, localfile)
108
+ _alert tag, "storing #{localfile}"
109
+ end
110
+
111
+ def _get_raise_localfile_not_fetched(remotefile, localfile)
112
+ msg = "FTP GET '#{remotefile}' should have created '#{localfile}'"
113
+ msg = "#{msg}, but didn't."
114
+ raise GetNotFetched, msg
115
+ end
116
+
117
+ def put(localfile, remotefile = File.basename(localfile))
118
+ tag = _put_tag_for(localfile)
119
+
120
+ _put_alert_exists(tag)
121
+ PutHelper.exist?(localfile) || _put_raise_not_found(remotefile, localfile)
122
+
123
+ if PutHelper.cached?(path, remotefile)
124
+ _put_cached(tag, path, localfile, remotefile)
125
+ else
126
+ _put_alert_miss(tag)
127
+ yield
128
+
129
+ _put_alert_storing(tag, remotefile)
130
+ PutHelper.write(path, localfile, remotefile)
131
+ end
132
+
133
+ true
134
+ end
135
+
136
+ def _put_tag_for(localfile)
137
+ tag = "ftpmock.cache.put '#{localfile}'"
138
+ tag += ", chdir: '#{chdir}'" if chdir
139
+ tag
140
+ end
141
+
142
+ def _put_alert_exists(tag)
143
+ _alert tag, 'file exists?'
144
+ end
145
+
146
+ def _put_alert_miss(tag)
147
+ _alert tag, 'miss!', :yellow
148
+ end
149
+
150
+ def _put_alert_storing(tag, remotefile)
151
+ _alert tag, "storing #{remotefile}"
152
+ end
153
+
154
+ def _put_cached(tag, path, localfile, remotefile)
155
+ diff = PutHelper.compare(path, localfile, remotefile)
156
+
157
+ _put_alert_hit(tag, diff.size)
158
+
159
+ diff.any? && _put_raise_localfile_differs(remotefile, localfile, diff)
160
+ end
161
+
162
+ def _put_alert_hit(tag, size)
163
+ color = size.zero? ? :green : :red
164
+ _alert tag, "hit! (#{size} differing lines)", color
165
+ end
166
+
167
+ def _put_raise_not_found(remotefile, localfile)
168
+ msg = "FTP PUT '#{remotefile}' has failed"
169
+ msg = "#{msg} because '#{localfile}' does not exist."
170
+ raise PutFileNotFound, msg
171
+ end
172
+
173
+ def _put_raise_localfile_differs(remotefile, localfile, diff)
174
+ spaces = ' ' * 20
175
+ VerboseUtils.puts
176
+ VerboseUtils.puts ColorUtils.highlight "#{spaces}Diffy Begin#{spaces}"
177
+ VerboseUtils.puts diff
178
+ VerboseUtils.puts ColorUtils.highlight "#{spaces} Diffy End #{spaces}"
179
+ VerboseUtils.puts
180
+
181
+ msg = "FTP PUT '#{remotefile}' has failed because"
182
+ msg = "#{msg} '#{localfile}' contents don't match #{path}/#{remotefile}"
183
+ raise PutLocalDiffersFromCache, msg
184
+ end
185
+ end
186
+ end