maid 0.10.0.pre.alpha.2 → 0.10.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: d8d0fa40b9069dd973a12021c729407e1f98719ea96e8ede17aff4426cd8d9eb
4
- data.tar.gz: ed334d76e2cdc9ba723e600a6f371efab241ea24c080e7009425dee9a99d52f4
3
+ metadata.gz: 386fffc38404ce847ae5650376f84be904056ad5d6acd86cea9311cedade94c1
4
+ data.tar.gz: 49c5f4a3b21d583d2edd09d73d862c495c2e8d5eb36c510401bc5ff216316c57
5
5
  SHA512:
6
- metadata.gz: 4be4e2a2771566d670b9b7a5d5966c334e3ca58c7c204dab7182654821b47b6076dc2ceb0e880de1a2e6966f110fee7422d289ffa058c9ba6861287afd2f60be
7
- data.tar.gz: 124d6e7f02282b4772b4a849acfad62efdc3277c08ea0696cd32b57672e199104bf314e53b609c47960e026b2073f4aba55d441de5061600fa9f499f9e90ceae
6
+ metadata.gz: 334f18ddb7a90a62a6b3c6136930c1724e08358ab7fb0dcca7011570b1b93bffa24958a07756c52f303f617aeea8cc02142d4d6163b75cfeaad3b71c32aeb34e
7
+ data.tar.gz: 397ca948024144b6beaa7f7139df13a66ff84b2240a3ffd8a716d67286334f5e3da6520e25e6d5df2ba8a3e5f8f417ec64fd29e42f4a955ef5fb24471b3a7dc3
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: "<Short description of the issue>"
5
+ labels: bug
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **👋 Before reporting a bug, please make sure you're running the latest available version of maid (`gem install maid`).**
11
+
12
+ **👋 If you're using Ruby 2.7+, please make sure you're running maid v0.10.0+ (`gem install maid --pre`)**
13
+
14
+ **Describe the bug**
15
+ A clear and concise description of what the bug is.
16
+
17
+ **To Reproduce**
18
+ Steps to trigger the issue.
19
+
20
+ **Expected behavior**
21
+ A clear and concise description of what you expected to happen.
22
+
23
+ **Logs**
24
+ If applicable, add logs to help explain your problem. You can find the logs at `~/.maid/maid.log`.
25
+
26
+ **Environment (please complete the information):**
27
+ - Maid version (`maid --version`): `<enter the command's output here>`
28
+ - OS, distribution (Linux), and version: <examples: OSX 12.0.0/Linux Mint 20.3>
29
+ - Ruby version (`ruby --version`): `<enter the command's output here>`
30
+
31
+ **Minimal `rules.rb` to reproduce the issue:**
32
+ ```ruby
33
+ # Rule(s)
34
+ ```
35
+
36
+ **Additional context**
37
+ Add any other context about the problem here.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ''
5
+ labels: feature
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Is your feature request related to a problem? Please describe.**
11
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
+
13
+ **Describe the solution you'd like**
14
+ A clear and concise description of what you want to happen.
15
+
16
+ **Describe alternatives you've considered**
17
+ A clear and concise description of any alternative solutions or features you've considered.
18
+
19
+ **Additional context**
20
+ Add any other context or screenshots about the feature request here.
@@ -38,8 +38,8 @@ jobs:
38
38
  token: ${{ secrets.BOT_GH_TOKEN }}
39
39
  # Uncomment for pre-releases, see
40
40
  # https://github.com/maid/maid/wiki/Release-Process
41
- prerelease: true
42
- release-as: v0.10.0-alpha.2
41
+ # prerelease: true
42
+ # release-as: v0.10.0-alpha.3
43
43
  - name: Set up Ruby
44
44
  uses: ruby/setup-ruby@v1
45
45
  with:
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.10.0-alpha.2"
2
+ ".": "0.10.0"
3
3
  }
data/.rubocop_todo.yml CHANGED
@@ -66,7 +66,7 @@ Metrics/MethodLength:
66
66
  # Offense count: 4
67
67
  # Configuration parameters: CountComments, CountAsOne.
68
68
  Metrics/ModuleLength:
69
- Max: 711
69
+ Max: 753
70
70
 
71
71
  # Offense count: 2
72
72
  # Configuration parameters: AllowedMethods, AllowedPatterns.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.10.0](https://github.com/maid/maid/compare/v0.10.0-alpha.3...v0.10.0) (2023-05-01)
