gomiko 0.0.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d45c618e4a7a89803cd1461e48fda3f8f46f67f6
4
+ data.tar.gz: b303721df183020acc7e8e588ca7673736651454
5
+ SHA512:
6
+ metadata.gz: e96e96d665e49eba35b7317598f509c5d106f6da8db1a5cc2d33d9a1cc23e8f685a0d5212deda2f26dea746bee5fc1902829e2452ba2633c0b0fd367019f9431
7
+ data.tar.gz: bdd7e442f59b1ce4047732c6de2bda6913f387a23c7d89e596a0874aa00cf14cabdd3e1a302561fed61e56259d6b2cabea256cefb78b43251332ed29eb1552fe
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/CHANGES ADDED
@@ -0,0 +1,6 @@
1
+ = Gomiko changelog
2
+
3
+ == Version 0.0.0 [2017-06-29] released
4
+
5
+ * initial release
6
+
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "rdoc", "~> 4.2"
10
+ gem "bundler", "~> 1.0"
11
+ gem "jeweler", "~> 2.3"
12
+ gem "simplecov", ">= 0"
13
+ gem 'test-unit', '~> 3.2'
14
+ gem 'filerenamer', '~> 0.0'
15
+ gem "tefil", '~> 0.1'
16
+ gem "builtinextension", '~> 0.1'
17
+ #gem "fakefs", '~> 0.11'
18
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2016 ippei94da
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ = Gomiko
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to gomiko
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
9
+ * Fork the project.
10
+ * Start a feature/bugfix branch.
11
+ * Commit and push until you are happy with your contribution.
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2016 ippei94da. See LICENSE.txt for
18
+ further details.
19
+
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
17
+ gem.name = "gomiko"
18
+ gem.homepage = "http://github.com/ippei94da/gomiko"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Trashbox with command line interface}
21
+ gem.description = %Q{
22
+ This Gem provides functionality similar to the Trash box in Windows OS.
23
+ The name 'gomiko' was originated from Japanese "gomibako".
24
+ If you think that it is "a shrine maiden(miko-san) who plays go", is it cute?
25
+ Gomiko provides the gomiko command;
26
+ it moves the file to ~/.trash with a change of rm.
27
+ And the command also can display the history of deletion and can execute undo.
28
+ Gomiko provides the Gomiko library.
29
+ It is designed so that the trash box can be handled from the Ruby program as well.
30
+ }
31
+ #この Gem は Windows のゴミ箱のような機能を提供します。
32
+ #gomiko という名前は日本語の「gomibako」を元につけられました。
33
+ #「碁を打つ巫女さん」だと思えば可愛いでしょ?
34
+ #gomiko は gomiko コマンドを提供します。
35
+ #gomiko コマンドは rm の変わりに ~/.trash にファイルを移動します。
36
+ #また削除履歴の表示や undo が備えられています。
37
+ #gomiko は、 Gomiko ライブラリを提供します。
38
+ #ゴミ箱が Ruby プログラム上からも扱えるように設計してあります。
39
+ gem.email = "ippei94da@gmail.com"
40
+ gem.authors = ["ippei94da"]
41
+ # dependencies defined in Gemfile
42
+ end
43
+ Jeweler::RubygemsDotOrgTasks.new
44
+
45
+ require 'rake/testtask'
46
+ Rake::TestTask.new(:test) do |test|
47
+ test.libs << 'lib' << 'test'
48
+ test.pattern = 'test/**/test_*.rb'
49
+ test.verbose = true
50
+ end
51
+
52
+ desc "Code coverage detail"
53
+ task :simplecov do
54
+ ENV['COVERAGE'] = "true"
55
+ Rake::Task['test'].execute
56
+ end
57
+
58
+ task :default => :test
59
+
60
+ require 'rdoc/task'
61
+ Rake::RDocTask.new do |rdoc|
62
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
63
+
64
+ rdoc.rdoc_dir = 'rdoc'
65
+ rdoc.title = "gomiko #{version}"
66
+ rdoc.rdoc_files.include('README*')
67
+ rdoc.rdoc_files.include('lib/**/*.rb')
68
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,96 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'thor'
4
+ require 'gomiko'
5
+ require 'pp'
6
+
7
+ class MyCommand < Thor
8
+ #def initialize
9
+ # @gomiko = Gomiko.new
10
+ #end
11
+
12
+ desc :rm, 'Throw files into trash directory'
13
+ #option :dry_run,
14
+ # desc: "Dry run, not extcute.",
15
+ # type: :boolean,
16
+ # default: false
17
+ def rm(* paths)
18
+ #paths.select do |path|
19
+ # File.exist? path
20
+ #end
21
+ Gomiko.new.throw(paths: paths)
22
+ end
23
+
24
+ desc :empty, 'Remove files in trash directory'
25
+ option "mtime",
26
+ #type: :numeric,
27
+ type: :string,
28
+ desc: 'Data was last modified n*24 hours ago.',
29
+ default: '0'
30
+ option "quiet", type: :boolean,
31
+ default: false
32
+ def empty(* ids)
33
+ Gomiko.new.empty(ids: ids,
34
+ mtime: options[:mtime].to_i,
35
+ verbose: ! options[:quiet])
36
+ end
37
+
38
+ desc :undo, 'Undo removed files from trash directory'
39
+ def undo(* dirs)
40
+ g = Gomiko.new
41
+
42
+ if Dir.glob("#{@trashdir}/*").empty?
43
+ puts "Nothing to undo in #{@trashdir}"
44
+ exit
45
+ end
46
+
47
+ dirs = [g.list[-1]] if dirs.empty?
48
+ dirs.each do |dir|
49
+ begin
50
+ g.undo(dir)
51
+ rescue Errno::EACCES
52
+ puts "Permission denined: #{dir}"
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+ ## list
59
+ desc :ls, 'Show trash directory'
60
+ option "long", type: :boolean,
61
+ default: false,
62
+ aliases: 'l'
63
+ def ls(* ids)
64
+ g = Gomiko.new
65
+ if g.list.empty?
66
+ puts "Nothing in ~/.trash"
67
+ exit
68
+ end
69
+ ids = g.list if ids.empty?
70
+ if options[:long]
71
+ ids.each do |id|
72
+ puts '-' * 60
73
+ results = g.info(id)
74
+ printf("%-10s: %s\n", 'size', results[0])
75
+ printf("%-10s: %s\n", 'id', results[1])
76
+ printf("%-10s: %s\n", 'guess path', results[2])
77
+ #pp results[3]
78
+ puts '+----- filetype in trash'
79
+ puts '| +--- filetype in original path'
80
+ puts '| | +- original path'
81
+ Tefil::ColumnFormer.new.form( results[3])
82
+ puts
83
+ end
84
+ else
85
+ results = [['size', 'ID', 'original paths[ ...]']]
86
+ #pp ids
87
+ results += ids.map do |id|
88
+ g.info(id)[0..2]
89
+ end
90
+ Tefil::ColumnFormer.new.form(results)
91
+ end
92
+ end
93
+ end
94
+
95
+ MyCommand.start(ARGV)
96
+
@@ -0,0 +1,250 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require 'fileutils'
5
+ require 'pathname'
6
+ require 'tefil'
7
+ require 'find'
8
+
9
+ #
10
+ #
11
+ #
12
+ class Gomiko
13
+
14
+ attr_reader :trashdir
15
+
16
+ #class NotFoundError < StandardError; end
17
+
18
+ def initialize(dir: nil, verbose: true)
19
+ if dir
20
+ @trashdir = dir
21
+ else
22
+ if ENV['UID'] == 0 # this is needed for 'su -m'
23
+ @trashdir ='/root/.trash'
24
+ else
25
+ @trashdir = ENV['HOME'] + "/.trash"
26
+ end
27
+ end
28
+ FileUtils.mkdir_p(@trashdir)
29
+ end
30
+
31
+ # If paths includes exist and not exist files,
32
+ # throw all exist file and report not exist files.
33
+ def throw(paths: , time: Time.new, verbose: true)
34
+ paths = paths.select do |path|
35
+ flag = FileTest.exist? path
36
+ unless flag
37
+ if verbose
38
+ puts "gomiko rm: cannot remove '#{path}': No such file or directory"
39
+ end
40
+ end
41
+ flag
42
+ end
43
+ return if paths.empty?
44
+
45
+ trash_subdir = mkdir_time(time)
46
+ paths.each do |path|
47
+ dst = trash_subdir + File.expand_path(path)
48
+ dst_dir = File.dirname dst
49
+ FileUtils.mkdir_p(dst_dir)
50
+ FileUtils.mv(path, dst_dir + '/', :verbose => verbose)
51
+ File.utime(time, time, trash_subdir)
52
+ end
53
+ end
54
+
55
+ def empty(ids: [], mtime: 0, time: Time.now, verbose: true)
56
+ ids.map! {|v| path2id v}
57
+ ids = list if ids.empty?
58
+ dirs = ids.map {|v| @trashdir + '/' + v}
59
+ dirs = dirs.select { |v|
60
+ begin
61
+ File.mtime("#{v}") - time < 86400 * mtime
62
+ rescue Errno::ENOENT
63
+ puts "Not found: #{v}"
64
+ end
65
+ }
66
+ if dirs.empty?
67
+ puts "No directory was emptied."
68
+ else
69
+ dirs.each {|path| FileUtils.rm_rf(path, :verbose => verbose)}
70
+ end
71
+ end
72
+
73
+ #def latest
74
+
75
+ def undo(id, verbose: true, io: $stdout)
76
+ id = path2id id
77
+ fullpath = Pathname.new(@trashdir) + id
78
+ Dir.glob("#{fullpath}/*").sort.each do |path|
79
+ graft(fullpath, '', dst_root: '/', verbose: verbose)
80
+ end
81
+ if Dir.glob("#{fullpath}/**/*").find {|path| FileTest.file? path}
82
+ io.puts "Unable to complete undo: #{fullpath}"
83
+ else
84
+ FileUtils.rm_rf fullpath # risky?
85
+ end
86
+ end
87
+
88
+ # Example of return data:
89
+ #236K 20170623-021233/home/ippei/private/ero/inbox/20170623-015917 ...
90
+ def info(id)
91
+ id = path2id id
92
+ cur_trash_dir = Pathname.new(@trashdir) + id
93
+ results = []
94
+ results << `du --human-readable --max-depth=0 #{cur_trash_dir}`.split(' ')[0]
95
+ results << id
96
+ #pp results
97
+
98
+ # 元のパスにファイルが存在しないものを抽出。
99
+ trash_paths = Dir.glob("#{cur_trash_dir}/**/*", File::FNM_DOTMATCH).sort
100
+
101
+ # '/.', で終わるのを除外
102
+ trash_paths = trash_paths.select { |t_path| ! /\/\.$/.match t_path }
103
+
104
+ #memo: ディレクトリのタイムスタンプ
105
+ #・atime … 最終アクセス時刻 (access time)
106
+ #・mtime … 最終変更時刻 (modify time)
107
+ #・ctime … 最終ステータス変更時刻 (change time)
108
+ #これらは作成日時じゃない。birthtime があるファイルシステムもあるが、Linux の ext4 とかはムリ。
109
+ # 存在しなければ、移動してきた
110
+ # 存在するならば、
111
+ # ゴミパスがディレクトリならば、
112
+ # 元パスがディレクトリならば
113
+ # 元パスの更新時刻が新しければ、新たに作られた
114
+ # 元パスの更新時刻が古ければ、削除次に作られたものなので無視
115
+ # 元パスがファイルならば、新たに作られた
116
+ # ゴミパスがファイルならば、
117
+ # 元パスがディレクトリならば、新たに作られた
118
+ # 元パスがファイルならば新たに作られ、重複。
119
+ #title_long = ['Exist']
120
+ #
121
+ #rm_target_candidates = []
122
+ candidates = [] # fo rm target
123
+ results_long = []
124
+ trash_paths.each do |trash_path|
125
+ orig_path = trash_path.sub(/^#{cur_trash_dir}/, '')
126
+ trash_type = ftype_str(trash_path)
127
+ if FileTest.exist? orig_path
128
+ orig_type = ftype_str(orig_path)
129
+
130
+ unless File.ftype(trash_path) == File.ftype(orig_path)
131
+ candidates << trash_path
132
+ end
133
+ ## waiting for implementing 'birthtime' on every system...
134
+ #if File.ctime(orig_path) < File.ctime(trash_path)
135
+ # compare_str = '<'
136
+ #elsif File.ctime(orig_path) > File.ctime(trash_path)
137
+ # # create after 'rm'
138
+ # compare_str = '>'
139
+ # candidates << trash_path
140
+ #else
141
+ # # create at the same time of 'rm'. rare event.
142
+ # compare_str = '='
143
+ # candidates << trash_path
144
+ #end
145
+ else
146
+ candidates << trash_path
147
+ orig_type = ' '
148
+ end
149
+ results_long << [ trash_type, orig_type,
150
+ trash_path.sub(/^#{cur_trash_dir}/, '')
151
+ ]
152
+ end
153
+
154
+ ## if no candidate, last file is adopted.
155
+ if trash_paths.empty?
156
+ results << '(empty)'
157
+ results << []
158
+ else
159
+ trash_paths
160
+ candidates = [trash_paths[-1] + ' (exist in original path)'] if candidates.empty?
161
+ candidates = candidates.map {|path|
162
+ tmp = path.sub(/^#{cur_trash_dir}/, '')
163
+ tmp += '/' if FileTest.directory? path
164
+ tmp
165
+ }
166
+ candidates = candidates.select {|path| ! FileTest.exist? path }
167
+ results << candidates[0]
168
+
169
+ ## output '...' when multiple.
170
+ candidates = candidates.select{|pa| ! pa.include? candidates[0]}
171
+ #pp candidates; exit
172
+ results[-1] += ' ...' unless candidates.empty?
173
+ results << results_long
174
+ #pp results
175
+ end
176
+ results
177
+ end
178
+
179
+ # ls, list
180
+ def list
181
+ Dir.glob("#{@trashdir}/*").map do |path|
182
+ path.sub(/^#{@trashdir}\//, '').split[0]
183
+ end . sort
184
+ end
185
+
186
+ private
187
+
188
+ # e.g., root_path = ~/.trash/20170123-012345
189
+ # path = home/ippei/foo
190
+ def graft(src_root, path, dst_root: '/', verbose: true)
191
+ src_root = Pathname.new(src_root)
192
+ path = Pathname.new(path)
193
+ dst_path = Pathname.new(dst_root) + path
194
+
195
+ if FileTest.directory? (dst_path)
196
+ Dir.glob("#{src_root + path}/*") do |next_path|
197
+ next_path = Pathname.new(next_path).relative_path_from(src_root)
198
+ graft(src_root, next_path, dst_root: dst_root, verbose: verbose)
199
+ end
200
+ elsif FileTest.exist? (dst_path)
201
+ puts "normal file already exist: #{dst_path}" if verbose
202
+ else
203
+ #pp src_root + path
204
+ #pp dst_path
205
+ FileUtils.mv(src_root + path, dst_path, noop: false, verbose: verbose )
206
+ end
207
+ return
208
+ end
209
+
210
+ def mkdir_time(time)
211
+ time_str = time.strftime('/%Y%m%d-%H%M%S')
212
+ dirname = nil
213
+
214
+ i = 0
215
+ while ! dirname
216
+
217
+ begin
218
+ #self.ls
219
+ try_name = @trashdir + "#{time_str}"
220
+ try_name += "-#{i}" if 1 <= i
221
+ #pp try_name
222
+ FileUtils.mkdir(try_name)
223
+ dirname = try_name
224
+ rescue Errno::EEXIST
225
+ i += 1
226
+ next
227
+ end
228
+ end
229
+ dirname
230
+ end
231
+
232
+ def ftype_str(path)
233
+ if File.directory? path
234
+ result = '/'
235
+ elsif File.symlink? path
236
+ result = '@'
237
+ elsif File.file? path
238
+ result = '.'
239
+ else
240
+ result = '?'
241
+ end
242
+ result
243
+ end
244
+
245
+ def path2id(path)
246
+ path.sub(/^#{@trashdir}\//, '')
247
+ end
248
+
249
+ end
250
+
@@ -0,0 +1 @@
1
+ gomibako
@@ -0,0 +1,33 @@
1
+ require 'simplecov'
2
+
3
+ module SimpleCov::Configuration
4
+ def clean_filters
5
+ @filters = []
6
+ end
7
+ end
8
+
9
+ SimpleCov.configure do
10
+ clean_filters
11
+ load_adapter 'test_frameworks'
12
+ end
13
+
14
+ ENV["COVERAGE"] && SimpleCov.start do
15
+ add_filter "/.rvm/"
16
+ end
17
+ require 'rubygems'
18
+ require 'bundler'
19
+ begin
20
+ Bundler.setup(:default, :development)
21
+ rescue Bundler::BundlerError => e
22
+ $stderr.puts e.message
23
+ $stderr.puts "Run `bundle install` to install missing gems"
24
+ exit e.status_code
25
+ end
26
+ require 'test/unit'
27
+
28
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
29
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
30
+ require 'gomiko'
31
+
32
+ class Test::Unit::TestCase
33
+ end
@@ -0,0 +1,320 @@
1
+ #! /usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require "pp"
5
+ require "helper"
6
+
7
+ class Gomiko
8
+ public :graft, :mkdir_time, :path2id
9
+ end
10
+
11
+ class TC_Gomiko < Test::Unit::TestCase
12
+
13
+ TMPDIR = "#{Dir.pwd}/test/tmp"
14
+ WORKDIR = "#{TMPDIR}/work"
15
+ TRASHDIR = "#{TMPDIR}/trash"
16
+
17
+ #pp WORKDIR; exit
18
+ def setup
19
+ FileUtils.rm_rf TMPDIR
20
+ FileUtils.mkdir_p WORKDIR
21
+ @g00 = Gomiko.new(dir: TRASHDIR, verbose: false)
22
+ end
23
+
24
+ def teardown
25
+ FileUtils.rm_rf TMPDIR
26
+ end
27
+
28
+ def test_initialize
29
+ FileUtils.rm_rf TRASHDIR
30
+ assert_false(FileTest.directory? TRASHDIR)
31
+ Gomiko.new(dir: TRASHDIR, verbose: false)
32
+ assert(FileTest.directory? TRASHDIR)
33
+ end
34
+
35
+ def test_throw
36
+ # remove file
37
+ a_relpath = 'test/tmp/a.txt'
38
+ a_fullpath = File.expand_path 'test/a.txt'
39
+ a_fullpath_dirname = File.dirname a_fullpath
40
+ FileUtils.touch a_relpath
41
+ @g00.throw(paths: [a_relpath], time: Time.new(2017, 1, 23, 12, 34, 56), verbose: false)
42
+ assert(FileTest.directory? "#{TRASHDIR}/20170123-123456#{a_fullpath_dirname}")
43
+ assert_false(FileTest.exist? a_relpath)
44
+ assert(FileTest.exist? ("#{TRASHDIR}/20170123-123456#{a_fullpath_dirname}"))
45
+ assert_equal( Time.new(2017, 1, 23, 12, 34, 56),
46
+ File.mtime("#{TRASHDIR}/20170123-123456"))
47
+
48
+
49
+
50
+ # remove directory
51
+ setup
52
+ a_relpath = 'test/tmp/b/a.txt'
53
+ a_fullpath = File.expand_path 'test/tmp/b/a.txt'
54
+ a_fullpath_dirname = File.dirname a_fullpath
55
+ FileUtils.mkdir_p 'test/tmp/b'
56
+ FileUtils.touch a_relpath
57
+ @g00.throw(paths: [a_relpath], time: Time.new(2017, 1, 23, 12, 34, 56), verbose: false)
58
+ assert(FileTest.directory? "#{TRASHDIR}/20170123-123456#{a_fullpath_dirname}")
59
+ assert_false(FileTest.exist? a_relpath)
60
+ assert(FileTest.exist? ("#{TRASHDIR}/20170123-123456#{a_fullpath_dirname}"))
61
+
62
+ @g00.throw(paths: [a_relpath, 'not_exist'],
63
+ time: Time.new(2017, 1, 23, 12, 34, 56),
64
+ verbose: false)
65
+ assert_false(FileTest.exist? (a_relpath))
66
+ end
67
+
68
+ def test_empty1
69
+ a_relpath = 'test/tmp/a.txt'
70
+ a_fullpath = File.expand_path 'test/tmp/a.txt'
71
+ FileUtils.touch a_relpath
72
+ @g00.throw(paths: [a_relpath], time: Time.new(2017, 1, 23, 12, 34, 56), verbose: false)
73
+ assert(File.exist? "#{TRASHDIR}/20170123-123456#{a_fullpath}")
74
+ @g00.empty(verbose: false)
75
+ assert_false(File.exist? "#{TRASHDIR}/20170123-123456#{a_fullpath}")
76
+ end
77
+
78
+ def test_empty2
79
+ a_relpath = 'test/tmp/a.txt'
80
+ b_relpath = 'test/tmp/b.txt'
81
+ a_fullpath = File.expand_path 'test/tmp/a.txt'
82
+ b_fullpath = File.expand_path 'test/tmp/b.txt'
83
+ FileUtils.touch a_relpath
84
+ FileUtils.touch b_relpath
85
+ @g00.throw(paths: [a_relpath], time: Time.new(2017, 1, 23, 12, 34, 56), verbose: false)
86
+ @g00.throw(paths: [b_relpath], time: Time.new(2017, 1, 23, 12, 34, 57), verbose: false)
87
+ assert(File.exist? "#{TRASHDIR}/20170123-123456#{a_fullpath}")
88
+ assert(File.exist? "#{TRASHDIR}/20170123-123457#{b_fullpath}")
89
+ @g00.empty(ids: ['20170123-123456'], verbose: false)
90
+ assert_false(File.exist? "#{TRASHDIR}/20170123-123456#{a_fullpath}")
91
+ assert (File.exist? "#{TRASHDIR}/20170123-123457#{b_fullpath}")
92
+ end
93
+
94
+ def test_empty3 #mtime
95
+ # mtime option
96
+ a_relpath = 'test/tmp/a.txt'
97
+ a_fullpath = File.expand_path 'test/tmp/a.txt'
98
+ FileUtils.touch a_relpath
99
+ @g00.throw(paths: [a_relpath],
100
+ time: Time.new(2017, 6, 15, 00, 00, 00),
101
+ verbose: false)
102
+
103
+ assert(File.exist? "#{TRASHDIR}/20170615-000000#{a_fullpath}")
104
+ @g00.empty(mtime: -10,
105
+ time: Time.new(2017, 6, 24, 23, 59, 59),
106
+ verbose: false)
107
+ assert(File.exist? "#{TRASHDIR}/20170615-000000#{a_fullpath}")
108
+ @g00.empty(mtime: -10,
109
+ time: Time.new(2017, 6, 25, 00, 00, 00),
110
+ verbose: false)
111
+ assert_false(File.exist? "#{TRASHDIR}/20170123-123456#{a_fullpath}")
112
+ end
113
+
114
+ def test_empty4 #mtime
115
+ # mtime option
116
+ a_relpath = 'test/tmp/a.txt'
117
+ b_relpath = 'test/tmp/b.txt'
118
+ c_relpath = 'test/tmp/c.txt'
119
+ d_relpath = 'test/tmp/d.txt'
120
+ a_fullpath = File.expand_path 'test/tmp/a.txt'
121
+ b_fullpath = File.expand_path 'test/tmp/b.txt'
122
+ c_fullpath = File.expand_path 'test/tmp/c.txt'
123
+ d_fullpath = File.expand_path 'test/tmp/d.txt'
124
+ FileUtils.touch a_relpath
125
+ FileUtils.touch b_relpath
126
+ FileUtils.touch c_relpath
127
+ FileUtils.touch d_relpath
128
+
129
+ @g00.throw(paths: [a_relpath],
130
+ time: Time.new(2017, 6, 15, 00, 00, 00),
131
+ verbose: false)
132
+ @g00.throw(paths: [b_relpath],
133
+ time: Time.new(2017, 6, 15, 12, 00, 00),
134
+ verbose: false)
135
+ @g00.throw(paths: [c_relpath],
136
+ time: Time.new(2017, 7, 15, 00, 00, 00),
137
+ verbose: false)
138
+ @g00.throw(paths: [d_relpath],
139
+ time: Time.new(2017, 7, 15, 12, 00, 00),
140
+ verbose: false)
141
+
142
+ assert(File.exist? "#{TRASHDIR}/20170615-000000#{a_fullpath}")
143
+ assert(File.exist? "#{TRASHDIR}/20170615-120000#{b_fullpath}")
144
+ assert(File.exist? "#{TRASHDIR}/20170715-000000#{c_fullpath}")
145
+ assert(File.exist? "#{TRASHDIR}/20170715-120000#{d_fullpath}")
146
+ @g00.empty(ids: %w(20170615-000000 20170715-000000),
147
+ mtime: -3,
148
+ time: Time.new(2017, 7, 16, 01, 00, 00),
149
+ verbose: false)
150
+ assert_false(File.exist? "#{TRASHDIR}/20170615-000000#{a_fullpath}")
151
+ assert (File.exist? "#{TRASHDIR}/20170615-120000#{b_fullpath}")
152
+ assert (File.exist? "#{TRASHDIR}/20170715-000000#{c_fullpath}")
153
+ assert (File.exist? "#{TRASHDIR}/20170715-120000#{d_fullpath}")
154
+ end
155
+
156
+ def test_undo1
157
+ FileUtils.mkdir_p "#{WORKDIR}/a/b"
158
+ FileUtils.touch "#{WORKDIR}/a/b/c.txt"
159
+ FileUtils.touch "#{WORKDIR}/a/b/d.txt"
160
+ @g00.throw(paths: ["#{WORKDIR}/a/b/c.txt"],
161
+ time: Time.new(2017, 1, 23, 12, 34, 56),
162
+ verbose: false)
163
+ @g00.throw(paths: ["#{WORKDIR}/a/b/d.txt"],
164
+ time: Time.new(2017, 1, 23, 12, 34, 57),
165
+ verbose: false)
166
+ assert(File.exist? "#{TRASHDIR}/20170123-123456/#{WORKDIR}/a/b/c.txt")
167
+ assert(File.exist? "#{TRASHDIR}/20170123-123457/#{WORKDIR}/a/b/d.txt")
168
+ @g00.undo("20170123-123456", verbose: false)
169
+ assert_false(File.exist? "#{TRASHDIR}/20170123-123456/#{WORKDIR}/a/b/c.txt")
170
+ assert (File.exist? "#{TRASHDIR}/20170123-123457/#{WORKDIR}/a/b/d.txt")
171
+ assert (File.exist? "#{WORKDIR}/a/b/c.txt")
172
+ end
173
+
174
+ def test_undo2
175
+ FileUtils.mkdir_p "#{WORKDIR}/a/b"
176
+ FileUtils.touch "#{WORKDIR}/a/b/c.txt"
177
+ FileUtils.touch "#{WORKDIR}/a/b/d.txt"
178
+ @g00.throw(paths: ["#{WORKDIR}/a/b/c.txt"],
179
+ time: Time.new(2017, 1, 23, 12, 34, 56),
180
+ verbose: false)
181
+ @g00.throw(paths: ["#{WORKDIR}/a/b/d.txt"],
182
+ time: Time.new(2017, 1, 23, 12, 34, 57),
183
+ verbose: false)
184
+ assert(File.exist? "#{TRASHDIR}/20170123-123456/#{WORKDIR}/a/b/c.txt")
185
+ assert(File.exist? "#{TRASHDIR}/20170123-123457/#{WORKDIR}/a/b/d.txt")
186
+ @g00.undo("#{TRASHDIR}/20170123-123456", verbose: false)
187
+ assert_false(File.exist? "#{TRASHDIR}/20170123-123456/#{WORKDIR}/a/b/c.txt")
188
+ assert (File.exist? "#{TRASHDIR}/20170123-123457/#{WORKDIR}/a/b/d.txt")
189
+ assert (File.exist? "#{WORKDIR}/a/b/c.txt")
190
+ end
191
+
192
+ # ls, list
193
+ def test_list1
194
+ a_relpath = 'test/tmp/a.txt'
195
+ FileUtils.touch a_relpath
196
+ @g00.throw(paths: [a_relpath],
197
+ time: Time.new(2017, 1, 23, 12, 34, 56),
198
+ verbose: false)
199
+ a_relpath = 'test/tmp/a.txt'
200
+ FileUtils.touch a_relpath
201
+ @g00.throw(paths: [a_relpath],
202
+ time: Time.new(2017, 1, 23, 12, 34, 57),
203
+ verbose: false)
204
+ corrects = ["20170123-123456", "20170123-123457" ]
205
+ assert_equal(corrects, @g00.list)
206
+ end
207
+
208
+ def test_list2
209
+ FileUtils.mkdir_p @g00.trashdir + '20170628-000000'
210
+ #pp @g00.list
211
+ #assert_equal(corrects, @g00.list)
212
+ end
213
+
214
+ def test_info1
215
+ path = "#{WORKDIR}/a.txt"
216
+ FileUtils.touch path
217
+ @g00.throw(paths: [path],
218
+ time: Time.new(2017, 1, 23, 12, 34, 56),
219
+ verbose: false)
220
+ #size is dependent on system
221
+ results = @g00.info("20170123-123456")
222
+ assert_equal('20170123-123456', results[1])
223
+ assert_equal(path, results[2])
224
+ #pp results[3]
225
+ corrects = [
226
+ ["/", "/", "/home"],
227
+ ["/", "/", "/home/ippei"],
228
+ ["/", "/", "/home/ippei/git"],
229
+ ["/", "/", "/home/ippei/git/gomiko"],
230
+ ["/", "/", "/home/ippei/git/gomiko/test"],
231
+ ["/", "/", "/home/ippei/git/gomiko/test/tmp"],
232
+ ["/", "/", "/home/ippei/git/gomiko/test/tmp/work"],
233
+ [".", " ", "/home/ippei/git/gomiko/test/tmp/work/a.txt"]
234
+ ]
235
+ assert_equal(corrects, results[3])
236
+
237
+ end
238
+
239
+ def test_info2
240
+ path = "#{WORKDIR}/.a"
241
+ FileUtils.touch path
242
+ @g00.throw(paths: [path],
243
+ time: Time.new(2017, 1, 23, 12, 34, 56),
244
+ verbose: false)
245
+ #size is dependent on system
246
+ results = @g00.info("20170123-123456")
247
+ assert_equal('20170123-123456', results[1])
248
+ assert_equal(path, results[2])
249
+ end
250
+
251
+ def test_info3
252
+ FileUtils.mkdir_p "#{WORKDIR}/a/"
253
+ FileUtils.touch "#{WORKDIR}/a/b"
254
+ @g00.throw(paths: ["#{WORKDIR}/a"],
255
+ time: Time.new(2017, 1, 23, 12, 34, 56),
256
+ verbose: false)
257
+ #size is dependent on system
258
+ results = @g00.info("20170123-123456")
259
+ assert_equal('20170123-123456', results[1])
260
+ assert_equal("#{WORKDIR}/a/", results[2])
261
+ end
262
+
263
+ def test_info4
264
+ FileUtils.mkdir_p "#{WORKDIR}/a/"
265
+ FileUtils.touch "#{WORKDIR}/a/b"
266
+ FileUtils.mkdir_p "#{WORKDIR}/c/"
267
+ FileUtils.touch "#{WORKDIR}/c/d"
268
+ @g00.throw(paths: ["#{WORKDIR}/a", "#{WORKDIR}/c"],
269
+ time: Time.new(2017, 1, 23, 12, 34, 56),
270
+ verbose: false)
271
+ #size is dependent on system
272
+ results = @g00.info("20170123-123456")
273
+ assert_equal('20170123-123456', results[1])
274
+ assert_equal("#{WORKDIR}/a/ ...", results[2])
275
+ end
276
+
277
+ def test_info5
278
+ FileUtils.mkdir_p "#{WORKDIR}/a/b"
279
+ @g00.throw(paths: ["#{WORKDIR}/a", "#{WORKDIR}/c"],
280
+ time: Time.new(2017, 1, 23, 12, 34, 56),
281
+ verbose: false)
282
+ FileUtils.mkdir_p "#{WORKDIR}/a/b"
283
+ results = @g00.info("20170123-123456")
284
+ #pp results
285
+ assert_equal('20170123-123456', results[1])
286
+ assert_equal("#{WORKDIR}/a/b (exist in original path)", results[2])
287
+ end
288
+
289
+ def test_graft
290
+ FileUtils.rm_rf( 'test/tmp/graft')
291
+ FileUtils.mkdir_p('test/tmp/graft/src/a/b/c')
292
+ FileUtils.mkdir_p('test/tmp/graft/dst/a/b/c')
293
+ FileUtils.touch( 'test/tmp/graft/src/a/b/c/d.txt')
294
+ #
295
+ @g00.graft('test/tmp/graft/src',
296
+ 'a',
297
+ dst_root: "test/tmp/graft/dst",
298
+ verbose: false)
299
+ assert(FileTest.directory?('test/tmp/graft/dst/a/b/c/'))
300
+ assert(FileTest.file?('test/tmp/graft/dst/a/b/c/d.txt'))
301
+ end
302
+
303
+ def test_mkdir_time
304
+ assert_false(FileTest.directory? "#{TRASHDIR}/20170123-123456")
305
+ @g00.mkdir_time(Time.new(2017, 1, 23, 12, 34, 56))
306
+ assert( FileTest.directory? "#{TRASHDIR}/20170123-123456")
307
+ assert_false(FileTest.directory? "#{TRASHDIR}/20170123-123456-1")
308
+ @g00.mkdir_time(Time.new(2017, 1, 23, 12, 34, 56))
309
+ assert( FileTest.directory? "#{TRASHDIR}/20170123-123456")
310
+ assert( FileTest.directory? "#{TRASHDIR}/20170123-123456-1")
311
+
312
+ end
313
+
314
+ def test_path2id
315
+ assert_equal("20170123-123456", @g00.path2id("#{TRASHDIR}/20170123-123456"))
316
+ assert_equal("20170123-123456", @g00.path2id("20170123-123456"))
317
+ end
318
+
319
+ end
320
+
metadata ADDED
@@ -0,0 +1,176 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gomiko
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - ippei94da
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rdoc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.2'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: jeweler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: test-unit
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.2'
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'
83
+ - !ruby/object:Gem::Dependency
84
+ name: filerenamer
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: tefil
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.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'
111
+ - !ruby/object:Gem::Dependency
112
+ name: builtinextension
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.1'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.1'
125
+ description: "\n This Gem provides functionality similar to the Trash box in Windows
126
+ OS.\n The name 'gomiko' was originated from Japanese \"gomibako\".\n If you
127
+ think that it is \"a shrine maiden(miko-san) who plays go\", is it cute?\n Gomiko
128
+ provides the gomiko command;\n it moves the file to ~/.trash with a change of
129
+ rm.\n And the command also can display the history of deletion and can execute
130
+ undo.\n Gomiko provides the Gomiko library.\n It is designed so that the trash
131
+ box can be handled from the Ruby program as well.\n "
132
+ email: ippei94da@gmail.com
133
+ executables:
134
+ - gomiko
135
+ extensions: []
136
+ extra_rdoc_files:
137
+ - LICENSE.txt
138
+ - README.rdoc
139
+ files:
140
+ - ".document"
141
+ - CHANGES
142
+ - Gemfile
143
+ - LICENSE.txt
144
+ - README.rdoc
145
+ - Rakefile
146
+ - VERSION
147
+ - bin/gomiko
148
+ - lib/gomiko.rb
149
+ - test/.gitignore
150
+ - test/helper.rb
151
+ - test/test_gomiko.rb
152
+ homepage: http://github.com/ippei94da/gomiko
153
+ licenses:
154
+ - MIT
155
+ metadata: {}
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ requirements: []
171
+ rubyforge_project:
172
+ rubygems_version: 2.5.1
173
+ signing_key:
174
+ specification_version: 4
175
+ summary: Trashbox with command line interface
176
+ test_files: []