file_discard 0.1.2 → 0.1.3

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
  SHA1:
3
- metadata.gz: 14285e9f6da20d84c8fcef7ab05e5925d23227da
4
- data.tar.gz: ba1853b5b923df31f372412dd4e4eae15f51851e
3
+ metadata.gz: 80106d989c491a8d79a5b2f6eca34d4a73a12bd1
4
+ data.tar.gz: 262dc75d7c97871b948ea70064df0f0021f07dcc
5
5
  SHA512:
6
- metadata.gz: aef2386c47392dd81be16d1b80b65db910dc96dfd7a2e67e8d1b5ab921136c65d9b40234170e93b06b18514065677acf383a31ddc2edbc9a11124c926df6ddc7
7
- data.tar.gz: 618672724fac62bbcef2ea0a57571cb4c4f3f8317ecdae0d026424365dfbe8be1a53f4c38cf84bec81675bc9cf0176e45672bd5192170f802a9b9a0acade83af
6
+ metadata.gz: e4370a3a0c0228c31b4f402224a1d3edf5d1918f4ee5c502ba6983fefc4bd27abf2e9c8c897f27310713229c4e1f1cbeda65ed2e5c127c4d2334f20550cb0bfb
7
+ data.tar.gz: 1f84dc4c065f51175c48332aacc3976b29a40c0db72f331bc79498ab6ae2dfcf1cb68aa1f1f94caa3ee54d42feabe59c81964e00eff2fda8af8d406141fd84a3
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- `FileDiscard` is a simple helper to make it easy for applications to move files to the correct trash folder. The location is determined by the platform and what file is being discarded (the latter is important so that files on other volumes/mountpoints are moved in to the appropriate trash folder).
1
+ FileDiscard is a simple helper to make it easy for applications to move files to the correct trash folder. The location is determined by the platform and what file is being discarded (the latter is important so that files on other volumes/mountpoints are moved in to the appropriate trash folder).
2
2
 
3
3
  ## Getting Started
4
4
 
@@ -9,17 +9,17 @@ Part of the `file_discard` gem is an executable that can be used as a drop-in re
9
9
  ```shell
10
10
  > discard
11
11
  Usage: discard [options] file ...
12
+ -d, --dir allow empty directories to be discarded
13
+ -r allow directories to be discarded recursively
14
+ -R, --recursive allow directories to be discarded recursively
12
15
  -v, --verbose show where files are discarded
13
16
  -h, --help show this message
14
17
  --version show version
15
18
 
16
19
  Options ignored to provide compatibility with "rm":
17
- -d
18
20
  -f
19
21
  -i
20
- -P
21
- -R
22
- -r
22
+ -I
23
23
  ```
24
24
 
25
25
  ### Using the Library
@@ -54,7 +54,7 @@ p.open('w') {|io| io.puts 'four'}
54
54
  Pathname.discard 'file4.txt'
55
55
  ```
56
56
 
57
- Another approach is to leave Ruby's [`File`](http://www.ruby-doc.org/core/File.html) and [`Pathname`](http://www.ruby-doc.org/stdlib/libdoc/pathname/rdoc/Pathname.html) classes alone and work directly with `FileDiscard`:
57
+ Another approach is to leave Ruby's [`File`](http://www.ruby-doc.org/core/File.html) and [`Pathname`](http://www.ruby-doc.org/stdlib/libdoc/pathname/rdoc/Pathname.html) classes alone and work directly with FileDiscard:
58
58
 
59
59
  ```ruby
60
60
  require 'file_discard'
@@ -73,7 +73,7 @@ FileDiscard.discard 'file6.txt'
73
73
 
74
74
  #### More Options
75
75
 
