-
Notifications
You must be signed in to change notification settings - Fork 0
/
back_that_ass_up.rb
172 lines (163 loc) · 4.73 KB
/
back_that_ass_up.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# back_that_ass_up.rb
# This script will pull a directory structure up, decreasing the total depth of
# any given file. Example:
#
# >ls dir
# foo bar baz
# >ls dir/foo
# a b c
# >back_that_ass_up dir
# >ls
# dir dir_foo dir_bar dir_baz
# >ls dir_foo
# a b c
#
# OR with depth 2
#
# >back_that_ass_up -2 dir
# >ls
# dir dir_foo_a dir_foo_b dir_foo_c dir_bar dir_baz
#
# OR destructively (and reconstructively)
#
# >back_that_ass_up -2 -destructive dir
# >ls -a
# .dir.btau .dir_foo.btau dir_foo_a dir_foo_b dir_foo_c dir_bar dir_baz
# >cat .dir_foo.btau
# This file was generated by back_that_ass_up.rb in order to allow reconstruction
# of the directory: dir/foo.
#
# AND then to reconstruct
#
# >back_that_ass_up -reconstruct dir
# >ls -a
# dir
require 'fileutils'
require 'pathname'
d = 1
$debug = false
$destructive = false
$reconstruct = false
b = nil
while arg = ARGV.shift
case
when arg =~ /^-(\d+)$/
d = $1.to_i
when arg == "-debug"
$debug = true
when arg == "-destructive"
$destructive = true
when arg == "-reconstruct"
$reconstruct = true
else
# I guess its the base directory.
b = Pathname.new(arg)
end
end
exit 1 unless b
exit 2 unless d > 0
exit 3 unless b.exist?
def btau(base, depth)
return [nil, []] if depth <= 0
puts "base: #{base.to_s}"
dirs = Dir[base.to_s + "/*"].select { |dir| File.directory? dir }
puts "dirs are #{Dir[base.to_s + "/*"].join(",")}"
if dirs.empty?
puts "#{base} is empty if directories."
return [nil, []]
end
puts base + " has: " + dirs.join(", ") if $debug
processed_dirs = []
new_dirs = []
dirs.each do |dir|
processed_dir, new_dir = btau(dir, depth-1)
processed_dirs << processed_dir
new_dirs += new_dir
end
processed_dirs.compact!
puts "processed_dirs: "+processed_dirs.join(", ") if $debug
puts "new_dirs: "+new_dirs.join(", ") if $debug
dirs = Dir[base.to_s + "/*"].select { |dir| File.directory? dir }
puts base + " now has: " + dirs.join(", ") if $debug
dirs = dirs - processed_dirs
puts " but only " + dirs.join(", ") + " are unprocessed." if $debug
my_new_dirs = []
dirs.each do |dir|
based = File.dirname(base)
baseb = File.basename(base)
dirb = File.basename(dir)
new_dir = "#{base}_#{dirb}"
my_new_dirs << new_dir
if new_dirs.include? dir
puts "#{dir} was created earlier. Moving instead of copying." if $debug
FileUtils.mv(dir, new_dir)
elsif $destructive
FileUtils.mv(dir, new_dir)
f = File.open(based + "/." + baseb + ".btau", "w")
f.puts "This file was generated by back_that_ass_up.rb in order to allow reconstruction"
f.puts "of the directory: #{base}."
f.close
else
puts "Making #{new_dir}" if $debug
Dir.mkdir new_dir
FileUtils.cp_r(Dir.glob("#{dir}/*"), new_dir)
end
end
processed_dirs.each do |dir|
# Maybe still need to copy/move a processed dir if it has files (not dirs) inside
files = Dir[dir + "/*"].select { |file| File.file? file }
unless files.empty?
puts "#{dir} still has regular files. Copying/moving..." if $debug
based = File.dirname(base)
baseb = File.basename(base)
dirb = File.basename(dir)
new_dir = "#{base}_#{dirb}"
my_new_dirs << new_dir
if new_dirs.include? dir
puts "#{dir} was created earlier. Moving instead of copying." if $debug
FileUtils.mv(dir, new_dir)
elsif $destructive
FileUtils.mv(dir, new_dir)
f = File.open(based + "/." + baseb + ".btau", "w")
f.puts "This file was generated by back_that_ass_up.rb in order to allow reconstruction"
f.puts "of the directory: #{base}."
f.close
else
puts "Making #{new_dir}" if $debug
Dir.mkdir new_dir
FileUtils.cp(files, new_dir)
end
end
end
return base, my_new_dirs
end
def reconstruct(base, depth)
b = Pathname.new(base)
dirname = b.dirname.to_s
basename = b.basename.to_s
dirs = Dir[dirname+"/#{basename}_*"]
btau = "#{dirname}/.#{basename}.btau"
return nil unless File.exists? btau
puts "found: #{btau}" if $debug
return nil unless File.exists? dirname+"/"+basename
puts "found: #{b}" if $debug
dirs.each do |dir|
new_dir = dir.sub(/^(.*)\/#{basename}_([^\/]+)$/, '\1/' + basename + '/\2')
puts "Moving #{dir} to #{new_dir}"
FileUtils.mv(dir, new_dir)
end
FileUtils.rm(btau)
btaus = Dir[dirname+"/#{basename}/.*"].select {|file| file =~ /\.btau$/}
puts "btaus: "+btaus.join(",") if $debug
btaus.each do |file|
file =~ /(.*)\/\.(.*)\.btau$/
next_dir = $1 + "/" + $2
puts "Next up... #{next_dir}"
reconstruct(next_dir, depth-1)
end
end
if $reconstruct
reconstruct(b.to_s.gsub(/\\/, '/'), d)
else
btau(b.to_s.gsub(/\\/, '/'), d)
end