headerkit 0.4.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.
- headerkit-0.4.0/.github/dependabot.yml +25 -0
- headerkit-0.4.0/.github/workflows/check-llvm.yml +113 -0
- headerkit-0.4.0/.github/workflows/check-python.yml +161 -0
- headerkit-0.4.0/.github/workflows/ci.yml +27 -0
- headerkit-0.4.0/.github/workflows/docs.yml +67 -0
- headerkit-0.4.0/.github/workflows/release.yml +84 -0
- headerkit-0.4.0/.github/workflows/test-install-libclang.yml +52 -0
- headerkit-0.4.0/.github/workflows/test.yml +43 -0
- headerkit-0.4.0/.gitignore +73 -0
- headerkit-0.4.0/.pre-commit-config.yaml +29 -0
- headerkit-0.4.0/AGENTS.md +49 -0
- headerkit-0.4.0/CHANGELOG.md +109 -0
- headerkit-0.4.0/CLAUDE.md +5 -0
- headerkit-0.4.0/LICENSE +21 -0
- headerkit-0.4.0/PKG-INFO +121 -0
- headerkit-0.4.0/README.md +70 -0
- headerkit-0.4.0/docs/guides/architecture.md +275 -0
- headerkit-0.4.0/docs/guides/cffi.md +174 -0
- headerkit-0.4.0/docs/guides/custom-backends.md +229 -0
- headerkit-0.4.0/docs/guides/custom-writers.md +311 -0
- headerkit-0.4.0/docs/guides/install-libclang.md +93 -0
- headerkit-0.4.0/docs/guides/installation.md +94 -0
- headerkit-0.4.0/docs/guides/quickstart.md +151 -0
- headerkit-0.4.0/docs/index.md +88 -0
- headerkit-0.4.0/docs/reference/backends.md +47 -0
- headerkit-0.4.0/docs/reference/cffi.md +31 -0
- headerkit-0.4.0/docs/reference/index.md +48 -0
- headerkit-0.4.0/docs/reference/install-libclang.md +19 -0
- headerkit-0.4.0/docs/reference/ir.md +110 -0
- headerkit-0.4.0/docs/reference/json.md +20 -0
- headerkit-0.4.0/docs/reference/writers.md +49 -0
- headerkit-0.4.0/docs/tutorials/ctypes-writer.md +363 -0
- headerkit-0.4.0/docs/tutorials/header-cleanup.md +408 -0
- headerkit-0.4.0/docs/tutorials/json-export.md +294 -0
- headerkit-0.4.0/docs/tutorials/pxd-writer.md +319 -0
- headerkit-0.4.0/headerkit/__init__.py +74 -0
- headerkit-0.4.0/headerkit/_clang/LICENSE +278 -0
- headerkit-0.4.0/headerkit/_clang/__init__.py +137 -0
- headerkit-0.4.0/headerkit/_clang/_version.py +333 -0
- headerkit-0.4.0/headerkit/_clang/v18/PROVENANCE +5 -0
- headerkit-0.4.0/headerkit/_clang/v18/__init__.py +0 -0
- headerkit-0.4.0/headerkit/_clang/v18/cindex.py +3977 -0
- headerkit-0.4.0/headerkit/_clang/v18/enumerations.py +33 -0
- headerkit-0.4.0/headerkit/_clang/v19/PROVENANCE +5 -0
- headerkit-0.4.0/headerkit/_clang/v19/__init__.py +0 -0
- headerkit-0.4.0/headerkit/_clang/v19/cindex.py +4103 -0
- headerkit-0.4.0/headerkit/_clang/v20/PROVENANCE +5 -0
- headerkit-0.4.0/headerkit/_clang/v20/__init__.py +0 -0
- headerkit-0.4.0/headerkit/_clang/v20/cindex.py +4232 -0
- headerkit-0.4.0/headerkit/_clang/v21/PROVENANCE +5 -0
- headerkit-0.4.0/headerkit/_clang/v21/__init__.py +0 -0
- headerkit-0.4.0/headerkit/_clang/v21/cindex.py +4631 -0
- headerkit-0.4.0/headerkit/backends/__init__.py +228 -0
- headerkit-0.4.0/headerkit/backends/libclang.py +2061 -0
- headerkit-0.4.0/headerkit/install_libclang.py +204 -0
- headerkit-0.4.0/headerkit/ir.py +770 -0
- headerkit-0.4.0/headerkit/py.typed +0 -0
- headerkit-0.4.0/headerkit/writers/__init__.py +260 -0
- headerkit-0.4.0/headerkit/writers/cffi.py +529 -0
- headerkit-0.4.0/headerkit/writers/json.py +247 -0
- headerkit-0.4.0/mkdocs.yml +99 -0
- headerkit-0.4.0/pyproject.toml +77 -0
- headerkit-0.4.0/tests/__init__.py +0 -0
- headerkit-0.4.0/tests/test_backends/__init__.py +0 -0
- headerkit-0.4.0/tests/test_backends/test_libclang.py +882 -0
- headerkit-0.4.0/tests/test_backends/test_registry.py +172 -0
- headerkit-0.4.0/tests/test_clang/__init__.py +0 -0
- headerkit-0.4.0/tests/test_clang/test_loader.py +140 -0
- headerkit-0.4.0/tests/test_clang/test_pypy_compat.py +148 -0
- headerkit-0.4.0/tests/test_clang/test_version_detect.py +438 -0
- headerkit-0.4.0/tests/test_clang/test_windows_detection.py +267 -0
- headerkit-0.4.0/tests/test_install_libclang.py +204 -0
- headerkit-0.4.0/tests/test_integration/__init__.py +0 -0
- headerkit-0.4.0/tests/test_integration/conftest.py +225 -0
- headerkit-0.4.0/tests/test_integration/test_real_headers.py +322 -0
- headerkit-0.4.0/tests/test_integration/test_roundtrip.py +599 -0
- headerkit-0.4.0/tests/test_ir.py +359 -0
- headerkit-0.4.0/tests/test_public_api.py +100 -0
- headerkit-0.4.0/tests/test_writers/__init__.py +0 -0
- headerkit-0.4.0/tests/test_writers/test_cffi.py +314 -0
- headerkit-0.4.0/tests/test_writers/test_json.py +637 -0
- headerkit-0.4.0/tests/test_writers/test_registry.py +273 -0
- headerkit-0.4.0/uv.lock +1020 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "github-actions"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
labels:
|
|
8
|
+
- "dependencies"
|
|
9
|
+
groups:
|
|
10
|
+
minor-and-patch:
|
|
11
|
+
update-types:
|
|
12
|
+
- "minor"
|
|
13
|
+
- "patch"
|
|
14
|
+
|
|
15
|
+
- package-ecosystem: "pip"
|
|
16
|
+
directory: "/"
|
|
17
|
+
schedule:
|
|
18
|
+
interval: "weekly"
|
|
19
|
+
labels:
|
|
20
|
+
- "dependencies"
|
|
21
|
+
groups:
|
|
22
|
+
minor-and-patch:
|
|
23
|
+
update-types:
|
|
24
|
+
- "minor"
|
|
25
|
+
- "patch"
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
name: Check LLVM Releases
|
|
2
|
+
|
|
3
|
+
# Detect new stable LLVM major versions that aren't yet vendored in headerkit/_clang/
|
|
4
|
+
# and open an issue with vendoring instructions.
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
schedule:
|
|
8
|
+
- cron: "0 10 * * 1" # Mondays at 10 AM UTC
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
issues: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
check:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
timeout-minutes: 10
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v6
|
|
20
|
+
|
|
21
|
+
- name: Detect new LLVM versions
|
|
22
|
+
id: detect
|
|
23
|
+
run: |
|
|
24
|
+
# Fetch all LLVM tags once and cache for reuse
|
|
25
|
+
all_tags=$(
|
|
26
|
+
git -c 'versionsort.suffix=-' \
|
|
27
|
+
ls-remote --exit-code --refs --sort='version:refname' --tags \
|
|
28
|
+
https://github.com/llvm/llvm-project 'llvmorg-*.*.*' \
|
|
29
|
+
| sed 's/.*llvmorg-//' \
|
|
30
|
+
| grep -v '-'
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# Get all stable LLVM major versions with releases (>= 18)
|
|
34
|
+
released_majors=$(
|
|
35
|
+
echo "$all_tags" \
|
|
36
|
+
| awk -F. '$1 >= 18 { print $1 }' \
|
|
37
|
+
| sort -un
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Get vendored major versions
|
|
41
|
+
vendored_majors=$(
|
|
42
|
+
ls -d headerkit/_clang/v*/ 2>/dev/null \
|
|
43
|
+
| sed 's|headerkit/_clang/v||; s|/||' \
|
|
44
|
+
| sort -n
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
echo "Released LLVM majors: $released_majors"
|
|
48
|
+
echo "Vendored majors: $vendored_majors"
|
|
49
|
+
|
|
50
|
+
# Find missing versions
|
|
51
|
+
missing=""
|
|
52
|
+
for major in $released_majors; do
|
|
53
|
+
if ! echo "$vendored_majors" | grep -qx "$major"; then
|
|
54
|
+
missing="$missing $major"
|
|
55
|
+
fi
|
|
56
|
+
done
|
|
57
|
+
missing=$(echo "$missing" | xargs)
|
|
58
|
+
|
|
59
|
+
echo "Missing: ${missing:-none}"
|
|
60
|
+
echo "missing=$missing" >> "$GITHUB_OUTPUT"
|
|
61
|
+
|
|
62
|
+
# Save tag list for reuse in the next step
|
|
63
|
+
{
|
|
64
|
+
echo "all_tags<<TAGS_EOF"
|
|
65
|
+
echo "$all_tags"
|
|
66
|
+
echo "TAGS_EOF"
|
|
67
|
+
} >> "$GITHUB_OUTPUT"
|
|
68
|
+
|
|
69
|
+
- name: Open issues for missing versions
|
|
70
|
+
if: steps.detect.outputs.missing != ''
|
|
71
|
+
env:
|
|
72
|
+
GH_TOKEN: ${{ github.token }}
|
|
73
|
+
MISSING: ${{ steps.detect.outputs.missing }}
|
|
74
|
+
ALL_TAGS: ${{ steps.detect.outputs.all_tags }}
|
|
75
|
+
run: |
|
|
76
|
+
for major in $MISSING; do
|
|
77
|
+
title="Vendor clang Python bindings for LLVM $major"
|
|
78
|
+
|
|
79
|
+
# Skip if issue already exists (open or closed)
|
|
80
|
+
existing=$(gh issue list --search "\"$title\" in:title" --state all --json number --jq 'length')
|
|
81
|
+
if [ "$existing" -gt 0 ]; then
|
|
82
|
+
echo "Issue already exists for LLVM $major, skipping"
|
|
83
|
+
continue
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# Get latest patch version for this major from cached tags
|
|
87
|
+
latest=$(
|
|
88
|
+
echo "$ALL_TAGS" \
|
|
89
|
+
| grep "^${major}\." \
|
|
90
|
+
| sort -t. -k1,1n -k2,2n -k3,3n \
|
|
91
|
+
| tail -1
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
body="A new LLVM major version ($major) has stable releases (latest: $latest) but no vendored bindings in \`headerkit/_clang/\`.
|
|
95
|
+
|
|
96
|
+
## Steps to vendor
|
|
97
|
+
|
|
98
|
+
1. Download the clang Python bindings from the LLVM $latest source:
|
|
99
|
+
\`\`\`
|
|
100
|
+
https://github.com/llvm/llvm-project/tree/llvmorg-$latest/clang/bindings/python/clang
|
|
101
|
+
\`\`\`
|
|
102
|
+
2. Create \`headerkit/_clang/v$major/\` with:
|
|
103
|
+
- \`__init__.py\`
|
|
104
|
+
- \`cindex.py\` (from the LLVM source)
|
|
105
|
+
- \`PROVENANCE\` (source URL, SHA256, license)
|
|
106
|
+
3. Update \`headerkit/_clang/__init__.py\` if the loader needs changes for the new version.
|
|
107
|
+
4. Add tests and verify with \`pytest\`.
|
|
108
|
+
|
|
109
|
+
*This issue was automatically created by the check-llvm workflow.*"
|
|
110
|
+
|
|
111
|
+
gh issue create --title "$title" --body "$body"
|
|
112
|
+
echo "Created issue for LLVM $major"
|
|
113
|
+
done
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Check for Python version support updates
|
|
2
|
+
#
|
|
3
|
+
# Runs weekly to detect:
|
|
4
|
+
# - New stable Python releases that should be added to the test matrix
|
|
5
|
+
# - Python versions reaching end-of-life that should be dropped
|
|
6
|
+
#
|
|
7
|
+
# Creates GitHub issues when action is needed.
|
|
8
|
+
#
|
|
9
|
+
# Manual trigger:
|
|
10
|
+
# Go to Actions -> Check Python Versions -> Run workflow
|
|
11
|
+
|
|
12
|
+
name: Check Python Versions
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
workflow_dispatch:
|
|
16
|
+
schedule:
|
|
17
|
+
- cron: '0 10 * * 1' # Weekly on Monday
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
check:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
permissions:
|
|
23
|
+
issues: write
|
|
24
|
+
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v6
|
|
27
|
+
|
|
28
|
+
- name: Setup python
|
|
29
|
+
uses: actions/setup-python@v6
|
|
30
|
+
with:
|
|
31
|
+
python-version: '3.13'
|
|
32
|
+
|
|
33
|
+
- name: Check Python versions
|
|
34
|
+
id: check
|
|
35
|
+
env:
|
|
36
|
+
GH_TOKEN: ${{ github.token }}
|
|
37
|
+
run: |
|
|
38
|
+
# Extract supported versions from pyproject.toml
|
|
39
|
+
supported=$(grep 'Programming Language :: Python :: 3\.' pyproject.toml \
|
|
40
|
+
| sed 's/.*Python :: //' | sed 's/".*//' | tr '\n' ' ')
|
|
41
|
+
min_python=$(grep 'requires-python' pyproject.toml \
|
|
42
|
+
| sed 's/.*>=\([0-9.]*\).*/\1/')
|
|
43
|
+
echo "supported=$supported" >> $GITHUB_OUTPUT
|
|
44
|
+
echo "min_python=$min_python" >> $GITHUB_OUTPUT
|
|
45
|
+
echo "Currently supported: $supported"
|
|
46
|
+
echo "Minimum Python: $min_python"
|
|
47
|
+
|
|
48
|
+
# Fetch Python release cycle data from endoflife.date API
|
|
49
|
+
curl -s https://endoflife.date/api/python.json > /tmp/python_versions.json
|
|
50
|
+
|
|
51
|
+
# Find stable versions we DON'T support yet
|
|
52
|
+
python3 -c "
|
|
53
|
+
import json, sys
|
|
54
|
+
with open('/tmp/python_versions.json') as f:
|
|
55
|
+
versions = json.load(f)
|
|
56
|
+
supported = '$supported'.split()
|
|
57
|
+
for v in versions:
|
|
58
|
+
cycle = v['cycle']
|
|
59
|
+
# Only consider 3.x versions
|
|
60
|
+
if not cycle.startswith('3.'):
|
|
61
|
+
continue
|
|
62
|
+
minor = int(cycle.split('.')[1])
|
|
63
|
+
# Only consider versions >= our minimum
|
|
64
|
+
min_minor = int('$min_python'.split('.')[1])
|
|
65
|
+
if minor < min_minor:
|
|
66
|
+
continue
|
|
67
|
+
# Check if this is a stable release (not pre-release)
|
|
68
|
+
if v.get('lts', False) or v.get('latest', ''):
|
|
69
|
+
if cycle not in supported:
|
|
70
|
+
print(f'NEW:{cycle}')
|
|
71
|
+
# Check for EOL versions we still support
|
|
72
|
+
eol = v.get('eol', '')
|
|
73
|
+
if eol and eol != 'false' and eol <= '$(date +%Y-%m-%d)':
|
|
74
|
+
if cycle in supported:
|
|
75
|
+
print(f'EOL:{cycle}:{eol}')
|
|
76
|
+
" > /tmp/version_actions.txt
|
|
77
|
+
|
|
78
|
+
cat /tmp/version_actions.txt
|
|
79
|
+
|
|
80
|
+
new=$(grep '^NEW:' /tmp/version_actions.txt | sed 's/NEW://' | tr '\n' ' ' || true)
|
|
81
|
+
eol=$(grep '^EOL:' /tmp/version_actions.txt || true)
|
|
82
|
+
|
|
83
|
+
echo "new_versions=$new" >> $GITHUB_OUTPUT
|
|
84
|
+
echo "eol_versions=$eol" >> $GITHUB_OUTPUT
|
|
85
|
+
|
|
86
|
+
- name: Create issue for new Python versions
|
|
87
|
+
if: steps.check.outputs.new_versions != ''
|
|
88
|
+
env:
|
|
89
|
+
GH_TOKEN: ${{ github.token }}
|
|
90
|
+
NEW_VERSIONS: ${{ steps.check.outputs.new_versions }}
|
|
91
|
+
SUPPORTED: ${{ steps.check.outputs.supported }}
|
|
92
|
+
run: |
|
|
93
|
+
for version in $NEW_VERSIONS; do
|
|
94
|
+
title="Add Python $version to test matrix"
|
|
95
|
+
|
|
96
|
+
# Check if issue already exists
|
|
97
|
+
existing=$(gh issue list --state open --search "$title" --json number,title \
|
|
98
|
+
--jq ".[] | select(.title == \"$title\") | .number")
|
|
99
|
+
if [ -n "$existing" ]; then
|
|
100
|
+
echo "Issue #$existing already open for Python $version, skipping"
|
|
101
|
+
continue
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
run_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
|
105
|
+
|
|
106
|
+
body=$(cat <<EOF
|
|
107
|
+
Python $version is now available as a stable release but is not in our test matrix.
|
|
108
|
+
|
|
109
|
+
## Currently Supported
|
|
110
|
+
$SUPPORTED
|
|
111
|
+
|
|
112
|
+
## Action Required
|
|
113
|
+
1. Add \`"Programming Language :: Python :: $version"\` to \`pyproject.toml\` classifiers
|
|
114
|
+
2. Add \`"$version"\` to the matrix in \`.github/workflows/test.yml\`
|
|
115
|
+
3. Verify all tests pass on Python $version
|
|
116
|
+
|
|
117
|
+
**Workflow run:** $run_url
|
|
118
|
+
EOF
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
gh issue create --title "$title" --body "$body" --label "dependencies"
|
|
122
|
+
done
|
|
123
|
+
|
|
124
|
+
- name: Create issue for EOL Python versions
|
|
125
|
+
if: steps.check.outputs.eol_versions != ''
|
|
126
|
+
env:
|
|
127
|
+
GH_TOKEN: ${{ github.token }}
|
|
128
|
+
EOL_VERSIONS: ${{ steps.check.outputs.eol_versions }}
|
|
129
|
+
SUPPORTED: ${{ steps.check.outputs.supported }}
|
|
130
|
+
run: |
|
|
131
|
+
echo "$EOL_VERSIONS" | grep '^EOL:' | while IFS=: read -r _ version eol_date; do
|
|
132
|
+
title="Drop Python $version (EOL $eol_date)"
|
|
133
|
+
|
|
134
|
+
# Check if issue already exists
|
|
135
|
+
existing=$(gh issue list --state open --search "$title" --json number,title \
|
|
136
|
+
--jq ".[] | select(.title == \"$title\") | .number")
|
|
137
|
+
if [ -n "$existing" ]; then
|
|
138
|
+
echo "Issue #$existing already open for Python $version EOL, skipping"
|
|
139
|
+
continue
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
run_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
|
143
|
+
|
|
144
|
+
body=$(cat <<EOF
|
|
145
|
+
Python $version reached end-of-life on $eol_date and no longer receives security patches.
|
|
146
|
+
|
|
147
|
+
## Currently Supported
|
|
148
|
+
$SUPPORTED
|
|
149
|
+
|
|
150
|
+
## Action Required
|
|
151
|
+
1. Remove \`"Programming Language :: Python :: $version"\` from \`pyproject.toml\` classifiers
|
|
152
|
+
2. Remove \`"$version"\` from the matrix in \`.github/workflows/test.yml\`
|
|
153
|
+
3. Update \`requires-python\` in \`pyproject.toml\` if this was the minimum version
|
|
154
|
+
4. Remove any version-specific workarounds for Python $version
|
|
155
|
+
|
|
156
|
+
**Workflow run:** $run_url
|
|
157
|
+
EOF
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
gh issue create --title "$title" --body "$body" --label "dependencies"
|
|
161
|
+
done
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
lint:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
timeout-minutes: 10
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v6
|
|
19
|
+
- uses: actions/setup-python@v6
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
cache: 'pip'
|
|
23
|
+
- run: pip install -e '.[lint]'
|
|
24
|
+
- uses: pre-commit/action@v3.0.1
|
|
25
|
+
|
|
26
|
+
test:
|
|
27
|
+
uses: ./.github/workflows/test.yml
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
version:
|
|
10
|
+
description: 'Version to deploy (e.g., 0.3)'
|
|
11
|
+
required: true
|
|
12
|
+
set_latest:
|
|
13
|
+
description: 'Set as latest?'
|
|
14
|
+
type: boolean
|
|
15
|
+
default: true
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: write
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
deploy:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
timeout-minutes: 10
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
with:
|
|
27
|
+
fetch-depth: 0
|
|
28
|
+
|
|
29
|
+
- uses: actions/setup-python@v6
|
|
30
|
+
with:
|
|
31
|
+
python-version: '3.12'
|
|
32
|
+
cache: 'pip'
|
|
33
|
+
|
|
34
|
+
- name: Install dependencies
|
|
35
|
+
run: pip install -e '.[docs]'
|
|
36
|
+
|
|
37
|
+
- name: Configure Git
|
|
38
|
+
run: |
|
|
39
|
+
git config user.name "github-actions[bot]"
|
|
40
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
41
|
+
|
|
42
|
+
- name: Extract version from tag
|
|
43
|
+
if: github.event_name == 'push'
|
|
44
|
+
id: version
|
|
45
|
+
run: |
|
|
46
|
+
TAG="${GITHUB_REF#refs/tags/v}"
|
|
47
|
+
MINOR="${TAG%.*}"
|
|
48
|
+
echo "version=$MINOR" >> "$GITHUB_OUTPUT"
|
|
49
|
+
echo "Deploying docs for version: $MINOR"
|
|
50
|
+
|
|
51
|
+
- name: Deploy versioned docs (tag push)
|
|
52
|
+
if: github.event_name == 'push'
|
|
53
|
+
run: |
|
|
54
|
+
mike deploy --push --update-aliases "${{ steps.version.outputs.version }}" latest
|
|
55
|
+
|
|
56
|
+
- name: Deploy versioned docs (manual)
|
|
57
|
+
if: github.event_name == 'workflow_dispatch'
|
|
58
|
+
run: |
|
|
59
|
+
if [ "${{ inputs.set_latest }}" = "true" ]; then
|
|
60
|
+
mike deploy --push --update-aliases "${{ inputs.version }}" latest
|
|
61
|
+
else
|
|
62
|
+
mike deploy --push "${{ inputs.version }}"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
- name: Set default version
|
|
66
|
+
if: github.event_name == 'push'
|
|
67
|
+
run: mike set-default --push latest
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Publish to PyPI when a version tag is pushed.
|
|
4
|
+
#
|
|
5
|
+
# Prerequisites (one-time setup):
|
|
6
|
+
# 1. Go to https://pypi.org/manage/account/publishing/
|
|
7
|
+
# 2. Add a pending publisher:
|
|
8
|
+
# - Owner: axiomantic
|
|
9
|
+
# - Repository: headerkit
|
|
10
|
+
# - Workflow: release.yml
|
|
11
|
+
# - Environment: pypi
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
tags: ["v*"]
|
|
16
|
+
|
|
17
|
+
permissions: {}
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
test:
|
|
21
|
+
uses: ./.github/workflows/test.yml
|
|
22
|
+
|
|
23
|
+
build:
|
|
24
|
+
needs: test
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 10
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v6
|
|
29
|
+
- uses: actions/setup-python@v6
|
|
30
|
+
with:
|
|
31
|
+
python-version: "3.12"
|
|
32
|
+
cache: 'pip'
|
|
33
|
+
- run: pip install build
|
|
34
|
+
- run: python -m build
|
|
35
|
+
- name: Verify version matches tag
|
|
36
|
+
run: |
|
|
37
|
+
TAG="${{ github.ref_name }}"
|
|
38
|
+
EXPECTED="${TAG#v}"
|
|
39
|
+
VERSION=$(python -c "
|
|
40
|
+
import tomllib
|
|
41
|
+
with open('pyproject.toml', 'rb') as f:
|
|
42
|
+
print(tomllib.load(f)['project']['version'])
|
|
43
|
+
")
|
|
44
|
+
if [ "$VERSION" != "$EXPECTED" ]; then
|
|
45
|
+
echo "::error::Version mismatch: tag=$EXPECTED, pyproject.toml=$VERSION"
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
- uses: actions/upload-artifact@v7
|
|
49
|
+
with:
|
|
50
|
+
name: dist
|
|
51
|
+
path: dist/
|
|
52
|
+
retention-days: 5
|
|
53
|
+
|
|
54
|
+
publish:
|
|
55
|
+
needs: build
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
timeout-minutes: 10
|
|
58
|
+
environment: pypi
|
|
59
|
+
permissions:
|
|
60
|
+
id-token: write
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/download-artifact@v8
|
|
63
|
+
with:
|
|
64
|
+
name: dist
|
|
65
|
+
path: dist/
|
|
66
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
67
|
+
|
|
68
|
+
github-release:
|
|
69
|
+
needs: [build, publish]
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
timeout-minutes: 10
|
|
72
|
+
permissions:
|
|
73
|
+
contents: write
|
|
74
|
+
steps:
|
|
75
|
+
- uses: actions/download-artifact@v8
|
|
76
|
+
with:
|
|
77
|
+
name: dist
|
|
78
|
+
path: dist/
|
|
79
|
+
- name: Create GitHub Release
|
|
80
|
+
env:
|
|
81
|
+
GH_TOKEN: ${{ github.token }}
|
|
82
|
+
TAG: ${{ github.ref_name }}
|
|
83
|
+
REPO: ${{ github.repository }}
|
|
84
|
+
run: gh release create "$TAG" dist/* --repo "$REPO" --generate-notes
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: Test install_libclang
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
install-libclang:
|
|
15
|
+
runs-on: ${{ matrix.os }}
|
|
16
|
+
timeout-minutes: 15
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v6
|
|
23
|
+
- uses: actions/setup-python@v6
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.10"
|
|
26
|
+
cache: 'pip'
|
|
27
|
+
|
|
28
|
+
- name: Install package
|
|
29
|
+
shell: bash
|
|
30
|
+
run: pip install -e .
|
|
31
|
+
|
|
32
|
+
- name: Run install_libclang
|
|
33
|
+
shell: bash
|
|
34
|
+
run: |
|
|
35
|
+
if [ "$RUNNER_OS" = "Linux" ]; then
|
|
36
|
+
sudo python -m headerkit.install_libclang --skip-verify
|
|
37
|
+
else
|
|
38
|
+
python -m headerkit.install_libclang --skip-verify
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
- name: Refresh PATH (Windows)
|
|
42
|
+
if: runner.os == 'Windows'
|
|
43
|
+
shell: pwsh
|
|
44
|
+
run: |
|
|
45
|
+
$machinePath = [Environment]::GetEnvironmentVariable("Path", "Machine")
|
|
46
|
+
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
|
47
|
+
$env:Path = "$machinePath;$userPath"
|
|
48
|
+
echo "Path=$env:Path" >> $env:GITHUB_ENV
|
|
49
|
+
|
|
50
|
+
- name: Verify libclang is usable
|
|
51
|
+
shell: bash
|
|
52
|
+
run: python -c "from headerkit.backends.libclang import is_system_libclang_available; assert is_system_libclang_available(), 'libclang not available after install'"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
test:
|
|
8
|
+
runs-on: ${{ matrix.os }}
|
|
9
|
+
timeout-minutes: 20
|
|
10
|
+
strategy:
|
|
11
|
+
fail-fast: false
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
14
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v6
|
|
17
|
+
- uses: actions/setup-python@v6
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ matrix.python-version }}
|
|
20
|
+
cache: 'pip'
|
|
21
|
+
- name: Install libclang (Ubuntu)
|
|
22
|
+
if: runner.os == 'Linux'
|
|
23
|
+
run: sudo apt-get update && sudo apt-get install -y libclang-dev
|
|
24
|
+
- name: Install libclang (macOS)
|
|
25
|
+
if: runner.os == 'macOS'
|
|
26
|
+
run: brew install llvm
|
|
27
|
+
- name: Verify LLVM (Windows)
|
|
28
|
+
if: runner.os == 'Windows'
|
|
29
|
+
shell: bash
|
|
30
|
+
run: |
|
|
31
|
+
clang --version
|
|
32
|
+
which clang || true
|
|
33
|
+
- name: Install package
|
|
34
|
+
shell: bash
|
|
35
|
+
run: pip install -e '.[test]'
|
|
36
|
+
- name: Cache test header downloads
|
|
37
|
+
uses: actions/cache@v4
|
|
38
|
+
with:
|
|
39
|
+
path: ~/.cache/headerkit-test-headers
|
|
40
|
+
key: test-headers-v1
|
|
41
|
+
- name: Run tests
|
|
42
|
+
shell: bash
|
|
43
|
+
run: pytest
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
*.egg-info/
|
|
24
|
+
*.egg
|
|
25
|
+
MANIFEST
|
|
26
|
+
|
|
27
|
+
# Installer logs
|
|
28
|
+
pip-log.txt
|
|
29
|
+
pip-delete-this-directory.txt
|
|
30
|
+
|
|
31
|
+
# Unit test / coverage
|
|
32
|
+
htmlcov/
|
|
33
|
+
.tox/
|
|
34
|
+
.nox/
|
|
35
|
+
.coverage
|
|
36
|
+
.coverage.*
|
|
37
|
+
.cache
|
|
38
|
+
nosetests.xml
|
|
39
|
+
coverage.xml
|
|
40
|
+
*.cover
|
|
41
|
+
*.py,cover
|
|
42
|
+
.hypothesis/
|
|
43
|
+
.pytest_cache/
|
|
44
|
+
|
|
45
|
+
# Environments
|
|
46
|
+
.env
|
|
47
|
+
.venv/
|
|
48
|
+
env/
|
|
49
|
+
venv/
|
|
50
|
+
ENV/
|
|
51
|
+
|
|
52
|
+
# IDE
|
|
53
|
+
.vscode/
|
|
54
|
+
.idea/
|
|
55
|
+
*.swp
|
|
56
|
+
*.swo
|
|
57
|
+
*~
|
|
58
|
+
|
|
59
|
+
# mypy
|
|
60
|
+
.mypy_cache/
|
|
61
|
+
|
|
62
|
+
# ruff
|
|
63
|
+
.ruff_cache/
|
|
64
|
+
|
|
65
|
+
# OS
|
|
66
|
+
.DS_Store
|
|
67
|
+
Thumbs.db
|
|
68
|
+
|
|
69
|
+
# Project
|
|
70
|
+
logs/
|
|
71
|
+
|
|
72
|
+
# MkDocs
|
|
73
|
+
site/
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v5.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
args: [--unsafe]
|
|
9
|
+
- id: check-toml
|
|
10
|
+
- id: check-merge-conflict
|
|
11
|
+
- id: check-added-large-files
|
|
12
|
+
args: [--maxkb=500]
|
|
13
|
+
- id: debug-statements
|
|
14
|
+
|
|
15
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
16
|
+
rev: v0.9.10
|
|
17
|
+
hooks:
|
|
18
|
+
- id: ruff
|
|
19
|
+
args: [--fix]
|
|
20
|
+
- id: ruff-format
|
|
21
|
+
|
|
22
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
23
|
+
rev: v1.15.0
|
|
24
|
+
hooks:
|
|
25
|
+
- id: mypy
|
|
26
|
+
args: [--strict]
|
|
27
|
+
additional_dependencies: []
|
|
28
|
+
pass_filenames: false
|
|
29
|
+
entry: mypy headerkit/
|