76
- Under the covers, `FileDiscard` makes use of [`FileUtils.mv`](http://ruby-doc.org/stdlib/libdoc/fileutils/rdoc/FileUtils.html#method-c-mv) and passes any other options through:
76
+ A call to discard can enable a report of the operation that is taking place:
77
77
 
78
78
  ```ruby
79
79
  require 'file_discard'
@@ -94,7 +94,9 @@ Pathname.discard 'file8.txt', verbose:true
94
94
  # ===> mv /path/to/file8.txt /Users/brad/.Trash/file8.txt
95
95
  ```
96
96
 
97
- Also of note is that `FileDiscard` will not blindly stomp on existing files already present in the trash. Instead, much like OS X's Finder, `FileDiscard` creates new file names based on the time when a collision occurs:
97
+ Other options can be enabled to allow discarding empty directories (:directory) or directories with items in them (:recursive).
98
+
99
+ Also of note is that FileDiscard will not blindly stomp on existing files already present in the trash. Instead, much like OS X's Finder, FileDiscard creates new file names based on the time when a collision occurs:
98
100
 
99
101
  ```ruby
100
102
  require 'file_discard'
@@ -154,16 +156,16 @@ Pathname.new('/path/to/my/home/a/trash/folder').children
154
156
  # ===> [#<Pathname:/path/to/my/home/a/trash/folder/myfile.txt>]
155
157
  ```
156
158
 
157
- Each `Discarder` is expected to provide the following (as passed to the base class initializer):
159
+ Each FileDiscard::Discarder is expected to provide the following (as passed to FileDiscard::Discarder.new):
158
160
 
159
- 1. `home`: An _absolute_ path to the home directory of the current user. `FileDiscard` will expand the path, so on systems that support it, special variables can be used (e.g. a tilde (~) will expand to the current user's home directory on OS X and Linux).
161
+ 1. `home`: An _absolute_ path to the home directory of the current user. FileDiscard will expand the path, so on systems that support it, special variables can be used (e.g. a tilde (~) will expand to the current user's home directory on OS X and Linux).
160
162
 
161
163
  2. `home_trash`: A _relative_ path where the trash is expected from the `home` directory.
162
164
 
163
165
  3. `mountpoint_trash_fmt`: A _relative_ path where the trash is expected from any given mountpoint. This string can optionally include a `%s` format specifier which will be replaced by the current user's numeric ID (ie. UID).
164
166
 
165
- The base `Discarder` will rely on comparison between mountpoints (as determined by [`Pathname#mountpoint?`](http://www.ruby-doc.org/stdlib/libdoc/pathname/rdoc/Pathname.html#method-i-mountpoint-3F)) to decide if the home trash should be used or if a shared trash for another mounted volume should be used. In other words, if the mountpoint of the file being trashed is _not_ the same as the `home` directory's mountpoint, the `Discarder` will use the trash located in the mountpoint associated with the file being discarded using the `mountpoint_trash_fmt` relative result as presented by the discarder.
167
+ The FileDiscard::Discarder will rely on comparison between mountpoints (as determined by [`Pathname#mountpoint?`](http://www.ruby-doc.org/stdlib/libdoc/pathname/rdoc/Pathname.html#method-i-mountpoint-3F)) to decide if the home trash should be used or if a shared trash for another mounted volume should be used. In other words, if the mountpoint of the file being trashed is _not_ the same as the `home` directory's mountpoint, the discarder will use the trash located in the mountpoint associated with the file being discarded using the `mountpoint_trash_fmt` relative result as presented by the discarder.
166
168
 
167
- If the trash location does not already exist, the `Discarder` will not automatically create it. Instead, it will raise a `Errno::ENOENT` exception for any discard request that attempts to move a file to a trash that does not exist. It is expected that the caller will ensure the trash directories are present before attempting to discard files.
169
+ If the trash location does not already exist, the FileDiscard::Discarder will not automatically create it. Instead, it will raise a FileDiscard::TrashMissing exception for any discard request that attempts to move a file to a trash that does not exist. It is expected that the caller will ensure the trash directories are present before attempting to discard files or make use of FileDiscard.create_trash_when_missing= to enable automatically creating missing trash folders.
168
170
 
169
- For a more complex example, check out the [`FileDiscard::LinuxDiscarder`](lib/file_discard.rb#L144-L164).
171
+ For a more complex example, see FileDiscard::LinuxDiscarder.
data/Rakefile CHANGED
@@ -1,57 +1,84 @@
1
1
  require 'rake'
2
2
  require 'rake/testtask'
3
3
  require 'rake/clean'
4
+ require 'rdoc/task'
4
5
  require 'rubygems/package_task'
5
6
 
6
7
  task default: :test
7
8
  task spec: :test
8
9
  task build: :package
9
10
 
10
- PKG_VERSION = '0.1.2'
11
+ PKG_VERSION = '0.1.3'
11
12
  NOW = Time.now.utc
12
13
 
13
14
  # delay updating the version file unless building the gem or package
15
+ VER_FN = 'lib/file_discard_version.rb'
14
16
  task :update_version do
15
- File.open('lib/file_discard_version.rb','w') do |f|
17
+ File.open(VER_FN,'w') do |f|
16
18
  f.puts <<EOF
17
19
  module FileDiscard
20
+ # :nodoc:
18
21
  VERSION = '#{PKG_VERSION}'
22
+ # :nodoc:
19
23
  RELEASE = '#{`git rev-parse --short HEAD`.chomp}:#{NOW.strftime('%Y%m%d%H%M%S')}'
20
24
  end
21
25
  EOF
22
26
  end
23
27
  end
24
- task package: :update_version
25
- task gem: :update_version
28
+
29
+ if File.exist? VER_FN
30
+ task package: :update_version
31
+ task gem: :update_version
32
+ else
33
+ Rake::Task[:update_version].execute
34
+ end
26
35
 
27
36
  Rake::TestTask.new do |t|
28
37
  t.pattern = "spec/*_spec.rb"
29
38
  end
30
39
 
40
+ RDOC_EXTRA_FILES = ['README.md','LICENSE']
41
+
42
+ RDoc::Task.new :rdoc do |rdoc|
43
+ rdoc.rdoc_files.include(*RDOC_EXTRA_FILES, 'lib/**/*.rb')
44
+ rdoc.title = 'FileDiscard'
45
+ rdoc.main = 'README.md'
46
+ rdoc.rdoc_dir = 'rdoc'
47
+ end
48
+
31
49
  def list_files
32
50
  if Dir.exist? '.git'
33
- `git ls-files -z`.split("\x0")
51
+ files = `git ls-files -z`.split("\x0")
34
52
  else
35
53
  # e.g. when installed and tasks are run from there...
36
- Dir.glob('**/*').select{|e| File.file? e}
54
+ files = Dir.glob('**/*').select{|e| File.file? e}
37
55
  end
56
+ files.delete '.gitignore'
57
+ files
38
58
  end
39
59
 
40
60
  spec = Gem::Specification.new do |s|
41
61
  s.name = 'file_discard'
42
- s.version = PKG_VERSION
43
- s.date = NOW.strftime('%Y-%m-%d')
44
- s.summary = 'Move files to the trash'
45
- s.description = 'Simple helper to move files to the trash folder'
46
- s.authors = ['Brad Robel-Forrest']
47
- s.email = 'brad+filediscard@gigglewax.com'
62
+ s.summary = 'Move files to the trash.'
63
+ s.description = 'Simple helper to move files to the trash folder.'
64
+
65
+ s.authors = ['Brad Robel-Forrest']
66
+ s.email = 'brad+filediscard@gigglewax.com'
67
+ s.homepage = 'https://github.com/bradrf/file_discard#readme'
68
+ s.license = 'MIT'
69
+
70
+ s.version = PKG_VERSION
71
+ s.date = NOW.strftime('%Y-%m-%d')
72
+
73
+ s.required_ruby_version = '>= 1.9.0'
74
+
48
75
  s.files = list_files << 'lib/file_discard_version.rb'
49
76
  s.test_files = s.files.grep(%r{^spec/})
50
77
  s.executables = %w(discard)
51
- s.homepage = 'https://github.com/bradrf/file_discard#readme'
52
- s.license = 'MIT'
53
78
 
54
- s.required_ruby_version = '>= 1.9.0'
79
+ s.has_rdoc = true
80
+ s.rdoc_options += ['--title','FileDiscard','--main','README.md']
81
+ s.extra_rdoc_files += RDOC_EXTRA_FILES
55
82
  end
56
83
 
57
84
  Gem::PackageTask.new(spec) do |pkg|
@@ -64,4 +91,4 @@ task :grip do
64
91
  exec 'grip --gfm --context=bradrf/file_discard'
65
92
  end
66
93
 
67
- CLOBBER.add 'coverage'
94
+ CLOBBER.include 'coverage', VER_FN
data/bin/discard CHANGED
@@ -9,6 +9,16 @@ parser = OptionParser.new do |opts|
9
9
  Version = FileDiscard::VERSION
10
10
  Release = FileDiscard::RELEASE
11
11
 
12
+ opts.on('-d', '--dir', 'allow empty directories to be discarded') do |v|
13
+ options.directory = v
14
+ end
15
+
16
+ [?r,?R].each do |o|
17
+ opts.on("-#{o}", '--recursive', 'allow directories to be discarded recursively') do |v|
18
+ options.recursive = v
19
+ end
20
+ end
21
+
12
22
  opts.on('-v', '--verbose', 'show where files are discarded') do |v|
13
23
  options.verbose = v
14
24
  end
@@ -25,7 +35,7 @@ parser = OptionParser.new do |opts|
25
35
 
26
36
  opts.separator('')
27
37
  opts.separator('Options ignored to provide compatibility with "rm":')
28
- [?d,?f,?i,?P,?R,?r].each {|a| opts.on("-#{a}")}
38
+ [?f,?i,?I].each {|o| opts.on("-#{o}")}
29
39
 
30
40
  opts.banner << ' file ...'
31
41
  end
data/lib/file_discard.rb CHANGED
@@ -30,12 +30,15 @@ module FileDiscard
30
30
  ######################################################################
31
31
  # Module Methods
32
32
 
33
+ # Extend Ruby's +File+ and +Pathname+ classes with Discarder.discard methods.
33
34
  def self.mix_it_in!
34
35
  [File, Pathname].each do |klass|
35
36
  klass.class_eval do
37
+ # :nodoc:
36
38
  def self.discard(*args)
37
39
  FileDiscard.discarder.discard(*args)
38
40
  end
41
+ # :nodoc:
39
42
  def discard(options = {})
40
43
  FileDiscard.discarder.discard(self, options)
41
44
  end
@@ -44,10 +47,12 @@ module FileDiscard
44
47
  self
45
48
  end
46
49
 
50
+ # See Discarder.discard for usage.
47
51
  def self.discard(*args)
48
52
  discarder.discard(*args)
49
53
  end
50
54
 
55
+ # Set the default discarder to use.
51
56
  def self.discarder=(discarder)
52
57
  @@discarder = discarder
53
58
  end
@@ -62,11 +67,27 @@ module FileDiscard
62
67
  end
63
68
  end
64
69
 
70
+ @@create_trash_when_missing = false
71
+
72
+ # Enable or disable the automatic creation of trash directories if they do not exist. The default
73
+ # is to raise a TrashMissing exception).
74
+ def self.create_trash_when_missing=(value)
75
+ @@create_trash_when_missing = value
76
+ end
77
+
78
+ def self.create_trash_when_missing
79
+ @@create_trash_when_missing
80
+ end
81
+
65
82
  ######################################################################
66
83
  # Discarders
67
84
 
85
+ # Raised when the configured trash directory for a given mountpoint does not exist.
86
+ class TrashMissing < Errno::ENOENT; end;
87
+
88
+ # The core logic for moving files to an appropriate trash directory.
68
89
  class Discarder
69
- SPECIAL_DIRS = ['.','..']
90
+ SPECIAL_DIRS = ['.','..'] # :nodoc:
70
91
 
71
92
  def initialize(home, home_trash, mountpoint_trash_fmt)
72
93
  home = pathname_for(home).expand_path
@@ -75,13 +96,39 @@ module FileDiscard
75
96
  @mountpoint_trash_fmt = mountpoint_trash_fmt
76
97
  end
77
98
 
78
- def discard(obj, move_options = {})
99
+ # Request that +obj+ be moved to the trash.
100
+ #
101
+ # +options+ - a hash of any of the following:
102
+ # * :directory - allow an empty directory to be discarded
103
+ # * :recursive - allow a directory to be discarded even if not empty
104
+ # * :verbose - report the move operation
105
+ #
106
+ # May raise:
107
+ # * Errno::EINVAL - +obj+ is "." or ".." which are not allowed to be discarded
108
+ # * Errno::EISDIR - +obj+ is a directory
109
+ # * Errno::ENOTEMPTY - +obj+ is a directory with children
110
+ # * Errno::ENOENT - +obj+ does not exist on the file system
111
+ # * TrashMissing - the trash directory for the mountpoint associated with +obj+ did not exist
112
+ #
113
+ def discard(obj, options = {})
79
114
  pn = pathname_for obj
80
- if SPECIAL_DIRS.include?(pn.basename.to_s)
81
- raise Errno::EINVAL.new(SPECIAL_DIRS.join(' and ') << ' may not be removed')
115
+ if pn.directory?
116
+ if SPECIAL_DIRS.include?(pn.basename.to_s)
117
+ raise Errno::EINVAL.new(SPECIAL_DIRS.join(' and ') << ' may not be removed')
118
+ end
119
+ unless options[:recursive]
120
+ raise Errno::EISDIR.new(pn.to_s) unless options[:directory]
121
+ raise Errno::ENOTEMPTY.new(pn.to_s) if pn.children.any?
122
+ end
82
123
  end
124
+
83
125
  trash = find_trash_for pn
84
- raise Errno::ENOENT.new(trash.to_s) unless trash.exist?
126
+ unless trash.exist?
127
+ raise TrashMissing.new(trash.to_s) unless FileDiscard.create_trash_when_missing
128
+ trash.mkpath
129
+ end
130
+
131
+ move_options = options.has_key?(:verbose) ? {verbose: options[:verbose]} : {}
85
132
  move(pn, trash, move_options)
86
133
  end
87
134
 
@@ -1,4 +1,6 @@
1
1
  module FileDiscard
2
- VERSION = '0.1.2'
3
- RELEASE = '6f7c646:20140606035238'
2
+ # :nodoc:
3
+ VERSION = '0.1.3'
4
+ # :nodoc:
5
+ RELEASE = '168a436:20140607032530'
4
6
  end
@@ -24,6 +24,7 @@ describe FileDiscard do
24
24
 
25
25
  @discarder = FileDiscard::OsxDiscarder.new(@home)
26
26
  FileDiscard.discarder = @discarder
27
+ FileDiscard.create_trash_when_missing = false
27
28
  end
28
29
 
29
30
  after do
@@ -49,7 +50,13 @@ describe FileDiscard do
49
50
 
50
51
  it 'should fail without trash' do
51
52
  f = File.new(@base.join('file.txt').to_s, 'w')
52
- ->{ f.discard }.must_raise Errno::ENOENT
53
+ ->{ f.discard }.must_raise FileDiscard::TrashMissing
54
+ end
55
+
56
+ it 'should support creating missing trash' do
57
+ FileDiscard.create_trash_when_missing = true
58
+ f = File.new(@base.join('file.txt').to_s, 'w')
59
+ f.discard
53
60
  end
54
61
 
55
62
  describe 'with trash in the home' do
@@ -62,6 +69,22 @@ describe FileDiscard do
62
69
  @trash.children(false).collect(&:to_s).sort
63
70
  end
64
71
 
72
+ it 'should conditionally allow removal of empty directories' do
73
+ d = @base.join('foozy')
74
+ d.mkdir
75
+ ->{ FileDiscard.discard(d) }.must_raise Errno::EISDIR
76
+ FileDiscard.discard(d, directory: true)
77
+ end
78
+
79
+ it 'should conditionally allow removal of non-empty directories' do
80
+ d = @base.join('foozy')
81
+ d.mkdir
82
+ f = d.join('stuff.txt')
83
+ f.open('w') {|io| io.puts 'stuff'}
84
+ ->{ FileDiscard.discard(d, directory: true) }.must_raise Errno::ENOTEMPTY
85
+ FileDiscard.discard(d, recursive: true)
86
+ end
87
+
65
88
  it 'should discard a file' do
66
89
  f = File.new(@base.join('file.txt').to_s, 'w')
67
90
  f.discard
metadata CHANGED
@@ -1,23 +1,24 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: file_discard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brad Robel-Forrest
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-06 00:00:00.000000000 Z
11
+ date: 2014-06-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Simple helper to move files to the trash folder
13
+ description: Simple helper to move files to the trash folder.
14
14
  email: brad+filediscard@gigglewax.com
15
15
  executables:
16
16
  - discard
17
17
  extensions: []
18
- extra_rdoc_files: []
18
+ extra_rdoc_files:
19
+ - README.md
20
+ - LICENSE
19
21
  files:
20
- - ".gitignore"
21
22
  - LICENSE
22
23
  - README.md
23
24
  - Rakefile
@@ -30,7 +31,11 @@ licenses:
30
31
  - MIT
31
32
  metadata: {}
32
33
  post_install_message:
33
- rdoc_options: []
34
+ rdoc_options:
35
+ - "--title"
36
+ - FileDiscard
37
+ - "--main"
38
+ - README.md
34
39
  require_paths:
35
40
  - lib
36
41
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -48,6 +53,6 @@ rubyforge_project:
48
53
  rubygems_version: 2.2.2
49
54
  signing_key:
50
55
  specification_version: 4
51
- summary: Move files to the trash
56
+ summary: Move files to the trash.
52
57
  test_files:
53
58
  - spec/file_discard_spec.rb
data/.gitignore DELETED
@@ -1,16 +0,0 @@
1
- lib/file_discard_version.rb
2
-
3
- *.gem
4
- *.rbc
5
- /coverage/
6
- /pkg/
7
-
8
- ## Documentation cache and generated files:
9
- /.yardoc/
10
- /_yardoc/
11
- /doc/
12
- /rdoc/
13
-
14
- .ruby-version
15
- .ruby-gemset
16
- .rvmrc