Skip to content

Commit 9519e76

Browse files
committed
Force removal of even readonly files in higurashi installer.
1 parent 081e28f commit 9519e76

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

higurashiInstaller.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,25 @@
33

44
import commandLineParser
55
import common
6-
import os, os.path as path, shutil, subprocess, glob
6+
import os, os.path as path, shutil, subprocess, glob, stat
77

88
########################################## Installer Functions and Classes ############################################
99
import gameScanner
1010

11+
def on_rm_error(func, path, exc_info):
12+
# path contains the path of the file that couldn't be removed
13+
# let's just assume that it's read-only and unlink it.
14+
os.chmod(path, stat.S_IWRITE)
15+
os.unlink(path)
16+
17+
# Remove a file, even if it's marked as readonly
18+
def forceRemove(path):
19+
os.chmod(path, stat.S_IWRITE)
20+
os.remove(path)
21+
22+
# Call shutil.rmtree, such that it even removes readonly files
23+
def forceRmTree(path):
24+
shutil.rmtree(path, onerror=on_rm_error)
1125

1226
class Installer:
1327
def __init__(self, fullInstallConfiguration):
@@ -80,21 +94,21 @@ def cleanOld(self):
8094

8195
try:
8296
for mg in glob.glob(compiledScriptsPattern):
83-
os.remove(mg)
97+
forceRemove(mg)
8498
except Exception:
8599
print('WARNING: Failed to clean up the [{}] compiledScripts'.format(compiledScriptsPattern))
86100
traceback.print_exc()
87101

88102
try:
89103
if path.isdir(oldCG):
90-
shutil.rmtree(oldCG)
104+
forceRmTree(oldCG)
91105
except Exception:
92106
print('WARNING: Failed to clean up the [{}] directory'.format(oldCG))
93107
traceback.print_exc()
94108

95109
try:
96110
if path.isdir(oldCGAlt):
97-
shutil.rmtree(oldCGAlt)
111+
forceRmTree(oldCGAlt)
98112
except Exception:
99113
print('WARNING: Failed to clean up the [{}] directory'.format(oldCGAlt))
100114
traceback.print_exc()
@@ -141,7 +155,7 @@ def _moveDirectoryIntoPlace(self, fromDir, toDir):
141155
self._moveDirectoryIntoPlace(fromDir=src, toDir=target)
142156
else:
143157
if path.exists(target):
144-
os.remove(target)
158+
forceRemove(target)
145159
shutil.move(src, target)
146160
os.rmdir(fromDir)
147161

@@ -152,7 +166,7 @@ def _moveFileIntoPlace(self, fromPath, toPath):
152166
"""
153167
if path.exists(fromPath):
154168
if path.exists(toPath):
155-
os.remove(toPath)
169+
forceRemove(toPath)
156170
shutil.move(fromPath, toPath)
157171

158172
def cleanup(self):
@@ -163,8 +177,8 @@ def cleanup(self):
163177
On mac, modifies the application Info.plist with new values if available
164178
"""
165179
try:
166-
shutil.rmtree(self.downloadDir)
167-
shutil.rmtree(self.extractDir)
180+
forceRmTree(self.downloadDir)
181+
forceRmTree(self.extractDir)
168182
except OSError:
169183
pass
170184

0 commit comments

Comments
 (0)