mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
idf_tools.py: add workaround for PermissionError in os.rename
Closes https://github.com/espressif/esp-idf/issues/4063 Closes https://github.com/espressif/esp-idf/issues/3819
This commit is contained in:
parent
81ffc87371
commit
3bbb758bc5
@ -61,6 +61,12 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
from urllib import urlretrieve
|
from urllib import urlretrieve
|
||||||
|
|
||||||
|
try:
|
||||||
|
from exceptions import WindowsError
|
||||||
|
except ImportError:
|
||||||
|
class WindowsError(OSError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
TOOLS_FILE = 'tools/tools.json'
|
TOOLS_FILE = 'tools/tools.json'
|
||||||
TOOLS_SCHEMA_FILE = 'tools/tools_schema.json'
|
TOOLS_SCHEMA_FILE = 'tools/tools_schema.json'
|
||||||
@ -254,13 +260,34 @@ def unpack(filename, destination):
|
|||||||
archive_obj.extractall(destination)
|
archive_obj.extractall(destination)
|
||||||
|
|
||||||
|
|
||||||
|
# Sometimes renaming a directory on Windows (randomly?) causes a PermissionError.
|
||||||
|
# This is confirmed to be a workaround:
|
||||||
|
# https://github.com/espressif/esp-idf/issues/3819#issuecomment-515167118
|
||||||
|
# https://github.com/espressif/esp-idf/issues/4063#issuecomment-531490140
|
||||||
|
# https://stackoverflow.com/a/43046729
|
||||||
|
def rename_with_retry(path_from, path_to):
|
||||||
|
if sys.platform.startswith('win'):
|
||||||
|
retry_count = 100
|
||||||
|
else:
|
||||||
|
retry_count = 1
|
||||||
|
|
||||||
|
for retry in range(retry_count):
|
||||||
|
try:
|
||||||
|
os.rename(path_from, path_to)
|
||||||
|
return
|
||||||
|
except (OSError, WindowsError): # WindowsError until Python 3.3, then OSError
|
||||||
|
if retry == retry_count - 1:
|
||||||
|
raise
|
||||||
|
warn('Rename {} to {} failed, retrying...'.format(path_from, path_to))
|
||||||
|
|
||||||
|
|
||||||
def strip_container_dirs(path, levels):
|
def strip_container_dirs(path, levels):
|
||||||
assert levels > 0
|
assert levels > 0
|
||||||
# move the original directory out of the way (add a .tmp suffix)
|
# move the original directory out of the way (add a .tmp suffix)
|
||||||
tmp_path = path + '.tmp'
|
tmp_path = path + '.tmp'
|
||||||
if os.path.exists(tmp_path):
|
if os.path.exists(tmp_path):
|
||||||
shutil.rmtree(tmp_path)
|
shutil.rmtree(tmp_path)
|
||||||
os.rename(path, tmp_path)
|
rename_with_retry(path, tmp_path)
|
||||||
os.mkdir(path)
|
os.mkdir(path)
|
||||||
base_path = tmp_path
|
base_path = tmp_path
|
||||||
# walk given number of levels down
|
# walk given number of levels down
|
||||||
@ -276,7 +303,7 @@ def strip_container_dirs(path, levels):
|
|||||||
for name in contents:
|
for name in contents:
|
||||||
move_from = os.path.join(base_path, name)
|
move_from = os.path.join(base_path, name)
|
||||||
move_to = os.path.join(path, name)
|
move_to = os.path.join(path, name)
|
||||||
os.rename(move_from, move_to)
|
rename_with_retry(move_from, move_to)
|
||||||
shutil.rmtree(tmp_path)
|
shutil.rmtree(tmp_path)
|
||||||
|
|
||||||
|
|
||||||
@ -544,7 +571,7 @@ class IDFTool(object):
|
|||||||
if not self.check_download_file(download_obj, local_temp_path):
|
if not self.check_download_file(download_obj, local_temp_path):
|
||||||
warn('Failed to download file {}'.format(local_temp_path))
|
warn('Failed to download file {}'.format(local_temp_path))
|
||||||
continue
|
continue
|
||||||
os.rename(local_temp_path, local_path)
|
rename_with_retry(local_temp_path, local_path)
|
||||||
downloaded = True
|
downloaded = True
|
||||||
break
|
break
|
||||||
if not downloaded:
|
if not downloaded:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user