gomiko 0.0.1 → 0.0.2

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: b4226809c289bd119c0709dd3bbaf6567f073090
4
- data.tar.gz: e7ba437969fa6110f09e81b0a6434fe5c84a9eee
3
+ metadata.gz: f8b7fe5fb79a9bb5367443536a87b5921a40418e
4
+ data.tar.gz: 82d3c68c49147dc2fc47424e931beb28be0288b2
5
5
  SHA512:
6
- metadata.gz: 9951ba37e62caec09a4856fe704b9eb62edcd7e8523fed13c3d5b37ad3faee61030f45527f3148271a566b1ea58e1b006b68cba82e17500bbad74e7b9bdfa187
7
- data.tar.gz: fb742c25708beb55d4e821171f34a85fad18cadb353c9c6ab13e1d44c2a05f812388b2ba8229995364cac3212ff281b86730fef81adc80a1454b428909194e3a
6
+ metadata.gz: 0a35f1a4f92507c422c6ef3b25194c15352e998803b6517b5f0ce0d0f54998e64d3f5af371f73366fb9f48cff99a5033872e49bab9cebc0a8ca63340c4b56bd2
7
+ data.tar.gz: a9fb7dac36de0007a651033542f0645b981c0626dbe7be10fde69372ad70b1826142062a03ca64df0e1e97f33cc7b4c90be5866adaae089dddaa86fff9b4ca8d
data/CHANGES CHANGED
@@ -1,5 +1,9 @@
1
1
  = Gomiko changelog
2
2
 
3
+ == Version 0.0.2 [2018-02-20] released
4
+
5
+ * small bugfix
6
+
3
7
  == Version 0.0.1 [2017-06-29] released
4
8
 
5
9
  * Bugfix a problem: enable to remove deadlink.
