Skip to content

Commit 3b7bac6

Browse files
committed
Update Cachedir file copy error handling to handle the expected exceptions shutil.SameFileError, IOError for the default copy shutil.copy(). Move notice that file has been retrieved until after the file has actually been copied and didn't thrown exception
1 parent 41f0bdf commit 3b7bac6

File tree

3 files changed

+19
-24
lines changed

3 files changed

+19
-24
lines changed

CHANGES.txt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
1515
From John Doe:
1616
- Whatever John Doe did.
1717

18+
From Raven Kopelman (@ravenAtSafe on GitHub):
19+
- Prevent files from being partially read from the cache. If there's an error while copying the file
20+
is now removed.
21+
1822
From Bill Prendergast:
1923
- Fixed SCons.Variables.PackageVariable to correctly test the default
2024
setting against both enable & disable strings. (Fixes #4702)
@@ -1547,13 +1551,6 @@ RELEASE 4.1.0 - Tues, 19 Jan 2021 15:04:42 -0700
15471551
From Daniel Moody:
15481552
- Fix issue where java parsed a class incorrectly from lambdas used after a new.
15491553

1550-
From Simon Tegelid
1551-
- Fix using TEMPFILE in multiple actions in an action list. Previously a builder, or command
1552-
with an action list like this:
1553-
['${TEMPFILE("xxx.py -otempfile $SOURCE")}', '${TEMPFILE("yyy.py -o$TARGET tempfile")}']
1554-
Could yield a single tempfile with the first TEMPFILE's contents, used by both steps
1555-
in the action list.
1556-
15571554
From Mats Wichmann:
15581555
- Complete tests for Dictionary, env.keys() and env.values() for
15591556
OverrideEnvironment. Enable env.setdefault() method, add tests.

SCons/CacheDir.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import shutil
3131
import stat
3232
import sys
33+
import shutil
3334
import tempfile
3435
import uuid
3536

@@ -61,39 +62,36 @@ def CacheRetrieveFunc(target, source, env) -> int:
6162
cd.CacheDebug('CacheRetrieve(%s): %s not in cache\n', t, cachefile)
6263
return 1
6364
cd.hits += 1
64-
cd.CacheDebug('CacheRetrieve(%s): retrieving from %s\n', t, cachefile)
6565
if SCons.Action.execute_actions:
6666
if fs.islink(cachefile):
6767
fs.symlink(fs.readlink(cachefile), t.get_internal_path())
6868
else:
6969
try:
7070
env.copy_from_cache(cachefile, t.get_internal_path())
71-
except:
72-
try:
71+
except (shutil.SameFileError, IOError) as e:
7372
# In case file was partially retrieved (and now corrupt)
7473
# delete it to avoid poisoning commands like 'ar' that
7574
# read from the initial state of the file they are writing
7675
# to.
7776
t.fs.unlink(t.get_internal_path())
78-
except:
79-
pass
80-
81-
raise
77+
cd.CacheDebug('CacheRetrieve(%s): Error while retrieving from %s deleting %s\n', t, cachefile)
78+
raise e
8279

8380
try:
8481
os.utime(cachefile, None)
8582
except OSError:
8683
pass
8784
st = fs.stat(cachefile)
88-
fs.chmod(t.get_internal_path(), stat.S_IMODE(st.st_mode) | stat.S_IWRITE)
85+
fs.chmod(t.get_internal_path(), stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
86+
cd.CacheDebug('CacheRetrieve(%s): retrieved from %s\n', t, cachefile)
8987
return 0
9088

9189
def CacheRetrieveString(target, source, env) -> str:
9290
t = target[0]
9391
cd = env.get_CacheDir()
9492
cachedir, cachefile = cd.cachepath(t)
9593
if t.fs.exists(cachefile):
96-
return "Retrieving `%s' from cache" % t.get_internal_path()
94+
return "Retrieved `%s' from cache" % t.get_internal_path()
9795
return None
9896

9997
CacheRetrieve = SCons.Action.Action(CacheRetrieveFunc, CacheRetrieveString)

test/CacheDir/debug.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,16 @@ def cat(env, source, target):
144144

145145
expect = \
146146
r"""Retrieved `aaa.out' from cache
147-
CacheRetrieve\(aaa.out\): retrieving from [0-9a-fA-F]+
147+
CacheRetrieve\(aaa.out\): retrieved from [0-9a-fA-F]+
148148
requests: [0-9]+, hits: [0-9]+, misses: [0-9]+, hit rate: [0-9]+\.[0-9]{2,}%
149149
Retrieved `bbb.out' from cache
150-
CacheRetrieve\(bbb.out\): retrieving from [0-9a-fA-F]+
150+
CacheRetrieve\(bbb.out\): retrieved from [0-9a-fA-F]+
151151
requests: [0-9]+, hits: [0-9]+, misses: [0-9]+, hit rate: [0-9]+\.[0-9]{2,}%
152152
Retrieved `ccc.out' from cache
153-
CacheRetrieve\(ccc.out\): retrieving from [0-9a-fA-F]+
153+
CacheRetrieve\(ccc.out\): retrieved from [0-9a-fA-F]+
154154
requests: [0-9]+, hits: [0-9]+, misses: [0-9]+, hit rate: [0-9]+\.[0-9]{2,}%
155155
Retrieved `all' from cache
156-
CacheRetrieve\(all\): retrieving from [0-9a-fA-F]+
156+
CacheRetrieve\(all\): retrieved from [0-9a-fA-F]+
157157
requests: [0-9]+, hits: [0-9]+, misses: [0-9]+, hit rate: [0-9]+\.[0-9]{2,}%
158158
"""
159159

@@ -178,13 +178,13 @@ def cat(env, source, target):
178178
stdout=expect)
179179

180180
expect = \
181-
r"""CacheRetrieve\(aaa.out\): retrieving from [0-9a-fA-F]+
181+
r"""CacheRetrieve\(aaa.out\): retrieved from [0-9a-fA-F]+
182182
requests: [0-9]+, hits: [0-9]+, misses: [0-9]+, hit rate: [0-9]+\.[0-9]{2,}%
183-
CacheRetrieve\(bbb.out\): retrieving from [0-9a-fA-F]+
183+
CacheRetrieve\(bbb.out\): retrieved from [0-9a-fA-F]+
184184
requests: [0-9]+, hits: [0-9]+, misses: [0-9]+, hit rate: [0-9]+\.[0-9]{2,}%
185-
CacheRetrieve\(ccc.out\): retrieving from [0-9a-fA-F]+
185+
CacheRetrieve\(ccc.out\): retrieved from [0-9a-fA-F]+
186186
requests: [0-9]+, hits: [0-9]+, misses: [0-9]+, hit rate: [0-9]+\.[0-9]{2,}%
187-
CacheRetrieve\(all\): retrieving from [0-9a-fA-F]+
187+
CacheRetrieve\(all\): retrieved from [0-9a-fA-F]+
188188
requests: [0-9]+, hits: [0-9]+, misses: [0-9]+, hit rate: [0-9]+\.[0-9]{2,}%
189189
"""
190190

0 commit comments

Comments
 (0)