gomiko 0.0.0 → 0.0.1
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 +4 -4
- data/CHANGES +6 -0
- data/README.md +404 -0
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/gomiko.gemspec +75 -0
- data/lib/gomiko.rb +34 -47
- data/test/test_gomiko.rb +39 -8
- metadata +4 -3
- data/README.rdoc +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4226809c289bd119c0709dd3bbaf6567f073090
|
4
|
+
data.tar.gz: e7ba437969fa6110f09e81b0a6434fe5c84a9eee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9951ba37e62caec09a4856fe704b9eb62edcd7e8523fed13c3d5b37ad3faee61030f45527f3148271a566b1ea58e1b006b68cba82e17500bbad74e7b9bdfa187
|
7
|
+
data.tar.gz: fb742c25708beb55d4e821171f34a85fad18cadb353c9c6ab13e1d44c2a05f812388b2ba8229995364cac3212ff281b86730fef81adc80a1454b428909194e3a
|
data/CHANGES
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
= Gomiko changelog
|
2
2
|
|
3
|
+
== Version 0.0.1 [2017-06-29] released
|
4
|
+
|
5
|
+
* Bugfix a problem: enable to remove deadlink.
|
6
|
+
* Bugfix a problem that 'gomiko ls' not show symlink deletion.
|
7
|
+
* Avoid exception when 'gomiko rm .'
|
8
|
+
|
3
9
|
== Version 0.0.0 [2017-06-29] released
|
4
10
|
|
5
11
|
* initial release
|
data/README.md
ADDED
@@ -0,0 +1,404 @@
|
|
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))
|
11
|
+
|
12
|
+
# Overview
|
13
|
+
|
14
|
+
Gomiko provides a mechanism to temporarily store files rather than delete them, such as the Windows snap box.
|
15
|
+
[Implement UNIX Technique / Shell](http://www.q-eng.imat.eng.osaka-cu.ac.jp/~ippei/html/unixtodaystips/shell.html#)
|
16
|
+
As you have done in the past,
|
17
|
+
I installed the dust box on the shell.
|
18
|
+
That's 99% of my requirements,
|
19
|
+
If you have been using it for a long time, you may have felt a shortage as follows.
|
20
|
+
|
21
|
+
* I want to hand lightly.
|
22
|
+
* If you delete a file in the program, you also want to enter the dust box.
|
23
|
+
|
24
|
+
Gomiko provides the gomiko command.
|
25
|
+
The gomiko command has the ability to move files to ~/.trash with changes in rm.
|
26
|
+
It also displays the history of deletion and undo.
|
27
|
+
Gomiko as a Gem provides the Gomiko library.
|
28
|
+
The Ruby program is designed to handle the dust box as well.
|
29
|
+
|
30
|
+
## before the name
|
31
|
+
|
32
|
+
The name "gomiko" was named as "Japanese box" in Japanese.
|
33
|
+
If you think that it is "a shrine maiden who plays go", is it cute?
|
34
|
+
|
35
|
+
# Install
|
36
|
+
|
37
|
+
Rubygems is used.
|
38
|
+
You can use Rubygems to install it as follows:
|
39
|
+
|
40
|
+
gem install gomiko
|
41
|
+
|
42
|
+
## Settings (you like)
|
43
|
+
|
44
|
+
The setting is basically unnecessary.
|
45
|
+
Also generates ~/.trash automatically.
|
46
|
+
If ~/.trash is present before gomiko and the file is there,
|
47
|
+
I think that at least a few of them will not work,
|
48
|
+
It would be more difficult to leave it empty.
|
49
|
+
|
50
|
+
If you decide to use gomiko in earnest,
|
51
|
+
I think you should make rm an alias for gomiko rm.
|
52
|
+
I have set the following in ~/.zshrc:
|
53
|
+
|
54
|
+
alias rm='gomiko rm'
|
55
|
+
|
56
|
+
I think that undo and empty subcommands should be typed like gomiko undo,
|
57
|
+
I have not created any aliases in particular.
|
58
|
+
|
59
|
+
|
60
|
+
# Command
|
61
|
+
|
62
|
+
The gomiko command is available.
|
63
|
+
Various functions are provided as this subcommand.
|
64
|
+
|
65
|
+
## gomiko help
|
66
|
+
|
67
|
+
If you do not specify an argument, or if you specify the subcommand help, a helper is displayed.
|
68
|
+
|
69
|
+
% gomiko
|
70
|
+
|
71
|
+
% gomiko help
|
72
|
+
|
73
|
+
If you specify a subcommand name after help, as in the following example, the help for the subcommand rm is:
|
74
|
+
|
75
|
+
% gomiko help rm
|
76
|
+
|
77
|
+
|
78
|
+
## gomiko rm
|
79
|
+
|
80
|
+
% gomiko rm foo.txt
|
81
|
+
|
82
|
+
It is replaced with the normal rm command.
|
83
|
+
To change the deletion
|
84
|
+
Move to the ~/.trash directory.
|
85
|
+
The moved file name is
|
86
|
+
"~/.trash/date-time/original full path"
|
87
|
+
It is becoming more and more common.
|
88
|
+
This
|
89
|
+
"Date-time" is the timing when gomiko was started,
|
90
|
+
It is not the time when the movement was performed internally.
|
91
|
+
For example, if `gomiko rm *` "deletes a large number of files and takes more than a second,
|
92
|
+
It can be entered in one "date-time".
|
93
|
+
|
94
|
+
You can specify more than one file at a time, as follows:
|
95
|
+
|
96
|
+
% gomiko rm foo.txt bar.txt */*.txt
|
97
|
+
|
98
|
+
You can also move the directory to the dust box without options, as shown below.
|
99
|
+
|
100
|
+
% gomiko rm dir1/ dir2/
|
101
|
+
|
102
|
+
When multiple gomiko rms are performed at the same time,
|
103
|
+
The first is
|
104
|
+
It will be the directory name `` ~/.trash/date - time ``,
|
105
|
+
From now on,
|
106
|
+
It is created in serial number after time like "~/.trash/date-time-1".
|
107
|
+
It is a mechanism that is similar to the Locked Directory of Exclusive Control,
|
108
|
+
Because only the process that generated the directory is in the directory,
|
109
|
+
It is also safe for file systems that share NFS over multiple machines.
|
110
|
+
|
111
|
+
After that, the file directory under ~/.trash/ will be called "trash ID directory"
|
112
|
+
The directory name is called the "ID".
|
113
|
+
Even if it was created manually rather than via gomiko rm,
|
114
|
+
It can be used as a trash ID directory, trash ID.
|
115
|
+
(Whether undo or other commands are intended to work is another matter.)
|
116
|
+
|
117
|
+
|
118
|
+
## gomiko undo
|
119
|
+
|
120
|
+
The subcommand undo provides the un-delete function for file deletion.
|
121
|
+
If you run it without arguments as in the following, you will undo the most recent contents of the trash ID directory.
|
122
|
+
|
123
|
+
% gomiko undo
|
124
|
+
|
125
|
+
Because undo removes the appropriate discovery ID directory,
|
126
|
+
If you run gomiko undo, you will then unhide the new Discovery ID directory.
|
127
|
+
In other words, running gomiko undo will continue to remove the deletion.
|
128
|
+
|
129
|
+
If the file exists in the original path that you deleted,
|
130
|
+
It does not issue a warning about the file in question and does not perform the move.
|
131
|
+
Other files are returned.
|
132
|
+
|
133
|
+
% gomiko undo
|
134
|
+
Normal file already exist: /home /ippei /tmp /gomiko /0
|
135
|
+
Can not undo: /home/ippei/.trash/20170623-133644
|
136
|
+
|
137
|
+
You can specify a false ID to execute undo on the argument.
|
138
|
+
|
139
|
+
% gomiko undo 20170623-133644
|
140
|
+
|
141
|
+
(In this case, the expansion of the memory card can not be normal.)
|
142
|
+
|
143
|
+
% gomiko undo 20170623-133644 20170623-123456
|
144
|
+
|
145
|
+
You can also specify the path
|
146
|
+
|
147
|
+
% gomiko undo ~/.trash/20170623-*
|
148
|
+
|
149
|
+
## gomiko empty
|
150
|
+
|
151
|
+
Empty the contents of the ~/.trash directory.
|
152
|
+
If the argument is omitted, all file directories in ~/.trash are considered.
|
153
|
+
Gomiko empty is also a file directory that is in ~/.trash without gomiko rm
|
154
|
+
It is targeted.
|
155
|
+
|
156
|
+
You can specify a false ID in the argument.
|
157
|
+
|
158
|
+
% gomiko empty 20170628-112425-2
|
159
|
+
|
160
|
+
It can be specified with a path instead of a false ID.
|
161
|
+
|
162
|
+
% gomiko empty ~/.trash/20170628-112425-2
|
163
|
+
|
164
|
+
### --mtime option
|
165
|
+
|
166
|
+
It is recommended that you periodically delete the contents of ~/.trash.
|
167
|
+
At that point, if you empty the file at some stage, the file you moved to ~/.trash
|
168
|
+
It is also possible to delete it.
|
169
|
+
If you look at the timestamp, for example, delete the file after seven days,
|
170
|
+
It is a routine method.
|
171
|
+
The --mtime option does this.
|
172
|
+
|
173
|
+
% gomiko empty --mtime=-7
|
174
|
+
|
175
|
+
, Delete the item that has passed 7 days or more.
|
176
|
+
Because we decided on the notation using the -mtime option of find,
|
177
|
+
Normally you will specify a negative number.
|
178
|
+
The default value of the - mtime option argument is 0,
|
179
|
+
All previously created trash ID directories are considered.
|
180
|
+
This time stan- dard,
|
181
|
+
We are looking at the time stamp (update time) of the geo ID directory.
|
182
|
+
Because you did not get the date from the file name,
|
183
|
+
Changing the file name does not change the date judgment.
|
184
|
+
|
185
|
+
If you use the --mtime option with the argument id of the argument,
|
186
|
+
Select an AND condition that matches both.
|
187
|
+
(Note: Even if it is considered to be an OR condition,
|
188
|
+
If you do OR, you only need to issue the command twice,
|
189
|
+
Because the AND condition is between the hand and the hand, the value is still.
|
190
|
+
I do not think that it should be used together.)
|
191
|
+
|
192
|
+
### --quiet option
|
193
|
+
|
194
|
+
You will not need to log the standard output when running with cron.
|
195
|
+
In such cases, the --quiet option can suppress the standard output.
|
196
|
+
|
197
|
+
% gomiko empty --quiet
|
198
|
+
|
199
|
+
When you run the empty subcommand manually
|
200
|
+
It is more pleasant to see something, and by default, --quiet is off.
|
201
|
+
|
202
|
+
## gomiko ls
|
203
|
+
|
204
|
+
Displays the contents of ~/.trash.
|
205
|
+
|
206
|
+
% gomiko ls
|
207
|
+
size date-time-id typical-path[ ...]
|
208
|
+
20K 20170623-125159 /home/ippei/tmp/gomiko/0
|
209
|
+
20K 20170623-125810 /home/ippei/tmp/gomiko/5 ...
|
210
|
+
84K 20170627-084500 /home/ippei/git/gomiko/test/gomiko/tmp/
|
211
|
+
24K 20170627-091649 /home/ippei/git/gomiko/a/
|
212
|
+
32K 20170627-091712 /home/ippei/git/gomiko/test/gomiko/b (exist in original path)
|
213
|
+
100K 20170627-092407 /home/ippei/git/gomiko/test/gomiko/tmp/
|
214
|
+
|
215
|
+
The first line is the title line of information.
|
216
|
+
The second and third lines are data.
|
217
|
+
The size of the first column is the size that can be acquired by du.
|
218
|
+
The second column is representative of the path that is assumed to be deleted.
|
219
|
+
This inference is based on the recursive search of the trash ID directory,
|
220
|
+
And it presents a file directory that does not exist on the actual full path.
|
221
|
+
Following the second column, "..." means that there is an assumed path other than the representative,
|
222
|
+
In other words, it is assumed that you have moved multiple files into a single box with a single command.
|
223
|
+
|
224
|
+
If the original path that you deleted contains a file that already exists,
|
225
|
+
It outputs (may exist newer file) as follows.
|
226
|
+
|
227
|
+
20K 20170623-125810 /home/ippei/tmp/gomiko/5 ...(may exist newer file)
|
228
|
+
|
229
|
+
You can specify a false ID for the argument.
|
230
|
+
|
231
|
+
% gomiko ls 20170623-125159 20170623-125810
|
232
|
+
size date-time-id typical-path[ ...]
|
233
|
+
20K 20170623-125159 /home/ippei/tmp/gomiko/0
|
234
|
+
20K 20170623-125810 /home/ippei/tmp/gomiko/5 ...
|
235
|
+
|
236
|
+
|
237
|
+
The path is OK even if it is a bad ID.
|
238
|
+
|
239
|
+
% gomiko ls ~/.trash/20170623-125*
|
240
|
+
size date-time-id typical-path[ ...]
|
241
|
+
20K 20170623-125159 /home/ippei/tmp/gomiko/0
|
242
|
+
20K 20170623-125810 /home/ippei/tmp/gomiko/5 ...
|
243
|
+
|
244
|
+
### --long, -l option
|
245
|
+
|
246
|
+
The --long (-l) option prints more information.
|
247
|
+
|
248
|
+
% gomiko ls --long
|
249
|
+
------------------------------------------------------------
|
250
|
+
size : 20K
|
251
|
+
id : 20170628-112425
|
252
|
+
guess path: /home/ippei/tmp/gomiko/0
|
253
|
+
+----- filetype in trash
|
254
|
+
| +--- filetype in original path
|
255
|
+
| | +- original path
|
256
|
+
/ / /home
|
257
|
+
/ / /home/ippei
|
258
|
+
/ / /home/ippei/tmp
|
259
|
+
/ / /home/ippei/tmp/gomiko
|
260
|
+
. /home/ippei/tmp/gomiko/0
|
261
|
+
|
262
|
+
------------------------------------------------------------
|
263
|
+
size : 20K
|
264
|
+
id : 20170628-112425-1
|
265
|
+
guess path: /home/ippei/tmp/gomiko/1
|
266
|
+
+----- filetype in trash
|
267
|
+
| +--- filetype in original path
|
268
|
+
| | +- original path
|
269
|
+
/ / /home
|
270
|
+
/ / /home/ippei
|
271
|
+
/ / /home/ippei/tmp
|
272
|
+
/ / /home/ippei/tmp/gomiko
|
273
|
+
. /home/ippei/tmp/gomiko/1
|
274
|
+
|
275
|
+
------------------------------------------------------------
|
276
|
+
size : 20K
|
277
|
+
id : 20170628-112425-3
|
278
|
+
guess path: /home/ippei/tmp/gomiko/3
|
279
|
+
+----- filetype in trash
|
280
|
+
| +--- filetype in original path
|
281
|
+
| | +- original path
|
282
|
+
/ / /home
|
283
|
+
/ / /home/ippei
|
284
|
+
/ / /home/ippei/tmp
|
285
|
+
/ / /home/ippei/tmp/gomiko
|
286
|
+
. /home/ippei/tmp/gomiko/3
|
287
|
+
|
288
|
+
It is divided by a horizontal line for each gummy ID.
|
289
|
+
Capacity (size),
|
290
|
+
The ID (id)
|
291
|
+
The guessed path (guess path)
|
292
|
+
Below is the information for all the directory files stored in the trash ID directory,
|
293
|
+
The first element of each line is the file type in the geo ID directory,
|
294
|
+
The next element is the file type of the original path on the current file tree.
|
295
|
+
The meaning of the letter that indicates the file type is as follows.
|
296
|
+
|
297
|
+
* "/" Directory
|
298
|
+
* "." Normal file
|
299
|
+
* " "(Blank) indicates that the file does not exist
|
300
|
+
|
301
|
+
|
302
|
+
# Library
|
303
|
+
|
304
|
+
Gomiko.new generates a Gomiko object,
|
305
|
+
By using Gomiko#throw,
|
306
|
+
You can use the dust box from the program.
|
307
|
+
|
308
|
+
|
309
|
+
# Rejected features
|
310
|
+
|
311
|
+
## It takes a long time to move to a local folder when deleting an NFS share file
|
312
|
+
|
313
|
+
Solutions to this need are difficult.
|
314
|
+
The problem is how to place the dust box directory equivalent to ~/.trash.
|
315
|
+
The df command provides information about the file system,
|
316
|
+
It is difficult to determine automatically due to various factors such as sym- bolic links and permutations.
|
317
|
+
For example, if you followed the expanded path of a symlink,
|
318
|
+
To the top-level directory that has the same file system or permission to write to itself
|
319
|
+
Let's imagine a policy of creating a gummy box directory.
|
320
|
+
If you delete it in /tmp, you will create a directory called /tmp/.trash.
|
321
|
+
I can not say that it is an amiable good.
|
322
|
+
In addition, there are multiple dust box directories,
|
323
|
+
It becomes difficult to know where the target file is stored.
|
324
|
+
The benefits are far less complex and complex, and there are fewer demerits.
|
325
|
+
It is possible to create an option to specify the location of the glove box directory,
|
326
|
+
There is no plan to make such an option at this time.
|
327
|
+
|
328
|
+
|
329
|
+
## mkdir and directory specification
|
330
|
+
|
331
|
+
Every time you run gomiko (or whenever you throw Gomiko#throw internally), a new gomi ID directory is created,
|
332
|
+
The granularity of gomiko undo is in that unit.
|
333
|
+
When you delete a file from a program,
|
334
|
+
There is a request that "we want to go to a common false ID directory in one process".
|
335
|
+
To solve this problem, create a gomi ID directory with gomiko mkdir,
|
336
|
+
You can specify gomiko rm or Gomiko#throw with that directory.
|
337
|
+
Although technological difficulties are not difficult,
|
338
|
+
This will cause problems as a program's log- ics.
|
339
|
+
The problem is that multiple file deletions can be the same path in a single trash ID directory.
|
340
|
+
Assuming that you have implemented the - id option in gomiko mkdir and gomiko rm,
|
341
|
+
Let's consider it in a shell script.
|
342
|
+
|
343
|
+
DIR=`gomiko mkdir`#Creates a new ID directory and returns its ID
|
344
|
+
touch a
|
345
|
+
gomiko rm --id=$ DIR a # Specify the id ID directory and drag it there.
|
346
|
+
touch a
|
347
|
+
gomiko rm --id=$ DIR a # It should be loaded into the same path of the same god ID directory.
|
348
|
+
|
349
|
+
The second gomiko rm causes duplication.
|
350
|
+
Because the file trees at different points in time are grouped together,
|
351
|
+
Such problems may arise.
|
352
|
+
As a program, you should position the geo-ID directory as a snapshot of the file tree at the time of the deletion.
|
353
|
+
|
354
|
+
From these, there is no plan to add this function.
|
355
|
+
|
356
|
+
## redo function
|
357
|
+
|
358
|
+
Currently, gomiko uses the data in ~/.trash files as its data
|
359
|
+
Processing is being performed.
|
360
|
+
By not having the history as a separate file,
|
361
|
+
And preserves the uniqueness of the information.
|
362
|
+
To do a redo, you need to remove the undo file from ~/.trash,
|
363
|
+
It is necessary to place a record somewhere.
|
364
|
+
As a result, the place of information becomes less centralized,
|
365
|
+
You have to be careful about maintaining consistency.
|
366
|
+
Even if gomiko itself does not have the redo function,
|
367
|
+
The same can be done by using the shell's histories.
|
368
|
+
Because I think that it is a function with a lot of effort in terms of work,
|
369
|
+
There is no plan to add this function.
|
370
|
+
|
371
|
+
## Using the Directory Creation Time
|
372
|
+
|
373
|
+
And the directory in the trash ID directory.
|
374
|
+
If we can compare the generation time of the source directories,
|
375
|
+
It will be possible to deduce more accurate delete targets.
|
376
|
+
For example, if you have a file called /a /b /c.txt,
|
377
|
+
Suppose you deleted it with /a /b.
|
378
|
+
The ending file directory is
|
379
|
+
/A and ~/.trash/ID/a/b.
|
380
|
+
If you then generate /a/b,
|
381
|
+
The /a/b should be later than the creation time by ~/.trash /false ID /a /b.
|
382
|
+
On the other hand, if you look at a, the ~/.trash/false ID /a generated by deletion should be later than the /a that was already present at the time of deletion.
|
383
|
+
You should be able to determine whether this is the directory generated after the deletion,
|
384
|
+
On Linux mainstream ext4 file systems
|
385
|
+
The file directory creation time is not recorded in the timestamp.
|
386
|
+
Therefore, this can not be used.
|
387
|
+
We will also consider when the file system that can be used at creation time is mainstream.
|
388
|
+
|
389
|
+
|
390
|
+
# Contributing to gomiko
|
391
|
+
|
392
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
393
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
394
|
+
* Fork the project.
|
395
|
+
* Start a feature/bugfix branch.
|
396
|
+
* Commit and push until you are happy with your contribution.
|
397
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
398
|
+
* 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.
|
399
|
+
|
400
|
+
# Copyright
|
401
|
+
|
402
|
+
Copyright (c) 2017 ippei94da. See LICENSE.txt for
|
403
|
+
further details.
|
404
|
+
|
data/Rakefile
CHANGED
@@ -16,6 +16,8 @@ Jeweler::Tasks.new do |gem|
|
|
16
16
|
# gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
|
17
17
|
gem.name = "gomiko"
|
18
18
|
gem.homepage = "http://github.com/ippei94da/gomiko"
|
19
|
+
#gem.homepage = "http://www.q-eng.imat.eng.osaka-cu.ac.jp/~ippei/html/gomiko/index.html"
|
20
|
+
|
19
21
|
gem.license = "MIT"
|
20
22
|
gem.summary = %Q{Trashbox with command line interface}
|
21
23
|
gem.description = %Q{
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.1
|
data/gomiko.gemspec
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: gomiko 0.0.1 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "gomiko"
|
9
|
+
s.version = "0.0.1"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["ippei94da"]
|
14
|
+
s.date = "2017-06-29"
|
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
|
+
s.email = "ippei94da@gmail.com"
|
17
|
+
s.executables = ["gomiko"]
|
18
|
+
s.extra_rdoc_files = [
|
19
|
+
"LICENSE.txt",
|
20
|
+
"README.md"
|
21
|
+
]
|
22
|
+
s.files = [
|
23
|
+
".document",
|
24
|
+
"CHANGES",
|
25
|
+
"Gemfile",
|
26
|
+
"LICENSE.txt",
|
27
|
+
"README.md",
|
28
|
+
"Rakefile",
|
29
|
+
"VERSION",
|
30
|
+
"bin/gomiko",
|
31
|
+
"gomiko.gemspec",
|
32
|
+
"lib/gomiko.rb",
|
33
|
+
"test/.gitignore",
|
34
|
+
"test/helper.rb",
|
35
|
+
"test/test_gomiko.rb"
|
36
|
+
]
|
37
|
+
s.homepage = "http://github.com/ippei94da/gomiko"
|
38
|
+
s.licenses = ["MIT"]
|
39
|
+
s.rubygems_version = "2.5.1"
|
40
|
+
s.summary = "Trashbox with command line interface"
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
s.specification_version = 4
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_development_dependency(%q<rdoc>, ["~> 4.2"])
|
47
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0"])
|
48
|
+
s.add_development_dependency(%q<jeweler>, ["~> 2.3"])
|
49
|
+
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
50
|
+
s.add_development_dependency(%q<test-unit>, ["~> 3.2"])
|
51
|
+
s.add_development_dependency(%q<filerenamer>, ["~> 0.0"])
|
52
|
+
s.add_development_dependency(%q<tefil>, ["~> 0.1"])
|
53
|
+
s.add_development_dependency(%q<builtinextension>, ["~> 0.1"])
|
54
|
+
else
|
55
|
+
s.add_dependency(%q<rdoc>, ["~> 4.2"])
|
56
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
57
|
+
s.add_dependency(%q<jeweler>, ["~> 2.3"])
|
58
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
59
|
+
s.add_dependency(%q<test-unit>, ["~> 3.2"])
|
60
|
+
s.add_dependency(%q<filerenamer>, ["~> 0.0"])
|
61
|
+
s.add_dependency(%q<tefil>, ["~> 0.1"])
|
62
|
+
s.add_dependency(%q<builtinextension>, ["~> 0.1"])
|
63
|
+
end
|
64
|
+
else
|
65
|
+
s.add_dependency(%q<rdoc>, ["~> 4.2"])
|
66
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
67
|
+
s.add_dependency(%q<jeweler>, ["~> 2.3"])
|
68
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
69
|
+
s.add_dependency(%q<test-unit>, ["~> 3.2"])
|
70
|
+
s.add_dependency(%q<filerenamer>, ["~> 0.0"])
|
71
|
+
s.add_dependency(%q<tefil>, ["~> 0.1"])
|
72
|
+
s.add_dependency(%q<builtinextension>, ["~> 0.1"])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
data/lib/gomiko.rb
CHANGED
@@ -32,7 +32,8 @@ class Gomiko
|
|
32
32
|
# throw all exist file and report not exist files.
|
33
33
|
def throw(paths: , time: Time.new, verbose: true)
|
34
34
|
paths = paths.select do |path|
|
35
|
-
flag = FileTest.exist?
|
35
|
+
flag = FileTest.symlink?(path) || FileTest.exist?(path) # for deadlink
|
36
|
+
#flag = FileTest.exist?(path) # for deadlink
|
36
37
|
unless flag
|
37
38
|
if verbose
|
38
39
|
puts "gomiko rm: cannot remove '#{path}': No such file or directory"
|
@@ -47,8 +48,13 @@ class Gomiko
|
|
47
48
|
dst = trash_subdir + File.expand_path(path)
|
48
49
|
dst_dir = File.dirname dst
|
49
50
|
FileUtils.mkdir_p(dst_dir)
|
50
|
-
|
51
|
-
|
51
|
+
if path == '.'
|
52
|
+
puts "gomiko rm: failed to remove '.': Invalid argument" if verbose
|
53
|
+
next
|
54
|
+
else
|
55
|
+
FileUtils.mv(path, dst_dir + '/', :verbose => verbose)
|
56
|
+
File.utime(time, time, trash_subdir)
|
57
|
+
end
|
52
58
|
end
|
53
59
|
end
|
54
60
|
|
@@ -93,85 +99,66 @@ class Gomiko
|
|
93
99
|
results = []
|
94
100
|
results << `du --human-readable --max-depth=0 #{cur_trash_dir}`.split(' ')[0]
|
95
101
|
results << id
|
96
|
-
#pp results
|
97
102
|
|
98
|
-
# 元のパスにファイルが存在しないものを抽出。
|
99
103
|
trash_paths = Dir.glob("#{cur_trash_dir}/**/*", File::FNM_DOTMATCH).sort
|
104
|
+
trash_paths = trash_paths.select { |t_path| ! /\/\.$/.match t_path } # '/.', で終わるのを除外
|
100
105
|
|
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
106
|
candidates = [] # fo rm target
|
123
107
|
results_long = []
|
108
|
+
additions = []
|
109
|
+
#flag_conflict = false
|
110
|
+
flag_include_file = false
|
124
111
|
trash_paths.each do |trash_path|
|
112
|
+
#pp trash_path
|
125
113
|
orig_path = trash_path.sub(/^#{cur_trash_dir}/, '')
|
126
114
|
trash_type = ftype_str(trash_path)
|
115
|
+
|
116
|
+
flag_include_file = true unless File.directory? trash_path
|
127
117
|
if FileTest.exist? orig_path
|
128
118
|
orig_type = ftype_str(orig_path)
|
129
|
-
|
130
|
-
|
119
|
+
if File.ftype(trash_path) != File.ftype(orig_path)
|
120
|
+
#flag_conflict = true
|
121
|
+
additions << 'conflict'
|
131
122
|
candidates << trash_path
|
132
123
|
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
124
|
else
|
146
125
|
candidates << trash_path
|
147
126
|
orig_type = ' '
|
148
127
|
end
|
149
128
|
results_long << [ trash_type, orig_type,
|
150
|
-
trash_path.sub(/^#{cur_trash_dir}/, '')
|
151
|
-
|
129
|
+
trash_path.sub(/^#{cur_trash_dir}/, '') ]
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
#pp flag_include_file
|
134
|
+
unless flag_include_file
|
135
|
+
pp 'a'
|
136
|
+
additions << 'only directory'
|
137
|
+
candidates << trash_paths[-1]
|
152
138
|
end
|
153
139
|
|
154
140
|
## if no candidate, last file is adopted.
|
141
|
+
#pp candidates
|
142
|
+
#pp trash_paths
|
155
143
|
if trash_paths.empty?
|
156
144
|
results << '(empty)'
|
157
145
|
results << []
|
158
146
|
else
|
159
|
-
|
160
|
-
|
147
|
+
#flag_conflict = true if candidates.empty?
|
148
|
+
additions << 'conflict' if candidates.empty?
|
161
149
|
candidates = candidates.map {|path|
|
162
150
|
tmp = path.sub(/^#{cur_trash_dir}/, '')
|
163
151
|
tmp += '/' if FileTest.directory? path
|
164
152
|
tmp
|
165
153
|
}
|
166
|
-
candidates = candidates.select {|path| ! FileTest.exist? path }
|
167
154
|
results << candidates[0]
|
168
155
|
|
169
156
|
## output '...' when multiple.
|
170
157
|
candidates = candidates.select{|pa| ! pa.include? candidates[0]}
|
171
|
-
#pp candidates; exit
|
172
158
|
results[-1] += ' ...' unless candidates.empty?
|
159
|
+
#results[2] += ' (conflict)' if flag_conflict
|
160
|
+
results[2] += ' (' + additions.join(',') + ')' unless additions.empty?
|
173
161
|
results << results_long
|
174
|
-
#pp results
|
175
162
|
end
|
176
163
|
results
|
177
164
|
end
|
data/test/test_gomiko.rb
CHANGED
@@ -32,7 +32,7 @@ class TC_Gomiko < Test::Unit::TestCase
|
|
32
32
|
assert(FileTest.directory? TRASHDIR)
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
35
|
+
def test_throw1
|
36
36
|
# remove file
|
37
37
|
a_relpath = 'test/tmp/a.txt'
|
38
38
|
a_fullpath = File.expand_path 'test/a.txt'
|
@@ -44,9 +44,9 @@ class TC_Gomiko < Test::Unit::TestCase
|
|
44
44
|
assert(FileTest.exist? ("#{TRASHDIR}/20170123-123456#{a_fullpath_dirname}"))
|
45
45
|
assert_equal( Time.new(2017, 1, 23, 12, 34, 56),
|
46
46
|
File.mtime("#{TRASHDIR}/20170123-123456"))
|
47
|
+
end
|
47
48
|
|
48
|
-
|
49
|
-
|
49
|
+
def test_throw2
|
50
50
|
# remove directory
|
51
51
|
setup
|
52
52
|
a_relpath = 'test/tmp/b/a.txt'
|
@@ -58,13 +58,32 @@ class TC_Gomiko < Test::Unit::TestCase
|
|
58
58
|
assert(FileTest.directory? "#{TRASHDIR}/20170123-123456#{a_fullpath_dirname}")
|
59
59
|
assert_false(FileTest.exist? a_relpath)
|
60
60
|
assert(FileTest.exist? ("#{TRASHDIR}/20170123-123456#{a_fullpath_dirname}"))
|
61
|
-
|
62
61
|
@g00.throw(paths: [a_relpath, 'not_exist'],
|
63
62
|
time: Time.new(2017, 1, 23, 12, 34, 56),
|
64
63
|
verbose: false)
|
65
64
|
assert_false(FileTest.exist? (a_relpath))
|
66
65
|
end
|
67
66
|
|
67
|
+
def test_throw3
|
68
|
+
# remove deadlink
|
69
|
+
a_relpath = 'test/tmp/a.txt'
|
70
|
+
b_relpath = 'test/tmp/b.txt'
|
71
|
+
a_fullpath = File.expand_path 'test/a.txt'
|
72
|
+
a_fullpath_dirname = File.dirname a_fullpath
|
73
|
+
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)
|
77
|
+
assert_false(FileTest.exist? a_relpath)
|
78
|
+
assert_false(FileTest.symlink? a_relpath)
|
79
|
+
pp "#{TRASHDIR}/20170123-123456#{a_fullpath_dirname}"
|
80
|
+
#sleep 60
|
81
|
+
|
82
|
+
t = "#{TRASHDIR}/20170123-123456#{a_fullpath_dirname}"
|
83
|
+
assert(FileTest.directory? t)
|
84
|
+
assert_false(FileTest.exist? a_relpath)
|
85
|
+
end
|
86
|
+
|
68
87
|
def test_empty1
|
69
88
|
a_relpath = 'test/tmp/a.txt'
|
70
89
|
a_fullpath = File.expand_path 'test/tmp/a.txt'
|
@@ -274,16 +293,29 @@ class TC_Gomiko < Test::Unit::TestCase
|
|
274
293
|
assert_equal("#{WORKDIR}/a/ ...", results[2])
|
275
294
|
end
|
276
295
|
|
277
|
-
def test_info5
|
296
|
+
def test_info5 # symlink
|
278
297
|
FileUtils.mkdir_p "#{WORKDIR}/a/b"
|
279
|
-
@g00.throw(paths: ["#{WORKDIR}/a"
|
298
|
+
@g00.throw(paths: ["#{WORKDIR}/a"],
|
280
299
|
time: Time.new(2017, 1, 23, 12, 34, 56),
|
281
300
|
verbose: false)
|
282
301
|
FileUtils.mkdir_p "#{WORKDIR}/a/b"
|
283
302
|
results = @g00.info("20170123-123456")
|
284
303
|
#pp results
|
285
304
|
assert_equal('20170123-123456', results[1])
|
286
|
-
assert_equal("#{WORKDIR}/a/b (
|
305
|
+
assert_equal("#{WORKDIR}/a/b/ (only directory)", results[2])
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_info6
|
309
|
+
FileUtils.touch("#{WORKDIR}/b")
|
310
|
+
FileUtils.ln_s("#{WORKDIR}/b", "#{WORKDIR}/a")
|
311
|
+
@g00.throw(paths: ["#{WORKDIR}/a"],
|
312
|
+
time: Time.new(2017, 1, 23, 12, 34, 56),
|
313
|
+
verbose: false)
|
314
|
+
FileUtils.touch("#{WORKDIR}/a")
|
315
|
+
results = @g00.info("20170123-123456")
|
316
|
+
#pp results
|
317
|
+
assert_equal('20170123-123456', results[1])
|
318
|
+
assert_equal("#{WORKDIR}/a (conflict)", results[2])
|
287
319
|
end
|
288
320
|
|
289
321
|
def test_graft
|
@@ -315,6 +347,5 @@ class TC_Gomiko < Test::Unit::TestCase
|
|
315
347
|
assert_equal("20170123-123456", @g00.path2id("#{TRASHDIR}/20170123-123456"))
|
316
348
|
assert_equal("20170123-123456", @g00.path2id("20170123-123456"))
|
317
349
|
end
|
318
|
-
|
319
350
|
end
|
320
351
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gomiko
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ippei94da
|
@@ -135,16 +135,17 @@ executables:
|
|
135
135
|
extensions: []
|
136
136
|
extra_rdoc_files:
|
137
137
|
- LICENSE.txt
|
138
|
-
- README.
|
138
|
+
- README.md
|
139
139
|
files:
|
140
140
|
- ".document"
|
141
141
|
- CHANGES
|
142
142
|
- Gemfile
|
143
143
|
- LICENSE.txt
|
144
|
-
- README.
|
144
|
+
- README.md
|
145
145
|
- Rakefile
|
146
146
|
- VERSION
|
147
147
|
- bin/gomiko
|
148
|
+
- gomiko.gemspec
|
148
149
|
- lib/gomiko.rb
|
149
150
|
- test/.gitignore
|
150
151
|
- test/helper.rb
|
data/README.rdoc
DELETED
@@ -1,19 +0,0 @@
|
|
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
|
-
|