4
+
5
+
6
+ ### Miscellaneous Chores
7
+
8
+ * release 0.10.0 ([1f35afd](https://github.com/maid/maid/commit/1f35afd2030bd74a5175ced5cd9766273162dea4))
9
+
10
+ ## [0.10.0-alpha.3](https://github.com/maid/maid/compare/v0.10.0-alpha.2...v0.10.0-alpha.3) (2023-04-04)
11
+
12
+
13
+ ### Features
14
+
15
+ * **maid:** improve `#watch` error message ([#287](https://github.com/maid/maid/issues/287)) ([0894cd6](https://github.com/maid/maid/commit/0894cd69665d5d9fe775b6b3df5a247f22f217d6))
16
+ * **tools:** add option to disable clobbering destination for `#move` ([#284](https://github.com/maid/maid/issues/284)) ([979413f](https://github.com/maid/maid/commit/979413fe284b61b43b33ba2169e72ed23043bcca))
17
+
3
18
  ## [0.10.0-alpha.2](https://github.com/maid/maid/compare/v0.10.0-alpha.1...v0.10.0-alpha.2) (2023-03-28)
4
19
 
5
20
 
data/Rakefile CHANGED
@@ -2,6 +2,7 @@ require 'bundler'
2
2
  require 'rake'
3
3
  require 'rspec/core/rake_task'
4
4
  require 'yard'
5
+ require 'rake/notes/rake_task'
5
6
 
6
7
  task default: :spec
7
8
 
data/SECURITY.md ADDED
@@ -0,0 +1,29 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ ### Maid gem
6
+ | Version | Supported |
7
+ | ------------ | ------------------ |
8
+ | >= 0.10.0 | :heavy_check_mark: |
9
+ | 0.7.0 | :heavy_check_mark: |
10
+ | < 0.7.0 | :x: |
11
+
12
+ ### Ruby
13
+ | Version | Supported |
14
+ | ------------ | ------------------ |
15
+ | >= 3.0 | :heavy_check_mark: |
16
+ | 2.7 | :warning: |
17
+ | <= 2.6 | :x: |
18
+
19
+ > :warning: Ruby 2.7 became EOL on 2023-03-31 and might be dropped in the near
20
+ > future. We strongly recommend using Ruby 3+.
21
+
22
+ ## Reporting a Vulnerability
23
+
24
+ To report a vulnerability, please open an issue. We will investigate and
25
+ respond in a timely manner.
26
+
27
+ If the vulnerability is accepted, we will work on a patch. Bear in mind that
28
+ this is a community effort and we can't commit to specific timeframes other
29
+ than best effort.
@@ -0,0 +1,42 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://nominatim.openstreetmap.org/reverse?accept-language=en&addressdetails=1&format=json&lat=-33.85608611111111&lon=151.219925
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - nginx
23
+ Date:
24
+ - Fri, 21 Apr 2023 12:28:49 GMT
25
+ Content-Type:
26
+ - application/json; charset=UTF-8
27
+ Transfer-Encoding:
28
+ - chunked
29
+ Connection:
30
+ - keep-alive
31
+ Keep-Alive:
32
+ - timeout=20
33
+ Access-Control-Allow-Origin:
34
+ - "*"
35
+ Access-Control-Allow-Methods:
36
+ - OPTIONS,GET
37
+ body:
38
+ encoding: ASCII-8BIT
39
+ string: !binary |-
40
+ eyJwbGFjZV9pZCI6Mjk4ODA4MzUxLCJsaWNlbmNlIjoiRGF0YSDCqSBPcGVuU3RyZWV0TWFwIGNvbnRyaWJ1dG9ycywgT0RiTCAxLjAuIGh0dHBzOi8vb3NtLm9yZy9jb3B5cmlnaHQiLCJvc21fdHlwZSI6InJlbGF0aW9uIiwib3NtX2lkIjo5NTk5NzIzLCJsYXQiOiItMzMuODU2Mzc3NjUiLCJsb24iOiIxNTEuMjE1NTcxODMwNzQ1MDYiLCJkaXNwbGF5X25hbWUiOiJOb3J0aGVybiBCb2FyZHdhbGssIFF1YXkgUXVhcnRlciwgU3lkbmV5LCBDb3VuY2lsIG9mIHRoZSBDaXR5IG9mIFN5ZG5leSwgTmV3IFNvdXRoIFdhbGVzLCAyMDAwLCBBdXN0cmFsaWEiLCJhZGRyZXNzIjp7InJvYWQiOiJOb3J0aGVybiBCb2FyZHdhbGsiLCJuZWlnaGJvdXJob29kIjoiUXVheSBRdWFydGVyIiwic3VidXJiIjoiU3lkbmV5IiwiY2l0eSI6IlN5ZG5leSIsIm11bmljaXBhbGl0eSI6IkNvdW5jaWwgb2YgdGhlIENpdHkgb2YgU3lkbmV5Iiwic3RhdGUiOiJOZXcgU291dGggV2FsZXMiLCJJU08zMTY2LTItbHZsNCI6IkFVLU5TVyIsInBvc3Rjb2RlIjoiMjAwMCIsImNvdW50cnkiOiJBdXN0cmFsaWEiLCJjb3VudHJ5X2NvZGUiOiJhdSJ9LCJib3VuZGluZ2JveCI6WyItMzMuODU2Njc0MiIsIi0zMy44NTYxMDk2IiwiMTUxLjIxNDU1NzkiLCIxNTEuMjE1OTA4NCJdfQ==
41
+ recorded_at: Fri, 21 Apr 2023 12:28:49 GMT
42
+ recorded_with: VCR 6.1.0
@@ -0,0 +1,42 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://nominatim.openstreetmap.org/reverse?accept-language=en&addressdetails=1&format=json&lat=-33.85608611111111&lon=151.219925
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - nginx
23
+ Date:
24
+ - Fri, 21 Apr 2023 12:29:51 GMT
25
+ Content-Type:
26
+ - application/json; charset=UTF-8
27
+ Transfer-Encoding:
28
+ - chunked
29
+ Connection:
30
+ - keep-alive
31
+ Keep-Alive:
32
+ - timeout=20
33
+ Access-Control-Allow-Origin:
34
+ - "*"
35
+ Access-Control-Allow-Methods:
36
+ - OPTIONS,GET
37
+ body:
38
+ encoding: ASCII-8BIT
39
+ string: !binary |-
40
+ eyJwbGFjZV9pZCI6Mjk4ODA4MzUxLCJsaWNlbmNlIjoiRGF0YSDCqSBPcGVuU3RyZWV0TWFwIGNvbnRyaWJ1dG9ycywgT0RiTCAxLjAuIGh0dHBzOi8vb3NtLm9yZy9jb3B5cmlnaHQiLCJvc21fdHlwZSI6InJlbGF0aW9uIiwib3NtX2lkIjo5NTk5NzIzLCJsYXQiOiItMzMuODU2Mzc3NjUiLCJsb24iOiIxNTEuMjE1NTcxODMwNzQ1MDYiLCJkaXNwbGF5X25hbWUiOiJOb3J0aGVybiBCb2FyZHdhbGssIFF1YXkgUXVhcnRlciwgU3lkbmV5LCBDb3VuY2lsIG9mIHRoZSBDaXR5IG9mIFN5ZG5leSwgTmV3IFNvdXRoIFdhbGVzLCAyMDAwLCBBdXN0cmFsaWEiLCJhZGRyZXNzIjp7InJvYWQiOiJOb3J0aGVybiBCb2FyZHdhbGsiLCJuZWlnaGJvdXJob29kIjoiUXVheSBRdWFydGVyIiwic3VidXJiIjoiU3lkbmV5IiwiY2l0eSI6IlN5ZG5leSIsIm11bmljaXBhbGl0eSI6IkNvdW5jaWwgb2YgdGhlIENpdHkgb2YgU3lkbmV5Iiwic3RhdGUiOiJOZXcgU291dGggV2FsZXMiLCJJU08zMTY2LTItbHZsNCI6IkFVLU5TVyIsInBvc3Rjb2RlIjoiMjAwMCIsImNvdW50cnkiOiJBdXN0cmFsaWEiLCJjb3VudHJ5X2NvZGUiOiJhdSJ9LCJib3VuZGluZ2JveCI6WyItMzMuODU2Njc0MiIsIi0zMy44NTYxMDk2IiwiMTUxLjIxNDU1NzkiLCIxNTEuMjE1OTA4NCJdfQ==
41
+ recorded_at: Fri, 21 Apr 2023 12:29:51 GMT
42
+ recorded_with: VCR 6.1.0
data/lib/maid/maid.rb CHANGED
@@ -88,6 +88,15 @@ class Maid::Maid
88
88
  end
89
89
 
90
90
  def watch(path, options = {}, &block)
91
+ full_path = File.expand_path(path)
92
+
93
+ unless File.directory?(full_path)
94
+ message = "#{full_path} cannot be a file and it must exist in order to watch it"
95
+
96
+ warn(message)
97
+ raise message
98
+ end
99
+
91
100
  @watches << ::Maid::Watch.new(self, path, options, &block)
92
101
  end
93
102
 
@@ -140,7 +149,7 @@ class Maid::Maid
140
149
  def default_trash_path
141
150
  # TODO: Refactor module declaration so this can be `Platform`
142
151
  if Maid::Platform.linux?
143
- # See the [FreeDesktop.org Trash specification](http://www.ramendik.ru/docs/trashspec.html)
152
+ # See the [FreeDesktop.org Trash specification](https://archive.is/cXir4)
144
153
  path = "#{XDG['DATA_HOME']}/Trash/files"
145
154
  elsif Maid::Platform.osx?
146
155
  path = File.expand_path('~/.Trash')
data/lib/maid/tools.rb CHANGED
@@ -24,33 +24,50 @@ module Maid::Tools
24
24
  # For showing deprecation notices
25
25
  include Deprecated
26
26
 
27
- # Move `sources` to a `destination` directory.
27
+ # Moves `sources` file(s) to a `destination` directory.
28
28
  #
29
29
  # Movement is only allowed to directories that already exist. If your
30
30
  # intention is to rename, see the `rename` method.
31
31
  #
32
- # ## Examples
33
- #
34
- # Single path:
35
- #
36
- # move('~/Downloads/foo.zip', '~/Archive/Software/Mac OS X/')
37
- #
38
- # Multiple paths:
39
- #
40
- # move(['~/Downloads/foo.zip', '~/Downloads/bar.zip'], '~/Archive/Software/Mac OS X/')
41
- # move(dir('~/Downloads/*.zip'), '~/Archive/Software/Mac OS X/')
42
- def move(sources, destination)
43
- expanded_destination = expand(destination)
44
-
45
- if File.directory?(expanded_destination)
32
+ # @example Single source file
33
+ # move('~/Downloads/foo.zip', '~/Archive/Software/Mac OS X/')
34
+ #
35
+ # @example Multiple source files
36
+ # move(['~/Downloads/foo.zip', '~/Downloads/bar.zip'],
37
+ # '~/Archive/Software/Mac OS X/')
38
+ # move(dir('~/Downloads/*.zip'), '~/Archive/Software/Mac OS X/')
39
+ #
40
+ # @example Overwrite destination file if it already exists
41
+ # move('~/Downloads/foo.zip', '~/Archive/Software/Mac OS X/')
42
+ # move('~/Downloads/foo.zip', '~/Archive/Software/Mac OS X/', clobber:
43
+ # true)
44
+ #
45
+ # @example Skip file if it already exists at destination
46
+ # move('~/Downloads/foo.zip', '~/Archive/Software/Mac OS X/', clobber:
47
+ # false)
48
+ #
49
+ # @param sources [String, Array<String>] the paths to the source files to
50
+ # move
51
+ # @param destination_dir [String] path of the directory where to move
52
+ # `sources` to
53
+ # @param [Hash] kwargs the arguments to modify behaviour
54
+ # @option kwargs [Boolean] :clobber (true) `true` to overwrite destination
55
+ # file if it exists, `false` to skip moving file if it exists
56
+ def move(sources, destination_dir, clobber: true)
57
+ expanded_destination_dir = expand(destination_dir)
58
+
59
+ if File.directory?(expanded_destination_dir)
46
60
  expand_all(sources).each do |source|
47
- log("move #{sh_escape(source)} #{sh_escape(expanded_destination)}")
48
- FileUtils.mv(source, expanded_destination, **@file_options)
61
+ log("move #{sh_escape(source)} #{sh_escape(expanded_destination_dir)}")
62
+
63
+ unless skip_move?(source, expanded_destination_dir, clobber)
64
+ FileUtils.mv(source, expanded_destination_dir, **@file_options)
65
+ end
49
66
  end
50
67
  else
51
68
  # Unix `mv` warns about the target not being a directory with multiple sources. Maid checks the same.
52
- warn("skipping move because #{sh_escape(expanded_destination)} is not a" \
53
- "directory (use 'mkdir' to create first, or use 'rename')")
69
+ warn("skipping move because #{sh_escape(expanded_destination_dir)} " \
70
+ "is not a directory (use 'mkdir' to create first, or use 'rename')")
54
71
  end
55
72
  end
56
73
 
@@ -1006,4 +1023,29 @@ module Maid::Tools
1006
1023
  []
1007
1024
  end
1008
1025
  end
1026
+
1027
+ # Predicate to tell whether the file should be skipped when moving.
1028
+ # @param source_path [String] the path to the source file
1029
+ # @param destination_dir [String] the path to the destination directory
1030
+ # @param clobber [Boolean] `true` to overwrite existing destination file,
1031
+ # `false` otherwise
1032
+ # @return [Boolean] whether to skip the move
1033
+ def skip_move?(source_path, destination_dir, clobber)
1034
+ destination_path = File.join(destination_dir, File.basename(source_path))
1035
+
1036
+ # if the destination file doesn't exist, we can move.
1037
+ return false unless File.exist?(destination_path)
1038
+
1039
+ log("#{destination_path} already exists")
1040
+
1041
+ # figure out whether to overwrite the existing destination file.
1042
+ if clobber
1043
+ log("clobbering enabled, moving #{File.basename(source_path)} anyway")
1044
+
1045
+ return false
1046
+ end
1047
+ log("clobbering disabled, skipping move for #{File.basename(source_path)}")
1048
+
1049
+ true
1050
+ end
1009
1051
  end
data/lib/maid/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Maid
4
- VERSION = '0.10.0-alpha.2'
4
+ VERSION = '0.10.0'
5
5
  SUMMARY = 'Be lazy. Let Maid clean up after you, based on rules you define. ' \
6
6
  'Think of it as "Hazel for hackers".'
7
7
  end
data/maid.gemspec CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ['Benjamin Oakes', 'Coaxial']
9
9
  s.email = ['hello@benjaminoakes.com', 'c+rubygems@64b.it']
10
- s.license = 'GPLv2'
10
+ s.license = 'GPL-2.0'
11
11
  s.homepage = 'http://github.com/maid/maid'
12
12
  s.summary = Maid::SUMMARY
13
13
  s.description = s.summary
@@ -53,6 +53,7 @@ Gem::Specification.new do |s|
53
53
  s.add_development_dependency('guard-rubocop')
54
54
  s.add_development_dependency('pry-byebug')
55
55
  s.add_development_dependency('rake', '~> 13.0.6')
56
+ s.add_development_dependency('rake-notes')
56
57
  s.add_development_dependency('redcarpet', '~> 3.6.0') # Soft dependency of `yard`
57
58
  s.add_development_dependency('rspec', '~> 3.12.0')
58
59
  s.add_development_dependency('rubocop')
@@ -60,6 +61,8 @@ Gem::Specification.new do |s|
60
61
  s.add_development_dependency('rubocop-rspec')
61
62
  s.add_development_dependency('simplecov')
62
63
  s.add_development_dependency('timecop', '~> 0.9.6')
64
+ s.add_development_dependency('vcr', '~> 6.1.0')
65
+ s.add_development_dependency('webmock', '~> 3.18.1')
63
66
  s.add_development_dependency('yard', '>= 0.9.11')
64
67
 
65
68
  # In Vagrant, polling won't cross over the OS boundary if you develop in the host OS but run your tests in the
@@ -95,7 +95,7 @@ describe 'Dependency expectations' do
95
95
  end
96
96
  end
97
97
 
98
- describe Geocoder do
98
+ describe Geocoder, vcr: { record: :new_episodes } do
99
99
  it 'translates latitude and longitude into street addresses' do
100
100
  city = Geocoder.search('-33.85608611111111,151.219925').map { |location| location.city }.uniq.compact
101
101
  expect(city).to eq(['Sydney'])
@@ -1,12 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module Maid
4
- describe Maid do
4
+ describe Maid, fakefs: true do
5
5
  let(:logger) { instance_spy('Logger') }
6
6
 
7
7
  before do
8
8
  allow(Logger).to receive(:new).and_return(logger)
9
- allow(FileUtils).to receive(:mkdir_p)
10
9
  end
11
10
 
12
11
  describe '.new' do
@@ -33,8 +32,11 @@ module Maid
33
32
  end
34
33
 
35
34
  it 'makes the log directory in case it does not exist' do
36
- expect(FileUtils).to receive(:mkdir_p).with('/home/username/log')
35
+ expect(File.exist?('/home/username/log')).to be false
36
+
37
37
  Maid.new(log_device: '/home/username/log/maid.log')
38
+
39
+ expect(File.exist?('/home/username/log')).to be true
38
40
  end
39
41
 
40
42
  it 'takes a logger object during intialization' do
@@ -58,8 +60,9 @@ module Maid
58
60
 
59
61
  it 'set the trash to the correct default path' do
60
62
  trash_path = "#{@home}/.local/share/Trash/files/"
61
- expect(FileUtils).to receive(:mkdir_p).with(trash_path).once
63
+
62
64
  maid = Maid.new
65
+
63
66
  expect(maid.trash_path).to eq(trash_path)
64
67
  end
65
68
  end
@@ -71,7 +74,7 @@ module Maid
71
74
 
72
75
  it 'sets the trash to the correct default path' do
73
76
  trash_path = "#{@home}/.Trash/"
74
- expect(FileUtils).to receive(:mkdir_p).with(trash_path).once
77
+
75
78
  maid = Maid.new
76
79
  expect(maid.trash_path).to eq(trash_path)
77
80
  end
@@ -86,8 +89,9 @@ module Maid
86
89
 
87
90
  it 'sets the trash to the given path, if provided' do
88
91
  trash_path = '/home/username/tmp/my_trash/'
89
- expect(FileUtils).to receive(:mkdir_p).with(trash_path).once
92
+
90
93
  maid = Maid.new(trash_path: trash_path)
94
+
91
95
  expect(maid.trash_path).not_to be_nil
92
96
  expect(maid.trash_path).to eq(trash_path)
93
97
  end
@@ -198,6 +202,7 @@ module Maid
198
202
  before do
199
203
  allow(Listen).to receive(:to)
200
204
  allow(Listen).to receive(:start)
205
+ FileUtils.mkdir_p('watch_dir')
201
206
  @maid = Maid.new
202
207
  end
203
208
 
@@ -215,6 +220,8 @@ module Maid
215
220
  # FIXME: Example is too long, shouldn't need the rubocop::disable
216
221
  it 'accepts a hash of options and passes them to Listen' do # rubocop:disable RSpec/ExampleLength
217
222
  hash = { some: :options }
223
+ FileUtils.mkdir_p('some_dir')
224
+
218
225
  @maid.watch('some_dir', hash) do
219
226
  rule 'test' do
220
227
  end
@@ -232,9 +239,29 @@ module Maid
232
239
 
233
240
  @maid.watches.last.run
234
241
  end
242
+
243
+ context('with a non-existent directory') do
244
+ let(:maid) { Maid.new }
245
+
246
+ it 'raises with an intelligible message' do
247
+ expect { maid.watch('/doesnt_exist/') }.to raise_error(/file.*exist/)
248
+ end
249
+
250
+ it 'logs an intelligible message' do
251
+ begin
252
+ maid.watch('/doesnt_exist')
253
+ # Suppressing the exception is fine, because we just want to test
254
+ # that the message is logged when it throws and the test above
255
+ # checks that the exception is raised.
256
+ rescue StandardError # rubocop:disable Lint/SuppressedException
257
+ end
258
+
259
+ expect(logger).to have_received(:warn).with(/file.*exist/)
260
+ end
261
+ end
235
262
  end
236
263
 
237
- describe '#repeat' do
264
+ describe '#repeat', fake_zoneinfo: true do
238
265
  before do
239
266
  @maid = Maid.new
240
267
  end
@@ -73,6 +73,59 @@ module Maid
73
73
  @maid.move([@src_file, another_file], @dst_dir)
74
74
  end
75
75
  end
76
+
77
+ context 'when the destination file already exists' do
78
+ let(:src_file) { '/tmp/src/test_file' }
79
+ let(:dst_dir) { '/tmp/dest/' }
80
+ let(:dst_file) { File.join(dst_dir, File.basename(src_file)) }
81
+ let(:maid) { Maid.new(logger: @logger) }
82
+
83
+ before do
84
+ FileUtils.mkdir_p(File.dirname(src_file))
85
+ FileUtils.mkdir_p(dst_dir)
86
+ FileUtils.touch(src_file)
87
+ FileUtils.touch(dst_file)
88
+ end
89
+
90
+ after do
91
+ FileUtils.rm_rf([src_file, dst_file])
92
+ end
93
+
94
+ context 'by default' do
95
+ let!(:original_mtime) { File.stat(dst_file).mtime }
96
+
97
+ before do
98
+ maid.move(src_file, dst_dir)
99
+ end
100
+
101
+ it 'logs an info message' do
102
+ expect(@logger).to have_received(:info).with(/already/)
103
+ expect(@logger).to have_received(:info).with(/anyway/)
104
+ expect(@logger).not_to have_received(:info).with(/skipping/)
105
+ end
106
+
107
+ it 'overwrites destination' do
108
+ expect(File.stat(dst_file).mtime).not_to eq(original_mtime)
109
+ end
110
+ end
111
+
112
+ context 'when clobber: false' do
113
+ let!(:original_mtime) { File.stat(dst_file).mtime }
114
+
115
+ before do
116
+ maid.move(src_file, dst_dir, clobber: false)
117
+ end
118
+
119
+ it 'logs an info message' do
120
+ expect(@logger).not_to have_received(:info).with(/anyway/)
121
+ expect(@logger).to have_received(:info).with(/skipping/)
122
+ end
123
+
124
+ it "doesn't overwrite the destination file" do
125
+ expect(File.stat(dst_file).mtime).to eq(original_mtime)
126
+ end
127
+ end
128
+ end
76
129
  end
77
130
 
78
131
  describe '#rename' do
@@ -670,7 +723,7 @@ module Maid
670
723
 
671
724
  describe '#location_city' do
672
725
  context 'given a JPEG image' do
673
- it 'reports the known location' do
726
+ it 'reports the known location', vcr: { record: :new_episodes } do
674
727
  sydney_path = File.join(file_fixtures_path, 'sydney.jpg')
675
728
  expect(@maid.location_city(sydney_path)).to eq('Sydney, New South Wales, AU')
676
729
  end
data/spec/spec_helper.rb CHANGED
@@ -16,6 +16,7 @@ require 'rspec'
16
16
  require 'timecop'
17
17
  require 'fakefs/spec_helpers'
18
18
  require 'pry-byebug'
19
+ require 'vcr'
19
20
 
20
21
  require 'maid'
21
22
 
@@ -25,6 +26,39 @@ RSpec.configure do |config|
25
26
  end
26
27
  config.include(FakeFS::SpecHelpers, fakefs: true)
27
28
  config.raise_errors_for_deprecations!
29
+
30
+ config.filter_run focus: true
31
+ config.run_all_when_everything_filtered = true
32
+
33
+ # NOTE: If a test fails because ENOENT /usr/share/zoneinfo/Africa/Abidjan,
34
+ # add `fake_zoneinfo: true` to the describe:
35
+ # `describe(MyClass, fake_zoneinfo: true do`
36
+ config.before(:context, fake_zoneinfo: true) do
37
+ # Rufus needs zoneinfo data to run, but when using FakeFS,
38
+ # /usr/share/zoneinfo doesn't exist on the FakeFS.
39
+ # On Linux, we just have to FakeFS::FileSystem.clone the directory and it
40
+ # just works.
41
+ # OSX is, of course, special. /usr/share/zoneinfo is a symlink on that
42
+ # platform, and `.clone` doesn't seem to be following symlinks. Instead, we
43
+ # have to copy the zoneinfo data to a temporary directory on the live
44
+ # filesystem, enable the FakeFS, clone that temporary directory, create
45
+ # /usr/share/zoneinfo onto the FakeFS, and finally copy the files into it.
46
+ # This way, they're available in the FakeFS where Rufus can find them.
47
+ include FakeFS::SpecHelpers
48
+ FakeFS.activate!
49
+
50
+ if Maid::Platform.osx?
51
+ FakeFS.deactivate!
52
+ FileUtils.mkdir_p('/tmp/')
53
+ FileUtils.cp_r('/usr/share/zoneinfo/', '/tmp/')
54
+ FakeFS.activate!
55
+ FakeFS::FileSystem.clone('/tmp/zoneinfo/')
56
+ FileUtils.mkdir_p('/usr/share/')
57
+ FileUtils.cp_r('/tmp/zoneinfo/', '/usr/share/')
58
+ end
59
+
60
+ FakeFS::FileSystem.clone('/usr/share/zoneinfo') if Maid::Platform.linux?
61
+ end
28
62
  end
29
63
 
30
64
  RSpec::Matchers.define :have_deprecated_method do |expected|
@@ -32,3 +66,10 @@ RSpec::Matchers.define :have_deprecated_method do |expected|
32
66
  expect(actual).to receive(:__deprecated_run_action__).with(expected, anything) # rubocop:disable RSpec/MessageSpies
33
67
  end
34
68
  end
69
+
70
+ VCR.configure do |config|
71
+ config.cassette_library_dir = 'fixtures/vcr_cassettes'
72
+ config.hook_into :webmock
73
+ # For autogenerating VCR cassettes' names based on the tests' metadata
74
+ config.configure_rspec_metadata!
75
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0.pre.alpha.2
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Oakes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-03-31 00:00:00.000000000 Z
12
+ date: 2023-05-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: deprecated
@@ -295,6 +295,20 @@ dependencies:
295
295
  - - "~>"
296
296
  - !ruby/object:Gem::Version
297
297
  version: 13.0.6
298
+ - !ruby/object:Gem::Dependency
299
+ name: rake-notes
300
+ requirement: !ruby/object:Gem::Requirement
301
+ requirements:
302
+ - - ">="
303
+ - !ruby/object:Gem::Version
304
+ version: '0'
305
+ type: :development
306
+ prerelease: false
307
+ version_requirements: !ruby/object:Gem::Requirement
308
+ requirements:
309
+ - - ">="
310
+ - !ruby/object:Gem::Version
311
+ version: '0'
298
312
  - !ruby/object:Gem::Dependency
299
313
  name: redcarpet
300
314
  requirement: !ruby/object:Gem::Requirement
@@ -393,6 +407,34 @@ dependencies:
393
407
  - - "~>"
394
408
  - !ruby/object:Gem::Version
395
409
  version: 0.9.6
410
+ - !ruby/object:Gem::Dependency
411
+ name: vcr
412
+ requirement: !ruby/object:Gem::Requirement
413
+ requirements:
414
+ - - "~>"
415
+ - !ruby/object:Gem::Version
416
+ version: 6.1.0
417
+ type: :development
418
+ prerelease: false
419
+ version_requirements: !ruby/object:Gem::Requirement
420
+ requirements:
421
+ - - "~>"
422
+ - !ruby/object:Gem::Version
423
+ version: 6.1.0
424
+ - !ruby/object:Gem::Dependency
425
+ name: webmock
426
+ requirement: !ruby/object:Gem::Requirement
427
+ requirements:
428
+ - - "~>"
429
+ - !ruby/object:Gem::Version
430
+ version: 3.18.1
431
+ type: :development
432
+ prerelease: false
433
+ version_requirements: !ruby/object:Gem::Requirement
434
+ requirements:
435
+ - - "~>"
436
+ - !ruby/object:Gem::Version
437
+ version: 3.18.1
396
438
  - !ruby/object:Gem::Dependency
397
439
  name: yard
398
440
  requirement: !ruby/object:Gem::Requirement
@@ -447,6 +489,8 @@ extra_rdoc_files: []
447
489
  files:
448
490
  - ".act-env"
449
491
  - ".act-secrets.example"
492
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
493
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
450
494
  - ".github/workflows/coverage.yml"
451
495
  - ".github/workflows/lint.yml"
452
496
  - ".github/workflows/release.yml"
@@ -468,8 +512,11 @@ files:
468
512
  - LICENSE
469
513
  - README.md
470
514
  - Rakefile
515
+ - SECURITY.md
471
516
  - Vagrantfile
472
517
  - bin/maid
518
+ - fixtures/vcr_cassettes/Dependency_expectations/Geocoder/translates_latitude_and_longitude_into_street_addresses.yml
519
+ - fixtures/vcr_cassettes/Maid_Tools/_location_city/given_a_JPEG_image/reports_the_known_location.yml
473
520
  - lib/maid.rb
474
521
  - lib/maid/app.rb
475
522
  - lib/maid/downloading.rb
@@ -518,7 +565,7 @@ files:
518
565
  - spec/spec_helper.rb
519
566
  homepage: http://github.com/maid/maid
520
567
  licenses:
521
- - GPLv2
568
+ - GPL-2.0
522
569
  metadata:
523
570
  bug_tracker_uri: https://github.com/maid/maid/issues
524
571
  changelog_uri: https://github.com/maid/maid/blob/master/CHANGELOG.md
@@ -538,11 +585,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
538
585
  version: 2.7.0
539
586
  required_rubygems_version: !ruby/object:Gem::Requirement
540
587
  requirements:
541
- - - ">"
588
+ - - ">="
542
589
  - !ruby/object:Gem::Version
543
- version: 1.3.1
590
+ version: '0'
544
591
  requirements: []
545
- rubygems_version: 3.3.26
592
+ rubygems_version: 3.4.6
546
593
  signing_key:
547
594
  specification_version: 4
548
595
  summary: Be lazy. Let Maid clean up after you, based on rules you define. Think of