filerenamer 0.0.9 → 0.0.10

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: ef14039a2f5ed2d362eaeb3fa26968426fcc67aa
4
- data.tar.gz: d5c8622c63d425f3ea1214835aa91c4b699457a4
3
+ metadata.gz: e838a2d6a783cce04970448bddc5fb3574aa95b2
4
+ data.tar.gz: de135ba52d266080dc0cfcbbf7e398c0ce6f83c0
5
5
  SHA512:
6
- metadata.gz: 7d8bb22c6030f5c4e3893c5fb215909fabacd9e4c4d95871b3a27f7f2d8744a456087c2e375de274e39c9c0f2cc720d407f949c0de38b4a74240c4e9c83a6777
7
- data.tar.gz: d517de1ee14162d122758470b4403ca8c8275ec65f01ec439e3628c2d57b5ab229f266fe8e54dbee9a1ae82e7aad491c33a8f2edd18e33a2c362cdbada0d40a7
6
+ metadata.gz: 2ab52c0bcf4209aef9fe09be8b7befe694bd4d503fb1865256b18b8d9f8a39f1df0e17a77f94f52243290827e1199b687245082a02882eb9dc5ad03d95e2c998
7
+ data.tar.gz: 46bbdb06d50e86f2bb20210a24ac9437e00c80306946fde25bd8c80a380da436ee974ee6f36c112d9afaed1bc34a21bdb2ce7f239bd8166f066dd7fba971bd40
data/CHANGES CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  <!-- Master -->
4
4
 
5
+
6
+ == Version 0.0.10 [2017-03-04] released
7
+
8
+ * Add RenameOrderer, a smart dependency resolver of rename processes.
9
+ * bin/rennum; --random option was renamed to --shuffle
10
+ * bin/rentime --jpg
11
+ * bin/rentime --tiff
12
+
5
13
  == Version 0.0.9 [2016-07-12] released
6
14
 
7
15
  * Add --git option
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.9
1
+ 0.0.10
@@ -2,11 +2,11 @@
2
2
  # coding: utf-8
3
3
 
4
4
  require "pp"
5
- gem "builtinextension"
5
+ #gem "builtinextension"
6
6
  require "string/escapezsh.rb"
7
7
  require "filerenamer.rb"
8
8
  #require "filerenamer/commander.rb"
9
- require "filerenamer/optionparser.rb"
9
+ #require "filerenamer/optionparser.rb"
10
10
 
11
11
  OPTIONS = {}
12
12
  op = FileRenamer::OptionParser.new
data/bin/rennum CHANGED
@@ -6,8 +6,9 @@
6
6
  # -i オプションで開始番号を指定
7
7
  # -p : preserve old name 元のファイル名を残す。foo.txt -> 001-foo.txt
8
8
  require 'pp'
9
- require 'filerenamer/commander.rb'
10
- require 'filerenamer/optionparser.rb'
9
+ require "filerenamer.rb"
10
+ #require 'filerenamer/commander.rb'
11
+ #require 'filerenamer/optionparser.rb'
11
12
 
12
13
 
13
14
  OPTIONS = {}
