knots 1.11.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.
Files changed (52) hide show
  1. knots-1.11.0/.github/workflows/build.yml +501 -0
  2. knots-1.11.0/.github/workflows/wheels.yml +109 -0
  3. knots-1.11.0/.gitignore +12 -0
  4. knots-1.11.0/.pre-commit-config.yaml +42 -0
  5. knots-1.11.0/.pre-commit-hooks.yaml +71 -0
  6. knots-1.11.0/AIM_BENCHMARK_RESULTS.md +225 -0
  7. knots-1.11.0/Cargo.lock +564 -0
  8. knots-1.11.0/Cargo.toml +60 -0
  9. knots-1.11.0/INITIAL_PAPER_IDEA.md +225 -0
  10. knots-1.11.0/LICENSE +21 -0
  11. knots-1.11.0/PKG-INFO +154 -0
  12. knots-1.11.0/README.md +135 -0
  13. knots-1.11.0/about.hbs +20 -0
  14. knots-1.11.0/about.toml +19 -0
  15. knots-1.11.0/docs/alternatives.rst +248 -0
  16. knots-1.11.0/docs/baseline.rst +112 -0
  17. knots-1.11.0/docs/ci-integration.rst +161 -0
  18. knots-1.11.0/docs/cli-reference.rst +220 -0
  19. knots-1.11.0/docs/conf.py +29 -0
  20. knots-1.11.0/docs/filters.rst +224 -0
  21. knots-1.11.0/docs/index.rst +25 -0
  22. knots-1.11.0/docs/installation.rst +61 -0
  23. knots-1.11.0/docs/metrics-reference.rst +191 -0
  24. knots-1.11.0/docs/output-formats.rst +117 -0
  25. knots-1.11.0/docs/quick-start.rst +200 -0
  26. knots-1.11.0/docs/test-complexity.rst +67 -0
  27. knots-1.11.0/docs/troubleshooting.rst +79 -0
  28. knots-1.11.0/example-pre-commit-config.yaml +111 -0
  29. knots-1.11.0/filter-example-exclude.json +14 -0
  30. knots-1.11.0/filter-example-include.json +15 -0
  31. knots-1.11.0/hooks/PRE_COMMIT_FRAMEWORK.md +517 -0
  32. knots-1.11.0/hooks/QUICKSTART.md +88 -0
  33. knots-1.11.0/hooks/README.md +389 -0
  34. knots-1.11.0/hooks/install-hook.sh +154 -0
  35. knots-1.11.0/hooks/pre-commit +140 -0
  36. knots-1.11.0/hooks/pre-commit-warning-only +116 -0
  37. knots-1.11.0/hooks/pre-commit-wrapper.sh +371 -0
  38. knots-1.11.0/hooks/test-complexity-wrapper.sh +268 -0
  39. knots-1.11.0/man/knots-test-complexity.1 +87 -0
  40. knots-1.11.0/man/knots.1 +274 -0
  41. knots-1.11.0/pyproject.toml +31 -0
  42. knots-1.11.0/rust-toolchain.toml +3 -0
  43. knots-1.11.0/sample-files/complex.c +99 -0
  44. knots-1.11.0/sample-files/nested.c +59 -0
  45. knots-1.11.0/sample-files/simple.c +28 -0
  46. knots-1.11.0/sample-files/simple.js +26 -0
  47. knots-1.11.0/sample-files/simple.py +23 -0
  48. knots-1.11.0/sample-files/simple.rs +26 -0
  49. knots-1.11.0/src/complexity.rs +2524 -0
  50. knots-1.11.0/src/lib.rs +55 -0
  51. knots-1.11.0/src/main.rs +2946 -0
  52. knots-1.11.0/tasks.py +184 -0
