Skip to content

Commit 81a0a03

Browse files
committed
Fix: Support relative paths in the run command
This addresses an issue where relative paths for dependencies were broken due to changes in how file contents are handled. With this update, temporary files (like the runtime script and lockfile) are now properly cleaned up within the runtime script itself.
1 parent 0dedc41 commit 81a0a03

File tree

4 files changed

+40
-6
lines changed

4 files changed

+40
-6
lines changed

src/juv/_run.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,19 @@ def run( # noqa: PLR0913
8787
elif mode == "managed":
8888
from ._run_managed import run as run_managed
8989

90-
run_managed(script, args, str(path), lockfile_contents)
90+
run_managed(
91+
script=script,
92+
args=args,
93+
filename=str(path),
94+
lockfile_contents=lockfile_contents,
95+
dir=target.parent,
96+
)
9197
else:
9298
from ._run_replace import run as run_replace
9399

94-
run_replace(script, args, lockfile_contents)
100+
run_replace(
101+
script=script,
102+
args=args,
103+
lockfile_contents=lockfile_contents,
104+
dir=target.parent,
105+
)

src/juv/_run_managed.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,11 @@ def display(url: str) -> None:
105105

106106

107107
def run(
108-
script: str, args: list[str], filename: str, lockfile_contents: str | None
108+
script: str,
109+
args: list[str],
110+
filename: str,
111+
lockfile_contents: str | None,
112+
dir: Path, # noqa: A002
109113
) -> None:
110114
console = Console()
111115
output_queue = Queue()
@@ -114,6 +118,7 @@ def run(
114118
mode="w+",
115119
delete=True,
116120
suffix=".py",
121+
dir=dir,
117122
encoding="utf-8",
118123
) as f:
119124
lockfile = Path(f"{f.name}.lock")
@@ -150,6 +155,5 @@ def run(
150155
with console.status("Shutting down..."):
151156
os.killpg(os.getpgid(process.pid), signal.SIGTERM)
152157
finally:
153-
lockfile.unlink(missing_ok=True)
154158
output_queue.put(None)
155159
output_thread.join()

src/juv/_run_replace.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
IS_WINDOWS = sys.platform.startswith("win")
1313

1414

15-
def run(script: str, args: list[str], lockfile_contents: str | None) -> None:
15+
def run(script: str, args: list[str], lockfile_contents: str | None, dir: Path) -> None: # noqa: A002
1616
with tempfile.NamedTemporaryFile(
1717
mode="w+",
1818
delete=True,
1919
suffix=".py",
20+
dir=dir,
2021
encoding="utf-8",
2122
) as f:
2223
lockfile = Path(f"{f.name}.lock")
@@ -57,5 +58,4 @@ def run(script: str, args: list[str], lockfile_contents: str | None) -> None:
5758
else:
5859
os.kill(process.pid, signal.SIGTERM)
5960
finally:
60-
lockfile.unlink(missing_ok=True)
6161
process.wait()

src/juv/_run_template.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,20 @@ def update_uv_lock(notebook_path: str):
8888
update_uv_lock(r"{notebook}")
8989
"""
9090

91+
DELETE_RUN_SCRIPT_AND_LOCKFILE = """
92+
import os
93+
from pathlib import Path
94+
95+
def delete_run_script_and_lockfile():
96+
Path(str(__file__)).unlink(missing_ok=True)
97+
lockfile_path = os.environ.get("JUV_LOCKFILE_PATH")
98+
if not lockfile_path:
99+
return
100+
Path(lockfile_path).unlink(missing_ok=True)
101+
102+
delete_run_script_and_lockfile()
103+
"""
104+
91105

92106
SETUP_JUPYTER_DATA_DIR = """
93107
import tempfile
@@ -157,6 +171,7 @@ def handle_termination(signum, frame):
157171
from jupyterlab.labapp import main
158172
159173
{UPDATE_LOCKFILE}
174+
{DELETE_RUN_SCRIPT_AND_LOCKFILE}
160175
{SETUP_JUPYTER_DATA_DIR}
161176
162177
if {is_managed}:
@@ -177,6 +192,7 @@ def handle_termination(signum, frame):
177192
from notebook.app import main
178193
179194
{UPDATE_LOCKFILE}
195+
{DELETE_RUN_SCRIPT_AND_LOCKFILE}
180196
{SETUP_JUPYTER_DATA_DIR}
181197
182198
if {is_managed}:
@@ -197,6 +213,7 @@ def handle_termination(signum, frame):
197213
from notebook.notebookapp import main
198214
199215
{UPDATE_LOCKFILE}
216+
{DELETE_RUN_SCRIPT_AND_LOCKFILE}
200217
{SETUP_JUPYTER_DATA_DIR}
201218
202219
if {is_managed}:
@@ -217,6 +234,7 @@ def handle_termination(signum, frame):
217234
from nbclassic.notebookapp import main
218235
219236
{UPDATE_LOCKFILE}
237+
{DELETE_RUN_SCRIPT_AND_LOCKFILE}
220238
{SETUP_JUPYTER_DATA_DIR}
221239
222240
if {is_managed}:
@@ -247,6 +265,7 @@ def prepare_run_script_and_uv_run_args( # noqa: PLR0913
247265
args=jupyter_args,
248266
SETUP_JUPYTER_DATA_DIR=SETUP_JUPYTER_DATA_DIR,
249267
UPDATE_LOCKFILE=UPDATE_LOCKFILE.format(notebook=target),
268+
DELETE_RUN_SCRIPT_AND_LOCKFILE=DELETE_RUN_SCRIPT_AND_LOCKFILE,
250269
is_managed=mode == "managed",
251270
)
252271
args = [

0 commit comments

Comments
 (0)