Skip to content

Commit c98ff83

Browse files
Implement code source from path on disk
1 parent d6080aa commit c98ff83

3 files changed

Lines changed: 39 additions & 10 deletions

File tree

examples/Racers.yaml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,19 @@ project:
1919
title: "{NAME} v{VERSION}"
2020

2121
inputs:
22+
# Can be share_link, github, or path
2223
code:
23-
# Can be share_link, github, or path
2424
type: share_link
2525
value: https://arcade.makecode.com/84426-33815-03715-00484
2626

27-
# code:
28-
# type: github
29-
# value: https://github.com/UnsignedArduino/Racers
30-
# checkout: master
27+
# code:
28+
# type: github
29+
# value: https://github.com/UnsignedArduino/Racers
30+
# checkout: master
3131

32-
# code:
33-
# type: path
34-
# value: "E:/Racers"
32+
# code:
33+
# type: path
34+
# value: "E:/Racers"
3535

3636
assets:
3737
# Icon is optional but highly recommended, it will be used as the favicon

src/mkcd2app/build_project/inputs/code.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
UrlAssetSource,
1919
)
2020
from mkcd2app.utils.logger import create_logger
21+
from mkcd2app.utils.paths import rmtree_robust
2122
from mkcd2app.utils.run import run_cmd
2223

2324
logger = create_logger(name=__name__, level=logging.INFO)
@@ -43,10 +44,9 @@ def fetch_code(config_yaml: str, node_modules_for_mkc: ContentDir) -> ContentDir
4344
# Clean previous output, not wasteful because redun already checks our inputs
4445
# and outputs to see if they changed
4546
if code_path.exists():
46-
shutil.rmtree(code_path)
47+
rmtree_robust(code_path)
4748

4849
# TODO: Implement source code download from GitHub
49-
# TODO: Implement source code copy
5050
match config.inputs.code.root:
5151
case ShareLinkCodeSource(value=url):
5252
logger.debug(f"Downloading source code from {url}")
@@ -55,8 +55,10 @@ def fetch_code(config_yaml: str, node_modules_for_mkc: ContentDir) -> ContentDir
5555
run_cmd(["npx", "mkc", "download", str(url)], cwd=code_path)
5656
case GitHubCodeSource(value=url, checkout=checkout_target):
5757
logger.debug(f"Downloading source code from {url}@{checkout_target}")
58+
raise NotImplementedError("GitHub code source not implemented yet")
5859
case PathCodeSource(value=path):
5960
logger.debug(f"Copying source code from {path}")
61+
shutil.copytree(path, code_path)
6062

6163
logger.debug("Source code downloaded")
6264
return ContentDir(str(code_path))

src/mkcd2app/utils/paths.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import os
2+
import shutil
3+
import stat
4+
from pathlib import Path
5+
from types import TracebackType
6+
from typing import Any
7+
8+
9+
def _remove_readonly(
10+
func: Any,
11+
path: str,
12+
exc_info: tuple[type[BaseException], BaseException, TracebackType],
13+
) -> None:
14+
"""shutil.rmtree error handler: clear read-only bit and retry.
15+
16+
Needed on Windows because git marks files under .git/objects (and
17+
sometimes .git itself) read-only, which makes os.unlink/os.rmdir
18+
raise PermissionError (WinError 5) even though we own the files.
19+
"""
20+
os.chmod(path, stat.S_IWRITE)
21+
func(path)
22+
23+
24+
def rmtree_robust(path: Path) -> None:
25+
if not path.exists():
26+
return
27+
shutil.rmtree(path, onerror=_remove_readonly)

0 commit comments

Comments
 (0)