@@ -0,0 +1,501 @@
1
+ name: Build and Release
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ tags:
8
+ - 'v*.*.*'
9
+ pull_request:
10
+ branches:
11
+ - main
12
+
13
+ jobs:
14
+ build:
15
+ name: Build
16
+ runs-on: ${{ matrix.os }}
17
+ strategy:
18
+ matrix:
19
+ include:
20
+ - os: ubuntu-22.04
21
+ artifact_name: knots-linux-x64
22
+ knots_binary: target/release/knots
23
+ test_complexity_binary: target/release/knots-test-complexity
24
+ - os: windows-2022
25
+ artifact_name: knots-windows-x64
26
+ knots_binary: target/release/knots.exe
27
+ test_complexity_binary: target/release/knots-test-complexity.exe
28
+
29
+ steps:
30
+ - name: Checkout code
31
+ uses: actions/checkout@v4
32
+
33
+ - name: Extract version from Cargo.toml
34
+ id: version
35
+ run: |
36
+ VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
37
+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
38
+ echo "Extracted version: $VERSION"
39
+ shell: bash
40
+
41
+ - name: Install Rust toolchain
42
+ uses: dtolnay/rust-toolchain@stable
43
+
44
+ - name: Verify Rust installation
45
+ run: |
46
+ rustc --version
47
+ cargo --version
48
+
49
+ - name: Cache cargo registry
50
+ uses: actions/cache@v4
51
+ with:
52
+ path: ~/.cargo/registry
53
+ key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
54
+
55
+ - name: Cache cargo index
56
+ uses: actions/cache@v4
57
+ with:
58
+ path: ~/.cargo/git
59
+ key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
60
+
61
+ - name: Cache target directory
62
+ uses: actions/cache@v4
63
+ with:
64
+ path: target
65
+ key: ${{ runner.os }}-target-${{ hashFiles('**/Cargo.lock') }}
66
+
67
+ - name: Security Audit - Check Dependencies
68
+ run: |
69
+ cargo install cargo-audit
70
+ cargo audit
71
+ continue-on-error: true
72
+
73
+ - name: Build Release Binary
74
+ run: cargo build --release --workspace
75
+
76
+ - name: Run Tests - Knots
77
+ run: cargo test --release -p knots
78
+ continue-on-error: true
79
+
80
+ - name: Run Tests - Test Complexity
81
+ run: cargo test --release -p knots-test-complexity
82
+ continue-on-error: true
83
+
84
+ - name: Verify Binaries
85
+ run: |
86
+ echo "=== Verifying binaries ==="
87
+ ${{ matrix.knots_binary }} --version
88
+ ${{ matrix.test_complexity_binary }} --help | head -5
89
+
90
+ - name: Install cargo-about
91
+ run: cargo install cargo-about --features cli
92
+
93
+ - name: Generate Third-Party Licenses
94
+ shell: bash
95
+ run: cargo about generate about.hbs -o THIRD_PARTY_LICENSES.txt
96
+
97
+ - name: Install cargo-cyclonedx
98
+ run: cargo install cargo-cyclonedx
99
+
100
+ - name: Generate SBOM (CycloneDX)
101
+ shell: bash
102
+ run: cargo cyclonedx --format json --spec-version 1.5
103
+
104
+ - name: List Build Output (Linux)
105
+ if: runner.os == 'Linux'
106
+ run: |
107
+ echo "=== Build Artifacts ==="
108
+ echo "Knots binary:"
109
+ ls -lh ${{ matrix.knots_binary }} || echo "Knots binary not found"
110
+ echo "Test-complexity binary:"
111
+ ls -lh ${{ matrix.test_complexity_binary }} || echo "Test-complexity binary not found"
112
+
113
+ - name: List Build Output (Windows)
114
+ if: runner.os == 'Windows'
115
+ run: |
116
+ Write-Host "=== Build Artifacts ==="
117
+ Write-Host "Knots binary:"
118
+ if (Test-Path "${{ matrix.knots_binary }}") {
119
+ Get-Item "${{ matrix.knots_binary }}" | Format-List Name, Length, LastWriteTime
120
+ } else {
121
+ Write-Host "Knots binary not found"
122
+ }
123
+ Write-Host "Test-complexity binary:"
124
+ if (Test-Path "${{ matrix.test_complexity_binary }}") {
125
+ Get-Item "${{ matrix.test_complexity_binary }}" | Format-List Name, Length, LastWriteTime
126
+ } else {
127
+ Write-Host "Test-complexity binary not found"
128
+ }
129
+ shell: pwsh
130
+
131
+ - name: Stage Artifacts (Linux)
132
+ if: runner.os == 'Linux'
133
+ run: |
134
+ VERSION="${{ steps.version.outputs.VERSION }}"
135
+ ARTIFACT_DIR="artifacts/${{ matrix.artifact_name }}-${VERSION}"
136
+ mkdir -p "${ARTIFACT_DIR}"
137
+ cp ${{ matrix.knots_binary }} "${ARTIFACT_DIR}/"
138
+ cp ${{ matrix.test_complexity_binary }} "${ARTIFACT_DIR}/"
139
+ cp README.md "${ARTIFACT_DIR}/" 2>/dev/null || true
140
+ cp LICENSE "${ARTIFACT_DIR}/" 2>/dev/null || true
141
+ cp THIRD_PARTY_LICENSES.txt "${ARTIFACT_DIR}/"
142
+ cp knots.cdx.json "${ARTIFACT_DIR}/"
143
+ cp knots-test-complexity/knots-test-complexity.cdx.json "${ARTIFACT_DIR}/"
144
+ cp knots-test-complexity/README.md "${ARTIFACT_DIR}/TEST_COMPLEXITY_README.md" 2>/dev/null || true
145
+ cp hooks/README.md "${ARTIFACT_DIR}/HOOKS_README.md" 2>/dev/null || true
146
+ mkdir -p "${ARTIFACT_DIR}/man"
147
+ cp man/knots.1 "${ARTIFACT_DIR}/man/"
148
+ cp man/knots-test-complexity.1 "${ARTIFACT_DIR}/man/"
149
+ echo "=== Artifacts staged ==="
150
+ ls -lhR "${ARTIFACT_DIR}/"
151
+ echo "ARTIFACT_DIR=${ARTIFACT_DIR}" >> $GITHUB_ENV
152
+
153
+ - name: Stage Artifacts (Windows)
154
+ if: runner.os == 'Windows'
155
+ run: |
156
+ $VERSION = "${{ steps.version.outputs.VERSION }}"
157
+ $ARTIFACT_DIR = "artifacts/${{ matrix.artifact_name }}-${VERSION}"
158
+ New-Item -ItemType Directory -Force -Path $ARTIFACT_DIR
159
+ Copy-Item "${{ matrix.knots_binary }}" -Destination $ARTIFACT_DIR
160
+ Copy-Item "${{ matrix.test_complexity_binary }}" -Destination $ARTIFACT_DIR
161
+ Copy-Item "README.md" -Destination $ARTIFACT_DIR -ErrorAction SilentlyContinue
162
+ Copy-Item "LICENSE" -Destination $ARTIFACT_DIR -ErrorAction SilentlyContinue
163
+ Copy-Item "THIRD_PARTY_LICENSES.txt" -Destination $ARTIFACT_DIR
164
+ Copy-Item "knots.cdx.json" -Destination $ARTIFACT_DIR
165
+ Copy-Item "knots-test-complexity/knots-test-complexity.cdx.json" -Destination $ARTIFACT_DIR
166
+ Copy-Item "knots-test-complexity/README.md" -Destination "$ARTIFACT_DIR/TEST_COMPLEXITY_README.md" -ErrorAction SilentlyContinue
167
+ Copy-Item "hooks/README.md" -Destination "$ARTIFACT_DIR/HOOKS_README.md" -ErrorAction SilentlyContinue
168
+ Write-Host "=== Artifacts staged ==="
169
+ Get-ChildItem $ARTIFACT_DIR
170
+ echo "ARTIFACT_DIR=${ARTIFACT_DIR}" >> $env:GITHUB_ENV
171
+ shell: pwsh
172
+
173
+ - name: Upload Build Artifacts
174
+ uses: actions/upload-artifact@v4
175
+ with:
176
+ name: ${{ matrix.artifact_name }}-${{ steps.version.outputs.VERSION }}
177
+ path: ${{ env.ARTIFACT_DIR }}
178
+ retention-days: 30
179
+
180
+ package:
181
+ name: Package Release
182
+ needs: build
183
+ runs-on: ubuntu-22.04
184
+ if: >-
185
+ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
186
+ && github.event_name != 'pull_request'
187
+ permissions:
188
+ contents: write
189
+
190
+ steps:
191
+ - name: Checkout code
192
+ uses: actions/checkout@v4
193
+
194
+ - name: Extract version from Cargo.toml
195
+ id: version
196
+ run: |
197
+ VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
198
+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
199
+ echo "Extracted version: $VERSION"
200
+
201
+ - name: Install packaging tools
202
+ run: |
203
+ sudo apt-get update
204
+ sudo apt-get install -y rpm libfuse2
205
+
206
+ - name: Download Linux Artifact
207
+ uses: actions/download-artifact@v4
208
+ with:
209
+ name: knots-linux-x64-${{ steps.version.outputs.VERSION }}
210
+ path: artifacts/knots-linux-x64-${{ steps.version.outputs.VERSION }}
211
+
212
+ - name: Download Windows Artifact
213
+ uses: actions/download-artifact@v4
214
+ with:
215
+ name: knots-windows-x64-${{ steps.version.outputs.VERSION }}
216
+ path: artifacts/knots-windows-x64-${{ steps.version.outputs.VERSION }}
217
+
218
+ - name: Restore binary execute bits
219
+ run: |
220
+ chmod +x artifacts/knots-linux-x64-${{ steps.version.outputs.VERSION }}/knots
221
+ chmod +x artifacts/knots-linux-x64-${{ steps.version.outputs.VERSION }}/knots-test-complexity
222
+
223
+ - name: Verify Release Package
224
+ run: |
225
+ echo "=== Downloaded Artifacts ==="
226
+ ls -lR artifacts/
227
+ echo ""
228
+ echo "Release package ready with version: ${{ steps.version.outputs.VERSION }}"
229
+
230
+ - name: Create Release Archive (Linux)
231
+ run: |
232
+ cd artifacts
233
+ tar -czf knots-linux-x64-${{ steps.version.outputs.VERSION }}.tar.gz knots-linux-x64-${{ steps.version.outputs.VERSION }}
234
+ cd ..
235
+
236
+ - name: Create Release Archive (Windows)
237
+ run: |
238
+ cd artifacts
239
+ zip -r knots-windows-x64-${{ steps.version.outputs.VERSION }}.zip knots-windows-x64-${{ steps.version.outputs.VERSION }}
240
+ cd ..
241
+
242
+ - name: Build deb package
243
+ run: |
244
+ VERSION="${{ steps.version.outputs.VERSION }}"
245
+ PKG_DIR="knots_${VERSION}_amd64"
246
+ mkdir -p "${PKG_DIR}/DEBIAN"
247
+ mkdir -p "${PKG_DIR}/usr/bin"
248
+ mkdir -p "${PKG_DIR}/usr/share/man/man1"
249
+ mkdir -p "${PKG_DIR}/usr/share/doc/knots"
250
+
251
+ # Control file
252
+ cat > "${PKG_DIR}/DEBIAN/control" << EOF
253
+ Package: knots
254
+ Version: ${VERSION}
255
+ Section: devel
256
+ Priority: optional
257
+ Architecture: amd64
258
+ Maintainer: Brandon Arrendondo <brandon@arrendondo.dev>
259
+ Homepage: https://github.com/brandon-arrendondo/knots
260
+ Description: Multi-language code complexity analyzer
261
+ A fast, powerful code complexity analyzer for C, C++, Rust, Python, and
262
+ JavaScript with visual indicators, built on tree-sitter. Knots computes
263
+ McCabe cyclomatic complexity, cognitive complexity, nesting depth, SLOC,
264
+ ABC complexity, and test scoring metrics. Includes knots-test-complexity
265
+ for validating unit test quality against source complexity.
266
+ EOF
267
+ # Remove leading whitespace from control file (heredoc indentation)
268
+ sed -i 's/^ //' "${PKG_DIR}/DEBIAN/control"
269
+
270
+ # Binaries
271
+ cp "artifacts/knots-linux-x64-${VERSION}/knots" "${PKG_DIR}/usr/bin/"
272
+ cp "artifacts/knots-linux-x64-${VERSION}/knots-test-complexity" "${PKG_DIR}/usr/bin/"
273
+ chmod 755 "${PKG_DIR}/usr/bin/knots"
274
+ chmod 755 "${PKG_DIR}/usr/bin/knots-test-complexity"
275
+
276
+ # Man pages
277
+ gzip -c man/knots.1 > "${PKG_DIR}/usr/share/man/man1/knots.1.gz"
278
+ gzip -c man/knots-test-complexity.1 > "${PKG_DIR}/usr/share/man/man1/knots-test-complexity.1.gz"
279
+
280
+ # Docs
281
+ cp README.md "${PKG_DIR}/usr/share/doc/knots/"
282
+ cp LICENSE "${PKG_DIR}/usr/share/doc/knots/copyright"
283
+ cp "artifacts/knots-linux-x64-${VERSION}/THIRD_PARTY_LICENSES.txt" \
284
+ "${PKG_DIR}/usr/share/doc/knots/"
285
+ cp "artifacts/knots-linux-x64-${VERSION}/knots.cdx.json" \
286
+ "${PKG_DIR}/usr/share/doc/knots/"
287
+ cp "artifacts/knots-linux-x64-${VERSION}/knots-test-complexity.cdx.json" \
288
+ "${PKG_DIR}/usr/share/doc/knots/"
289
+
290
+ dpkg-deb --build --root-owner-group "${PKG_DIR}"
291
+ mv "${PKG_DIR}.deb" "artifacts/"
292
+ echo "=== deb package ==="
293
+ dpkg-deb --info "artifacts/${PKG_DIR}.deb"
294
+
295
+ - name: Build rpm package
296
+ run: |
297
+ VERSION="${{ steps.version.outputs.VERSION }}"
298
+
299
+ mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
300
+
301
+ # Create tarball for rpmbuild
302
+ TARDIR="knots-${VERSION}"
303
+ mkdir -p "${TARDIR}/bin"
304
+ mkdir -p "${TARDIR}/man"
305
+ mkdir -p "${TARDIR}/doc"
306
+ cp "artifacts/knots-linux-x64-${VERSION}/knots" "${TARDIR}/bin/"
307
+ cp "artifacts/knots-linux-x64-${VERSION}/knots-test-complexity" "${TARDIR}/bin/"
308
+ cp man/knots.1 "${TARDIR}/man/"
309
+ cp man/knots-test-complexity.1 "${TARDIR}/man/"
310
+ cp README.md "${TARDIR}/doc/"
311
+ cp LICENSE "${TARDIR}/doc/"
312
+ cp "artifacts/knots-linux-x64-${VERSION}/THIRD_PARTY_LICENSES.txt" "${TARDIR}/doc/"
313
+ cp "artifacts/knots-linux-x64-${VERSION}/knots.cdx.json" "${TARDIR}/doc/"
314
+ cp "artifacts/knots-linux-x64-${VERSION}/knots-test-complexity.cdx.json" "${TARDIR}/doc/"
315
+ tar -czf "rpmbuild/SOURCES/knots-${VERSION}.tar.gz" "${TARDIR}"
316
+ rm -rf "${TARDIR}"
317
+
318
+ # Spec file
319
+ cat > rpmbuild/SPECS/knots.spec << 'SPEC_EOF'
320
+ Name: knots
321
+ Version: VERSION_PLACEHOLDER
322
+ Release: 1%{?dist}
323
+ Summary: Multi-language code complexity analyzer
324
+ License: MIT
325
+ URL: https://github.com/brandon-arrendondo/knots
326
+ Source0: %{name}-%{version}.tar.gz
327
+
328
+ %description
329
+ A fast, powerful code complexity analyzer for C, C++, Rust, Python, and
330
+ JavaScript with visual indicators, built on tree-sitter. Knots computes
331
+ McCabe cyclomatic complexity, cognitive complexity, nesting depth, SLOC,
332
+ ABC complexity, and test scoring metrics. Includes knots-test-complexity
333
+ for validating unit test quality against source complexity.
334
+
335
+ %prep
336
+ %setup -q
337
+
338
+ %install
339
+ mkdir -p %{buildroot}%{_bindir}
340
+ mkdir -p %{buildroot}%{_mandir}/man1
341
+ mkdir -p %{buildroot}%{_docdir}/%{name}
342
+ install -m 755 bin/knots %{buildroot}%{_bindir}/knots
343
+ install -m 755 bin/knots-test-complexity %{buildroot}%{_bindir}/knots-test-complexity
344
+ install -m 644 man/knots.1 %{buildroot}%{_mandir}/man1/knots.1
345
+ install -m 644 man/knots-test-complexity.1 %{buildroot}%{_mandir}/man1/knots-test-complexity.1
346
+ install -m 644 doc/README.md %{buildroot}%{_docdir}/%{name}/README.md
347
+ install -m 644 doc/LICENSE %{buildroot}%{_docdir}/%{name}/LICENSE
348
+ install -m 644 doc/THIRD_PARTY_LICENSES.txt %{buildroot}%{_docdir}/%{name}/THIRD_PARTY_LICENSES.txt
349
+ install -m 644 doc/knots.cdx.json %{buildroot}%{_docdir}/%{name}/knots.cdx.json
350
+ install -m 644 doc/knots-test-complexity.cdx.json %{buildroot}%{_docdir}/%{name}/knots-test-complexity.cdx.json
351
+
352
+ %files
353
+ %{_bindir}/knots
354
+ %{_bindir}/knots-test-complexity
355
+ %{_mandir}/man1/knots.1*
356
+ %{_mandir}/man1/knots-test-complexity.1*
357
+ %doc %{_docdir}/%{name}/README.md
358
+ %doc %{_docdir}/%{name}/THIRD_PARTY_LICENSES.txt
359
+ %doc %{_docdir}/%{name}/knots.cdx.json
360
+ %doc %{_docdir}/%{name}/knots-test-complexity.cdx.json
361
+ %license %{_docdir}/%{name}/LICENSE
362
+ SPEC_EOF
363
+
364
+ # Fix indentation and substitute version
365
+ sed -i 's/^ //' rpmbuild/SPECS/knots.spec
366
+ sed -i "s/VERSION_PLACEHOLDER/${VERSION}/" rpmbuild/SPECS/knots.spec
367
+
368
+ rpmbuild --define "_topdir $(pwd)/rpmbuild" -bb rpmbuild/SPECS/knots.spec
369
+ cp rpmbuild/RPMS/x86_64/knots-*.rpm artifacts/
370
+ echo "=== rpm package ==="
371
+ rpm -qip artifacts/knots-*.rpm
372
+
373
+ - name: Build AppImage
374
+ run: |
375
+ VERSION="${{ steps.version.outputs.VERSION }}"
376
+
377
+ # Download appimagetool
378
+ curl -Lo appimagetool https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
379
+ chmod +x appimagetool
380
+
381
+ # Create AppDir structure
382
+ APPDIR="knots.AppDir"
383
+ mkdir -p "${APPDIR}/usr/bin"
384
+ mkdir -p "${APPDIR}/usr/share/man/man1"
385
+ mkdir -p "${APPDIR}/usr/share/metainfo"
386
+ mkdir -p "${APPDIR}/usr/share/icons/hicolor/256x256/apps"
387
+
388
+ # Binaries
389
+ cp "artifacts/knots-linux-x64-${VERSION}/knots" "${APPDIR}/usr/bin/"
390
+ cp "artifacts/knots-linux-x64-${VERSION}/knots-test-complexity" "${APPDIR}/usr/bin/"
391
+ chmod 755 "${APPDIR}/usr/bin/knots"
392
+ chmod 755 "${APPDIR}/usr/bin/knots-test-complexity"
393
+
394
+ # Man pages
395
+ cp man/knots.1 "${APPDIR}/usr/share/man/man1/"
396
+ cp man/knots-test-complexity.1 "${APPDIR}/usr/share/man/man1/"
397
+
398
+ # License docs
399
+ mkdir -p "${APPDIR}/usr/share/doc/knots"
400
+ cp LICENSE "${APPDIR}/usr/share/doc/knots/"
401
+ cp "artifacts/knots-linux-x64-${VERSION}/THIRD_PARTY_LICENSES.txt" \
402
+ "${APPDIR}/usr/share/doc/knots/"
403
+ cp "artifacts/knots-linux-x64-${VERSION}/knots.cdx.json" \
404
+ "${APPDIR}/usr/share/doc/knots/"
405
+ cp "artifacts/knots-linux-x64-${VERSION}/knots-test-complexity.cdx.json" \
406
+ "${APPDIR}/usr/share/doc/knots/"
407
+
408
+ # Desktop entry
409
+ cat > "${APPDIR}/knots.desktop" << EOF
410
+ [Desktop Entry]
411
+ Type=Application
412
+ Name=knots
413
+ Exec=knots
414
+ Icon=knots
415
+ Comment=Multi-language code complexity analyzer
416
+ Categories=Development;
417
+ Terminal=true
418
+ NoDisplay=true
419
+ EOF
420
+ sed -i 's/^ //' "${APPDIR}/knots.desktop"
421
+
422
+ # Icon (generate a simple SVG icon)
423
+ cat > "${APPDIR}/knots.svg" << 'SVG_EOF'
424
+ <?xml version="1.0" encoding="UTF-8"?>
425
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256">
426
+ <rect width="256" height="256" rx="32" fill="#2d3748"/>
427
+ <text x="128" y="160" font-family="monospace" font-size="120" font-weight="bold" fill="#e2e8f0" text-anchor="middle">K</text>
428
+ </svg>
429
+ SVG_EOF
430
+ sed -i 's/^ //' "${APPDIR}/knots.svg"
431
+ cp "${APPDIR}/knots.svg" "${APPDIR}/usr/share/icons/hicolor/256x256/apps/"
432
+
433
+ # AppRun
434
+ cat > "${APPDIR}/AppRun" << 'APPRUN_EOF'
435
+ #!/bin/bash
436
+ SELF=$(readlink -f "$0")
437
+ HERE=${SELF%/*}
438
+ export PATH="${HERE}/usr/bin:${PATH}"
439
+ export MANPATH="${HERE}/usr/share/man:${MANPATH}"
440
+
441
+ ARGV0="${ARGV0:-knots}"
442
+ case "$(basename "${ARGV0}")" in
443
+ knots-test-complexity)
444
+ exec "${HERE}/usr/bin/knots-test-complexity" "$@"
445
+ ;;
446
+ *)
447
+ exec "${HERE}/usr/bin/knots" "$@"
448
+ ;;
449
+ esac
450
+ APPRUN_EOF
451
+ chmod +x "${APPDIR}/AppRun"
452
+
453
+ # Build AppImage
454
+ ARCH=x86_64 ./appimagetool "${APPDIR}" "artifacts/knots-${VERSION}-x86_64.AppImage"
455
+ echo "=== AppImage ==="
456
+ ls -lh "artifacts/knots-${VERSION}-x86_64.AppImage"
457
+
458
+ - name: Upload Release Archives
459
+ uses: actions/upload-artifact@v4
460
+ with:
461
+ name: release-packages-${{ steps.version.outputs.VERSION }}
462
+ path: |
463
+ artifacts/*.tar.gz
464
+ artifacts/*.zip
465
+ artifacts/*.deb
466
+ artifacts/*.rpm
467
+ artifacts/*.AppImage
468
+ retention-days: 90
469
+
470
+ - name: Create GitHub Release
471
+ if: startsWith(github.ref, 'refs/tags/v')
472
+ uses: softprops/action-gh-release@v2
473
+ with:
474
+ generate_release_notes: true
475
+ files: |
476
+ artifacts/*.tar.gz
477
+ artifacts/*.zip
478
+ artifacts/*.deb
479
+ artifacts/*.rpm
480
+ artifacts/*.AppImage
481
+
482
+ docs:
483
+ name: Docs
484
+ runs-on: ubuntu-latest
485
+ permissions:
486
+ contents: write
487
+ steps:
488
+ - uses: actions/checkout@v4
489
+
490
+ - name: Install Sphinx and theme
491
+ run: pip install sphinx sphinx-rtd-theme
492
+
493
+ - name: Build HTML docs
494
+ run: sphinx-build -W -b html docs docs/_build/html
495
+
496
+ - name: Deploy to GitHub Pages
497
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
498
+ uses: peaceiris/actions-gh-pages@v4
499
+ with:
500
+ github_token: ${{ secrets.GITHUB_TOKEN }}
501
+ publish_dir: docs/_build/html
@@ -0,0 +1,109 @@
1
+ name: Wheels (PyPI)
2
+
3
+ # Build per-platform wheels + sdists for the `knots` and `knots-test-complexity`
4
+ # binaries with maturin (bindings = "bin"), and publish them to PyPI via Trusted
5
+ # Publishing (OIDC, no API token) on a v*.*.* tag. These prebuilt wheels are what
6
+ # the knots-pre-commit mirror repo installs, giving a zero-compile first run.
7
+ #
8
+ # Validate the matrix without publishing by running this workflow manually
9
+ # (Actions tab -> "Wheels (PyPI)" -> Run workflow); publish only happens on tags.
10
+
11
+ on:
12
+ push:
13
+ tags:
14
+ - 'v*.*.*'
15
+ workflow_dispatch:
16
+
17
+ permissions:
18
+ contents: read
19
+
20
+ jobs:
21
+ build:
22
+ name: build ${{ matrix.package.name }} (${{ matrix.platform.id }})
23
+ runs-on: ${{ matrix.platform.runner }}
24
+ strategy:
25
+ fail-fast: false
26
+ matrix:
27
+ package:
28
+ - { name: knots, manifest: Cargo.toml }
29
+ - { name: knots-test-complexity, manifest: knots-test-complexity/Cargo.toml }
30
+ platform:
31
+ # `id` must be unique per row — macOS and Linux share the bare
32
+ # x86_64/aarch64 target labels, which would otherwise collide as
33
+ # artifact names (upload-artifact@v4 rejects duplicate names).
34
+ - { id: linux-x86_64, runner: ubuntu-22.04, target: x86_64, manylinux: auto }
35
+ - { id: linux-aarch64, runner: ubuntu-22.04, target: aarch64, manylinux: auto }
36
+ - { id: musl-x86_64, runner: ubuntu-22.04, target: x86_64-unknown-linux-musl, manylinux: musllinux_1_2 }
37
+ - { id: musl-aarch64, runner: ubuntu-22.04, target: aarch64-unknown-linux-musl, manylinux: musllinux_1_2 }
38
+ # Both macOS arches build on the Apple-Silicon runner; x86_64 is
39
+ # cross-compiled. Avoids the deprecated/scarce macos-13 Intel runners.
40
+ - { id: macos-x86_64, runner: macos-14, target: x86_64-apple-darwin }
41
+ - { id: macos-aarch64, runner: macos-14, target: aarch64 }
42
+ - { id: windows-x64, runner: windows-2022, target: x64 }
43
+ steps:
44
+ - uses: actions/checkout@v4
45
+
46
+ - name: Build wheel
47
+ uses: PyO3/maturin-action@v1
48
+ with:
49
+ command: build
50
+ target: ${{ matrix.platform.target }}
51
+ # bindings = "bin" comes from each crate's pyproject.toml; -m selects it.
52
+ args: --release --out dist -m ${{ matrix.package.manifest }}
53
+ manylinux: ${{ matrix.platform.manylinux }}
54
+ sccache: 'true'
55
+
56
+ - name: Upload wheel artifact
57
+ uses: actions/upload-artifact@v4
58
+ with:
59
+ name: wheel-${{ matrix.package.name }}-${{ matrix.platform.id }}
60
+ path: dist/*.whl
61
+
62
+ sdist:
63
+ name: sdist ${{ matrix.package.name }}
64
+ runs-on: ubuntu-22.04
65
+ strategy:
66
+ matrix:
67
+ package:
68
+ - { name: knots, manifest: Cargo.toml }
69
+ - { name: knots-test-complexity, manifest: knots-test-complexity/Cargo.toml }
70
+ steps:
71
+ - uses: actions/checkout@v4
72
+
73
+ - name: Build sdist
74
+ uses: PyO3/maturin-action@v1
75
+ with:
76
+ command: sdist
77
+ args: --out dist -m ${{ matrix.package.manifest }}
78
+
79
+ - name: Upload sdist artifact
80
+ uses: actions/upload-artifact@v4
81
+ with:
82
+ name: sdist-${{ matrix.package.name }}
83
+ path: dist/*.tar.gz
84
+
85
+ publish:
86
+ name: Publish to PyPI
87
+ needs: [build, sdist]
88
+ runs-on: ubuntu-22.04
89
+ if: startsWith(github.ref, 'refs/tags/v')
90
+ environment: release
91
+ permissions:
92
+ id-token: write # required for PyPI Trusted Publishing (OIDC)
93
+ steps:
94
+ - name: Download all artifacts
95
+ uses: actions/download-artifact@v4
96
+ with:
97
+ path: dist
98
+ merge-multiple: true # flatten wheel-*/ and sdist-*/ into dist/
99
+
100
+ - name: Publish to PyPI
101
+ uses: pypa/gh-action-pypi-publish@release/v1
102
+ with:
103
+ packages-dir: dist
104
+ # Files route to their PyPI project by name: knots-* vs
105
+ # knots_test_complexity-*. Both projects must trust this workflow.
106
+ # skip-existing makes re-runs idempotent: already-published files
107
+ # (e.g. a version where one package uploaded and the other failed)
108
+ # are skipped instead of erroring on "file already exists".
109
+ skip-existing: true
@@ -0,0 +1,12 @@
1
+ report.txt
2
+ target/
3
+ THIRD_PARTY_LICENSES.txt
4
+ *.cdx.json
5
+ docs/_build/
6
+
7
+ # maturin / PyPI build output
8
+ dist/
9
+ *.whl
10
+
11
+ .todo-sqlite-cli
12
+ *.db
@@ -0,0 +1,42 @@
1
+ # Pre-commit hooks for knots
2
+ # Install: pre-commit install
3
+ # Run manually: pre-commit run --all-files
4
+
5
+ repos:
6
+ - repo: local
7
+ hooks:
8
+ - id: cargo-fmt
9
+ name: cargo fmt (auto-fix)
10
+ description: Format Rust code with rustfmt
11
+ entry: bash -c 'cargo fmt --all 2>&1 && echo "Formatting complete"'
12
+ language: system
13
+ pass_filenames: false
14
+ types: [rust]
15
+ verbose: true
16
+
17
+ - id: cargo-clippy
18
+ name: cargo clippy
19
+ description: Lint Rust code with Clippy - deny warnings (all targets including tests)
20
+ entry: bash -c 'cargo clippy --all-targets --all-features -- -D warnings 2>&1'
21
+ language: system
22
+ pass_filenames: false
23
+ types: [rust]
24
+ verbose: true
25
+
26
+ - id: cargo-test
27
+ name: cargo test
28
+ description: Run the test suite
29
+ entry: bash -c 'cargo test --workspace 2>&1'
30
+ language: system
31
+ pass_filenames: false
32
+ types: [rust]
33
+ verbose: true
34
+
35
+ - id: knots-self-check
36
+ name: knots (self-check)
37
+ description: Check this repo's own Rust source complexity with knots
38
+ entry: bash -c 'cargo run --quiet -- --mccabe-threshold=15 --cognitive-threshold=15 --nesting-threshold=5 --sloc-threshold=50 --abc-threshold=10.0 --return-threshold=3 "$@"' --
39
+ language: system
40
+ types: [rust]
41
+ pass_filenames: true
42
+ verbose: true