jupyter-builder 0.1.0a2__py3-none-any.whl → 0.1.0a3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jupyter_builder/__init__.py +1 -1
- jupyter_builder/base_extension_app.py +1 -3
- jupyter_builder/commands.py +2 -1
- jupyter_builder/debug_log_file_mixin.py +7 -7
- jupyter_builder/extension_commands/build.py +4 -4
- jupyter_builder/extension_commands/develop.py +2 -2
- jupyter_builder/extension_commands/watch.py +4 -4
- jupyter_builder/federated_extensions.py +22 -25
- jupyter_builder/federated_extensions_requirements.py +12 -12
- jupyter_builder/jupyterlab_semver.py +399 -4
- {jupyter_builder-0.1.0a2.dist-info → jupyter_builder-0.1.0a3.dist-info}/METADATA +2 -2
- jupyter_builder-0.1.0a3.dist-info/RECORD +20 -0
- jupyter_builder/jupyterlab_server_req.py +0 -66
- jupyter_builder-0.1.0a2.dist-info/RECORD +0 -21
- {jupyter_builder-0.1.0a2.dist-info → jupyter_builder-0.1.0a3.dist-info}/WHEEL +0 -0
- {jupyter_builder-0.1.0a2.dist-info → jupyter_builder-0.1.0a3.dist-info}/entry_points.txt +0 -0
- {jupyter_builder-0.1.0a2.dist-info → jupyter_builder-0.1.0a3.dist-info}/licenses/LICENSE +0 -0
jupyter_builder/__init__.py
CHANGED
|
@@ -9,5 +9,5 @@ except ImportError:
|
|
|
9
9
|
# the package from a stable release or in editable mode: https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs
|
|
10
10
|
import warnings
|
|
11
11
|
|
|
12
|
-
warnings.warn("Importing 'jupyter_builder' outside a proper installation.")
|
|
12
|
+
warnings.warn("Importing 'jupyter_builder' outside a proper installation.", stacklevel=1)
|
|
13
13
|
__version__ = "dev"
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# Distributed under the terms of the Modified BSD License.
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
7
|
+
|
|
7
8
|
import os
|
|
8
9
|
from copy import copy
|
|
9
10
|
|
|
@@ -15,9 +16,6 @@ from .debug_log_file_mixin import DebugLogFileMixin
|
|
|
15
16
|
|
|
16
17
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
# from .federated_labextensions import build_labextension, develop_labextension_py, watch_labextension
|
|
20
|
-
|
|
21
19
|
flags = dict(base_flags)
|
|
22
20
|
|
|
23
21
|
develop_flags = copy(flags)
|
jupyter_builder/commands.py
CHANGED
|
@@ -41,7 +41,8 @@ def _compare_ranges(spec1, spec2, drop_prerelease1=False, drop_prerelease2=False
|
|
|
41
41
|
# Set return_value to a sentinel value
|
|
42
42
|
return_value = False
|
|
43
43
|
|
|
44
|
-
# r1.set may be a list of ranges if the range involved an ||,
|
|
44
|
+
# r1.set may be a list of ranges if the range involved an ||,
|
|
45
|
+
# so we need to test for overlaps between each pair.
|
|
45
46
|
for r1set, r2set in itertools.product(r1.set, r2.set):
|
|
46
47
|
x1 = r1set[0].semver
|
|
47
48
|
x2 = r1set[-1].semver
|
|
@@ -47,18 +47,18 @@ class DebugLogFileMixin(Configurable):
|
|
|
47
47
|
for line in msg:
|
|
48
48
|
self.log.debug(line)
|
|
49
49
|
if isinstance(ex, SystemExit):
|
|
50
|
-
warnings.warn(
|
|
50
|
+
warnings.warn(
|
|
51
|
+
f"An error occurred. See the log file for details: {log_path}", stacklevel=1
|
|
52
|
+
)
|
|
51
53
|
raise
|
|
52
|
-
warnings.warn("An error occurred.")
|
|
53
|
-
warnings.warn(msg[-1].strip())
|
|
54
|
-
warnings.warn(f"See the log file for details: {log_path}")
|
|
54
|
+
warnings.warn("An error occurred.", stacklevel=1)
|
|
55
|
+
warnings.warn(msg[-1].strip(), stacklevel=1)
|
|
56
|
+
warnings.warn(f"See the log file for details: {log_path}", stacklevel=1)
|
|
55
57
|
self.exit(1)
|
|
56
58
|
else:
|
|
57
59
|
log.removeHandler(_debug_handler)
|
|
58
60
|
_debug_handler.flush()
|
|
59
61
|
_debug_handler.close()
|
|
60
|
-
|
|
62
|
+
with contextlib.suppress(FileNotFoundError):
|
|
61
63
|
os.remove(log_path)
|
|
62
|
-
except FileNotFoundError:
|
|
63
|
-
pass
|
|
64
64
|
log.removeHandler(_debug_handler)
|
|
@@ -5,9 +5,9 @@ import os
|
|
|
5
5
|
|
|
6
6
|
from traitlets import Bool, Unicode
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
8
|
+
from jupyter_builder.base_extension_app import BaseExtensionApp
|
|
9
|
+
from jupyter_builder.core_path import default_core_path
|
|
10
|
+
from jupyter_builder.federated_extensions import build_labextension
|
|
11
11
|
|
|
12
12
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
13
13
|
|
|
@@ -27,7 +27,7 @@ class BuildLabExtensionApp(BaseExtensionApp):
|
|
|
27
27
|
help="Directory containing core application package.json file",
|
|
28
28
|
)
|
|
29
29
|
|
|
30
|
-
aliases = {
|
|
30
|
+
aliases = { # noqa: RUF012
|
|
31
31
|
"static-url": "BuildLabExtensionApp.static_url",
|
|
32
32
|
"development": "BuildLabExtensionApp.development",
|
|
33
33
|
"source-map": "BuildLabExtensionApp.source_map",
|
|
@@ -7,8 +7,8 @@ from copy import copy
|
|
|
7
7
|
from jupyter_core.application import base_flags
|
|
8
8
|
from traitlets import Bool, Unicode
|
|
9
9
|
|
|
10
|
-
from
|
|
11
|
-
from
|
|
10
|
+
from jupyter_builder.base_extension_app import BaseExtensionApp
|
|
11
|
+
from jupyter_builder.federated_extensions import develop_labextension_py
|
|
12
12
|
|
|
13
13
|
flags = dict(base_flags)
|
|
14
14
|
develop_flags = copy(flags)
|
|
@@ -5,9 +5,9 @@ import os
|
|
|
5
5
|
|
|
6
6
|
from traitlets import Bool, Unicode
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
8
|
+
from jupyter_builder.base_extension_app import BaseExtensionApp
|
|
9
|
+
from jupyter_builder.core_path import default_core_path
|
|
10
|
+
from jupyter_builder.federated_extensions import watch_labextension
|
|
11
11
|
|
|
12
12
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
13
13
|
|
|
@@ -25,7 +25,7 @@ class WatchLabExtensionApp(BaseExtensionApp):
|
|
|
25
25
|
help="Directory containing core application package.json file",
|
|
26
26
|
)
|
|
27
27
|
|
|
28
|
-
aliases = {
|
|
28
|
+
aliases = { # noqa: RUF012
|
|
29
29
|
"core-path": "WatchLabExtensionApp.core_path",
|
|
30
30
|
"development": "WatchLabExtensionApp.development",
|
|
31
31
|
"source-map": "WatchLabExtensionApp.source_map",
|
|
@@ -25,7 +25,6 @@ from jupyter_core.paths import ENV_JUPYTER_PATH, SYSTEM_JUPYTER_PATH, jupyter_da
|
|
|
25
25
|
from jupyter_core.utils import ensure_dir_exists
|
|
26
26
|
from jupyter_server.extension.serverextension import ArgumentConflict
|
|
27
27
|
|
|
28
|
-
# from jupyterlab_server.config import get_federated_extensions
|
|
29
28
|
from .federated_extensions_requirements import get_federated_extensions
|
|
30
29
|
|
|
31
30
|
try:
|
|
@@ -33,6 +32,8 @@ try:
|
|
|
33
32
|
except ImportError:
|
|
34
33
|
from tomli import load
|
|
35
34
|
|
|
35
|
+
from .core_path import default_core_path
|
|
36
|
+
|
|
36
37
|
# from .commands import _test_overlap TO BE DONE -----------------------------
|
|
37
38
|
|
|
38
39
|
DEPRECATED_ARGUMENT = object()
|
|
@@ -95,7 +96,7 @@ def develop_labextension( # noqa
|
|
|
95
96
|
ensure_dir_exists(labext)
|
|
96
97
|
|
|
97
98
|
if isinstance(path, (list, tuple)):
|
|
98
|
-
msg = "path must be a string pointing to a single extension to install; call this function multiple times to install multiple extensions"
|
|
99
|
+
msg = "path must be a string pointing to a single extension to install; call this function multiple times to install multiple extensions" # noqa: E501
|
|
99
100
|
raise TypeError(msg)
|
|
100
101
|
|
|
101
102
|
if not destination:
|
|
@@ -104,7 +105,7 @@ def develop_labextension( # noqa
|
|
|
104
105
|
full_dest = normpath(pjoin(labext, destination))
|
|
105
106
|
if overwrite and os.path.lexists(full_dest):
|
|
106
107
|
if logger:
|
|
107
|
-
logger.info("Removing: %s"
|
|
108
|
+
logger.info("Removing: %s", full_dest)
|
|
108
109
|
if os.path.isdir(full_dest) and not os.path.islink(full_dest):
|
|
109
110
|
shutil.rmtree(full_dest)
|
|
110
111
|
else:
|
|
@@ -124,14 +125,15 @@ def develop_labextension( # noqa
|
|
|
124
125
|
if platform.platform().startswith("Windows"):
|
|
125
126
|
msg = (
|
|
126
127
|
"Symlinks can be activated on Windows 10 for Python version 3.8 or higher"
|
|
127
|
-
" by activating the 'Developer Mode'. That may not be allowed by your administrators.\n"
|
|
128
|
+
" by activating the 'Developer Mode'. That may not be allowed by your administrators.\n" # noqa: E501
|
|
128
129
|
"See https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development"
|
|
129
130
|
)
|
|
130
131
|
raise OSError(msg) from e
|
|
131
132
|
raise
|
|
132
133
|
|
|
133
134
|
elif not os.path.islink(full_dest):
|
|
134
|
-
|
|
135
|
+
msg = f"{full_dest} exists and is not a symlink"
|
|
136
|
+
raise ValueError(msg)
|
|
135
137
|
|
|
136
138
|
elif os.path.isdir(path):
|
|
137
139
|
path = pjoin(os.path.abspath(path), "") # end in path separator
|
|
@@ -139,7 +141,7 @@ def develop_labextension( # noqa
|
|
|
139
141
|
dest_dir = pjoin(full_dest, parent[len(path) :])
|
|
140
142
|
if not os.path.exists(dest_dir):
|
|
141
143
|
if logger:
|
|
142
|
-
logger.info("Making directory: %s"
|
|
144
|
+
logger.info("Making directory: %s", dest_dir)
|
|
143
145
|
os.makedirs(dest_dir)
|
|
144
146
|
for file_name in files:
|
|
145
147
|
src = pjoin(parent, file_name)
|
|
@@ -152,7 +154,7 @@ def develop_labextension( # noqa
|
|
|
152
154
|
return full_dest
|
|
153
155
|
|
|
154
156
|
|
|
155
|
-
def develop_labextension_py(
|
|
157
|
+
def develop_labextension_py( # noqa: PLR0913
|
|
156
158
|
module,
|
|
157
159
|
user=False,
|
|
158
160
|
sys_prefix=False,
|
|
@@ -195,10 +197,7 @@ def develop_labextension_py(
|
|
|
195
197
|
return full_dests
|
|
196
198
|
|
|
197
199
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
def build_labextension(
|
|
200
|
+
def build_labextension( # noqa: PLR0913
|
|
202
201
|
path, logger=None, development=False, static_url=None, source_map=False, core_path=None
|
|
203
202
|
):
|
|
204
203
|
"""Build a labextension in the given path"""
|
|
@@ -208,7 +207,7 @@ def build_labextension(
|
|
|
208
207
|
ext_path = str(Path(path).resolve())
|
|
209
208
|
|
|
210
209
|
if logger:
|
|
211
|
-
logger.info("Building extension in %s"
|
|
210
|
+
logger.info("Building extension in %s", path)
|
|
212
211
|
|
|
213
212
|
builder = _ensure_builder(ext_path, core_path)
|
|
214
213
|
|
|
@@ -223,7 +222,7 @@ def build_labextension(
|
|
|
223
222
|
subprocess.check_call(arguments, cwd=ext_path) # noqa S603
|
|
224
223
|
|
|
225
224
|
|
|
226
|
-
def watch_labextension(
|
|
225
|
+
def watch_labextension( # noqa: PLR0913
|
|
227
226
|
path, labextensions_path, logger=None, development=False, source_map=False, core_path=None
|
|
228
227
|
):
|
|
229
228
|
"""Watch a labextension in a given path"""
|
|
@@ -231,7 +230,7 @@ def watch_labextension(
|
|
|
231
230
|
ext_path = str(Path(path).resolve())
|
|
232
231
|
|
|
233
232
|
if logger:
|
|
234
|
-
logger.info("Building extension in %s"
|
|
233
|
+
logger.info("Building extension in %s", path)
|
|
235
234
|
|
|
236
235
|
# Check to see if we need to create a symlink
|
|
237
236
|
federated_extensions = get_federated_extensions(labextensions_path)
|
|
@@ -274,9 +273,8 @@ def _ensure_builder(ext_path, core_path):
|
|
|
274
273
|
dep_version2 = ext_data.get("devDependencies", {}).get("@jupyterlab/builder")
|
|
275
274
|
dep_version2 = dep_version2 or ext_data.get("dependencies", {}).get("@jupyterlab/builder")
|
|
276
275
|
if dep_version2 is None:
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
)
|
|
276
|
+
msg = f"Extensions require a devDependency on @jupyterlab/builder@{dep_version1}"
|
|
277
|
+
raise ValueError(msg)
|
|
280
278
|
|
|
281
279
|
# if we have installed from disk (version is a path), assume we know what
|
|
282
280
|
# we are doing and do not check versions.
|
|
@@ -310,7 +308,7 @@ def _ensure_builder(ext_path, core_path):
|
|
|
310
308
|
# )
|
|
311
309
|
|
|
312
310
|
# if not overlap:
|
|
313
|
-
# msg = f"Extensions require a devDependency on @jupyterlab/builder@{dep_version1}, you have a dependency on {dep_version2}"
|
|
311
|
+
# msg = f"Extensions require a devDependency on @jupyterlab/builder@{dep_version1}, you have a dependency on {dep_version2}" # noqa: E501
|
|
314
312
|
# raise ValueError(msg)
|
|
315
313
|
|
|
316
314
|
return osp.join(
|
|
@@ -339,10 +337,10 @@ def _should_copy(src, dest, logger=None):
|
|
|
339
337
|
# we add a fudge factor to work around a bug in python 2.x
|
|
340
338
|
# that was fixed in python 3.x: https://bugs.python.org/issue12904
|
|
341
339
|
if logger:
|
|
342
|
-
logger.warning("Out of date: %s"
|
|
340
|
+
logger.warning("Out of date: %s", dest)
|
|
343
341
|
return True
|
|
344
342
|
if logger:
|
|
345
|
-
logger.info("Up to date: %s"
|
|
343
|
+
logger.info("Up to date: %s", dest)
|
|
346
344
|
return False
|
|
347
345
|
|
|
348
346
|
|
|
@@ -388,9 +386,8 @@ def _get_labextension_dir(user=False, sys_prefix=False, prefix=None, labextensio
|
|
|
388
386
|
]
|
|
389
387
|
conflicting_set = [f"{n}={v!r}" for n, v in conflicting if v]
|
|
390
388
|
if len(conflicting_set) > 1:
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
)
|
|
389
|
+
conflict = ", ".join(conflicting_set)
|
|
390
|
+
msg = f"cannot specify more than one of user, sys_prefix, prefix, or labextensions_dir, but got: {conflict}" # noqa: E501
|
|
394
391
|
raise ArgumentConflict(msg)
|
|
395
392
|
if user:
|
|
396
393
|
labext = pjoin(jupyter_data_dir(), "labextensions")
|
|
@@ -449,8 +446,8 @@ def _get_labextension_metadata(module): # noqa
|
|
|
449
446
|
if not package:
|
|
450
447
|
try:
|
|
451
448
|
package = (
|
|
452
|
-
subprocess.check_output(
|
|
453
|
-
[sys.executable, "setup.py", "--name"],
|
|
449
|
+
subprocess.check_output( # noqa: S603
|
|
450
|
+
[sys.executable, "setup.py", "--name"],
|
|
454
451
|
cwd=mod_path,
|
|
455
452
|
)
|
|
456
453
|
.decode("utf8")
|
|
@@ -50,21 +50,21 @@ def get_federated_extensions(labextensions_path: list[str]) -> dict[str, Any]:
|
|
|
50
50
|
with open(ext_path, encoding="utf-8") as fid:
|
|
51
51
|
pkgdata = json.load(fid)
|
|
52
52
|
if pkgdata["name"] not in federated_extensions:
|
|
53
|
-
data =
|
|
54
|
-
name
|
|
55
|
-
version
|
|
56
|
-
description
|
|
57
|
-
url
|
|
58
|
-
ext_dir
|
|
59
|
-
ext_path
|
|
60
|
-
is_local
|
|
61
|
-
dependencies
|
|
62
|
-
jupyterlab
|
|
63
|
-
|
|
53
|
+
data = {
|
|
54
|
+
"name": pkgdata["name"],
|
|
55
|
+
"version": pkgdata["version"],
|
|
56
|
+
"description": pkgdata.get("description", ""),
|
|
57
|
+
"url": get_package_url(pkgdata),
|
|
58
|
+
"ext_dir": ext_dir,
|
|
59
|
+
"ext_path": osp.dirname(ext_path),
|
|
60
|
+
"is_local": False,
|
|
61
|
+
"dependencies": pkgdata.get("dependencies", {}),
|
|
62
|
+
"jupyterlab": pkgdata.get("jupyterlab", {}),
|
|
63
|
+
}
|
|
64
64
|
|
|
65
65
|
# Add repository info if available
|
|
66
66
|
if "repository" in pkgdata and "url" in pkgdata.get("repository", {}):
|
|
67
|
-
data["repository"] =
|
|
67
|
+
data["repository"] = {"url": pkgdata.get("repository").get("url")}
|
|
68
68
|
|
|
69
69
|
install_path = osp.join(osp.dirname(ext_path), "install.json")
|
|
70
70
|
if osp.exists(install_path):
|
|
@@ -27,6 +27,329 @@
|
|
|
27
27
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
|
|
30
|
+
import logging
|
|
31
|
+
import re
|
|
32
|
+
|
|
33
|
+
logger = logging.getLogger(__name__)
|
|
34
|
+
|
|
35
|
+
SEMVER_SPEC_VERSION = "2.0.0"
|
|
36
|
+
|
|
37
|
+
string_type = str
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class _R:
|
|
41
|
+
def __init__(self, i):
|
|
42
|
+
self.i = i
|
|
43
|
+
|
|
44
|
+
def __call__(self):
|
|
45
|
+
v = self.i
|
|
46
|
+
self.i += 1
|
|
47
|
+
return v
|
|
48
|
+
|
|
49
|
+
def value(self):
|
|
50
|
+
return self.i
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class Extendlist(list):
|
|
54
|
+
def __setitem__(self, i, v):
|
|
55
|
+
try:
|
|
56
|
+
list.__setitem__(self, i, v)
|
|
57
|
+
except IndexError:
|
|
58
|
+
if len(self) == i:
|
|
59
|
+
self.append(v)
|
|
60
|
+
else:
|
|
61
|
+
raise
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def list_get(xs, i):
|
|
65
|
+
try:
|
|
66
|
+
return xs[i]
|
|
67
|
+
except IndexError:
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
R = _R(0)
|
|
72
|
+
src = Extendlist()
|
|
73
|
+
regexp = {}
|
|
74
|
+
|
|
75
|
+
# The following Regular Expressions can be used for tokenizing,
|
|
76
|
+
# validating, and parsing SemVer version strings.
|
|
77
|
+
|
|
78
|
+
# ## Numeric Identifier
|
|
79
|
+
# A single `0`, or a non-zero digit followed by zero or more digits.
|
|
80
|
+
|
|
81
|
+
NUMERICIDENTIFIER = R()
|
|
82
|
+
src[NUMERICIDENTIFIER] = "0|[1-9]\\d*"
|
|
83
|
+
|
|
84
|
+
NUMERICIDENTIFIERLOOSE = R()
|
|
85
|
+
src[NUMERICIDENTIFIERLOOSE] = "[0-9]+"
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# ## Non-numeric Identifier
|
|
89
|
+
# Zero or more digits, followed by a letter or hyphen, and then zero or
|
|
90
|
+
# more letters, digits, or hyphens.
|
|
91
|
+
|
|
92
|
+
NONNUMERICIDENTIFIER = R()
|
|
93
|
+
src[NONNUMERICIDENTIFIER] = "\\d*[a-zA-Z-][a-zA-Z0-9-]*"
|
|
94
|
+
|
|
95
|
+
# ## Main Version
|
|
96
|
+
# Three dot-separated numeric identifiers.
|
|
97
|
+
|
|
98
|
+
MAINVERSION = R()
|
|
99
|
+
src[MAINVERSION] = (
|
|
100
|
+
"("
|
|
101
|
+
+ src[NUMERICIDENTIFIER]
|
|
102
|
+
+ ")\\."
|
|
103
|
+
+ "("
|
|
104
|
+
+ src[NUMERICIDENTIFIER]
|
|
105
|
+
+ ")\\."
|
|
106
|
+
+ "("
|
|
107
|
+
+ src[NUMERICIDENTIFIER]
|
|
108
|
+
+ ")"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
MAINVERSIONLOOSE = R()
|
|
112
|
+
src[MAINVERSIONLOOSE] = (
|
|
113
|
+
"("
|
|
114
|
+
+ src[NUMERICIDENTIFIERLOOSE]
|
|
115
|
+
+ ")\\."
|
|
116
|
+
+ "("
|
|
117
|
+
+ src[NUMERICIDENTIFIERLOOSE]
|
|
118
|
+
+ ")\\."
|
|
119
|
+
+ "("
|
|
120
|
+
+ src[NUMERICIDENTIFIERLOOSE]
|
|
121
|
+
+ ")"
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# ## Pre-release Version Identifier
|
|
126
|
+
# A numeric identifier, or a non-numeric identifier.
|
|
127
|
+
|
|
128
|
+
PRERELEASEIDENTIFIER = R()
|
|
129
|
+
src[PRERELEASEIDENTIFIER] = "(?:" + src[NUMERICIDENTIFIER] + "|" + src[NONNUMERICIDENTIFIER] + ")"
|
|
130
|
+
|
|
131
|
+
PRERELEASEIDENTIFIERLOOSE = R()
|
|
132
|
+
src[PRERELEASEIDENTIFIERLOOSE] = (
|
|
133
|
+
"(?:" + src[NUMERICIDENTIFIERLOOSE] + "|" + src[NONNUMERICIDENTIFIER] + ")"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# ## Pre-release Version
|
|
138
|
+
# Hyphen, followed by one or more dot-separated pre-release version
|
|
139
|
+
# identifiers.
|
|
140
|
+
|
|
141
|
+
PRERELEASE = R()
|
|
142
|
+
src[PRERELEASE] = (
|
|
143
|
+
"(?:-(" + src[PRERELEASEIDENTIFIER] + "(?:\\." + src[PRERELEASEIDENTIFIER] + ")*))"
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
PRERELEASELOOSE = R()
|
|
147
|
+
src[PRERELEASELOOSE] = (
|
|
148
|
+
"(?:-?(" + src[PRERELEASEIDENTIFIERLOOSE] + "(?:\\." + src[PRERELEASEIDENTIFIERLOOSE] + ")*))"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# ## Build Metadata Identifier
|
|
152
|
+
# Any combination of digits, letters, or hyphens.
|
|
153
|
+
|
|
154
|
+
BUILDIDENTIFIER = R()
|
|
155
|
+
src[BUILDIDENTIFIER] = "[0-9A-Za-z-]+"
|
|
156
|
+
|
|
157
|
+
# ## Build Metadata
|
|
158
|
+
# Plus sign, followed by one or more period-separated build metadata
|
|
159
|
+
# identifiers.
|
|
160
|
+
|
|
161
|
+
BUILD = R()
|
|
162
|
+
src[BUILD] = "(?:\\+(" + src[BUILDIDENTIFIER] + "(?:\\." + src[BUILDIDENTIFIER] + ")*))"
|
|
163
|
+
|
|
164
|
+
# ## Full Version String
|
|
165
|
+
# A main version, followed optionally by a pre-release version and
|
|
166
|
+
# build metadata.
|
|
167
|
+
|
|
168
|
+
# Note that the only major, minor, patch, and pre-release sections of
|
|
169
|
+
# the version string are capturing groups. The build metadata is not a
|
|
170
|
+
# capturing group, because it should not ever be used in version
|
|
171
|
+
# comparison.
|
|
172
|
+
|
|
173
|
+
FULL = R()
|
|
174
|
+
FULLPLAIN = "v?" + src[MAINVERSION] + src[PRERELEASE] + "?" + src[BUILD] + "?"
|
|
175
|
+
|
|
176
|
+
src[FULL] = "^" + FULLPLAIN + "$"
|
|
177
|
+
|
|
178
|
+
# like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
|
|
179
|
+
# also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
|
|
180
|
+
# common in the npm registry.
|
|
181
|
+
LOOSEPLAIN = "[v=\\s]*" + src[MAINVERSIONLOOSE] + src[PRERELEASELOOSE] + "?" + src[BUILD] + "?"
|
|
182
|
+
|
|
183
|
+
LOOSE = R()
|
|
184
|
+
src[LOOSE] = "^" + LOOSEPLAIN + "$"
|
|
185
|
+
|
|
186
|
+
GTLT = R()
|
|
187
|
+
src[GTLT] = "((?:<|>)?=?)"
|
|
188
|
+
|
|
189
|
+
# Something like "2.*" or "1.2.x".
|
|
190
|
+
# Note that "x.x" is a valid xRange identifier, meaning "any version"
|
|
191
|
+
# Only the first item is strictly required.
|
|
192
|
+
XRANGEIDENTIFIERLOOSE = R()
|
|
193
|
+
src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + "|x|X|\\*"
|
|
194
|
+
XRANGEIDENTIFIER = R()
|
|
195
|
+
src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + "|x|X|\\*"
|
|
196
|
+
|
|
197
|
+
XRANGEPLAIN = R()
|
|
198
|
+
src[XRANGEPLAIN] = (
|
|
199
|
+
"[v=\\s]*("
|
|
200
|
+
+ src[XRANGEIDENTIFIER]
|
|
201
|
+
+ ")"
|
|
202
|
+
+ "(?:\\.("
|
|
203
|
+
+ src[XRANGEIDENTIFIER]
|
|
204
|
+
+ ")"
|
|
205
|
+
+ "(?:\\.("
|
|
206
|
+
+ src[XRANGEIDENTIFIER]
|
|
207
|
+
+ ")"
|
|
208
|
+
+ "(?:"
|
|
209
|
+
+ src[PRERELEASE]
|
|
210
|
+
+ ")?"
|
|
211
|
+
+ src[BUILD]
|
|
212
|
+
+ "?"
|
|
213
|
+
+ ")?)?"
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
XRANGEPLAINLOOSE = R()
|
|
217
|
+
src[XRANGEPLAINLOOSE] = (
|
|
218
|
+
"[v=\\s]*("
|
|
219
|
+
+ src[XRANGEIDENTIFIERLOOSE]
|
|
220
|
+
+ ")"
|
|
221
|
+
+ "(?:\\.("
|
|
222
|
+
+ src[XRANGEIDENTIFIERLOOSE]
|
|
223
|
+
+ ")"
|
|
224
|
+
+ "(?:\\.("
|
|
225
|
+
+ src[XRANGEIDENTIFIERLOOSE]
|
|
226
|
+
+ ")"
|
|
227
|
+
+ "(?:"
|
|
228
|
+
+ src[PRERELEASELOOSE]
|
|
229
|
+
+ ")?"
|
|
230
|
+
+ src[BUILD]
|
|
231
|
+
+ "?"
|
|
232
|
+
+ ")?)?"
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
XRANGE = R()
|
|
236
|
+
src[XRANGE] = "^" + src[GTLT] + "\\s*" + src[XRANGEPLAIN] + "$"
|
|
237
|
+
XRANGELOOSE = R()
|
|
238
|
+
src[XRANGELOOSE] = "^" + src[GTLT] + "\\s*" + src[XRANGEPLAINLOOSE] + "$"
|
|
239
|
+
|
|
240
|
+
# Tilde ranges.
|
|
241
|
+
# Meaning is "reasonably at or greater than"
|
|
242
|
+
LONETILDE = R()
|
|
243
|
+
src[LONETILDE] = "(?:~>?)"
|
|
244
|
+
|
|
245
|
+
TILDETRIM = R()
|
|
246
|
+
src[TILDETRIM] = "(\\s*)" + src[LONETILDE] + "\\s+"
|
|
247
|
+
regexp[TILDETRIM] = re.compile(src[TILDETRIM], re.M)
|
|
248
|
+
tildeTrimReplace = r"\1~"
|
|
249
|
+
|
|
250
|
+
TILDE = R()
|
|
251
|
+
src[TILDE] = "^" + src[LONETILDE] + src[XRANGEPLAIN] + "$"
|
|
252
|
+
TILDELOOSE = R()
|
|
253
|
+
src[TILDELOOSE] = "^" + src[LONETILDE] + src[XRANGEPLAINLOOSE] + "$"
|
|
254
|
+
|
|
255
|
+
# Caret ranges.
|
|
256
|
+
# Meaning is "at least and backwards compatible with"
|
|
257
|
+
LONECARET = R()
|
|
258
|
+
src[LONECARET] = "(?:\\^)"
|
|
259
|
+
|
|
260
|
+
CARETTRIM = R()
|
|
261
|
+
src[CARETTRIM] = "(\\s*)" + src[LONECARET] + "\\s+"
|
|
262
|
+
regexp[CARETTRIM] = re.compile(src[CARETTRIM], re.M)
|
|
263
|
+
caretTrimReplace = r"\1^"
|
|
264
|
+
|
|
265
|
+
CARET = R()
|
|
266
|
+
src[CARET] = "^" + src[LONECARET] + src[XRANGEPLAIN] + "$"
|
|
267
|
+
CARETLOOSE = R()
|
|
268
|
+
src[CARETLOOSE] = "^" + src[LONECARET] + src[XRANGEPLAINLOOSE] + "$"
|
|
269
|
+
|
|
270
|
+
# A simple gt/lt/eq thing, or just "" to indicate "any version"
|
|
271
|
+
COMPARATORLOOSE = R()
|
|
272
|
+
src[COMPARATORLOOSE] = "^" + src[GTLT] + "\\s*(" + LOOSEPLAIN + ")$|^$"
|
|
273
|
+
COMPARATOR = R()
|
|
274
|
+
src[COMPARATOR] = "^" + src[GTLT] + "\\s*(" + FULLPLAIN + ")$|^$"
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
# An expression to strip any whitespace between the gtlt and the thing
|
|
278
|
+
# it modifies, so that `> 1.2.3` ==> `>1.2.3`
|
|
279
|
+
COMPARATORTRIM = R()
|
|
280
|
+
src[COMPARATORTRIM] = "(\\s*)" + src[GTLT] + "\\s*(" + LOOSEPLAIN + "|" + src[XRANGEPLAIN] + ")"
|
|
281
|
+
|
|
282
|
+
# this one has to use the /g flag
|
|
283
|
+
regexp[COMPARATORTRIM] = re.compile(src[COMPARATORTRIM], re.M)
|
|
284
|
+
comparatorTrimReplace = r"\1\2\3"
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
# Something like `1.2.3 - 1.2.4`
|
|
288
|
+
# Note that these all use the loose form, because they'll be
|
|
289
|
+
# checked against either the strict or loose comparator form
|
|
290
|
+
# later.
|
|
291
|
+
HYPHENRANGE = R()
|
|
292
|
+
src[HYPHENRANGE] = (
|
|
293
|
+
"^\\s*(" + src[XRANGEPLAIN] + ")" + "\\s+-\\s+" + "(" + src[XRANGEPLAIN] + ")" + "\\s*$"
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
HYPHENRANGELOOSE = R()
|
|
297
|
+
src[HYPHENRANGELOOSE] = (
|
|
298
|
+
"^\\s*("
|
|
299
|
+
+ src[XRANGEPLAINLOOSE]
|
|
300
|
+
+ ")"
|
|
301
|
+
+ "\\s+-\\s+"
|
|
302
|
+
+ "("
|
|
303
|
+
+ src[XRANGEPLAINLOOSE]
|
|
304
|
+
+ ")"
|
|
305
|
+
+ "\\s*$"
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
# Star ranges basically just allow anything at all.
|
|
309
|
+
STAR = R()
|
|
310
|
+
src[STAR] = "(<|>)?=?\\s*\\*"
|
|
311
|
+
|
|
312
|
+
# version name recovery for convenient
|
|
313
|
+
RECOVERYVERSIONNAME = R()
|
|
314
|
+
_n = src[NUMERICIDENTIFIER]
|
|
315
|
+
_pre = src[PRERELEASELOOSE]
|
|
316
|
+
src[RECOVERYVERSIONNAME] = f"v?({_n})(?:\\.({_n}))?{_pre}?"
|
|
317
|
+
|
|
318
|
+
# Compile to actual regexp objects.
|
|
319
|
+
# All are flag-free, unless they were created above with a flag.
|
|
320
|
+
for i in range(R.value()):
|
|
321
|
+
logger.debug("genregxp %s %s", i, src[i])
|
|
322
|
+
if i not in regexp:
|
|
323
|
+
regexp[i] = re.compile(src[i])
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def parse(version, loose):
|
|
327
|
+
r = regexp[LOOSE] if loose else regexp[FULL]
|
|
328
|
+
m = r.search(version)
|
|
329
|
+
if m:
|
|
330
|
+
return semver(version, loose)
|
|
331
|
+
else:
|
|
332
|
+
return None
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def valid(version, loose):
|
|
336
|
+
v = parse(version, loose)
|
|
337
|
+
if v.version:
|
|
338
|
+
return v
|
|
339
|
+
else:
|
|
340
|
+
return None
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def clean(version, loose):
|
|
344
|
+
s = parse(version, loose)
|
|
345
|
+
if s:
|
|
346
|
+
return s.version
|
|
347
|
+
else:
|
|
348
|
+
return None
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
NUMERIC = re.compile(r"^\d+$")
|
|
352
|
+
|
|
30
353
|
|
|
31
354
|
def semver(version, loose):
|
|
32
355
|
if isinstance(version, SemVer):
|
|
@@ -65,7 +388,7 @@ class SemVer:
|
|
|
65
388
|
self.prerelease = []
|
|
66
389
|
else:
|
|
67
390
|
self.prerelease = [
|
|
68
|
-
(int(
|
|
391
|
+
(int(id_) if NUMERIC.search(id_) else id_) for id_ in m.group(3).split(".")
|
|
69
392
|
]
|
|
70
393
|
else:
|
|
71
394
|
# these are actually numbers
|
|
@@ -77,7 +400,7 @@ class SemVer:
|
|
|
77
400
|
self.prerelease = []
|
|
78
401
|
else:
|
|
79
402
|
self.prerelease = [
|
|
80
|
-
(int(
|
|
403
|
+
(int(id_) if NUMERIC.search(id_) else id_) for id_ in m.group(4).split(".")
|
|
81
404
|
]
|
|
82
405
|
if m.group(5):
|
|
83
406
|
self.build = m.group(5).split(".")
|
|
@@ -116,7 +439,7 @@ class SemVer:
|
|
|
116
439
|
or compare_identifiers(str(self.patch), str(other.patch))
|
|
117
440
|
)
|
|
118
441
|
|
|
119
|
-
def compare_pre(self, other):
|
|
442
|
+
def compare_pre(self, other): # noqa PLR0911
|
|
120
443
|
if not isinstance(other, SemVer):
|
|
121
444
|
other = make_semver(other, self.loose)
|
|
122
445
|
|
|
@@ -226,16 +549,88 @@ class SemVer:
|
|
|
226
549
|
else:
|
|
227
550
|
self.prerelease = [identifier, 0]
|
|
228
551
|
else:
|
|
229
|
-
|
|
552
|
+
msg = f"invalid increment argument: {release}"
|
|
553
|
+
raise ValueError(msg)
|
|
230
554
|
self.format()
|
|
231
555
|
self.raw = self.version
|
|
232
556
|
return self
|
|
233
557
|
|
|
234
558
|
|
|
559
|
+
def inc(version, release, loose, identifier=None): # wow!
|
|
560
|
+
try:
|
|
561
|
+
return make_semver(version, loose).inc(release, identifier=identifier).version
|
|
562
|
+
except Exception as e:
|
|
563
|
+
logger.debug(e, exc_info=5)
|
|
564
|
+
return None
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
def compare_identifiers(a, b):
|
|
568
|
+
anum = NUMERIC.search(a)
|
|
569
|
+
bnum = NUMERIC.search(b)
|
|
570
|
+
|
|
571
|
+
if anum and bnum:
|
|
572
|
+
a = int(a)
|
|
573
|
+
b = int(b)
|
|
574
|
+
|
|
575
|
+
if anum and not bnum:
|
|
576
|
+
return -1
|
|
577
|
+
elif bnum and not anum:
|
|
578
|
+
return 1
|
|
579
|
+
elif a < b:
|
|
580
|
+
return -1
|
|
581
|
+
elif a > b:
|
|
582
|
+
return 1
|
|
583
|
+
else:
|
|
584
|
+
return 0
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
def rcompare_identifiers(a, b):
|
|
588
|
+
return compare_identifiers(b, a)
|
|
589
|
+
|
|
590
|
+
|
|
235
591
|
def compare(a, b, loose):
|
|
236
592
|
return make_semver(a, loose).compare(b)
|
|
237
593
|
|
|
238
594
|
|
|
595
|
+
def compare_loose(a, b):
|
|
596
|
+
return compare(a, b, True)
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
def rcompare(a, b, loose):
|
|
600
|
+
return compare(b, a, loose)
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
def make_key_function(loose):
|
|
604
|
+
def key_function(version):
|
|
605
|
+
v = make_semver(version, loose)
|
|
606
|
+
key = (v.major, v.minor, v.patch)
|
|
607
|
+
if v.prerelease: # noqa SIM108
|
|
608
|
+
key = key + tuple(v.prerelease)
|
|
609
|
+
else:
|
|
610
|
+
# NOT having a prerelease is > having one
|
|
611
|
+
key = (*key, float("inf"))
|
|
612
|
+
|
|
613
|
+
return key
|
|
614
|
+
|
|
615
|
+
return key_function
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
loose_key_function = make_key_function(True)
|
|
619
|
+
full_key_function = make_key_function(True)
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
def sort(list_, loose):
|
|
623
|
+
keyf = loose_key_function if loose else full_key_function
|
|
624
|
+
list_.sort(key=keyf)
|
|
625
|
+
return list_
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
def rsort(list_, loose):
|
|
629
|
+
keyf = loose_key_function if loose else full_key_function
|
|
630
|
+
list_.sort(key=keyf, reverse=True)
|
|
631
|
+
return list_
|
|
632
|
+
|
|
633
|
+
|
|
239
634
|
def gt(a, b, loose):
|
|
240
635
|
return compare(a, b, loose) > 0
|
|
241
636
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: jupyter_builder
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a3
|
|
4
4
|
Summary: JupyterLab build tools
|
|
5
5
|
Project-URL: Homepage, https://jupyter.org
|
|
6
6
|
Project-URL: Source, https://github.com/jupyterlab/jupyterlab_builder
|
|
@@ -58,7 +58,7 @@ Requires-Dist: build; extra == 'dev'
|
|
|
58
58
|
Requires-Dist: hatch; extra == 'dev'
|
|
59
59
|
Requires-Dist: mypy; extra == 'dev'
|
|
60
60
|
Requires-Dist: pre-commit; extra == 'dev'
|
|
61
|
-
Requires-Dist: ruff==0.
|
|
61
|
+
Requires-Dist: ruff==0.5.5; extra == 'dev'
|
|
62
62
|
Provides-Extra: test
|
|
63
63
|
Requires-Dist: copier<10,>=9.2; extra == 'test'
|
|
64
64
|
Requires-Dist: coverage; extra == 'test'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
jupyter_builder/__init__.py,sha256=i9jPM1fNuaGMXu7HCFm6KbNkedsu1J-LqVIcDeeoUCc,582
|
|
2
|
+
jupyter_builder/base_extension_app.py,sha256=w82d89smSMulUGlPDI_A4PVxRz2Zg7myC7NXcEevX4Y,1622
|
|
3
|
+
jupyter_builder/commands.py,sha256=DgG1GGBQ_NEKVreOX2JAnNjOtR-znxs-u56ZiokPvOo,3446
|
|
4
|
+
jupyter_builder/core_path.py,sha256=8cFbRg81aZj8LQiHFkXuHtlDffwDu4IlUypyaiI1gH8,245
|
|
5
|
+
jupyter_builder/debug_log_file_mixin.py,sha256=EVc25sTNjYRnHf9sPQHffR8O5apqG7SJlZq5T9EAfMM,2256
|
|
6
|
+
jupyter_builder/federated_extensions.py,sha256=VnrCOgG31Ed_m18gLsxWV5diU2vpj8lXSZpHzXoBoWQ,17226
|
|
7
|
+
jupyter_builder/federated_extensions_requirements.py,sha256=t3sD-WiO0Y4SOmn113-1aGhMzOqoQLCZAMnhliIM5vk,2997
|
|
8
|
+
jupyter_builder/jlpm.py,sha256=kYE6Pk9TADEhcxKkUXr6V0AhNdGDr5XnYO-D679R580,1233
|
|
9
|
+
jupyter_builder/jupyterlab_semver.py,sha256=8wQusESSz_3rmnJsWVVn13C4mM5mt5HAdAsAUCjrD8c,18563
|
|
10
|
+
jupyter_builder/main.py,sha256=PGZ4MGYG20yDqonoQg_vKkeCzCkKKnrCOtU056Wdvr4,2231
|
|
11
|
+
jupyter_builder/yarn.js,sha256=8EYGlNp3NZisReCOECOR_8DMDfMWLkfeZ-URewpzhq4,2221431
|
|
12
|
+
jupyter_builder/extension_commands/__init__.py,sha256=eXcK7cn7Qj8A1SBiMJ4ptlf2WFErhSxG9QSKFtENyhU,101
|
|
13
|
+
jupyter_builder/extension_commands/build.py,sha256=u_RQGl5_Pt2A7I2SdTk4tZ3hUNR83X4pFqigOzWXA6g,1638
|
|
14
|
+
jupyter_builder/extension_commands/develop.py,sha256=2B9jrjceulO9sE7-TqcyVtTrjKkk713LqRbN5oMmxYU,1724
|
|
15
|
+
jupyter_builder/extension_commands/watch.py,sha256=QIfIxX__6NfXeIla7BCr0doqqxA9rkd4ApKuCMk709A,1521
|
|
16
|
+
jupyter_builder-0.1.0a3.dist-info/METADATA,sha256=Il2z55hJFeIusPAATRJ0Wkn6NN3uXv0RmBqQqzmswUM,5300
|
|
17
|
+
jupyter_builder-0.1.0a3.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
18
|
+
jupyter_builder-0.1.0a3.dist-info/entry_points.txt,sha256=pQlwFs3R6-sOlkEDXzXwxu0tVNn4aBkaDJ8qRebDZko,95
|
|
19
|
+
jupyter_builder-0.1.0a3.dist-info/licenses/LICENSE,sha256=T4GK8L2cxFmaXUe48VaSUF3T6pnn14gWtH1rXdz5VkI,1532
|
|
20
|
+
jupyter_builder-0.1.0a3.dist-info/RECORD,,
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
"""JupyterLab Server config"""
|
|
2
|
-
|
|
3
|
-
# Copyright (c) Jupyter Development Team.
|
|
4
|
-
# Distributed under the terms of the Modified BSD License.
|
|
5
|
-
from __future__ import annotations
|
|
6
|
-
|
|
7
|
-
import json
|
|
8
|
-
import os.path as osp
|
|
9
|
-
from glob import iglob
|
|
10
|
-
from itertools import chain
|
|
11
|
-
from os.path import join as pjoin
|
|
12
|
-
from typing import Any
|
|
13
|
-
|
|
14
|
-
# -----------------------------------------------------------------------------
|
|
15
|
-
# Module globals
|
|
16
|
-
# -----------------------------------------------------------------------------
|
|
17
|
-
|
|
18
|
-
DEFAULT_TEMPLATE_PATH = osp.join(osp.dirname(__file__), "templates")
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def get_package_url(data: dict[str, Any]) -> str:
|
|
22
|
-
"""Get the url from the extension data"""
|
|
23
|
-
# homepage, repository are optional
|
|
24
|
-
if "homepage" in data:
|
|
25
|
-
url = data["homepage"]
|
|
26
|
-
elif "repository" in data and isinstance(data["repository"], dict):
|
|
27
|
-
url = data["repository"].get("url", "")
|
|
28
|
-
else:
|
|
29
|
-
url = ""
|
|
30
|
-
return url
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def get_federated_extensions(labextensions_path: list[str]) -> dict[str, Any]:
|
|
34
|
-
"""Get the metadata about federated extensions"""
|
|
35
|
-
federated_extensions = {}
|
|
36
|
-
for ext_dir in labextensions_path:
|
|
37
|
-
# extensions are either top-level directories, or two-deep in @org directories
|
|
38
|
-
for ext_path in chain(
|
|
39
|
-
iglob(pjoin(ext_dir, "[!@]*", "package.json")),
|
|
40
|
-
iglob(pjoin(ext_dir, "@*", "*", "package.json")),
|
|
41
|
-
):
|
|
42
|
-
with open(ext_path, encoding="utf-8") as fid:
|
|
43
|
-
pkgdata = json.load(fid)
|
|
44
|
-
if pkgdata["name"] not in federated_extensions:
|
|
45
|
-
data = dict(
|
|
46
|
-
name=pkgdata["name"],
|
|
47
|
-
version=pkgdata["version"],
|
|
48
|
-
description=pkgdata.get("description", ""),
|
|
49
|
-
url=get_package_url(pkgdata),
|
|
50
|
-
ext_dir=ext_dir,
|
|
51
|
-
ext_path=osp.dirname(ext_path),
|
|
52
|
-
is_local=False,
|
|
53
|
-
dependencies=pkgdata.get("dependencies", dict()),
|
|
54
|
-
jupyterlab=pkgdata.get("jupyterlab", dict()),
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
# Add repository info if available
|
|
58
|
-
if "repository" in pkgdata and "url" in pkgdata.get("repository", {}):
|
|
59
|
-
data["repository"] = dict(url=pkgdata.get("repository").get("url"))
|
|
60
|
-
|
|
61
|
-
install_path = osp.join(osp.dirname(ext_path), "install.json")
|
|
62
|
-
if osp.exists(install_path):
|
|
63
|
-
with open(install_path, encoding="utf-8") as fid:
|
|
64
|
-
data["install"] = json.load(fid)
|
|
65
|
-
federated_extensions[data["name"]] = data
|
|
66
|
-
return federated_extensions
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
jupyter_builder/__init__.py,sha256=ucoo7W6O_PAP5ESIJ1klJViiKWeJbUqFCuc_QrW3XV8,568
|
|
2
|
-
jupyter_builder/base_extension_app.py,sha256=NTtICU1zbc8n64Hd9tJ86FuYX7q5xqDVHhbmBAEINjw,1726
|
|
3
|
-
jupyter_builder/commands.py,sha256=-h9brmCXhrKRMtefcqHEv4VnMREgWOkfU2PZmaxNraI,3440
|
|
4
|
-
jupyter_builder/core_path.py,sha256=8cFbRg81aZj8LQiHFkXuHtlDffwDu4IlUypyaiI1gH8,245
|
|
5
|
-
jupyter_builder/debug_log_file_mixin.py,sha256=816tIlPySoCbJak9Cj6eE57VjeQjz2jdySYsj4hqESw,2181
|
|
6
|
-
jupyter_builder/federated_extensions.py,sha256=IaS7VIKlb09wgkIjjYhSXUJY8qYNpmCOMyLPWw3fKlI,17177
|
|
7
|
-
jupyter_builder/federated_extensions_requirements.py,sha256=R-sAx1shGaGOwA9dIMPIc3kslEW2ih1w8RdrKWtZJ3c,2983
|
|
8
|
-
jupyter_builder/jlpm.py,sha256=kYE6Pk9TADEhcxKkUXr6V0AhNdGDr5XnYO-D679R580,1233
|
|
9
|
-
jupyter_builder/jupyterlab_semver.py,sha256=E7SKvf9ca4uDBWf_oSji5OHurycAIF8cUt4rwafHQto,9330
|
|
10
|
-
jupyter_builder/jupyterlab_server_req.py,sha256=LKn_merwDkCT17OCsqTuOoRaX4uGGhyz-25wwiDkE2c,2613
|
|
11
|
-
jupyter_builder/main.py,sha256=PGZ4MGYG20yDqonoQg_vKkeCzCkKKnrCOtU056Wdvr4,2231
|
|
12
|
-
jupyter_builder/yarn.js,sha256=8EYGlNp3NZisReCOECOR_8DMDfMWLkfeZ-URewpzhq4,2221431
|
|
13
|
-
jupyter_builder/extension_commands/__init__.py,sha256=eXcK7cn7Qj8A1SBiMJ4ptlf2WFErhSxG9QSKFtENyhU,101
|
|
14
|
-
jupyter_builder/extension_commands/build.py,sha256=Px55wxLrOgh_OGzUebHw2cplepOn8WyU38gbqKvHTWk,1580
|
|
15
|
-
jupyter_builder/extension_commands/develop.py,sha256=Ztl9qniWlxE86imNOpcNOLbPsZGRMhYQ3c_-_ozUICI,1696
|
|
16
|
-
jupyter_builder/extension_commands/watch.py,sha256=OKuFk3N1vk2Yb-Cmy2yLOECCsNNn-qC0DcwSAkeyGGs,1463
|
|
17
|
-
jupyter_builder-0.1.0a2.dist-info/METADATA,sha256=hBwpgheUzkezL5-z7yJALfmd3Y1ZpIPjnkeZHwQYZtQ,5300
|
|
18
|
-
jupyter_builder-0.1.0a2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
19
|
-
jupyter_builder-0.1.0a2.dist-info/entry_points.txt,sha256=pQlwFs3R6-sOlkEDXzXwxu0tVNn4aBkaDJ8qRebDZko,95
|
|
20
|
-
jupyter_builder-0.1.0a2.dist-info/licenses/LICENSE,sha256=T4GK8L2cxFmaXUe48VaSUF3T6pnn14gWtH1rXdz5VkI,1532
|
|
21
|
-
jupyter_builder-0.1.0a2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|