Skip to content

Commit 4a4bbc5

Browse files
committed
Preprocess: automate renaming of case conflicts
This automates renaming of files that conflict on case-insensitive file systems. The search for conflicts respects new names of files renamed because of unwanted characters.
1 parent dacac63 commit 4a4bbc5

File tree

1 file changed

+37
-12
lines changed

1 file changed

+37
-12
lines changed

commands/preprocess.py

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -113,19 +113,35 @@ def find_files_to_be_renamed(root):
113113
new_fn = new_fn.replace('*', '_star_')
114114
result[fn] = new_fn
115115

116-
# rename files that conflict on case-insensitive filesystems
117-
# TODO perform this automatically
118-
result['NAN.html'] = 'NAN.2.html'
116+
# find files that conflict on case-insensitive filesystems
117+
for dir, _, filenames in os.walk(root):
118+
seen = dict()
119+
for fn in (result.get(s, s) for s in filenames):
120+
low = fn.lower()
121+
num = seen.setdefault(low, 0)
122+
if num > 0:
123+
name, ext = os.path.splitext(fn)
124+
# add file with its path -> only rename that occurrence
125+
result[os.path.join(dir, fn)] = "{}.{}{}".format(name, num + 1, ext)
126+
seen[low] += 1
119127

120128
return result
121129

122130
def rename_files(root, rename_map):
123131
for dir, old_fn in ((dir, fn) for dir, _, filenames in os.walk(root) for fn in filenames):
132+
src_path = os.path.join(dir, old_fn)
133+
124134
new_fn = rename_map.get(old_fn)
125-
if new_fn is not None:
126-
src_path = os.path.join(dir, old_fn)
135+
if new_fn:
136+
# look for case conflict of the renamed file
137+
new_path = os.path.join(dir, new_fn)
138+
new_fn = rename_map.get(new_path, new_fn)
139+
else:
140+
# original filename unchanged, look for case conflict
141+
new_fn = rename_map.get(src_path)
142+
if new_fn:
127143
dst_path = os.path.join(dir, new_fn)
128-
print("Renaming '{0}' to \n '{1}'".format(src_path, dst_path))
144+
print("Renaming {0}\n to {1}".format(src_path, dst_path))
129145
shutil.move(src_path, dst_path)
130146

131147
def find_html_files(root):
@@ -143,7 +159,7 @@ def is_loader_link(target):
143159

144160
def transform_loader_link(target, file, root):
145161
# Absolute loader.php links need to be made relative
146-
abstarget = os.path.join(root, "common/" + convert_loader_name(target))
162+
abstarget = os.path.join(root, "common", convert_loader_name(target))
147163
return os.path.relpath(abstarget, os.path.dirname(file))
148164

149165
def is_ranges_placeholder(target):
@@ -175,8 +191,8 @@ def is_external_link(target):
175191
url = urllib.parse.urlparse(target)
176192
return url.scheme != '' or url.netloc != ''
177193

178-
def trasform_relative_link(rename_map, target):
179-
# urllib.parse tuple is (scheme, host, path, params, query, fragment)
194+
def trasform_relative_link(rename_map, target, file):
195+
# urlparse returns (scheme, host, path, params, query, fragment)
180196
_, _, path, params, _, fragment = urllib.parse.urlparse(target)
181197
assert params == ''
182198

@@ -185,8 +201,17 @@ def trasform_relative_link(rename_map, target):
185201
path = path.replace('../mwiki/','../common/')
186202

187203
dir, fn = os.path.split(path)
188-
fn = rename_map.get(fn, fn)
189-
path = os.path.join(dir, fn)
204+
new_fn = rename_map.get(fn)
205+
if new_fn:
206+
# look for case conflict of the renamed file
207+
abstarget = os.path.normpath(os.path.join(os.path.dirname(file), dir, new_fn))
208+
new_fn = rename_map.get(abstarget, new_fn)
209+
else:
210+
# original filename unchanged, look for case conflict
211+
abstarget = os.path.normpath(os.path.join(os.path.dirname(file), path))
212+
new_fn = rename_map.get(abstarget)
213+
if new_fn:
214+
path = os.path.join(dir, new_fn)
190215

191216
path = urllib.parse.quote(path)
192217
return urllib.parse.urlunparse(('', '', path, params, '', fragment))
@@ -205,7 +230,7 @@ def transform_link(rename_map, target, file, root):
205230
if is_external_link(target):
206231
return target
207232

208-
return trasform_relative_link(rename_map, target)
233+
return trasform_relative_link(rename_map, target, file)
209234

210235
def has_class(el, *classes_to_check):
211236
value = el.get('class')

0 commit comments

Comments
 (0)