Skip to content

Commit

Permalink
Add workaround for cleaning out read-only files when wiping repo cont…
Browse files Browse the repository at this point in the history
…ext.
  • Loading branch information
jaraco committed Aug 19, 2024
1 parent 4f8fcfb commit 1aca011
Showing 1 changed file with 31 additions and 3 deletions.
34 changes: 31 additions & 3 deletions jaraco/context/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,30 @@ def composed(*args, **kwargs):
"""


def remove_readonly(func, path, exc_info):
import errno
import stat

excvalue = exc_info[1]
if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
# change the file to be readable,writable,executable: 0777
os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
# retry
func(path)
else:
raise


def windows_safe_remover():
import platform

return (
functools.partial(shutil.rmtree, onerror=remove_readonly)
if platform.system() == 'Windows'
else shutil.rmtree
)


@contextlib.contextmanager
def temp_dir(remover: Callable[[str], None] = shutil.rmtree) -> Iterator[str]:
"""
Expand All @@ -142,7 +166,6 @@ def temp_dir(remover: Callable[[str], None] = shutil.rmtree) -> Iterator[str]:
>>> import pathlib
>>> with temp_dir() as the_dir:
... assert os.path.isdir(the_dir)
... _ = pathlib.Path(the_dir).joinpath('somefile').write_text('contents', encoding='utf-8')
>>> assert not os.path.exists(the_dir)
"""
temp_dir = tempfile.mkdtemp()
Expand All @@ -152,12 +175,17 @@ def temp_dir(remover: Callable[[str], None] = shutil.rmtree) -> Iterator[str]:
remover(temp_dir)


windows_safe_temp_dir = functools.partial(temp_dir, remover=windows_safe_remover)


@contextlib.contextmanager
def repo_context(
url,
branch: str | None = None,
quiet: bool = True,
dest_ctx: Callable[[], contextlib.AbstractContextManager[str]] = temp_dir,
dest_ctx: Callable[
[], contextlib.AbstractContextManager[str]
] = windows_safe_temp_dir,
):
"""
Check out the repo indicated by url.
Expand All @@ -168,7 +196,7 @@ def repo_context(
>>> repo = repo_context('https://github.com/jaraco/jaraco.context')
>>> with repo as dest:
... listing = os.listdir(dest)
... __import__('time').sleep(__import__('platform').system() == 'Windows')
... __import__('time').sleep(__import__('platform').system() == 'Windows') # #12
>>> 'README.rst' in listing
True
"""
Expand Down

0 comments on commit 1aca011

Please sign in to comment.