data/README.md CHANGED
@@ -1,13 +1,4 @@
1
- % Gomiko
2
- % Ippei Kishida
3
- % Last-modified:2017/06/29 11:08:02.
4
- <!-- vim:syntax=markdown
5
- <u> ■■■■ HERE ■■■■ </u>
6
-
7
- TODO 用語統一
8
- -->
9
-
10
- (→ [Japanese version](index-ja.html))
1
+ (→ [Japanese version](http://www.q-eng.imat.eng.osaka-cu.ac.jp/~ippei/html/gomiko/index-ja.html))
11
2
 
12
3
  # Overview
13
4
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
data/bin/gomiko CHANGED
@@ -15,15 +15,11 @@ class MyCommand < Thor
15
15
  # type: :boolean,
16
16
  # default: false
17
17
  def rm(* paths)
18
- #paths.select do |path|
19
- # File.exist? path
20
- #end
21
18
  Gomiko.new.throw(paths: paths)
22
19
  end
23
20
 
24
21
  desc :empty, 'Remove files in trash directory'
25
22
  option "mtime",
26
- #type: :numeric,
27
23
  type: :string,
28
24
  desc: 'Data was last modified n*24 hours ago.',
29
25
  default: '0'
@@ -39,12 +35,12 @@ class MyCommand < Thor
39
35
  def undo(* dirs)
40
36
  g = Gomiko.new
41
37
 
42
- if Dir.glob("#{@trashdir}/*").empty?
43
- puts "Nothing to undo in #{@trashdir}"
38
+ if g.dir_list.empty?
39
+ puts "Nothing to undo in #{g.trashdir}"
44
40
  exit
45
41
  end
46
42
 
47
- dirs = [g.list[-1]] if dirs.empty?
43
+ dirs = [g.dir_list[-1]] if dirs.empty?
48
44
  dirs.each do |dir|
49
45
  begin
50
46
  g.undo(dir)
@@ -52,29 +48,32 @@ class MyCommand < Thor
52
48
  puts "Permission denined: #{dir}"
53
49
  end
54
50
  end
55
-
56
51
  end
57
52
 
58
53
  ## list
59
54
  desc :ls, 'Show trash directory'
60
55
  option "long", type: :boolean,
56
+ desc: "use a long format",
61
57
  default: false,
62
58
  aliases: 'l'
59
+ option "all", type: :boolean,
60
+ desc: "show all history including after undo",
61
+ default: false,
62
+ aliases: 'a'
63
63
  def ls(* ids)
64
64
  g = Gomiko.new
65
- if g.list.empty?
65
+ if g.dir_list.empty?
66
66
  puts "Nothing in ~/.trash"
67
67
  exit
68
68
  end
69
- ids = g.list if ids.empty?
69
+ ids = g.dir_list if ids.empty?
70
70
  if options[:long]
71
71
  ids.each do |id|
72
72
  puts '-' * 60
73
73
  results = g.info(id)
74
74
  printf("%-10s: %s\n", 'size', results[0])
75
75
  printf("%-10s: %s\n", 'id', results[1])
76
- printf("%-10s: %s\n", 'guess path', results[2])
77
- #pp results[3]
76
+ printf("%-10s: %s\n", 'path(s)', results[2])
78
77
  puts '+----- filetype in trash'
79
78
  puts '| +--- filetype in original path'
80
79
  puts '| | +- original path'
@@ -89,6 +88,13 @@ class MyCommand < Thor
89
88
  end
90
89
  Tefil::ColumnFormer.new.form(results)
91
90
  end
91
+ if options[:all]
92
+ g.yaml_list.each do |file|
93
+ id = file.sub(".yaml", "")
94
+ next if g.dir_list.include?(id)
95
+ puts "undo #{id}"
96
+ end
97
+ end
92
98
  end
93
99
  end
94
100
 
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: gomiko 0.0.1 ruby lib
5
+ # stub: gomiko 0.0.2 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "gomiko"
9
- s.version = "0.0.1"
9
+ s.version = "0.0.2"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["ippei94da"]
14
- s.date = "2017-06-29"
14
+ s.date = "2018-02-20"
15
15
  s.description = "\n This Gem provides functionality similar to the Trash box in Windows OS.\n The name 'gomiko' was originated from Japanese \"gomibako\".\n If you think that it is \"a shrine maiden(miko-san) who plays go\", is it cute?\n Gomiko provides the gomiko command;\n it moves the file to ~/.trash with a change of rm.\n And the command also can display the history of deletion and can execute undo.\n Gomiko provides the Gomiko library.\n It is designed so that the trash box can be handled from the Ruby program as well.\n "
16
16
  s.email = "ippei94da@gmail.com"
17
17
  s.executables = ["gomiko"]
@@ -5,6 +5,7 @@ require 'fileutils'
5
5
  require 'pathname'
6
6
  require 'tefil'
7
7
  require 'find'
8
+ require 'yaml'
8
9
 
9
10
  #
10
11
  #
@@ -30,13 +31,12 @@ class Gomiko
30
31
 
31
32
  # If paths includes exist and not exist files,
32
33
  # throw all exist file and report not exist files.
33
- def throw(paths: , time: Time.new, verbose: true)
34
+ def throw(paths: , time: Time.new, verbose: true, io: $stdout)
34
35
  paths = paths.select do |path|
35
36
  flag = FileTest.symlink?(path) || FileTest.exist?(path) # for deadlink
36
- #flag = FileTest.exist?(path) # for deadlink
37
37
  unless flag
38
38
  if verbose
39
- puts "gomiko rm: cannot remove '#{path}': No such file or directory"
39
+ io.puts "gomiko rm: cannot remove '#{path}': No such file or directory"
40
40
  end
41
41
  end
42
42
  flag
@@ -44,40 +44,51 @@ class Gomiko
44
44
  return if paths.empty?
45
45
 
46
46
  trash_subdir = mkdir_time(time)
47
+ File.open(trash_subdir + ".yaml", "w") do |yaml_io|
48
+ YAML.dump( { 'pwd' => ENV["PWD"], 'paths' => paths }, yaml_io)
49
+ end
50
+
47
51
  paths.each do |path|
48
52
  dst = trash_subdir + File.expand_path(path)
49
53
  dst_dir = File.dirname dst
50
54
  FileUtils.mkdir_p(dst_dir)
51
55
  if path == '.'
52
- puts "gomiko rm: failed to remove '.': Invalid argument" if verbose
56
+ io.puts "gomiko rm: failed to remove '.': Invalid argument" if verbose
53
57
  next
54
58
  else
55
- FileUtils.mv(path, dst_dir + '/', :verbose => verbose)
59
+ FileUtils.mv(path, dst_dir + '/')
60
+ io.puts "mv #{path} #{dst_dir}" if verbose
56
61
  File.utime(time, time, trash_subdir)
57
62
  end
58
63
  end
59
64
  end
60
65
 
61
- def empty(ids: [], mtime: 0, time: Time.now, verbose: true)
62
- ids.map! {|v| path2id v}
63
- ids = list if ids.empty?
64
- dirs = ids.map {|v| @trashdir + '/' + v}
65
- dirs = dirs.select { |v|
66
+ def empty(ids: [], mtime: 0, time: Time.now, verbose: true, io: $stdout)
67
+ if ids.empty?
68
+ tgts = (dir_list + yaml_list.map{|v| v.sub(".yaml", "")}).sort.uniq
69
+ else
70
+ tgts = ids.map {|v| path2id(v.sub(".yaml", ""))}
71
+ end
72
+ tgts = tgts.select { |v|
66
73
  begin
67
- File.mtime("#{v}") - time < 86400 * mtime
74
+ str2datetime(v) - time < 86400 * mtime
68
75
  rescue Errno::ENOENT
69
- puts "Not found: #{v}"
76
+ io.puts "Not found: #{v}"
70
77
  end
71
78
  }
72
- if dirs.empty?
73
- puts "No directory was emptied."
79
+ tgts.map! {|v| @trashdir + '/' + v}
80
+ if tgts.empty?
81
+ io.puts "No directory was emptied."
74
82
  else
75
- dirs.each {|path| FileUtils.rm_rf(path, :verbose => verbose)}
83
+ tgts.each do |path|
84
+ ["", ".yaml"].each do |ext|
85
+ new_path = path + ext
86
+ FileUtils.rm_rf(new_path, :verbose => verbose) if File.exist? new_path
87
+ end
88
+ end
76
89
  end
77
90
  end
78
91
 
79
- #def latest
80
-
81
92
  def undo(id, verbose: true, io: $stdout)
82
93
  id = path2id id
83
94
  fullpath = Pathname.new(@trashdir) + id
@@ -92,7 +103,11 @@ class Gomiko
92
103
  end
93
104
 
94
105
  # Example of return data:
95
- #236K 20170623-021233/home/ippei/private/ero/inbox/20170623-015917 ...
106
+ # [
107
+ # 236K,
108
+ # 20170623-021233,
109
+ # [/home/ippei/tmp/a.txt, /home/ippei/tmp/b.txt ]
110
+ # ]
96
111
  def info(id)
97
112
  id = path2id id
98
113
  cur_trash_dir = Pathname.new(@trashdir) + id
@@ -109,10 +124,8 @@ class Gomiko
109
124
  #flag_conflict = false
110
125
  flag_include_file = false
111
126
  trash_paths.each do |trash_path|
112
- #pp trash_path
113
127
  orig_path = trash_path.sub(/^#{cur_trash_dir}/, '')
114
128
  trash_type = ftype_str(trash_path)
115
-
116
129
  flag_include_file = true unless File.directory? trash_path
117
130
  if FileTest.exist? orig_path
118
131
  orig_type = ftype_str(orig_path)
@@ -128,30 +141,24 @@ class Gomiko
128
141
  results_long << [ trash_type, orig_type,
129
142
  trash_path.sub(/^#{cur_trash_dir}/, '') ]
130
143
  end
131
-
132
-
133
- #pp flag_include_file
134
144
  unless flag_include_file
135
- pp 'a'
136
145
  additions << 'only directory'
137
146
  candidates << trash_paths[-1]
138
147
  end
139
148
 
149
+ results << YAML.load_file(cur_trash_dir.to_s + ".yaml")['paths'][0]
140
150
  ## if no candidate, last file is adopted.
141
- #pp candidates
142
- #pp trash_paths
143
151
  if trash_paths.empty?
144
- results << '(empty)'
152
+ #results << '(empty)'
145
153
  results << []
146
154
  else
147
- #flag_conflict = true if candidates.empty?
148
155
  additions << 'conflict' if candidates.empty?
149
- candidates = candidates.map {|path|
150
- tmp = path.sub(/^#{cur_trash_dir}/, '')
151
- tmp += '/' if FileTest.directory? path
152
- tmp
153
- }
154
- results << candidates[0]
156
+ #candidates = candidates.map {|path|
157
+ # tmp = path.sub(/^#{cur_trash_dir}/, '')
158
+ # tmp += '/' if FileTest.directory? path
159
+ # tmp
160
+ #}
161
+ #results << candidates[0]
155
162
 
156
163
  ## output '...' when multiple.
157
164
  candidates = candidates.select{|pa| ! pa.include? candidates[0]}
@@ -163,15 +170,31 @@ class Gomiko
163
170
  results
164
171
  end
165
172
 
166
- # ls, list
167
- def list
168
- Dir.glob("#{@trashdir}/*").map do |path|
173
+ # ls, yaml_list
174
+ # return stocked yaml.
175
+ def yaml_list
176
+ Dir.glob("#{@trashdir}/*.yaml").map { |path|
169
177
  path.sub(/^#{@trashdir}\//, '').split[0]
170
- end . sort
178
+ } . sort
179
+ end
180
+
181
+ # ls, dir_list
182
+ # return stocked directories.
183
+ def dir_list
184
+ Dir.glob("#{@trashdir}/*").select { |path|
185
+ FileTest.directory? path
186
+ } .map { |path|
187
+ path.sub(/^#{@trashdir}\//, '').split[0]
188
+ } . sort
171
189
  end
172
190
 
173
191
  private
174
192
 
193
+ def str2datetime(str)
194
+ /(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})(\d{2})/ =~ str
195
+ Time.new( $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i)
196
+ end
197
+
175
198
  # e.g., root_path = ~/.trash/20170123-012345
176
199
  # path = home/ippei/foo
177
200
  def graft(src_root, path, dst_root: '/', verbose: true)
@@ -187,8 +210,6 @@ class Gomiko
187
210
  elsif FileTest.exist? (dst_path)
188
211
  puts "normal file already exist: #{dst_path}" if verbose
189
212
  else
190
- #pp src_root + path
191
- #pp dst_path
192
213
  FileUtils.mv(src_root + path, dst_path, noop: false, verbose: verbose )
193
214
  end
194
215
  return
@@ -205,7 +226,6 @@ class Gomiko
205
226
  #self.ls
206
227
  try_name = @trashdir + "#{time_str}"
207
228
  try_name += "-#{i}" if 1 <= i
208
- #pp try_name
209
229
  FileUtils.mkdir(try_name)
210
230
  dirname = try_name
211
231
  rescue Errno::EEXIST
@@ -14,7 +14,6 @@ class TC_Gomiko < Test::Unit::TestCase
14
14
  WORKDIR = "#{TMPDIR}/work"
15
15
  TRASHDIR = "#{TMPDIR}/trash"
16
16
 
17
- #pp WORKDIR; exit
18
17
  def setup
19
18
  FileUtils.rm_rf TMPDIR
20
19
  FileUtils.mkdir_p WORKDIR
@@ -44,6 +43,12 @@ class TC_Gomiko < Test::Unit::TestCase
44
43
  assert(FileTest.exist? ("#{TRASHDIR}/20170123-123456#{a_fullpath_dirname}"))
45
44
  assert_equal( Time.new(2017, 1, 23, 12, 34, 56),
46
45
  File.mtime("#{TRASHDIR}/20170123-123456"))
46
+ assert(FileTest.exist? "#{TRASHDIR}/20170123-123456.yaml")
47
+ yaml = YAML.load_file "#{TRASHDIR}/20170123-123456.yaml"
48
+ assert_equal(
49
+ {"pwd"=>"/home/ippei/git/gomiko", "paths"=>["test/tmp/a.txt"]},
50
+ yaml
51
+ )
47
52
  end
48
53
 
49
54
  def test_throw2
@@ -71,13 +76,9 @@ class TC_Gomiko < Test::Unit::TestCase
71
76
  a_fullpath = File.expand_path 'test/a.txt'
72
77
  a_fullpath_dirname = File.dirname a_fullpath
73
78
  FileUtils.ln_s(b_relpath, a_relpath)
74
- #FileUtils.rm b_relpath
75
- #@g00.throw(paths: [a_relpath], time: Time.new(2017, 1, 23, 12, 34, 56), verbose: false)
76
- @g00.throw(paths: [a_relpath], time: Time.new(2017, 1, 23, 12, 34, 56), verbose: true)
79
+ @g00.throw(paths: [a_relpath], time: Time.new(2017, 1, 23, 12, 34, 56), verbose: true, io: StringIO.new)
77
80
  assert_false(FileTest.exist? a_relpath)
78
81
  assert_false(FileTest.symlink? a_relpath)
79
- pp "#{TRASHDIR}/20170123-123456#{a_fullpath_dirname}"
80
- #sleep 60
81
82
 
82
83
  t = "#{TRASHDIR}/20170123-123456#{a_fullpath_dirname}"
83
84
  assert(FileTest.directory? t)
@@ -107,7 +108,9 @@ class TC_Gomiko < Test::Unit::TestCase
107
108
  assert(File.exist? "#{TRASHDIR}/20170123-123457#{b_fullpath}")
108
109
  @g00.empty(ids: ['20170123-123456'], verbose: false)
109
110
  assert_false(File.exist? "#{TRASHDIR}/20170123-123456#{a_fullpath}")
111
+ assert_false(File.exist? "#{TRASHDIR}/20170123-123456.yaml")
110
112
  assert (File.exist? "#{TRASHDIR}/20170123-123457#{b_fullpath}")
113
+ assert (File.exist? "#{TRASHDIR}/20170123-123457.yaml")
111
114
  end
112
115
 
113
116
  def test_empty3 #mtime
@@ -122,11 +125,13 @@ class TC_Gomiko < Test::Unit::TestCase
122
125
  assert(File.exist? "#{TRASHDIR}/20170615-000000#{a_fullpath}")
123
126
  @g00.empty(mtime: -10,
124
127
  time: Time.new(2017, 6, 24, 23, 59, 59),
125
- verbose: false)
128
+ verbose: false,
129
+ io: StringIO.new)
126
130
  assert(File.exist? "#{TRASHDIR}/20170615-000000#{a_fullpath}")
127
131
  @g00.empty(mtime: -10,
128
132
  time: Time.new(2017, 6, 25, 00, 00, 00),
129
- verbose: false)
133
+ verbose: false,
134
+ io: StringIO.new)
130
135
  assert_false(File.exist? "#{TRASHDIR}/20170123-123456#{a_fullpath}")
131
136
  end
132
137
 
@@ -165,7 +170,8 @@ class TC_Gomiko < Test::Unit::TestCase
165
170
  @g00.empty(ids: %w(20170615-000000 20170715-000000),
166
171
  mtime: -3,
167
172
  time: Time.new(2017, 7, 16, 01, 00, 00),
168
- verbose: false)
173
+ verbose: false,
174
+ io: File::NULL)
169
175
  assert_false(File.exist? "#{TRASHDIR}/20170615-000000#{a_fullpath}")
170
176
  assert (File.exist? "#{TRASHDIR}/20170615-120000#{b_fullpath}")
171
177
  assert (File.exist? "#{TRASHDIR}/20170715-000000#{c_fullpath}")
@@ -208,8 +214,9 @@ class TC_Gomiko < Test::Unit::TestCase
208
214
  assert (File.exist? "#{WORKDIR}/a/b/c.txt")
209
215
  end
210
216
 
211
- # ls, list
212
- def test_list1
217
+
218
+ # ls, dir_list
219
+ def test_dir_list1
213
220
  a_relpath = 'test/tmp/a.txt'
214
221
  FileUtils.touch a_relpath
215
222
  @g00.throw(paths: [a_relpath],
@@ -220,14 +227,12 @@ class TC_Gomiko < Test::Unit::TestCase
220
227
  @g00.throw(paths: [a_relpath],
221
228
  time: Time.new(2017, 1, 23, 12, 34, 57),
222
229
  verbose: false)
223
- corrects = ["20170123-123456", "20170123-123457" ]
224
- assert_equal(corrects, @g00.list)
230
+ corrects = [ "20170123-123456", "20170123-123457" ]
231
+ assert_equal(corrects, @g00.dir_list)
225
232
  end
226
233
 
227
- def test_list2
234
+ def test_dir_list2
228
235
  FileUtils.mkdir_p @g00.trashdir + '20170628-000000'
229
- #pp @g00.list
230
- #assert_equal(corrects, @g00.list)
231
236
  end
232
237
 
233
238
  def test_info1
@@ -240,7 +245,6 @@ class TC_Gomiko < Test::Unit::TestCase
240
245
  results = @g00.info("20170123-123456")
241
246
  assert_equal('20170123-123456', results[1])
242
247
  assert_equal(path, results[2])
243
- #pp results[3]
244
248
  corrects = [
245
249
  ["/", "/", "/home"],
246
250
  ["/", "/", "/home/ippei"],
@@ -276,7 +280,7 @@ class TC_Gomiko < Test::Unit::TestCase
276
280
  #size is dependent on system
277
281
  results = @g00.info("20170123-123456")
278
282
  assert_equal('20170123-123456', results[1])
279
- assert_equal("#{WORKDIR}/a/", results[2])
283
+ assert_equal("#{WORKDIR}/a", results[2])
280
284
  end
281
285
 
282
286
  def test_info4
@@ -290,7 +294,7 @@ class TC_Gomiko < Test::Unit::TestCase
290
294
  #size is dependent on system
291
295
  results = @g00.info("20170123-123456")
292
296
  assert_equal('20170123-123456', results[1])
293
- assert_equal("#{WORKDIR}/a/ ...", results[2])
297
+ assert_equal("#{WORKDIR}/a ...", results[2])
294
298
  end
295
299
 
296
300
  def test_info5 # symlink
@@ -300,9 +304,8 @@ class TC_Gomiko < Test::Unit::TestCase
300
304
  verbose: false)
301
305
  FileUtils.mkdir_p "#{WORKDIR}/a/b"
302
306
  results = @g00.info("20170123-123456")
303
- #pp results
304
307
  assert_equal('20170123-123456', results[1])
305
- assert_equal("#{WORKDIR}/a/b/ (only directory)", results[2])
308
+ assert_equal("#{WORKDIR}/a (only directory)", results[2])
306
309
  end
307
310
 
308
311
  def test_info6
@@ -313,7 +316,6 @@ class TC_Gomiko < Test::Unit::TestCase
313
316
  verbose: false)
314
317
  FileUtils.touch("#{WORKDIR}/a")
315
318
  results = @g00.info("20170123-123456")
316
- #pp results
317
319
  assert_equal('20170123-123456', results[1])
318
320
  assert_equal("#{WORKDIR}/a (conflict)", results[2])
319
321
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gomiko
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ippei94da
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-29 00:00:00.000000000 Z
11
+ date: 2018-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdoc