-
Notifications
You must be signed in to change notification settings - Fork 1
fix: resolve critical relative path issues in packaged build #185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
abfb3b2
af60e30
264c165
fb7f7d0
a40113f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| #!/usr/bin/env python3 | ||
| # SPDX-FileCopyrightText: 2025 Knitli Inc. | ||
| # SPDX-FileContributor: Adam Poulemanos <adam@knit.li> | ||
| # | ||
| # SPDX-License-Identifier: MIT OR Apache-2.0 | ||
| """Generate JSON schema for CodeWeaver settings. | ||
|
|
||
| This script generates the JSON schema file for CodeWeaver settings validation. | ||
| It should be run during the build process when the schema version changes or | ||
| when the schema file doesn't exist. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import sys | ||
| from pathlib import Path | ||
|
|
||
|
|
||
| def main() -> int: | ||
| """Generate the JSON schema file for CodeWeaver settings.""" | ||
| # Add src to path so we can import codeweaver | ||
| repo_root = Path(__file__).parent.parent.parent | ||
| src_path = repo_root / "src" | ||
| if src_path not in sys.path: | ||
| sys.path.insert(0, str(src_path)) | ||
|
|
||
| from codeweaver.config.settings import CodeWeaverSettings | ||
|
|
||
| # Get the schema version from CodeWeaverSettings | ||
| version = CodeWeaverSettings.model_fields["__version__"].default | ||
| schema_dir = repo_root / "schema" / f"v{version}" | ||
| schema_file = schema_dir / "codeweaver.schema.json" | ||
|
|
||
| # Check if schema file already exists | ||
| if schema_file.exists(): | ||
| print(f"Schema file already exists: {schema_file}") | ||
| print("Skipping schema generation. Delete the file to regenerate.") | ||
| return 0 | ||
|
|
||
| # Generate schema | ||
| print(f"Generating schema for version {version}...") | ||
| schema_dir.mkdir(parents=True, exist_ok=True) | ||
|
|
||
| schema_bytes = CodeWeaverSettings.json_schema() | ||
| bytes_written = schema_file.write_bytes(schema_bytes) | ||
|
|
||
| print(f"✓ Generated schema file: {schema_file}") | ||
| print(f" Size: {bytes_written:,} bytes") | ||
|
|
||
| return 0 | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| sys.exit(main()) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| #!/usr/bin/env python3 | ||
| # SPDX-FileCopyrightText: 2025 Knitli Inc. | ||
| # SPDX-FileContributor: Adam Poulemanos <adam@knit.li> | ||
| # | ||
| # SPDX-License-Identifier: MIT OR Apache-2.0 | ||
| """Master build preparation script for CodeWeaver. | ||
|
|
||
| This script orchestrates all the build preparation steps in the correct order: | ||
| 1. Generate supported languages list | ||
| 2. Generate provider lists | ||
| 3. Update node-types from tree-sitter grammars | ||
| 4. Preprocess node-types into cached format | ||
| 5. Generate JSON schema (if needed) | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import subprocess | ||
| import sys | ||
| from pathlib import Path | ||
|
|
||
|
|
||
| def run_script(script_path: Path, *args: str) -> int: | ||
| """Run a script and return its exit code.""" | ||
| script_name = script_path.name | ||
| print(f"\n{'=' * 70}") | ||
| print(f"Running: {script_name}") | ||
| print(f"{'=' * 70}") | ||
|
|
||
| result = subprocess.run( | ||
| [sys.executable, str(script_path), *args], | ||
| cwd=script_path.parent.parent.parent, | ||
| check=False, | ||
| ) | ||
|
|
||
| if result.returncode != 0: | ||
| print(f"✗ {script_name} failed with exit code {result.returncode}") | ||
| return result.returncode | ||
|
|
||
| print(f"✓ {script_name} completed successfully") | ||
| return 0 | ||
|
|
||
|
|
||
| def main() -> int: | ||
| """Run all build preparation steps.""" | ||
| repo_root = Path(__file__).parent.parent.parent | ||
| scripts_build = repo_root / "scripts" / "build" | ||
| scripts_lang = repo_root / "scripts" / "language-support" | ||
|
|
||
| print("=" * 70) | ||
| print("CodeWeaver Build Preparation") | ||
| print("=" * 70) | ||
|
|
||
| # Step 1: Generate supported languages | ||
| exit_code = run_script(scripts_build / "generate-supported-languages.py") | ||
| if exit_code != 0: | ||
| return exit_code | ||
|
|
||
| # Step 2: Generate provider lists | ||
| exit_code = run_script(scripts_build / "generate-provider-lists.py") | ||
| if exit_code != 0: | ||
| return exit_code | ||
|
|
||
| # Step 3: Update node-types from tree-sitter grammars | ||
| exit_code = run_script( | ||
| scripts_lang / "download-ts-grammars.py", "fetch", "--only-update", "--only-node-types" | ||
| ) | ||
| if exit_code != 0: | ||
| return exit_code | ||
|
|
||
| # Step 4: Preprocess node-types into cache | ||
| exit_code = run_script(scripts_build / "preprocess-node-types.py") | ||
| if exit_code != 0: | ||
| return exit_code | ||
|
|
||
| # Step 5: Generate schema (if needed) | ||
| exit_code = run_script(scripts_build / "generate-schema.py") | ||
| if exit_code != 0: | ||
| return exit_code | ||
|
|
||
| print("\n" + "=" * 70) | ||
| print("✓ Build preparation completed successfully!") | ||
| print("=" * 70) | ||
|
|
||
| return 0 | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| sys.exit(main()) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| #!/usr/bin/env python3 | ||
| # SPDX-FileCopyrightText: 2025 Knitli Inc. | ||
| # SPDX-FileContributor: Adam Poulemanos <adam@knit.li> | ||
| # | ||
| # SPDX-License-Identifier: MIT OR Apache-2.0 | ||
| """Preprocess node-types JSON files and cache the parsed grammar data. | ||
|
|
||
| This script loads all tree-sitter node-types.json files, parses them into | ||
| CodeWeaver's internal Thing/Category representation, and serializes the | ||
| result to a pickle cache. This cache is loaded at runtime for fast startup. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import pickle | ||
| import sys | ||
| from pathlib import Path | ||
|
|
||
|
|
||
| def main() -> int: | ||
| """Preprocess node types and generate cache file.""" | ||
| # Add src to path so we can import codeweaver | ||
| repo_root = Path(__file__).parent.parent.parent | ||
| src_path = repo_root / "src" | ||
| if src_path not in sys.path: | ||
| sys.path.insert(0, str(src_path)) | ||
|
|
||
| from codeweaver.semantic.node_type_parser import NodeTypeParser | ||
|
|
||
| print("Preprocessing node-types JSON files...") | ||
|
|
||
| # Create parser and process all languages (disable cache since we're building it) | ||
| parser = NodeTypeParser(use_cache=False) | ||
| all_things = parser.parse_all_nodes() | ||
|
|
||
| print(f" Parsed {len(all_things)} Things/Categories across all languages") | ||
|
|
||
| # Get the cache from the parser's registration cache | ||
| # Note: We only cache the registration_cache, not all_things, | ||
| # since all_things can be reconstructed from the cache at runtime | ||
| cache_data = { | ||
| "registration_cache": parser.registration_cache, | ||
| } | ||
|
|
||
| # Write cache file | ||
| cache_file = repo_root / "src" / "codeweaver" / "data" / "node_types_cache.pkl" | ||
| print(f"Writing cache to {cache_file}...") | ||
|
|
||
| with cache_file.open("wb") as f: | ||
| pickle.dump(cache_data, f, protocol=pickle.HIGHEST_PROTOCOL) | ||
|
|
||
| cache_size = cache_file.stat().st_size | ||
| print(f"✓ Generated node_types cache: {cache_file}") | ||
| print(f" Size: {cache_size:,} bytes ({cache_size / 1024:.1f} KB)") | ||
|
|
||
| return 0 | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| sys.exit(main()) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,18 +48,21 @@ | |
| import shutil | ||
| import subprocess | ||
|
|
||
| from pathlib import Path | ||
|
|
||
| if git := (shutil.which("git") is not None): | ||
| # Try to get version from git if available | ||
| # Git commands work from any directory within a repo, so no need to specify cwd | ||
| if git := shutil.which("git"): | ||
| git_describe = subprocess.run( | ||
| ["describe", "--tags", "--always", "--dirty"], # noqa: S607 | ||
| executable=git, | ||
| [git, "describe", "--tags", "--always", "--dirty"], | ||
| capture_output=True, | ||
| text=True, | ||
| check=True, | ||
| cwd=str(Path(__file__).parent.parent.parent), | ||
| check=False, | ||
| ) | ||
|
Comment on lines
54
to
59
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. security (python.lang.security.audit.dangerous-subprocess-use-audit): Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. Source: opengrep |
||
| __version__ = git_describe.stdout.strip() | ||
| if git_describe.returncode == 0: | ||
| __version__ = git_describe.stdout.strip() | ||
| else: | ||
| __version__ = "0.0.0" | ||
| else: | ||
| __version__ = "0.0.0" | ||
| except Exception: | ||
| __version__ = "0.0.0" | ||
| return __version__ | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.