node-walk 0.2.0__tar.gz → 0.3.0__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.
- node_walk-0.3.0/.github/workflows/release.yml +133 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/CHANGELOG.md +4 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/PKG-INFO +1 -1
- {node_walk-0.2.0 → node_walk-0.3.0}/pyproject.toml +5 -2
- node_walk-0.3.0/src/node_walk/__init__.py +8 -0
- node_walk-0.2.0/.github/workflows/release.yml +0 -158
- node_walk-0.2.0/src/node_walk/__init__.py +0 -3
- {node_walk-0.2.0 → node_walk-0.3.0}/.github/workflows/ci.yml +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/.gitignore +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/LICENSE +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/README.md +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/plans/plan.md +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/plans/traversable-graph.md +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/analysis/__init__.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/analysis/base.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/analysis/python/__init__.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/analysis/python/analyzer.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/analysis/python/scope.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/analysis/python/visitor.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/analysis/python_analyzer.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/cli/__init__.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/cli/main.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/indexer.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/ir/__init__.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/ir/enums.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/ir/models.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/query/__init__.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/query/engine.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/query/tree_formatter.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/storage/__init__.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/storage/base.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/storage/repository.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/storage/schema.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/storage/sqlite_store.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/web/__init__.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/web/app.js +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/web/index.html +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/web/server.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/src/node_walk/web/style.css +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/tests/fixtures/nested_project/base.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/tests/fixtures/nested_project/impl.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/tests/fixtures/simple_project/services.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/tests/test_ir.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/tests/test_python_analyzer.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/tests/test_query_engine.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/tests/test_storage.py +0 -0
- {node_walk-0.2.0 → node_walk-0.3.0}/tests/test_web_server.py +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
name: Release & Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
bump_type:
|
|
7
|
+
description: "Version bump type"
|
|
8
|
+
required: true
|
|
9
|
+
default: "patch"
|
|
10
|
+
type: choice
|
|
11
|
+
options:
|
|
12
|
+
- "patch"
|
|
13
|
+
- "minor"
|
|
14
|
+
- "major"
|
|
15
|
+
target:
|
|
16
|
+
description: "Publish destination"
|
|
17
|
+
required: true
|
|
18
|
+
default: "pypi"
|
|
19
|
+
type: choice
|
|
20
|
+
options:
|
|
21
|
+
- "pypi"
|
|
22
|
+
- "testpypi"
|
|
23
|
+
|
|
24
|
+
permissions:
|
|
25
|
+
contents: write
|
|
26
|
+
id-token: write
|
|
27
|
+
|
|
28
|
+
jobs:
|
|
29
|
+
release:
|
|
30
|
+
name: Auto-bump, Tag, Build & Publish
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- name: Check out repository
|
|
34
|
+
uses: actions/checkout@v4
|
|
35
|
+
with:
|
|
36
|
+
fetch-depth: 0
|
|
37
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
38
|
+
|
|
39
|
+
- name: Set up Python
|
|
40
|
+
uses: actions/setup-python@v5
|
|
41
|
+
with:
|
|
42
|
+
python-version: "3.11"
|
|
43
|
+
|
|
44
|
+
- name: Install build tools
|
|
45
|
+
run: |
|
|
46
|
+
python -m pip install --upgrade pip
|
|
47
|
+
pip install build hatchling hatch-vcs
|
|
48
|
+
|
|
49
|
+
- name: Calculate Version, Update Changelog & Create Tag
|
|
50
|
+
id: auto_tag
|
|
51
|
+
run: |
|
|
52
|
+
python - << 'EOF'
|
|
53
|
+
import os, re, subprocess, datetime
|
|
54
|
+
|
|
55
|
+
bump = os.environ.get("INPUT_BUMP_TYPE", "patch")
|
|
56
|
+
|
|
57
|
+
# 1. Find latest git tag
|
|
58
|
+
try:
|
|
59
|
+
latest_tag = subprocess.check_output(["git", "describe", "--tags", "--abbrev=0"], text=True).strip()
|
|
60
|
+
except Exception:
|
|
61
|
+
latest_tag = "v0.1.0"
|
|
62
|
+
|
|
63
|
+
current_ver = latest_tag.lstrip("v")
|
|
64
|
+
parts = [int(p) for p in re.findall(r'\d+', current_ver)]
|
|
65
|
+
while len(parts) < 3:
|
|
66
|
+
parts.append(0)
|
|
67
|
+
|
|
68
|
+
# 2. Calculate target version
|
|
69
|
+
if bump == "major":
|
|
70
|
+
target_ver = f"{parts[0]+1}.0.0"
|
|
71
|
+
elif bump == "minor":
|
|
72
|
+
target_ver = f"{parts[0]}.{parts[1]+1}.0"
|
|
73
|
+
else:
|
|
74
|
+
target_ver = f"{parts[0]}.{parts[1]}.{parts[2]+1}"
|
|
75
|
+
|
|
76
|
+
new_tag = f"v{target_ver}"
|
|
77
|
+
today = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d")
|
|
78
|
+
|
|
79
|
+
print(f"Release version: {target_ver} (from {current_ver} via {bump} bump)")
|
|
80
|
+
|
|
81
|
+
# 3. Update CHANGELOG.md automatically
|
|
82
|
+
changelog_path = "CHANGELOG.md"
|
|
83
|
+
if os.path.exists(changelog_path):
|
|
84
|
+
with open(changelog_path, "r", encoding="utf-8") as f:
|
|
85
|
+
content = f.read()
|
|
86
|
+
|
|
87
|
+
replacement = f"## [Unreleased]\n\n---\n\n## [{target_ver}] - {today}"
|
|
88
|
+
if "## [Unreleased]" in content:
|
|
89
|
+
new_content = content.replace("## [Unreleased]", replacement, 1)
|
|
90
|
+
with open(changelog_path, "w", encoding="utf-8") as f:
|
|
91
|
+
f.write(new_content)
|
|
92
|
+
print(f"Updated {changelog_path} with header [{target_ver}] - {today}")
|
|
93
|
+
|
|
94
|
+
# 4. Configure git bot, commit changelog, and push tag + commit
|
|
95
|
+
subprocess.run(["git", "config", "user.name", "github-actions[bot]"], check=True)
|
|
96
|
+
subprocess.run(["git", "config", "user.email", "github-actions[bot]@users.noreply.github.com"], check=True)
|
|
97
|
+
|
|
98
|
+
# Commit CHANGELOG update
|
|
99
|
+
subprocess.run(["git", "add", "CHANGELOG.md"], check=True)
|
|
100
|
+
subprocess.run(["git", "commit", "-m", f"chore(release): release {new_tag} [skip ci]"], check=True)
|
|
101
|
+
|
|
102
|
+
# Tag the commit
|
|
103
|
+
subprocess.run(["git", "tag", "-a", new_tag, "-m", f"Release {new_tag}"], check=True)
|
|
104
|
+
|
|
105
|
+
# Push commit and tag back to repository
|
|
106
|
+
branch = os.environ.get("GITHUB_REF_NAME", "main")
|
|
107
|
+
remote_url = f"https://x-access-token:{os.environ['GITHUB_TOKEN']}@github.com/{os.environ['GITHUB_REPOSITORY']}.git"
|
|
108
|
+
subprocess.run(["git", "push", remote_url, f"HEAD:{branch}"], check=True)
|
|
109
|
+
subprocess.run(["git", "push", remote_url, new_tag], check=True)
|
|
110
|
+
|
|
111
|
+
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as out:
|
|
112
|
+
out.write(f"version={target_ver}\n")
|
|
113
|
+
out.write(f"tag={new_tag}\n")
|
|
114
|
+
EOF
|
|
115
|
+
env:
|
|
116
|
+
INPUT_BUMP_TYPE: ${{ inputs.bump_type }}
|
|
117
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
118
|
+
|
|
119
|
+
- name: Build package distributions
|
|
120
|
+
run: python -m build
|
|
121
|
+
|
|
122
|
+
- name: Publish to PyPI
|
|
123
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
124
|
+
with:
|
|
125
|
+
repository-url: ${{ (inputs.target == 'testpypi') && 'https://test.pypi.org/legacy/' || '' }}
|
|
126
|
+
skip-existing: true
|
|
127
|
+
|
|
128
|
+
- name: Create GitHub Release
|
|
129
|
+
uses: softprops/action-gh-release@v2
|
|
130
|
+
with:
|
|
131
|
+
tag_name: ${{ steps.auto_tag.outputs.tag }}
|
|
132
|
+
files: dist/*
|
|
133
|
+
generate_release_notes: true
|
|
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
## [0.3.0] - 2026-08-23
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
14
18
|
## [0.2.0] - 2026-08-23
|
|
15
19
|
### Added
|
|
16
20
|
- **`node-walk serve` command**: Launches an embedded local HTTP server (`localhost:7777` by default) and auto-opens the browser to the interactive graph explorer. Accepts `--port`, `--host`, and `--no-open` flags.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["hatchling"]
|
|
2
|
+
requires = ["hatchling", "hatch-vcs"]
|
|
3
3
|
build-backend = "hatchling.build"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
@@ -39,7 +39,10 @@ nodewalk = "node_walk.cli.main:app"
|
|
|
39
39
|
node_walk = "node_walk.cli.main:app"
|
|
40
40
|
|
|
41
41
|
[tool.hatch.version]
|
|
42
|
-
|
|
42
|
+
source = "vcs"
|
|
43
|
+
|
|
44
|
+
[tool.hatch.version.raw-options]
|
|
45
|
+
local_scheme = "no-local-version"
|
|
43
46
|
|
|
44
47
|
[tool.hatch.build.targets.wheel]
|
|
45
48
|
packages = ["src/node_walk"]
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
name: Release & Publish
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- "v*.*.*"
|
|
7
|
-
workflow_dispatch:
|
|
8
|
-
inputs:
|
|
9
|
-
version:
|
|
10
|
-
description: "Version to publish (e.g. 0.1.1, patch, minor, major) — leave blank to use current __init__.py version"
|
|
11
|
-
required: false
|
|
12
|
-
default: ""
|
|
13
|
-
type: string
|
|
14
|
-
target:
|
|
15
|
-
description: "Target repository to publish to"
|
|
16
|
-
required: true
|
|
17
|
-
default: "pypi"
|
|
18
|
-
type: choice
|
|
19
|
-
options:
|
|
20
|
-
- "pypi"
|
|
21
|
-
- "testpypi"
|
|
22
|
-
create_github_release:
|
|
23
|
-
description: "Create a GitHub Release with built distribution assets"
|
|
24
|
-
required: false
|
|
25
|
-
default: true
|
|
26
|
-
type: boolean
|
|
27
|
-
is_prerelease:
|
|
28
|
-
description: "Mark GitHub Release as pre-release"
|
|
29
|
-
required: false
|
|
30
|
-
default: false
|
|
31
|
-
type: boolean
|
|
32
|
-
|
|
33
|
-
jobs:
|
|
34
|
-
build:
|
|
35
|
-
name: Build source and binary distribution
|
|
36
|
-
runs-on: ubuntu-latest
|
|
37
|
-
steps:
|
|
38
|
-
- name: Check out repository
|
|
39
|
-
uses: actions/checkout@v4
|
|
40
|
-
with:
|
|
41
|
-
fetch-depth: 0
|
|
42
|
-
|
|
43
|
-
- name: Set up Python
|
|
44
|
-
uses: actions/setup-python@v5
|
|
45
|
-
with:
|
|
46
|
-
python-version: "3.11"
|
|
47
|
-
|
|
48
|
-
- name: Set release version
|
|
49
|
-
id: set_version
|
|
50
|
-
run: |
|
|
51
|
-
python - << 'EOF'
|
|
52
|
-
import os, re
|
|
53
|
-
|
|
54
|
-
tag = os.environ.get("GITHUB_REF_NAME", "")
|
|
55
|
-
input_ver = os.environ.get("INPUT_VERSION", "").strip()
|
|
56
|
-
init_path = "src/node_walk/__init__.py"
|
|
57
|
-
|
|
58
|
-
with open(init_path, "r", encoding="utf-8") as f:
|
|
59
|
-
content = f.read()
|
|
60
|
-
|
|
61
|
-
m = re.search(r'__version__\s*=\s*["\']([^"\']+)["\']', content)
|
|
62
|
-
current_ver = m.group(1) if m else "0.1.0"
|
|
63
|
-
|
|
64
|
-
target_ver = current_ver
|
|
65
|
-
|
|
66
|
-
if input_ver:
|
|
67
|
-
if input_ver in ("patch", "minor", "major"):
|
|
68
|
-
parts = [int(p) for p in re.findall(r'\d+', current_ver)]
|
|
69
|
-
while len(parts) < 3:
|
|
70
|
-
parts.append(0)
|
|
71
|
-
if input_ver == "major":
|
|
72
|
-
target_ver = f"{parts[0]+1}.0.0"
|
|
73
|
-
elif input_ver == "minor":
|
|
74
|
-
target_ver = f"{parts[0]}.{parts[1]+1}.0"
|
|
75
|
-
elif input_ver == "patch":
|
|
76
|
-
target_ver = f"{parts[0]}.{parts[1]}.{parts[2]+1}"
|
|
77
|
-
else:
|
|
78
|
-
target_ver = input_ver.lstrip("v")
|
|
79
|
-
elif os.environ.get("GITHUB_REF_TYPE") == "tag" and tag.startswith("v"):
|
|
80
|
-
target_ver = tag.lstrip("v")
|
|
81
|
-
|
|
82
|
-
print(f"Setting package version to: {target_ver}")
|
|
83
|
-
new_content = re.sub(r'__version__\s*=\s*["\'][^"\']+["\']', f'__version__ = "{target_ver}"', content)
|
|
84
|
-
with open(init_path, "w", encoding="utf-8") as f:
|
|
85
|
-
f.write(new_content)
|
|
86
|
-
|
|
87
|
-
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as out:
|
|
88
|
-
out.write(f"version={target_ver}\n")
|
|
89
|
-
EOF
|
|
90
|
-
env:
|
|
91
|
-
INPUT_VERSION: ${{ inputs.version }}
|
|
92
|
-
|
|
93
|
-
- name: Install build tools
|
|
94
|
-
run: |
|
|
95
|
-
python -m pip install --upgrade pip
|
|
96
|
-
pip install build hatchling
|
|
97
|
-
|
|
98
|
-
- name: Build distributions
|
|
99
|
-
run: python -m build
|
|
100
|
-
|
|
101
|
-
- name: Store distribution packages
|
|
102
|
-
uses: actions/upload-artifact@v4
|
|
103
|
-
with:
|
|
104
|
-
name: python-package-distributions
|
|
105
|
-
path: dist/
|
|
106
|
-
|
|
107
|
-
publish:
|
|
108
|
-
name: Publish distribution
|
|
109
|
-
needs: [build]
|
|
110
|
-
runs-on: ubuntu-latest
|
|
111
|
-
environment:
|
|
112
|
-
name: ${{ inputs.target || 'pypi' }}
|
|
113
|
-
url: ${{ (inputs.target == 'testpypi') && 'https://test.pypi.org/p/node-walk' || 'https://pypi.org/p/node-walk' }}
|
|
114
|
-
permissions:
|
|
115
|
-
id-token: write # Required for Trusted Publishing (OIDC)
|
|
116
|
-
|
|
117
|
-
steps:
|
|
118
|
-
- name: Download distribution packages
|
|
119
|
-
uses: actions/download-artifact@v4
|
|
120
|
-
with:
|
|
121
|
-
name: python-package-distributions
|
|
122
|
-
path: dist/
|
|
123
|
-
|
|
124
|
-
- name: Publish to PyPI / TestPyPI
|
|
125
|
-
uses: pypa/gh-action-pypi-publish@release/v1
|
|
126
|
-
with:
|
|
127
|
-
repository-url: ${{ (inputs.target == 'testpypi') && 'https://test.pypi.org/legacy/' || '' }}
|
|
128
|
-
skip-existing: true
|
|
129
|
-
|
|
130
|
-
github-release:
|
|
131
|
-
name: Create GitHub Release
|
|
132
|
-
needs: [build]
|
|
133
|
-
if: ${{ inputs.create_github_release != false }}
|
|
134
|
-
runs-on: ubuntu-latest
|
|
135
|
-
permissions:
|
|
136
|
-
contents: write
|
|
137
|
-
|
|
138
|
-
steps:
|
|
139
|
-
- name: Download distribution packages
|
|
140
|
-
uses: actions/download-artifact@v4
|
|
141
|
-
with:
|
|
142
|
-
name: python-package-distributions
|
|
143
|
-
path: dist/
|
|
144
|
-
|
|
145
|
-
- name: Extract package version from distribution filename
|
|
146
|
-
id: get_version
|
|
147
|
-
run: |
|
|
148
|
-
FILE=$(ls dist/*.whl | head -n 1)
|
|
149
|
-
VERSION=$(basename "$FILE" | sed -E 's/.*-([0-9]+\.[0-9]+\.[0-9]+[a-zA-Z0-9._]*)-.*/\1/')
|
|
150
|
-
echo "version=v$VERSION" >> $GITHUB_OUTPUT
|
|
151
|
-
|
|
152
|
-
- name: Create GitHub Release
|
|
153
|
-
uses: softprops/action-gh-release@v2
|
|
154
|
-
with:
|
|
155
|
-
tag_name: ${{ steps.get_version.outputs.version }}
|
|
156
|
-
files: dist/*
|
|
157
|
-
generate_release_notes: true
|
|
158
|
-
prerelease: ${{ inputs.is_prerelease || false }}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|