@@ -18,8 +19,8 @@ op.on("-i num", "--initial", "Indicate initial number."){ |val|
18
19
  op.on("-p", "--preserve", "Preserve old name."){
19
20
  OPTIONS[:preserve] = true
20
21
  }
21
- op.on("-r", "--random", "Random number."){
22
- OPTIONS[:random] = true
22
+ op.on("--shuffle", "Shuffle number."){
23
+ OPTIONS[:shuffle] = true
23
24
  }
24
25
  op.parse!(ARGV)
25
26
 
@@ -29,7 +30,7 @@ files = FileRenamer::Commander.files(ARGV)
29
30
  last_number = OPTIONS[:init].to_i + files.size - 1
30
31
  width = last_number.to_s.size
31
32
 
32
- files.shuffle! if OPTIONS[:random]
33
+ files.shuffle! if OPTIONS[:shuffle]
33
34
 
34
35
  fr = FileRenamer::Commander.new(op.options, files)
35
36
 
data/bin/renpad CHANGED
@@ -4,8 +4,9 @@
4
4
  # Pad 0 onto the first numeric character series in filenames to become the same length.
5
5
 
6
6
  require "pp"
7
- require "filerenamer/commander.rb"
8
- require "filerenamer/optionparser.rb"
7
+ require "filerenamer.rb"
8
+ #require "filerenamer/commander.rb"
9
+ #require "filerenamer/optionparser.rb"
9
10
 
10
11
  PATTERN = /^(\D*)(\d+)(.*)$/
11
12
 
data/bin/renpar CHANGED
@@ -11,8 +11,9 @@ require "rubygems"
11
11
  gem "builtinextension"
12
12
  require "string/splitparens.rb"
13
13
 
14
- require "filerenamer/commander.rb"
15
- require "filerenamer/optionparser.rb"
14
+ require "filerenamer.rb"
15
+ #require "filerenamer/commander.rb"
16
+ #require "filerenamer/optionparser.rb"
16
17
 
17
18
 
18
19
  OPTIONS = {}
data/bin/renreg CHANGED
@@ -1,8 +1,9 @@
1
1
  #! /usr/bin/env ruby
2
2
  # coding: utf-8
3
3
 
4
- require "filerenamer/commander.rb"
5
- require "filerenamer/optionparser.rb"
4
+ require "filerenamer.rb"
5
+ #require "filerenamer/commander.rb"
6
+ #require "filerenamer/optionparser.rb"
6
7
 
7
8
  op = FileRenamer::OptionParser.new
8
9
  op.parse!(ARGV)
data/bin/rensub CHANGED
@@ -1,8 +1,9 @@
1
1
  #! /usr/bin/env ruby
2
2
  # coding: utf-8
3
3
 
4
- require "filerenamer/commander.rb"
5
- require "filerenamer/optionparser.rb"
4
+ require "filerenamer.rb"
5
+ #require "filerenamer/commander.rb"
6
+ #require "filerenamer/optionparser.rb"
6
7
 
7
8
  OPTIONS = {}
8
9
  op = FileRenamer::OptionParser.new
@@ -4,27 +4,35 @@
4
4
  require "pp"
5
5
  require "filerenamer.rb"
6
6
  require "optparse"
7
+ require "exifr"
7
8
 
8
9
  ## option analysis
9
10
  OPTIONS = {}
10
- op = OptionParser.new
11
+ op = FileRenamer::OptionParser.new
11
12
  #op.banner = [
12
13
  # "Usage: #{File.basename("#{__FILE__}")}",
13
14
  #].join("\n")
14
- op.on("-p" , "--preserve" , "Preserve old name"){OPTIONS[:preserve] = true}
15
- op.parse!(ARGV)
16
-
17
- op = FileRenamer::OptionParser.new
15
+ op.on("-p", "--preserve", "preserve old name"){OPTIONS[:preserve] = true}
16
+ op.on("-j", "--jpg" , "exif date_time_original from JPG"){OPTIONS[:jpg] = true}
17
+ op.on("-t", "--tiff", "exif date_time_original from TIFF"){OPTIONS[:tiff] = true} # Canon CR2, Nikon NEF
18
+ op.on("-s char", "--separator=char", "Separator like '/' in 'YY/MM/DD/'"){|v| OPTIONS[:separator] = v}
18
19
  op.parse!(ARGV)
20
+ s = OPTIONS[:separator]
19
21
 
20
22
  fr = FileRenamer::Commander.new(op.options, ARGV)
21
23
  fr.execute do |filename|
22
24
  extname = File.extname filename
23
25
  old_base = filename.sub(/#{extname}$/, "")
24
26
  dirname = File.dirname filename
25
- date = File.mtime(filename)
27
+ if OPTIONS[:jpg]
28
+ date = EXIFR::JPEG.new(filename).date_time
29
+ elsif OPTIONS[:tiff]
30
+ date = EXIFR::TIFF.new(filename).date_time
31
+ else
32
+ date = File.mtime(filename)
33
+ end
26
34
 
27
- new_basename = dirname + date.strftime("/%Y%m%d-%H%M%S")
35
+ new_basename = dirname + date.strftime("/%Y#{s.to_s}%m#{s.to_s}%d#{s || '-'}%H%M%S")
28
36
  new_basename += "-#{old_base}" if OPTIONS[:preserve]
29
37
  newname = new_basename + extname
30
38
  newname
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,16 +1,6 @@
1
1
  require "fileutils"
2
2
  require "filerenamer/commander.rb"
3
3
  require "filerenamer/optionparser.rb"
4
- #require "filerenamer/manipulation.rb"
5
- #require "filerenamer/manipulation/mv.rb"
6
- #require "filerenamer/manipulation/cp.rb"
7
- #require "filerenamer/manipulation/ln.rb"
8
- #require "filerenamer/manipulation/lns.rb"
9
- ##require "filerenamer/manipulation/rm.rb"
10
- #require "filerenamer/manipulationqueue.rb"
11
- ##require "filerenamer/manipulation/mkdirp.rb" not prepare due to ambiguous behavior.
12
- ##require "filerenamer/manipulation/rmdirp.rb" not prepare due to ambiguous behavior.
13
- #require "filerenamer/filetreesimulator.rb"
14
- #require "filerenamer/filetreesimulator/file.rb"
4
+ require "filerenamer/renameorderer.rb"
15
5
 
16
6
  module FileRenamer; end
@@ -1,14 +1,15 @@
1
1
  #! /usr/bin/env ruby
2
2
  # coding: utf-8
3
3
 
4
+ #gem "builtinextension"
5
+ require "filerenamer/optionparser.rb"
6
+ require "fileutils"
7
+ require "optparse"
4
8
  require "rubygems"
5
- gem "builtinextension"
6
9
  require "string/escapezsh.rb"
7
10
  require "string/width.rb"
8
-
9
- require "fileutils"
10
- require "optparse"
11
- require "filerenamer/optionparser.rb"
11
+ require 'tmpdir'
12
+ require 'pathname'
12
13
 
13
14
  # ファイル群の名前変更を一括して行うためのクラス。
14
15
  # 他のアプリケーションからも使えるけれど、
@@ -29,7 +30,7 @@ require "filerenamer/optionparser.rb"
29
30
  # 途中まで変換してから interrupt されたときに
30
31
  # 中にあるファイルごと消される可能性がありそう。
31
32
  # そのため、メソッド内で自分で temporary directory を作成する。
32
- #
33
+ #
33
34
  # 没案
34
35
  # rename_rule メソッドをデフォルトで例外にしておいて、
35
36
  # コマンドスクリプト側で定義するという方法は、
@@ -37,234 +38,243 @@ require "filerenamer/optionparser.rb"
37
38
  # 自由度が少なくなる。
38
39
  # たとえば old_str, new_str を渡したい時と、
39
40
  # 更新時刻でリネームしたいときでは必要な引数の数が異なる。
40
- module FileRenamer
41
- class Commander
42
- attr_reader :files
43
-
44
- class NoRenameRuleError < Exception; end
45
- class OptionError < Exception; end
46
-
47
- def self.files(strs)
48
- if strs.empty?
49
- return Dir::glob("*").sort
50
- else
51
- return strs
52
- end
41
+ class FileRenamer::Commander
42
+ attr_reader :files
43
+
44
+ class NoRenameRuleError < StandardError; end
45
+ class OptionError < StandardError; end
46
+ class ModeError < StandardError; end
47
+
48
+ def self.files(strs)
49
+ if strs.empty?
50
+ return Dir::glob("*").sort
51
+ else
52
+ return strs
53
53
  end
54
+ end
54
55
 
55
- #:yes と :no が両方 true ならば例外。
56
- #:copy, :move, :hardlink, :symlink, :git のうち、1つ以下が true。
57
- #全て nil ならば :move が true になる。
58
- #:quiet が true ならば自動的に :yes が立てられる。
59
- #:quiet が true で :no も true ならば例外。
60
- def initialize(options, files)
61
- @options = options
62
-
63
- if (@options[:yes] && @options[:no])
64
- raise OptionError,
65
- "Conflict options: --yes and --no."
66
- end
56
+ #:yes と :no が両方 true ならば例外。
57
+ #:copy, :move, :hardlink, :symlink, :git のうち、1つ以下が true。
58
+ #全て nil ならば :move が true になる。
59
+ #:quiet が true ならば自動的に :yes が立てられる。
60
+ #:quiet が true で :no も true ならば例外。
61
+ def initialize(options, files)
62
+ @options = options
67
63
 
68
- fileProcessModes = []
69
- [:move, :copy, :hardlink, :symlink, :git].each do |mode|
70
- fileProcessModes << mode if @options[mode]
71
- end
72
- # 1つもなければ :move に。
73
- @options[:move] = true if fileProcessModes == []
74
- # 2つ以上あれば例外。
75
- if fileProcessModes.size > 1
76
- raise OptionError,
77
- "File process modes duplicate: #{fileProcessModes.join(", ")}"
78
- end
79
- @command = "mv" if @options[:move]
80
- @command = "cp -r" if @options[:copy]
81
- @command = "ln" if @options[:hardlink]
82
- @command = "ln -s" if @options[:symlink]
83
- @command = "git mv" if @options[:git]
84
-
85
- # :quiet ならば自動的に :yes
86
- @options[:yes] = true if @options[:quiet]
87
-
88
- # :quiet と同時に :no なら例外
89
- if @options[:quiet] && @options[:no]
90
- raise OptionError,
91
- "Conflict options: --quiet and --no"
92
- end
64
+ if (@options[:yes] && @options[:no])
65
+ raise OptionError, "Conflict options: --yes and --no."
66
+ end
93
67
 
94
- @files = self.class.files(files)
68
+ fileProcessModes = []
69
+ [:move, :copy, :hardlink, :symlink, :git].each do |mode|
70
+ fileProcessModes << mode if @options[mode]
71
+ end
72
+ # mode が1つもなければ :move に。
73
+ @options[:move] = true if fileProcessModes == []
74
+ # 2つ以上あれば例外。
75
+ if fileProcessModes.size > 1
76
+ raise OptionError,
77
+ "File process modes duplicate: #{fileProcessModes.join(", ")}"
95
78
  end
96
79
 
97
- # 変更される名前のリストを表示し、ユーザの指示に従って実行する。
98
- # ユーザの入力は [y|Y] で始まる文字列ならば実行、
99
- # それ以外なら実行しない。
100
- # files は対象のファイル名のリスト。
101
- # 新しい名前の生成方法をブロックで渡す。
102
- # ブロックがなければ例外 FileRenamerNoRenameRuleError
103
- def execute(&block)
104
- new_names = make_new_names(&block)
105
-
106
- ok_files, ng_files = check_new_names(new_names)
107
-
108
- unless @options[:quiet]
109
- if ok_files.size > 0
110
- puts "Enable files:"
111
- max_width = ok_files.keys.max_by{|file| file.width}.width
112
- ok_files.keys.sort.each do |old|
113
- printf(" %s %s%s %s\n",
114
- @command, old, " " * (max_width - old.width), ok_files[old]
115
- )
116
- end
117
- end
80
+ @mode = :move if @options[:move]
81
+ @mode = :copy if @options[:copy]
82
+ @mode = :hardlink if @options[:hardlink]
83
+ @mode = :symlink if @options[:symlink]
84
+ @mode = :git if @options[:git]
85
+
86
+ case @mode
87
+ when :move ; then; @command = "mv"
88
+ when :copy ; then; @command = "cp -r"
89
+ when :hardlink ; then; @command = "ln"
90
+ when :symlink ; then; @command = "ln -s"
91
+ when :git ; then; @command = "git mv"
92
+ else
93
+ raise ModeError, "Unknown mode: #{@mode}"
94
+ end
118
95
 
119
- if ng_files.size > 0
120
- puts "Unable files:"
121
- max_width = ng_files.keys.max_by{|file| file.width}.width
122
- ng_files.keys.sort.each do |old|
123
- printf(" %s %s%s %s\n",
124
- @command, old, " " * (max_width - old.width), ng_files[old]
125
- )
126
- end
127
- puts
128
- end
129
- end
96
+ @options[:yes] = true if @options[:quiet] # :quiet ならば自動的に :yes
130
97
 
131
- if ok_files.empty?
132
- puts "Done. No executable files." unless @options[:quiet]
133
- return
134
- elsif @options[:no]
135
- puts "Execute? no"
136
- return
137
- end
98
+ if @options[:quiet] && @options[:no] # :quiet と同時に :no なら例外
99
+ raise OptionError, "Conflict options: --quiet and --no"
100
+ end
138
101
 
139
- if @options[:yes]
140
- puts "Execute? yes" unless @options[:quiet]
141
- elsif (! ask_yes?)
142
- return
143
- end
144
- ok_files.each do |old, new|
145
- run(old, new)
102
+ @files = self.class.files(files)
103
+ end
104
+
105
+ # 変更される名前のリストを表示し、ユーザの指示に従って実行する。
106
+ # ユーザの入力は [y|Y] で始まる文字列ならば実行、
107
+ # それ以外なら実行しない。
108
+ # 新しい名前の生成方法をブロックで渡す。
109
+ # ブロックがなければ例外 FileRenamerNoRenameRuleError
110
+ def execute(&block)
111
+ new_names = make_new_names(&block)
112
+
113
+ if @mode == :move || @mode == :git
114
+ ro = FileRenamer::RenameOrderer.new(new_names)
115
+ ok_files = ro.rename_processes
116
+ ng_files = ro.unable_processes
117
+ else
118
+ ok_files = []
119
+ ng_files = []
120
+ new_names.each do |old, new|
121
+ if File.exist? new
122
+ ng_files << [old, new]
123
+ else
124
+ ok_files << [old, new]
125
+ end
146
126
  end
147
127
  end
148
128
 
149
- private
129
+ show_conversions(ok_files, "Enable files:")
130
+ #show_conversions(ng_files, "Unable files:")
131
+
132
+ (puts "Execute? no"; return) if @options[:no]
150
133
 
151
- def make_new_names(&block)
152
- #pp @files
153
- results = {}
154
- @files.each { |i| results[i] = yield i }
155
- return results
134
+ if ok_files.empty?
135
+ puts "Done. No executable files." unless @options[:quiet]
136
+ return
156
137
  end
157
138
 
158
- # 新しい名前リストを受け取り、問題なくリネームできるものと
159
- # できないものを選別する。
160
- # OK, NG の順に2つの配列を返す。
161
- #
162
- # 判断基準は、以下の AND 条件。
163
- # - 新しい名前が古い名前リストに含まれないこと。
164
- # - 新しい名前が新しい名前リストに1つ(自分)のみしかないこと。
165
- # - 新しい名前のファイルが既に存在しないこと。
166
- #
167
- # 没案
168
- # 新しい名前が変換されない古い名前であれば、
169
- # これも NG リストに追加する。(表示用)
170
- # このルールにすると、変換に順序依存が生じる可能性があり、
171
- # temporary directory を経由する必要ができる。
172
- # その結果、リネーム過程で深い temporary directory を
173
- # 作成したり削除したりしなければならなくなる。
174
- def check_new_names(old_new_hash)
175
- ok_files = {}
176
- ng_files = {}
177
-
178
- old_new_hash.each do |old, new|
179
- # 変化がない場合はスルー
180
- next if old == new
181
-
182
- # 新しい名前に nil が定義されていてもスルー
183
- next if new == nil
184
-
185
- # 既に存在していれば、既に存在するファイルごと NG に登録。
186
- if FileTest.exist?(new)
187
- ng_files[old] = new
188
- ng_files[new] = new
189
- next
190
- end
139
+ if @options[:yes]
140
+ puts "Execute? yes" unless @options[:quiet]
141
+ elsif (! ask_yes?)
142
+ return
143
+ end
191
144
 
192
- # new が複数 重複していれば、 NG。
193
- if (old_new_hash.values.select{|name| name == new}.size > 1)
194
- ng_files[old] = new
195
- next
196
- end
145
+ convert( ok_files)
146
+ end
197
147
 
198
- # new が old に含まれていれば、NG。
199
- if (old_new_hash.keys.include?(new))
200
- ng_files[old] = new
201
- next
202
- end
148
+ private
149
+
150
+ def show_conversions(conversions, heading)
151
+ #STDOUT.puts conversions
152
+ return if conversions.size == 0
153
+ return if @options[:quiet]
154
+ puts heading
155
+ max_width = conversions.max_by{|old, new| old.width}[0].width
156
+ conversions.each do |old, new|
157
+ printf(" %s %s%s %s\n",
158
+ @command, old, " " * (max_width - old.width), new
159
+ )
160
+ end
161
+ puts
162
+ end
203
163
 
204
- # 上記以外の場合ならば OK
164
+ def make_new_names(&block)
165
+ results = {}
166
+ @files.each { |i| results[i] = yield i }
167
+ return results
168
+ end
205
169
 
206
- ok_files[old] = new
207
- end
208
- return ok_files, ng_files
170
+ ## 新しい名前リストを受け取り、問題なくリネームできるものと
171
+ ## できないものを選別する。
172
+ ## OK, NG の順に2つの配列を返す。
173
+ ##def ok_new_names(old_new_hash)
174
+ ##end
175
+ ##def ng_new_names(old_new_hash)
176
+ #def check_new_names(old_new_hash)
177
+ # ok_files = {}
178
+ # ng_files = {}
179
+
180
+ # old_new_hash.each do |old, new|
181
+ # next if old == new # 変化がない場合は無視
182
+ # next if new == nil # 新しい名前に nil が定義されていたら無視
183
+
184
+ # #宛先が、宛先リスト内で重複していると、NG リスト入り
185
+ # if (old_new_hash.values.select{|name| name == new}.size > 1)
186
+ # ng_files[old] = new
187
+ # next
188
+ # end
189
+
190
+ # # 宛先パスにファイルが既存、かつ、元ファイル名リストに含まれていなければ、NG
191
+ # if FileTest.exist?(new) && ! old_new_hash.keys.include?(new)
192
+ # ng_files[old] = new
193
+ # next
194
+ # end
195
+
196
+ # ok_files[old] = new # 上記以外の場合ならば OK
197
+ # end
198
+ # return ok_files, ng_files
199
+ #end
200
+
201
+ # ユーザに判断を求める。
202
+ # 標準入力から文字列を受け取り、
203
+ # [y|Y] から始まる文字列なら true を、
204
+ # それ以外なら false を返す。
205
+ def ask_yes?
206
+ puts "Execute?"
207
+ if /^y/i =~ $stdin.gets
208
+ return true
209
+ else
210
+ return false
209
211
  end
212
+ end
210
213
 
211
- # ユーザに判断を求める。
212
- # 標準入力から文字列を受け取り、
213
- # [y|Y] から始まる文字列なら true を、
214
- # それ以外なら false を返す。
215
- def ask_yes?
216
- puts "Execute?"
217
- str = $stdin.gets
218
- if /^y/i =~ str
219
- return true
220
- else
221
- return false
222
- end
214
+ # コマンドを表示しつつ実行。
215
+ # 既にファイルチェックされているはずなので、チェックはしない。
216
+ # ディレクトリが必要になればここで作成。
217
+ # ディレクトリが不要になればここで削除。
218
+ def convert(conversions)
219
+ #tmpdir = Dir.mktmpdir('rename', './')
220
+
221
+ #int_paths = {} #intermediate paths
222
+ #conversions.each { |old, new| int_paths[old] = tmpdir + '/' + old }
223
+ #conversions.each { |old, new| int_paths[old] = tmpdir + '/' + old }
224
+ #int_paths.each { |old, int| transplant(old, int) }
225
+ #int_paths.each { |old, int| rmdir_p old }
226
+
227
+ conversions.each { |old, new| transplant(old, new) }
228
+ #int_paths.each { |old, int| rmdir_p int }
229
+ end
230
+
231
+ # Move from root to root.
232
+ # src_path and tgt_path are paths.
233
+ def transplant(src_path, tgt_path)
234
+ #pp src_path, tgt_path;exit
235
+ # 変換先のディレクトリがなければ生成
236
+ tgt_dir = File.dirname(tgt_path)
237
+ unless FileTest.exist?(tgt_dir)
238
+ #puts " make directory: #{tgt_dir}" unless @options[:quiet]
239
+ FileUtils.mkdir_p(tgt_dir)
223
240
  end
224
241
 
225
- # コマンドを表示しつつ実行。
226
- # 既にファイルチェックされているはずなので、チェックはしない。
227
- # 少なくとも当面は。
228
- # ディレクトリが必要ならここで作成。
229
- # ディレクトリが不要になればここで削除。
230
- # 本来ここでない方が分かり易い気もするのだが、ここに追加するのが一番簡単なので。
231
- def run(old, new)
232
- # 変換先のディレクトリがなければ生成
233
- #pp old, new; exit
234
- paths(new).each do |directory|
235
- unless FileTest.exist?(directory)
236
- puts " make directory: #{directory}" unless @options[:quiet]
237
- FileUtils.mkdir_p(directory)
238
- end
239
- end
242
+ # 変換の実行
243
+ command = " #{@command} #{src_path.escape_zsh} #{tgt_path.escape_zsh}"
244
+ #puts command unless @options[:quiet]
245
+ system(command)
246
+
247
+ ##STDIN.gets
248
+ # 変換元のディレクトリが空になっていれば削除
249
+ src_dir = File.dirname(src_path)
250
+ #pp Dir.entries(src_dir)
251
+ if Dir.entries(src_dir).size == 2 # . と .. のみ
252
+ #puts " remove directory: #{src_dir}" unless @options[:quiet]
253
+ rmdir_p(src_dir)
254
+ end
255
+ end
240
256
 
241
- # 変換の実行
242
- command = " #{@command} #{old.escape_zsh} #{new.escape_zsh}"
243
- puts command unless @options[:quiet]
244
- system(command)
245
-
246
- # 変換元のディレクトリが空になっていれば削除
247
- dirs = paths(old)
248
- dirs.reverse.each do |directory|
249
- if Dir.entries(directory).size == 2 # . と .. のみ
250
- puts " remove directory: #{directory}" unless @options[:quiet]
251
- Dir.rmdir(directory)
252
- end
253
- end
257
+ # パスに含まれるディレクトリ名を、階層ごとに切り分けたソート済配列にして返す。
258
+ # 最後の要素は含まない。
259
+ # e.g. foo/bar/baz.txt => ["foo", "foo/bar"]
260
+ # e.g. /foo/bar/baz.txt => ["/foo", "foo/bar"]
261
+ def paths(path)
262
+ dirs = path.split("/")
263
+ results = []
264
+ (dirs.size - 1).times do |i|
265
+ results << dirs[0..i].join("/")
254
266
  end
267
+ results.delete_at(0) if results[0] == ""
268
+ return results
269
+ end
255
270
 
256
- # パスに含まれるディレクトリ名を、階層ごとに切り分けたソート済配列にして返す。
257
- # 最後の要素は含まない。
258
- # e.g. foo/bar/baz.txt => ["foo", "foo/bar"]
259
- # e.g. /foo/bar/baz.txt => ["/foo", "foo/bar"]
260
- def paths(path)
261
- dirs = path.split("/")
262
- results = []
263
- (dirs.size - 1).times do |i|
264
- results << dirs[0..i].join("/")
271
+ def rmdir_p(path)
272
+ Pathname.new(path).ascend do |p_path|
273
+ begin
274
+ Dir.rmdir p_path
275
+ rescue
276
+ break
265
277
  end
266
- results.delete_at(0) if results[0] == ""
267
- return results
268
278
  end
269
279
  end
270
280
  end