2
2
import os
3
3
from subprocess import check_call , DEVNULL
4
4
from tempfile import TemporaryDirectory
5
+ import json
5
6
import shutil
6
7
from pathlib import Path
7
8
8
9
from traitlets import List , Unicode
9
10
10
11
from empack .file_packager import pack_python_core
11
12
12
- from jupyterlite .constants import SHARE_LABEXTENSIONS
13
- from jupyterlite .addons .federated_extensions import FederatedExtensionAddon
13
+ from jupyterlite .constants import SHARE_LABEXTENSIONS , UTF8
14
+ from jupyterlite .addons .federated_extensions import (
15
+ FederatedExtensionAddon ,
16
+ ENV_EXTENSIONS ,
17
+ )
18
+
19
+ JUPYTERLITE_XEUS_PYTHON = "@jupyterlite/xeus-python-kernel"
14
20
15
21
# TODO Make this configurable
16
22
PYTHON_VERSION = "3.10"
@@ -98,7 +104,13 @@ def __init__(self, *args, **kwargs):
98
104
99
105
def pre_build (self , manager ):
100
106
"""yield a doit task to create the emscripten-32 env and grab anything we need from it"""
101
- # Bail early if there is nothing to do
107
+ # Install the jupyterlite-xeus-python ourselves
108
+ for pkg_json in self .env_extensions (ENV_EXTENSIONS ):
109
+ pkg_data = json .loads (pkg_json .read_text (** UTF8 ))
110
+ if pkg_data .get ("name" ) == JUPYTERLITE_XEUS_PYTHON :
111
+ yield from self .safe_copy_extension (pkg_json )
112
+
113
+ # Bail early if there is no extra package to install
102
114
if not self .packages and not self .xeus_python_version :
103
115
return []
104
116
@@ -116,12 +128,12 @@ def pre_build(self, manager):
116
128
# Find the federated extensions in the emscripten-env and install them
117
129
root = self .prefix_path / SHARE_LABEXTENSIONS
118
130
119
- if not self . is_sys_prefix_ignored ():
120
- for pkg_json in self .env_extensions (root ):
121
- yield from self .copy_one_extension (pkg_json )
131
+ # Copy federated extensions found in the emscripten-env
132
+ for pkg_json in self .env_extensions (root ):
133
+ yield from self .safe_copy_extension (pkg_json )
122
134
123
135
# TODO Currently we're shamelessly overwriting the
124
- # python_data.{js,data} into the labextension.
136
+ # python_data.{js,data} into the jupyterlite-xeus-python labextension.
125
137
# We should really find a nicer way.
126
138
# (make jupyterlite-xeus-python extension somewhat configurable?)
127
139
dest = self .output_extensions / "@jupyterlite" / "xeus-python-kernel" / "static"
@@ -131,14 +143,14 @@ def pre_build(self, manager):
131
143
for file in ["python_data.js" , "python_data.data" ]:
132
144
yield dict (
133
145
task_dep = task_dep ,
134
- name = f"copy:{ file } " ,
146
+ name = f"xeus: copy:{ file } " ,
135
147
actions = [(self .copy_one , [Path (self .cwd .name ) / file , dest / file ])],
136
148
)
137
149
138
150
for file in ["xpython_wasm.js" , "xpython_wasm.wasm" ]:
139
151
yield dict (
140
152
task_dep = task_dep ,
141
- name = f"copy:{ file } " ,
153
+ name = f"xeus: copy:{ file } " ,
142
154
actions = [
143
155
(
144
156
self .copy_one ,
@@ -237,3 +249,22 @@ def post_build(self, manager):
237
249
del os .environ ["CONDARC" ]
238
250
239
251
return []
252
+
253
+ def safe_copy_extension (self , pkg_json ):
254
+ """Copy a labextension, and overwrite it
255
+ if it's already in the output
256
+ """
257
+ pkg_path = pkg_json .parent
258
+ stem = json .loads (pkg_json .read_text (** UTF8 ))["name" ]
259
+ dest = self .output_extensions / stem
260
+ file_dep = [
261
+ p
262
+ for p in pkg_path .rglob ("*" )
263
+ if not (p .is_dir () or self .is_ignored_sourcemap (p .name ))
264
+ ]
265
+
266
+ yield dict (
267
+ name = f"xeus:copy:ext:{ stem } " ,
268
+ file_dep = file_dep ,
269
+ actions = [(self .copy_one , [pkg_path , dest ])],
270
+ )
0 commit comments