mystmd 1.3.6__tar.gz → 1.3.7__tar.gz
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.
- {mystmd-1.3.6 → mystmd-1.3.7}/PKG-INFO +3 -1
- {mystmd-1.3.6 → mystmd-1.3.7}/_package.json +2 -2
- {mystmd-1.3.6 → mystmd-1.3.7}/pyproject.toml +20 -1
- mystmd-1.3.7/src/mystmd_py/main.py +151 -0
- {mystmd-1.3.6 → mystmd-1.3.7}/src/mystmd_py/myst.cjs +2 -2
- mystmd-1.3.7/src/mystmd_py/nodeenv.py +76 -0
- mystmd-1.3.6/src/mystmd_py/main.py +0 -46
- {mystmd-1.3.6 → mystmd-1.3.7}/.gitignore +0 -0
- {mystmd-1.3.6 → mystmd-1.3.7}/LICENSE +0 -0
- {mystmd-1.3.6 → mystmd-1.3.7}/README.md +0 -0
- {mystmd-1.3.6 → mystmd-1.3.7}/src/mystmd_py/__init__.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: mystmd
|
3
|
-
Version: 1.3.
|
3
|
+
Version: 1.3.7
|
4
4
|
Summary: Command line tools for MyST Markdown
|
5
5
|
Project-URL: Homepage, https://github.com/jupyter-book/mystmd
|
6
6
|
Project-URL: Bug Tracker, https://github.com/jupyter-book/mystmd/issues
|
@@ -21,6 +21,8 @@ Classifier: Programming Language :: Python :: 3.11
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.12
|
22
22
|
Classifier: Topic :: Scientific/Engineering
|
23
23
|
Requires-Python: >=3.8
|
24
|
+
Requires-Dist: platformdirs~=4.2.2
|
25
|
+
Requires-Dist: nodeenv~=1.9.1
|
24
26
|
Provides-Extra: execute
|
25
27
|
Requires-Dist: ipykernel; extra == 'execute'
|
26
28
|
Requires-Dist: jupyter-server; extra == 'execute'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "mystmd",
|
3
|
-
"version": "1.3.
|
3
|
+
"version": "1.3.7",
|
4
4
|
"description": "Command line tools for MyST Markdown",
|
5
5
|
"author": "Rowan Cockett <rowan@curvenote.com>",
|
6
6
|
"license": "MIT",
|
@@ -45,6 +45,6 @@
|
|
45
45
|
"commander": "^10.0.1",
|
46
46
|
"core-js": "^3.31.1",
|
47
47
|
"js-yaml": "^4.1.0",
|
48
|
-
"myst-cli": "^1.3.
|
48
|
+
"myst-cli": "^1.3.7"
|
49
49
|
}
|
50
50
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
[build-system]
|
2
|
-
requires = ["hatchling", "hatch-nodejs-version"]
|
2
|
+
requires = ["hatchling", "hatch-nodejs-version", "hatch-deps-selector"]
|
3
3
|
build-backend = "hatchling.build"
|
4
4
|
|
5
5
|
[project]
|
@@ -34,6 +34,25 @@ myst = "mystmd_py.main:main"
|
|
34
34
|
source = "nodejs"
|
35
35
|
path = "_package.json"
|
36
36
|
|
37
|
+
[tool.hatch.build.hooks.selector]
|
38
|
+
default-variant = "pypi"
|
39
|
+
# Name of the env-var that controls which `selector.variants` entry
|
40
|
+
# is used
|
41
|
+
env-var = "MYSTMD_PACKAGE_VARIANT"
|
42
|
+
|
43
|
+
# Ensure that we only bring in nodeenv for PyPI
|
44
|
+
[tool.hatch.build.hooks.selector.variants.pypi]
|
45
|
+
dependencies = [
|
46
|
+
"platformdirs~=4.2.2",
|
47
|
+
"nodeenv~=1.9.1"
|
48
|
+
]
|
49
|
+
|
50
|
+
# Conda-forge has no additional dependencies to the `project.dependencies`
|
51
|
+
# This section is not needed (the env-var can be set to "")
|
52
|
+
# But this makes it more explicit
|
53
|
+
[tool.hatch.build.hooks.selector.variants.conda-forge]
|
54
|
+
dependencies = []
|
55
|
+
|
37
56
|
[tool.hatch.metadata.hooks.nodejs]
|
38
57
|
fields = ["description", "authors", "urls", "keywords", "license"]
|
39
58
|
path = "_package.json"
|
@@ -0,0 +1,151 @@
|
|
1
|
+
import os
|
2
|
+
import pathlib
|
3
|
+
import platform
|
4
|
+
import shutil
|
5
|
+
import subprocess
|
6
|
+
import sys
|
7
|
+
import re
|
8
|
+
import textwrap
|
9
|
+
|
10
|
+
|
11
|
+
NODEENV_VERSION = "18.0.0"
|
12
|
+
INSTALL_NODEENV_KEY = "MYSTMD_ALLOW_NODEENV"
|
13
|
+
|
14
|
+
|
15
|
+
class PermissionDeniedError(Exception): ...
|
16
|
+
|
17
|
+
|
18
|
+
class NodeEnvCreationError(Exception): ...
|
19
|
+
|
20
|
+
|
21
|
+
def is_windows():
|
22
|
+
return platform.system() == "Windows"
|
23
|
+
|
24
|
+
|
25
|
+
def find_installed_node():
|
26
|
+
# shutil.which can find things with PATHEXT, but 3.12.0 breaks this by preferring NODE over NODE.EXE on Windows
|
27
|
+
return shutil.which("node.exe") if is_windows() else shutil.which("node")
|
28
|
+
|
29
|
+
|
30
|
+
def find_nodeenv_path():
|
31
|
+
# The conda packaging of this package does not need to install node!
|
32
|
+
import platformdirs
|
33
|
+
|
34
|
+
return platformdirs.user_data_path(
|
35
|
+
appname="myst", appauthor=False, version=NODEENV_VERSION
|
36
|
+
)
|
37
|
+
|
38
|
+
|
39
|
+
def ask_to_install_node(path):
|
40
|
+
if env_value := os.environ.get(INSTALL_NODEENV_KEY, "").lower():
|
41
|
+
return env_value in {"yes", "true", "1", "y"}
|
42
|
+
|
43
|
+
return input(f"❔ Install Node.js in '{path}'? (y/N): ").lower() == "y"
|
44
|
+
|
45
|
+
|
46
|
+
def create_nodeenv(env_path):
|
47
|
+
command = [
|
48
|
+
sys.executable,
|
49
|
+
"-m",
|
50
|
+
"nodeenv",
|
51
|
+
"-v",
|
52
|
+
f"--node={NODEENV_VERSION}",
|
53
|
+
"--prebuilt",
|
54
|
+
"--clean-src",
|
55
|
+
env_path,
|
56
|
+
]
|
57
|
+
result = subprocess.run(command, capture_output=True, encoding="utf-8")
|
58
|
+
if result.returncode:
|
59
|
+
shutil.rmtree(env_path)
|
60
|
+
raise NodeEnvCreationError(result.stderr)
|
61
|
+
else:
|
62
|
+
return env_path
|
63
|
+
|
64
|
+
|
65
|
+
def find_any_node(binary_path):
|
66
|
+
node_path = find_installed_node()
|
67
|
+
if node_path is not None:
|
68
|
+
return pathlib.Path(node_path).absolute(), binary_path
|
69
|
+
|
70
|
+
nodeenv_path = find_nodeenv_path()
|
71
|
+
if not nodeenv_path.exists():
|
72
|
+
print("❗ Node.js (node) is required to run MyST, but could not be found`.")
|
73
|
+
if ask_to_install_node(nodeenv_path):
|
74
|
+
print(f"⚙️ Attempting to install Node.js in {nodeenv_path} ...")
|
75
|
+
create_nodeenv(nodeenv_path)
|
76
|
+
print(f"ℹ️ Successfully installed Node.js {NODEENV_VERSION}")
|
77
|
+
else:
|
78
|
+
raise PermissionDeniedError("Node.js installation was not permitted")
|
79
|
+
|
80
|
+
# Find the executable path
|
81
|
+
new_node_path = (
|
82
|
+
(nodeenv_path / "Scripts" / "node.exe")
|
83
|
+
if is_windows()
|
84
|
+
else (nodeenv_path / "bin" / "node")
|
85
|
+
)
|
86
|
+
new_path = os.pathsep.join(
|
87
|
+
[*binary_path.split(os.pathsep), str(new_node_path.parent)]
|
88
|
+
)
|
89
|
+
return new_node_path, new_path
|
90
|
+
|
91
|
+
|
92
|
+
def main():
|
93
|
+
# Find NodeJS (and potential new PATH)
|
94
|
+
binary_path = os.environ.get("PATH", os.defpath)
|
95
|
+
try:
|
96
|
+
node_path, os_path = find_any_node(binary_path)
|
97
|
+
except NodeEnvCreationError as err:
|
98
|
+
message = textwrap.indent(err.args[0], " ")
|
99
|
+
raise SystemExit(
|
100
|
+
"💥 The attempt to install Node.js was unsuccessful.\n"
|
101
|
+
f"🔍 Underlying error:\n{message}\n\n"
|
102
|
+
"ℹ️ We recommend installing the latest LTS release, using your preferred package manager "
|
103
|
+
"or following instructions here: https://nodejs.org\n\n"
|
104
|
+
) from err
|
105
|
+
except PermissionDeniedError as err:
|
106
|
+
raise SystemExit(
|
107
|
+
"💥 The attempt to install Node.js failed because the user denied the request.\n"
|
108
|
+
"ℹ️ We recommend installing the latest LTS release, using your preferred package manager "
|
109
|
+
"or following instructions here: https://nodejs.org\n\n"
|
110
|
+
) from err
|
111
|
+
|
112
|
+
# Build new env dict
|
113
|
+
node_env = {**os.environ, "PATH": os_path}
|
114
|
+
|
115
|
+
# Check version
|
116
|
+
_version = subprocess.run(
|
117
|
+
[node_path, "-v"], capture_output=True, check=True, text=True, env=node_env
|
118
|
+
).stdout
|
119
|
+
major_version_match = re.match(r"v(\d+).*", _version)
|
120
|
+
|
121
|
+
if major_version_match is None:
|
122
|
+
raise SystemExit(f"MyST could not determine the version of Node.js: {_version}")
|
123
|
+
major_version = int(major_version_match[1])
|
124
|
+
if not (major_version in {18, 20, 22} or major_version > 22):
|
125
|
+
raise SystemExit(
|
126
|
+
f"MyST requires node 18, 20, or 22+; you are running node {major_version}.\n\n"
|
127
|
+
"Please update to the latest LTS release, using your preferred package manager\n"
|
128
|
+
"or following instructions here: https://nodejs.org/en/download"
|
129
|
+
)
|
130
|
+
|
131
|
+
# Find path to compiled JS
|
132
|
+
js_path = (pathlib.Path(__file__).parent / "myst.cjs").resolve()
|
133
|
+
|
134
|
+
# Build args for Node.js process
|
135
|
+
myst_node_args = [js_path, *sys.argv[1:]]
|
136
|
+
myst_env = {**node_env, "MYST_LANG": "PYTHON"}
|
137
|
+
|
138
|
+
# Invoke appropriate binary for platform
|
139
|
+
if platform.system() == "Windows":
|
140
|
+
result = subprocess.run([node_path, *myst_node_args], env=myst_env)
|
141
|
+
sys.exit(result.returncode)
|
142
|
+
else:
|
143
|
+
os.execve(
|
144
|
+
node_path,
|
145
|
+
[node_path.name, *myst_node_args],
|
146
|
+
myst_env,
|
147
|
+
)
|
148
|
+
|
149
|
+
|
150
|
+
if __name__ == "__main__":
|
151
|
+
main()
|
@@ -193562,7 +193562,7 @@ var {
|
|
193562
193562
|
} = import_index.default;
|
193563
193563
|
|
193564
193564
|
// src/version.ts
|
193565
|
-
var version = "1.3.
|
193565
|
+
var version = "1.3.7";
|
193566
193566
|
var version_default = version;
|
193567
193567
|
|
193568
193568
|
// ../myst-cli/dist/build/build.js
|
@@ -289038,7 +289038,7 @@ var import_node_path15 = __toESM(require("path"), 1);
|
|
289038
289038
|
var import_nbtx = __toESM(require_cjs2(), 1);
|
289039
289039
|
|
289040
289040
|
// ../myst-cli/dist/version.js
|
289041
|
-
var version2 = "1.3.
|
289041
|
+
var version2 = "1.3.7";
|
289042
289042
|
var version_default2 = version2;
|
289043
289043
|
|
289044
289044
|
// ../myst-cli/dist/utils/headers.js
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import os
|
2
|
+
import pathlib
|
3
|
+
import shutil
|
4
|
+
import subprocess
|
5
|
+
import sys
|
6
|
+
|
7
|
+
|
8
|
+
NODEENV_VERSION = "18.0.0"
|
9
|
+
INSTALL_NODEENV_KEY = "MYSTMD_ALLOW_NODEENV"
|
10
|
+
|
11
|
+
|
12
|
+
class PermissionDeniedError(Exception): ...
|
13
|
+
|
14
|
+
|
15
|
+
class NodeEnvCreationError(Exception): ...
|
16
|
+
|
17
|
+
|
18
|
+
def find_installed_node():
|
19
|
+
return shutil.which("node") or shutil.which("node.exe") or shutil.which("node.cmd")
|
20
|
+
|
21
|
+
|
22
|
+
def find_nodeenv_path():
|
23
|
+
# The conda packaging of this package does not need to install node!
|
24
|
+
import platformdirs
|
25
|
+
return platformdirs.user_data_path(
|
26
|
+
appname="myst", appauthor=False, version=NODEENV_VERSION
|
27
|
+
)
|
28
|
+
|
29
|
+
|
30
|
+
def ask_to_install_node(path):
|
31
|
+
if env_value := os.environ.get(INSTALL_NODEENV_KEY, "").lower():
|
32
|
+
return env_value in {"yes", "true", "1", "y"}
|
33
|
+
|
34
|
+
return input(f"❔ Install Node.js in '{path}'? (y/N): ").lower() == "y"
|
35
|
+
|
36
|
+
|
37
|
+
def create_nodeenv(env_path):
|
38
|
+
command = [
|
39
|
+
sys.executable,
|
40
|
+
"-m",
|
41
|
+
"nodeenv",
|
42
|
+
"-v",
|
43
|
+
f"--node={NODEENV_VERSION}",
|
44
|
+
"--prebuilt",
|
45
|
+
"--clean-src",
|
46
|
+
env_path,
|
47
|
+
]
|
48
|
+
result = subprocess.run(command, capture_output=True, encoding="utf-8")
|
49
|
+
if result.returncode:
|
50
|
+
shutil.rmtree(env_path)
|
51
|
+
raise NodeEnvCreationError(result.stderr)
|
52
|
+
else:
|
53
|
+
return env_path
|
54
|
+
|
55
|
+
|
56
|
+
def find_any_node(binary_path):
|
57
|
+
node_path = find_installed_node()
|
58
|
+
if node_path is not None:
|
59
|
+
return pathlib.Path(node_path).absolute(), binary_path
|
60
|
+
|
61
|
+
nodeenv_path = find_nodeenv_path()
|
62
|
+
if not nodeenv_path.exists():
|
63
|
+
print("❗ Node.js (node) is required to run MyST, but could not be found`.")
|
64
|
+
if ask_to_install_node(nodeenv_path):
|
65
|
+
print(f"⚙️ Attempting to install Node.js in {nodeenv_path} ...")
|
66
|
+
create_nodeenv(nodeenv_path)
|
67
|
+
print(f"ℹ️ Successfully installed Node.js {NODEENV_VERSION}")
|
68
|
+
else:
|
69
|
+
raise PermissionDeniedError("Node.js installation was not permitted")
|
70
|
+
|
71
|
+
new_path = os.pathsep.join(
|
72
|
+
[*binary_path.split(os.pathsep), str(nodeenv_path / "bin")]
|
73
|
+
)
|
74
|
+
return nodeenv_path / "bin" / "node", new_path
|
75
|
+
|
76
|
+
|
@@ -1,46 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import pathlib
|
3
|
-
import shutil
|
4
|
-
import subprocess
|
5
|
-
import sys
|
6
|
-
import re
|
7
|
-
|
8
|
-
|
9
|
-
def main():
|
10
|
-
NODE_LOCATION = (
|
11
|
-
shutil.which("node") or shutil.which("node.exe") or shutil.which("node.cmd")
|
12
|
-
)
|
13
|
-
PATH_TO_BIN_JS = (pathlib.Path(__file__).parent / "myst.cjs").resolve()
|
14
|
-
|
15
|
-
if not NODE_LOCATION:
|
16
|
-
raise SystemExit(
|
17
|
-
"You must install node >=18 to run MyST\n\n"
|
18
|
-
"We recommend installing the latest LTS release, using your preferred package manager\n"
|
19
|
-
"or following instructions here: https://nodejs.org/en/download"
|
20
|
-
)
|
21
|
-
node = pathlib.Path(NODE_LOCATION).absolute()
|
22
|
-
|
23
|
-
_version = subprocess.run(
|
24
|
-
[node, "-v"], capture_output=True, check=True, text=True
|
25
|
-
).stdout
|
26
|
-
major_version_match = re.match(r"v(\d+).*", _version)
|
27
|
-
|
28
|
-
if major_version_match is None:
|
29
|
-
raise SystemExit(f"MyST could not determine the version of Node.js: {_version}")
|
30
|
-
|
31
|
-
major_version = int(major_version_match[1])
|
32
|
-
if not (major_version in {18, 20, 22} or major_version > 22):
|
33
|
-
raise SystemExit(
|
34
|
-
f"MyST requires node 18, 20, or 22+; you are running node {major_version}.\n\n"
|
35
|
-
"Please update to the latest LTS release, using your preferred package manager\n"
|
36
|
-
"or following instructions here: https://nodejs.org/en/download"
|
37
|
-
)
|
38
|
-
os.execve(
|
39
|
-
node,
|
40
|
-
[node.name, PATH_TO_BIN_JS, *sys.argv[1:]],
|
41
|
-
{**os.environ, "MYST_LANG": "PYTHON"},
|
42
|
-
)
|
43
|
-
|
44
|
-
|
45
|
-
if __name__ == "__main__":
|
46
|
-
main()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|