Skip to content

Commit 4f903f0

Browse files
committed
Add version indicators with pinned package versions from extraction
1 parent 37116cc commit 4f903f0

27 files changed

+1236
-1267
lines changed

scripts/extract.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -686,14 +686,42 @@ class DependencyExtractor:
686686
def __init__(self, config_loader: ConfigLoader):
687687
self.config = config_loader
688688

689+
def _get_package_version(self, import_name: str) -> str | None:
690+
"""Get installed version of a package (strips local version identifiers)."""
691+
try:
692+
module = importlib.import_module(import_name)
693+
version = getattr(module, '__version__', None)
694+
if version:
695+
# Strip local version identifier (e.g., +g22f8f27) - not supported by PyPI
696+
version = version.split('+')[0]
697+
return version
698+
except ImportError:
699+
return None
700+
689701
def extract(self) -> dict:
690-
"""Extract all dependency information."""
702+
"""Extract all dependency information including installed versions."""
691703
pyodide_config = self.config.load_pyodide_config()
692704
pyodide_packages = self.config.load_requirements("requirements-pyodide.txt")
693705

706+
# Get installed versions and create pinned package specs
707+
extracted_versions = {}
708+
for pkg in pyodide_packages:
709+
version = self._get_package_version(pkg["import"])
710+
if version:
711+
extracted_versions[pkg["import"]] = version
712+
base_name = pkg["pip"].split(">=")[0].split("==")[0].split("<=")[0].split("<")[0].split(">")[0]
713+
714+
# Only pin release versions (not dev versions which aren't on PyPI)
715+
if ".dev" in version:
716+
print(f" {base_name} {version} is dev version, keeping original spec: {pkg['pip']}")
717+
else:
718+
pkg["pip"] = f"{base_name}=={version}"
719+
print(f" Pinned {base_name} to version {version}")
720+
694721
return {
695722
"pyodide": pyodide_config,
696-
"packages": pyodide_packages
723+
"packages": pyodide_packages,
724+
"extracted_versions": extracted_versions
697725
}
698726

699727

@@ -816,16 +844,32 @@ def write_dependencies(self, data: dict) -> None:
816844
"""Write dependencies.ts file."""
817845
pyodide = data.get("pyodide", {})
818846
packages = data.get("packages", [])
847+
extracted_versions = data.get("extracted_versions", {})
848+
849+
# Read PathView version from package.json (at project root, 2 levels up from src/lib)
850+
package_json_path = self.output_dir.parent.parent / "package.json"
851+
pathview_version = "0.0.0"
852+
if package_json_path.exists():
853+
try:
854+
package_data = json.loads(package_json_path.read_text(encoding="utf-8"))
855+
pathview_version = package_data.get("version", "0.0.0")
856+
except Exception:
857+
pass
819858

820859
lines = [
821860
"// Auto-generated by scripts/extract.py - DO NOT EDIT",
822861
"// Source: scripts/config/requirements-pyodide.txt, scripts/config/pyodide.json",
823862
"",
863+
f"export const PATHVIEW_VERSION = '{pathview_version}';",
864+
"",
824865
f"export const PYODIDE_VERSION = '{pyodide.get('version', '0.26.2')}';",
825866
"export const PYODIDE_CDN_URL = `https://cdn.jsdelivr.net/pyodide/v${PYODIDE_VERSION}/full/pyodide.mjs`;",
826867
"",
827868
f"export const PYODIDE_PRELOAD = {json.dumps(pyodide.get('preload', []))} as const;",
828869
"",
870+
"/** Package versions extracted at build time (pinned for runtime) */",
871+
f"export const EXTRACTED_VERSIONS: Record<string, string> = {json.dumps(extracted_versions)};",
872+
"",
829873
"export interface PackageConfig {",
830874
" pip: string;",
831875
" pre: boolean;",

src/lib/components/WelcomeModal.svelte

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import { scale, fade } from 'svelte/transition';
55
import { cubicOut } from 'svelte/easing';
66
import Icon from '$lib/components/icons/Icon.svelte';
7+
import { PATHVIEW_VERSION, EXTRACTED_VERSIONS } from '$lib/constants/dependencies';
78
89
interface Example {
910
name: string;
@@ -95,6 +96,9 @@
9596
<div class="dialog-backdrop" transition:fade={{ duration: 150 }} onclick={onClose} onkeydown={(e) => e.key === 'Escape' && onClose()} role="presentation">
9697
<!-- svelte-ignore a11y_no_static_element_interactions, a11y_click_events_have_key_events -->
9798
<div class="modal glass-panel" transition:scale={{ start: 0.95, duration: 200, easing: cubicOut }} onclick={(e) => e.stopPropagation()} role="dialog" tabindex="-1">
99+
<div class="version-info">
100+
PathView {PATHVIEW_VERSION} · {Object.entries(EXTRACTED_VERSIONS).map(([pkg, ver]) => `${pkg.replace('_', '-')} ${ver}`).join(' · ')}
101+
</div>
98102
<div class="header">
99103
<img src="{base}/pathview_logo.png" alt="PathView" class="logo" />
100104
</div>
@@ -163,6 +167,7 @@
163167
/* Uses global .dialog-backdrop from app.css */
164168
165169
.modal {
170+
position: relative;
166171
width: 90%;
167172
max-width: 780px;
168173
padding: 24px;
@@ -173,6 +178,14 @@
173178
overflow: hidden;
174179
}
175180
181+
.version-info {
182+
position: absolute;
183+
top: 8px;
184+
right: 12px;
185+
font-size: 9px;
186+
color: var(--text-disabled);
187+
}
188+
176189
.header {
177190
text-align: center;
178191
padding: 24px 0;

src/lib/constants/dependencies.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
// Auto-generated by scripts/extract.py - DO NOT EDIT
22
// Source: scripts/config/requirements-pyodide.txt, scripts/config/pyodide.json
33

4+
export const PATHVIEW_VERSION = '0.4.5';
5+
46
export const PYODIDE_VERSION = '0.26.2';
57
export const PYODIDE_CDN_URL = `https://cdn.jsdelivr.net/pyodide/v${PYODIDE_VERSION}/full/pyodide.mjs`;
68

79
export const PYODIDE_PRELOAD = ["numpy", "scipy", "micropip"] as const;
810

11+
/** Package versions extracted at build time (pinned for runtime) */
12+
export const EXTRACTED_VERSIONS: Record<string, string> = {"pathsim": "0.16.5", "pathsim_chem": "0.2rc3.dev1"};
13+
914
export interface PackageConfig {
1015
pip: string;
1116
pre: boolean;
@@ -16,7 +21,7 @@ export interface PackageConfig {
1621
export const PYTHON_PACKAGES: PackageConfig[] =
1722
[
1823
{
19-
"pip": "pathsim",
24+
"pip": "pathsim==0.16.5",
2025
"required": true,
2126
"pre": true,
2227
"import": "pathsim"

0 commit comments

Comments
 (0)