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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/CHANGES +6 -0
- data/Gemfile +18 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +68 -0
- data/VERSION +1 -0
- data/bin/gomiko +96 -0
- data/lib/gomiko.rb +250 -0
- data/test/.gitignore +1 -0
- data/test/helper.rb +33 -0
- data/test/test_gomiko.rb +320 -0
- metadata +176 -0
checksums.yaml
ADDED
@@ -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
|
data/.document
ADDED
data/CHANGES
ADDED
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
|
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.rdoc
ADDED
@@ -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
|
+
|
data/Rakefile
ADDED
@@ -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
|
data/bin/gomiko
ADDED
@@ -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
|
+
|
data/lib/gomiko.rb
ADDED
@@ -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
|
+
|
data/test/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
gomibako
|
data/test/helper.rb
ADDED
@@ -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
|
data/test/test_gomiko.rb
ADDED
@@ -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: []
|