jupyter-builder 0.1.0a2__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 +13 -0
- jupyter_builder/base_extension_app.py +65 -0
- jupyter_builder/commands.py +115 -0
- jupyter_builder/core_path.py +10 -0
- jupyter_builder/debug_log_file_mixin.py +64 -0
- jupyter_builder/extension_commands/__init__.py +2 -0
- jupyter_builder/extension_commands/build.py +56 -0
- jupyter_builder/extension_commands/develop.py +58 -0
- jupyter_builder/extension_commands/watch.py +54 -0
- jupyter_builder/federated_extensions.py +492 -0
- jupyter_builder/federated_extensions_requirements.py +74 -0
- jupyter_builder/jlpm.py +43 -0
- jupyter_builder/jupyterlab_semver.py +252 -0
- jupyter_builder/jupyterlab_server_req.py +66 -0
- jupyter_builder/main.py +54 -0
- jupyter_builder/yarn.js +878 -0
- jupyter_builder-0.1.0a2.dist-info/METADATA +119 -0
- jupyter_builder-0.1.0a2.dist-info/RECORD +21 -0
- jupyter_builder-0.1.0a2.dist-info/WHEEL +4 -0
- jupyter_builder-0.1.0a2.dist-info/entry_points.txt +3 -0
- jupyter_builder-0.1.0a2.dist-info/licenses/LICENSE +29 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# Copyright (c) Jupyter Development Team.
|
|
2
|
+
# Distributed under the terms of the Modified BSD License.
|
|
3
|
+
|
|
4
|
+
# This file comes from https://github.com/podhmo/python-semver/blob/b42e9896e391e086b773fc621b23fa299d16b874/semver/__init__.py
|
|
5
|
+
#
|
|
6
|
+
# It is licensed under the following license:
|
|
7
|
+
#
|
|
8
|
+
# MIT License
|
|
9
|
+
|
|
10
|
+
# Copyright (c) 2016 podhmo
|
|
11
|
+
|
|
12
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
# in the Software without restriction, including without limitation the rights
|
|
15
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
# furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
# copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
# SOFTWARE.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def semver(version, loose):
|
|
32
|
+
if isinstance(version, SemVer):
|
|
33
|
+
if version.loose == loose:
|
|
34
|
+
return version
|
|
35
|
+
else:
|
|
36
|
+
version = version.version
|
|
37
|
+
elif not isinstance(version, string_type): # xxx:
|
|
38
|
+
raise ValueError(f"Invalid Version: {version}")
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
if (!(this instanceof SemVer))
|
|
42
|
+
return new SemVer(version, loose);
|
|
43
|
+
"""
|
|
44
|
+
return SemVer(version, loose)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
make_semver = semver
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class SemVer:
|
|
51
|
+
def __init__(self, version, loose):
|
|
52
|
+
logger.debug("SemVer %s, %s", version, loose)
|
|
53
|
+
self.loose = loose
|
|
54
|
+
self.raw = version
|
|
55
|
+
|
|
56
|
+
m = regexp[LOOSE if loose else FULL].search(version.strip())
|
|
57
|
+
if not m:
|
|
58
|
+
if not loose:
|
|
59
|
+
raise ValueError(f"Invalid Version: {version}")
|
|
60
|
+
m = regexp[RECOVERYVERSIONNAME].search(version.strip())
|
|
61
|
+
self.major = int(m.group(1)) if m.group(1) else 0
|
|
62
|
+
self.minor = int(m.group(2)) if m.group(2) else 0
|
|
63
|
+
self.patch = 0
|
|
64
|
+
if not m.group(3):
|
|
65
|
+
self.prerelease = []
|
|
66
|
+
else:
|
|
67
|
+
self.prerelease = [
|
|
68
|
+
(int(id) if NUMERIC.search(id) else id) for id in m.group(3).split(".")
|
|
69
|
+
]
|
|
70
|
+
else:
|
|
71
|
+
# these are actually numbers
|
|
72
|
+
self.major = int(m.group(1))
|
|
73
|
+
self.minor = int(m.group(2))
|
|
74
|
+
self.patch = int(m.group(3))
|
|
75
|
+
# numberify any prerelease numeric ids
|
|
76
|
+
if not m.group(4):
|
|
77
|
+
self.prerelease = []
|
|
78
|
+
else:
|
|
79
|
+
self.prerelease = [
|
|
80
|
+
(int(id) if NUMERIC.search(id) else id) for id in m.group(4).split(".")
|
|
81
|
+
]
|
|
82
|
+
if m.group(5):
|
|
83
|
+
self.build = m.group(5).split(".")
|
|
84
|
+
else:
|
|
85
|
+
self.build = []
|
|
86
|
+
|
|
87
|
+
self.format() # xxx:
|
|
88
|
+
|
|
89
|
+
def format(self):
|
|
90
|
+
self.version = f"{self.major}.{self.minor}.{self.patch}"
|
|
91
|
+
if len(self.prerelease) > 0:
|
|
92
|
+
self.version += "-{}".format(".".join(str(v) for v in self.prerelease))
|
|
93
|
+
return self.version
|
|
94
|
+
|
|
95
|
+
def __repr__(self):
|
|
96
|
+
return f"<SemVer {self} >"
|
|
97
|
+
|
|
98
|
+
def __str__(self):
|
|
99
|
+
return self.version
|
|
100
|
+
|
|
101
|
+
def compare(self, other):
|
|
102
|
+
logger.debug("SemVer.compare %s %s %s", self.version, self.loose, other)
|
|
103
|
+
if not isinstance(other, SemVer):
|
|
104
|
+
other = make_semver(other, self.loose)
|
|
105
|
+
result = self.compare_main(other) or self.compare_pre(other)
|
|
106
|
+
logger.debug("compare result %s", result)
|
|
107
|
+
return result
|
|
108
|
+
|
|
109
|
+
def compare_main(self, other):
|
|
110
|
+
if not isinstance(other, SemVer):
|
|
111
|
+
other = make_semver(other, self.loose)
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
compare_identifiers(str(self.major), str(other.major))
|
|
115
|
+
or compare_identifiers(str(self.minor), str(other.minor))
|
|
116
|
+
or compare_identifiers(str(self.patch), str(other.patch))
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
def compare_pre(self, other):
|
|
120
|
+
if not isinstance(other, SemVer):
|
|
121
|
+
other = make_semver(other, self.loose)
|
|
122
|
+
|
|
123
|
+
# NOT having a prerelease is > having one
|
|
124
|
+
is_self_more_than_zero = len(self.prerelease) > 0
|
|
125
|
+
is_other_more_than_zero = len(other.prerelease) > 0
|
|
126
|
+
|
|
127
|
+
if not is_self_more_than_zero and is_other_more_than_zero:
|
|
128
|
+
return 1
|
|
129
|
+
elif is_self_more_than_zero and not is_other_more_than_zero:
|
|
130
|
+
return -1
|
|
131
|
+
elif not is_self_more_than_zero and not is_other_more_than_zero:
|
|
132
|
+
return 0
|
|
133
|
+
|
|
134
|
+
i = 0
|
|
135
|
+
while True:
|
|
136
|
+
a = list_get(self.prerelease, i)
|
|
137
|
+
b = list_get(other.prerelease, i)
|
|
138
|
+
logger.debug("prerelease compare %s: %s %s", i, a, b)
|
|
139
|
+
i += 1
|
|
140
|
+
if a is None and b is None:
|
|
141
|
+
return 0
|
|
142
|
+
elif b is None:
|
|
143
|
+
return 1
|
|
144
|
+
elif a is None:
|
|
145
|
+
return -1
|
|
146
|
+
elif a == b:
|
|
147
|
+
continue
|
|
148
|
+
else:
|
|
149
|
+
return compare_identifiers(str(a), str(b))
|
|
150
|
+
|
|
151
|
+
def inc(self, release, identifier=None):
|
|
152
|
+
logger.debug("inc release %s %s", self.prerelease, release)
|
|
153
|
+
if release == "premajor":
|
|
154
|
+
self.prerelease = []
|
|
155
|
+
self.patch = 0
|
|
156
|
+
self.minor = 0
|
|
157
|
+
self.major += 1
|
|
158
|
+
self.inc("pre", identifier=identifier)
|
|
159
|
+
elif release == "preminor":
|
|
160
|
+
self.prerelease = []
|
|
161
|
+
self.patch = 0
|
|
162
|
+
self.minor += 1
|
|
163
|
+
self.inc("pre", identifier=identifier)
|
|
164
|
+
elif release == "prepatch":
|
|
165
|
+
# If this is already a prerelease, it will bump to the next version
|
|
166
|
+
# drop any prereleases that might already exist, since they are not
|
|
167
|
+
# relevant at this point.
|
|
168
|
+
self.prerelease = []
|
|
169
|
+
self.inc("patch", identifier=identifier)
|
|
170
|
+
self.inc("pre", identifier=identifier)
|
|
171
|
+
elif release == "prerelease":
|
|
172
|
+
# If the input is a non-prerelease version, this acts the same as
|
|
173
|
+
# prepatch.
|
|
174
|
+
if len(self.prerelease) == 0:
|
|
175
|
+
self.inc("patch", identifier=identifier)
|
|
176
|
+
self.inc("pre", identifier=identifier)
|
|
177
|
+
elif release == "major":
|
|
178
|
+
# If this is a pre-major version, bump up to the same major version.
|
|
179
|
+
# Otherwise increment major.
|
|
180
|
+
# 1.0.0-5 bumps to 1.0.0
|
|
181
|
+
# 1.1.0 bumps to 2.0.0
|
|
182
|
+
if self.minor != 0 or self.patch != 0 or len(self.prerelease) == 0:
|
|
183
|
+
self.major += 1
|
|
184
|
+
self.minor = 0
|
|
185
|
+
self.patch = 0
|
|
186
|
+
self.prerelease = []
|
|
187
|
+
elif release == "minor":
|
|
188
|
+
# If this is a pre-minor version, bump up to the same minor version.
|
|
189
|
+
# Otherwise increment minor.
|
|
190
|
+
# 1.2.0-5 bumps to 1.2.0
|
|
191
|
+
# 1.2.1 bumps to 1.3.0
|
|
192
|
+
if self.patch != 0 or len(self.prerelease) == 0:
|
|
193
|
+
self.minor += 1
|
|
194
|
+
self.patch = 0
|
|
195
|
+
self.prerelease = []
|
|
196
|
+
elif release == "patch":
|
|
197
|
+
# If this is not a pre-release version, it will increment the patch.
|
|
198
|
+
# If it is a pre-release it will bump up to the same patch version.
|
|
199
|
+
# 1.2.0-5 patches to 1.2.0
|
|
200
|
+
# 1.2.0 patches to 1.2.1
|
|
201
|
+
if len(self.prerelease) == 0:
|
|
202
|
+
self.patch += 1
|
|
203
|
+
self.prerelease = []
|
|
204
|
+
elif release == "pre":
|
|
205
|
+
# This probably shouldn't be used publicly.
|
|
206
|
+
# 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.
|
|
207
|
+
logger.debug("inc prerelease %s", self.prerelease)
|
|
208
|
+
if len(self.prerelease) == 0:
|
|
209
|
+
self.prerelease = [0]
|
|
210
|
+
else:
|
|
211
|
+
i = len(self.prerelease) - 1
|
|
212
|
+
while i >= 0:
|
|
213
|
+
if isinstance(self.prerelease[i], int):
|
|
214
|
+
self.prerelease[i] += 1
|
|
215
|
+
i -= 2
|
|
216
|
+
i -= 1
|
|
217
|
+
# ## this is needless code in python ##
|
|
218
|
+
# if i == -1: # didn't increment anything
|
|
219
|
+
# self.prerelease.append(0)
|
|
220
|
+
if identifier is not None:
|
|
221
|
+
# 1.2.0-beta.1 bumps to 1.2.0-beta.2,
|
|
222
|
+
# 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
|
|
223
|
+
if self.prerelease[0] == identifier:
|
|
224
|
+
if not isinstance(self.prerelease[1], int):
|
|
225
|
+
self.prerelease = [identifier, 0]
|
|
226
|
+
else:
|
|
227
|
+
self.prerelease = [identifier, 0]
|
|
228
|
+
else:
|
|
229
|
+
raise ValueError(f"invalid increment argument: {release}")
|
|
230
|
+
self.format()
|
|
231
|
+
self.raw = self.version
|
|
232
|
+
return self
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def compare(a, b, loose):
|
|
236
|
+
return make_semver(a, loose).compare(b)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def gt(a, b, loose):
|
|
240
|
+
return compare(a, b, loose) > 0
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def lt(a, b, loose):
|
|
244
|
+
return compare(a, b, loose) < 0
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def gte(a, b, loose):
|
|
248
|
+
return compare(a, b, loose) >= 0
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def lte(a, b, loose):
|
|
252
|
+
return compare(a, b, loose) <= 0
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
jupyter_builder/main.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Copyright (c) Jupyter Development Team.
|
|
2
|
+
# Distributed under the terms of the Modified BSD License.
|
|
3
|
+
|
|
4
|
+
# # Copyright (c) Jupyter Development Team.
|
|
5
|
+
# # Distributed under the terms of the Modified BSD License.
|
|
6
|
+
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
from jupyter_core.application import JupyterApp
|
|
10
|
+
|
|
11
|
+
from jupyter_builder.extension_commands.build import BuildLabExtensionApp
|
|
12
|
+
from jupyter_builder.extension_commands.develop import DevelopLabExtensionApp
|
|
13
|
+
from jupyter_builder.extension_commands.watch import WatchLabExtensionApp
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class LabExtensionApp(JupyterApp):
|
|
17
|
+
"""Base jupyter labextension command entry point"""
|
|
18
|
+
|
|
19
|
+
name = "jupyter labextension"
|
|
20
|
+
# version = VERSION
|
|
21
|
+
description = "Work with JupyterLab extensions"
|
|
22
|
+
# examples = _EXAMPLES
|
|
23
|
+
|
|
24
|
+
subcommands = {
|
|
25
|
+
# "install": (InstallLabExtensionApp, "Install labextension(s)"),
|
|
26
|
+
# "update": (UpdateLabExtensionApp, "Update labextension(s)"),
|
|
27
|
+
# "uninstall": (UninstallLabExtensionApp, "Uninstall labextension(s)"),
|
|
28
|
+
# "list": (ListLabExtensionsApp, "List labextensions"),
|
|
29
|
+
# "link": (LinkLabExtensionApp, "Link labextension(s)"),
|
|
30
|
+
# "unlink": (UnlinkLabExtensionApp, "Unlink labextension(s)"),
|
|
31
|
+
# "enable": (EnableLabExtensionsApp, "Enable labextension(s)"),
|
|
32
|
+
# "disable": (DisableLabExtensionsApp, "Disable labextension(s)"),
|
|
33
|
+
# "lock": (LockLabExtensionsApp, "Lock labextension(s)"),
|
|
34
|
+
# "unlock": (UnlockLabExtensionsApp, "Unlock labextension(s)"),
|
|
35
|
+
# "check": (CheckLabExtensionsApp, "Check labextension(s)"),
|
|
36
|
+
"develop": (DevelopLabExtensionApp, "(developer) Develop labextension(s)"),
|
|
37
|
+
"build": (BuildLabExtensionApp, "(developer) Build labextension"),
|
|
38
|
+
"watch": (WatchLabExtensionApp, "(developer) Watch labextension"),
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
def start(self):
|
|
42
|
+
"""Perform the App's functions as configured"""
|
|
43
|
+
super().start()
|
|
44
|
+
|
|
45
|
+
# The above should have called a subcommand and raised NoStart; if we
|
|
46
|
+
# get here, it didn't, so we should self.log.info a message.
|
|
47
|
+
subcmds = ", ".join(sorted(self.subcommands))
|
|
48
|
+
self.exit(f"Please supply at least one subcommand: {subcmds}")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
main = LabExtensionApp.launch_instance
|
|
52
|
+
|
|
53
|
+
if __name__ == "__main__":
|
|
54
|
+
sys.exit(main())
|