liburlparser 1.6.1__tar.gz → 2.1.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 (151) hide show
  1. liburlparser-2.1.0/.github/workflows/cmake.yml +148 -0
  2. liburlparser-2.1.0/.github/workflows/orchestrator.yml +142 -0
  3. liburlparser-2.1.0/.github/workflows/process_release.py +77 -0
  4. liburlparser-2.1.0/.github/workflows/release_template.md +15 -0
  5. liburlparser-2.1.0/.github/workflows/wheels.yml +74 -0
  6. liburlparser-2.1.0/ARCHITECTURE.md +553 -0
  7. liburlparser-2.1.0/CMakeLists.txt +253 -0
  8. {liburlparser-1.6.1 → liburlparser-2.1.0}/PKG-INFO +200 -96
  9. {liburlparser-1.6.1 → liburlparser-2.1.0}/README.md +195 -87
  10. liburlparser-2.1.0/benchmarks/.gitignore +1 -0
  11. liburlparser-2.1.0/benchmarks/CMakeLists.txt +148 -0
  12. liburlparser-2.1.0/benchmarks/OPTIMIZATION_NOTES.md +334 -0
  13. liburlparser-2.1.0/benchmarks/README.md +184 -0
  14. liburlparser-2.1.0/benchmarks/cmake/Download.cmake +26 -0
  15. liburlparser-2.1.0/benchmarks/corpus/.gitignore +3 -0
  16. liburlparser-2.1.0/benchmarks/corpus/generate_corpus.py +71 -0
  17. liburlparser-2.1.0/benchmarks/cpp/CMakeLists.txt +44 -0
  18. liburlparser-2.1.0/benchmarks/cpp/abspath_fix_verification/README.md +41 -0
  19. liburlparser-2.1.0/benchmarks/cpp/abspath_fix_verification/fair_compare.cpp +81 -0
  20. liburlparser-2.1.0/benchmarks/cpp/bench.cpp +605 -0
  21. liburlparser-2.1.0/benchmarks/cpp/psl_structures/README.md +95 -0
  22. liburlparser-2.1.0/benchmarks/cpp/psl_structures/psl_structure_comparison.cpp +713 -0
  23. liburlparser-2.1.0/benchmarks/python/CMakeLists.txt +77 -0
  24. liburlparser-2.1.0/benchmarks/python/bench.py +523 -0
  25. liburlparser-2.1.0/benchmarks/python/binding_fast_path_ab.py +50 -0
  26. liburlparser-2.1.0/benchmarks/python/requirements.txt +15 -0
  27. liburlparser-2.1.0/benchmarks/report/CMakeLists.txt +53 -0
  28. liburlparser-2.1.0/benchmarks/report/generate_report.py +214 -0
  29. liburlparser-2.1.0/benchmarks/report/template.html.jinja2 +192 -0
  30. liburlparser-2.1.0/benchmarks/results/report.html +918 -0
  31. liburlparser-2.1.0/cmake/DynamicVersion.cmake +119 -0
  32. liburlparser-2.1.0/cmake/EmbedFile.cmake +57 -0
  33. liburlparser-2.1.0/cmake/FixLCovPaths.cmake +9 -0
  34. liburlparser-2.1.0/cmake/GenerateIframe.cmake +23 -0
  35. liburlparser-2.1.0/cmake/PublicSuffixList.cmake +164 -0
  36. liburlparser-2.1.0/cmake/coverage_iframe.html.in +156 -0
  37. liburlparser-2.1.0/cmake/liburlparserConfig.cmake +26 -0
  38. liburlparser-2.1.0/cmake/utils/embedded_string.in.h +28 -0
  39. liburlparser-2.1.0/docs/CMakeLists.txt +179 -0
  40. liburlparser-2.1.0/docs/CreateDocs.cmake +31 -0
  41. liburlparser-2.1.0/docs/InjectComment.cmake +85 -0
  42. liburlparser-2.1.0/docs/UrlParserPages.cmake +198 -0
  43. liburlparser-2.1.0/docs/cli/examples.md +44 -0
  44. liburlparser-2.1.0/docs/cli/index.md +32 -0
  45. liburlparser-2.1.0/docs/cli/installation.md +34 -0
  46. liburlparser-2.1.0/docs/cli/options.md +27 -0
  47. liburlparser-2.1.0/docs/convert_page.py +378 -0
  48. liburlparser-2.1.0/docs/cpp/CreateDocs.cmake +61 -0
  49. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/cpp/Doxyfile.in +8 -7
  50. liburlparser-2.1.0/docs/cpp/footer.html.in +27 -0
  51. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/cpp/mainpage.md +25 -25
  52. liburlparser-2.1.0/docs/images/liburlparser-sq.txt +6 -0
  53. liburlparser-2.1.0/docs/index.html.in +463 -0
  54. liburlparser-2.1.0/docs/initial_comment.in +15 -0
  55. liburlparser-2.1.0/docs/page.html.in +420 -0
  56. liburlparser-2.1.0/docs/python/CreateDocs.cmake +60 -0
  57. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/python/docs/api/psl.md +6 -7
  58. liburlparser-2.1.0/docs/python/docs/api/reference.rst +41 -0
  59. liburlparser-2.1.0/docs/python/docs/conf.py +94 -0
  60. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/python/docs/index.md +18 -1
  61. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/python/docs/installation.md +3 -9
  62. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/python/docs/usage/advanced.md +10 -10
  63. liburlparser-2.1.0/docs/section.html.in +468 -0
  64. liburlparser-2.1.0/docs/urlparser-docs.css +438 -0
  65. liburlparser-2.1.0/examples/find_liburlparser_via_python/CMakeLists.txt +26 -0
  66. liburlparser-2.1.0/examples/find_liburlparser_via_python/main.cpp +13 -0
  67. liburlparser-2.1.0/examples/main.cpp +202 -0
  68. liburlparser-2.1.0/include/urlparser.h +1084 -0
  69. {liburlparser-1.6.1 → liburlparser-2.1.0}/pyproject.toml +52 -30
  70. liburlparser-2.1.0/requirements-dev.txt +21 -0
  71. liburlparser-2.1.0/src/ankerl/LICENSE +21 -0
  72. liburlparser-2.1.0/src/ankerl/README.md +23 -0
  73. liburlparser-2.1.0/src/ankerl/stl.h +83 -0
  74. liburlparser-2.1.0/src/ankerl/unordered_dense.h +2239 -0
  75. liburlparser-2.1.0/src/bindings/python/binding_py.cpp +662 -0
  76. liburlparser-2.1.0/src/bindings/python/liburlparser/__init__.py +45 -0
  77. {liburlparser-1.6.1/src → liburlparser-2.1.0/src/bindings/python}/liburlparser/__main__.py +24 -2
  78. liburlparser-2.1.0/src/bindings/python/liburlparser/core.py +44 -0
  79. {liburlparser-1.6.1 → liburlparser-2.1.0/src}/public_suffix_list.dat +1129 -442
  80. liburlparser-2.1.0/src/urlparser.cpp +2301 -0
  81. liburlparser-2.1.0/tests/CMakeLists.txt +136 -0
  82. liburlparser-2.1.0/tests/coverage_dashboard.html.in +608 -0
  83. liburlparser-2.1.0/tests/cpp/CMakeLists.txt +133 -0
  84. liburlparser-2.1.0/tests/cpp/fuzz_abspath.cpp +113 -0
  85. liburlparser-2.1.0/tests/cpp/perf_regression_guard.cpp +129 -0
  86. liburlparser-2.1.0/tests/cpp/test_host.cpp +547 -0
  87. liburlparser-2.1.0/tests/cpp/test_idna.cpp +62 -0
  88. liburlparser-2.1.0/tests/cpp/test_normalize.cpp +234 -0
  89. liburlparser-2.1.0/tests/cpp/test_percent_codec.cpp +82 -0
  90. liburlparser-2.1.0/tests/cpp/test_resolve.cpp +74 -0
  91. liburlparser-2.1.0/tests/cpp/test_scp_url.cpp +93 -0
  92. liburlparser-2.1.0/tests/cpp/test_url.cpp +296 -0
  93. {liburlparser-1.6.1 → liburlparser-2.1.0}/tests/data/host_data.csv +4 -1
  94. {liburlparser-1.6.1 → liburlparser-2.1.0}/tests/data/url_data.csv +4 -1
  95. liburlparser-2.1.0/tests/genhtml.css +241 -0
  96. liburlparser-2.1.0/tests/python/CMakeLists.txt +128 -0
  97. {liburlparser-1.6.1 → liburlparser-2.1.0}/tests/python/test_cli_subprocess.py +58 -8
  98. liburlparser-2.1.0/tests/python/test_extra.py +40 -0
  99. liburlparser-2.1.0/tests/python/test_host.py +147 -0
  100. liburlparser-2.1.0/tests/python/test_idna.py +43 -0
  101. liburlparser-2.1.0/tests/python/test_memory.py +82 -0
  102. liburlparser-2.1.0/tests/python/test_normalize.py +146 -0
  103. liburlparser-2.1.0/tests/python/test_percent_codec.py +60 -0
  104. liburlparser-2.1.0/tests/python/test_resolve.py +39 -0
  105. liburlparser-2.1.0/tests/python/test_scp_url.py +66 -0
  106. liburlparser-2.1.0/tests/python/test_url.py +115 -0
  107. liburlparser-2.1.0/tests/utest/utest.h +1305 -0
  108. liburlparser-2.1.0/tests/utest/utest_main.cxx +3 -0
  109. liburlparser-2.1.0/version.py +250 -0
  110. liburlparser-1.6.1/.github/workflows/cmake.yml +0 -79
  111. liburlparser-1.6.1/.github/workflows/docs.yml +0 -72
  112. liburlparser-1.6.1/.github/workflows/wheels.yml +0 -124
  113. liburlparser-1.6.1/.gitmodules +0 -7
  114. liburlparser-1.6.1/CMakeLists.txt +0 -230
  115. liburlparser-1.6.1/examples/main.cpp +0 -159
  116. liburlparser-1.6.1/include/urlparser.h +0 -332
  117. liburlparser-1.6.1/src/binding/about.cpp +0 -19
  118. liburlparser-1.6.1/src/binding/bind_core/main.cpp +0 -154
  119. liburlparser-1.6.1/src/liburlparser/__init__.py +0 -12
  120. liburlparser-1.6.1/src/liburlparser/core.py +0 -46
  121. liburlparser-1.6.1/src/psl.cpp +0 -181
  122. liburlparser-1.6.1/src/psl.h +0 -106
  123. liburlparser-1.6.1/src/url.cpp +0 -944
  124. liburlparser-1.6.1/src/url.h +0 -313
  125. liburlparser-1.6.1/src/urlparser_host.cpp +0 -177
  126. liburlparser-1.6.1/src/urlparser_url.cpp +0 -165
  127. liburlparser-1.6.1/tests/cpp/test_host.cpp +0 -73
  128. liburlparser-1.6.1/tests/cpp/test_url.cpp +0 -91
  129. liburlparser-1.6.1/tests/python/test_extra.py +0 -22
  130. liburlparser-1.6.1/tests/python/test_host.py +0 -21
  131. liburlparser-1.6.1/tests/python/test_url.py +0 -29
  132. {liburlparser-1.6.1 → liburlparser-2.1.0}/.clang-format +0 -0
  133. {liburlparser-1.6.1 → liburlparser-2.1.0}/.gitignore +0 -0
  134. {liburlparser-1.6.1 → liburlparser-2.1.0}/LICENSE +0 -0
  135. {liburlparser-1.6.1 → liburlparser-2.1.0}/cmake/PyProject.cmake +0 -0
  136. {liburlparser-1.6.1 → liburlparser-2.1.0}/conda.recipe/meta.yaml +0 -0
  137. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/cpp/header.html +0 -0
  138. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/cpp/images/interface-arch.svg +0 -0
  139. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/cpp/images/url-parsing-process.svg +0 -0
  140. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/images/logo/liburlparser-logo-1.svg +0 -0
  141. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/images/logo/liburlparser-logo-2.svg +0 -0
  142. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/python/docs/api/host.md +0 -0
  143. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/python/docs/api/url.md +0 -0
  144. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/python/docs/examples.md +0 -0
  145. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/python/docs/performance.md +0 -0
  146. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/python/docs/usage/basic.md +0 -0
  147. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/python/docs/usage/cli.md +0 -0
  148. {liburlparser-1.6.1 → liburlparser-2.1.0}/docs/python/mkdocs.yml +0 -0
  149. {liburlparser-1.6.1 → liburlparser-2.1.0}/examples/common.h +0 -0
  150. {liburlparser-1.6.1/src → liburlparser-2.1.0/src/bindings/python}/liburlparser/utils.py +0 -0
  151. {liburlparser-1.6.1 → liburlparser-2.1.0}/tests/cpp/common.h +0 -0
@@ -0,0 +1,148 @@
1
+ name: cmake stuff
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ workflow_call:
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ build-and-test:
11
+ strategy:
12
+ matrix:
13
+ os: [ubuntu-latest, macos-latest, windows-latest]
14
+
15
+ runs-on: ${{ matrix.os }}
16
+
17
+ steps:
18
+ - name: Checkout repository
19
+ uses: actions/checkout@v6
20
+
21
+ - name: Set up Python
22
+ uses: actions/setup-python@v6
23
+ with:
24
+ python-version: "3.11"
25
+ cache: "pip"
26
+
27
+ - name: Install python deps
28
+ run: pip install -r requirements-dev.txt
29
+
30
+ - name: Build Project
31
+ uses: threeal/cmake-action@v2.1.0
32
+ with:
33
+ build-dir: build
34
+ options: |
35
+ CMAKE_BUILD_TYPE=Release
36
+ BUILD_PYTHON=ON
37
+
38
+ - name: Build
39
+ run: cmake --build build -j4 --config Release
40
+
41
+ - name: Run tests (Linux/macOS)
42
+ if: runner.os != 'Windows'
43
+ run: ctest --test-dir build --output-on-failure --extra-verbose
44
+
45
+
46
+ build-docs:
47
+ needs: build-and-test
48
+ # if: github.event_name == 'push' && github.ref == 'refs/heads/master'
49
+ runs-on: ubuntu-latest
50
+
51
+ steps:
52
+ - name: Checkout repository
53
+ uses: actions/checkout@v6
54
+
55
+ - name: Setup cmake
56
+ uses: jwlawson/actions-setup-cmake@v2
57
+ with:
58
+ cmake-version: '3.28.x'
59
+
60
+ - name: Install apt dependencies
61
+ run: |
62
+ sudo apt-get update
63
+ sudo apt-get install -y doxygen graphviz
64
+
65
+ - name: Set up Python
66
+ uses: actions/setup-python@v6
67
+ with:
68
+ python-version: "3.11"
69
+ cache: "pip"
70
+
71
+ - name: Install python deps
72
+ run: pip install -r requirements-dev.txt
73
+
74
+ - name: Configure CMake
75
+ run: |
76
+ cmake -B build \
77
+ -DCMAKE_BUILD_TYPE=Release \
78
+ -DBUILD_PYTHON=ON
79
+
80
+ - name: Build documentation
81
+ run: cmake --build build --target urlparser_docs
82
+
83
+ - name: List docs directory
84
+ run: find build/docs/out -maxdepth 2
85
+
86
+ - name: Upload documentation artifacts
87
+ uses: actions/upload-artifact@v7
88
+ with:
89
+ name: cmake-documentation
90
+ path: build/docs/out
91
+ retention-days: 5
92
+
93
+ build-coverage:
94
+ # needs: build-and-test
95
+ # if: github.event_name == 'push' && github.ref == 'refs/heads/master'
96
+ runs-on: ubuntu-latest
97
+
98
+ steps:
99
+ - name: Checkout repository
100
+ uses: actions/checkout@v6
101
+
102
+ - name: Setup cmake
103
+ uses: jwlawson/actions-setup-cmake@v2
104
+ with:
105
+ cmake-version: '3.28.x'
106
+
107
+ - name: Set up Python
108
+ uses: actions/setup-python@v6
109
+ with:
110
+ python-version: "3.11"
111
+ cache: "pip"
112
+
113
+ - name: Install python dependencies
114
+ run: pip install -r requirements-dev.txt
115
+
116
+ - name: Install coverage tools
117
+ run: |
118
+ sudo apt-get update
119
+ sudo apt-get install -y lcov
120
+
121
+ - name: Configure CMake with coverage
122
+ run: |
123
+ cmake -B build \
124
+ -DBUILD_PYTHON=ON
125
+
126
+ - name: Generate coverage report
127
+ run: cmake --build build --target urlparser_coverage
128
+
129
+ - name: Upload coverage to Codecov
130
+ uses: codecov/codecov-action@v5
131
+ with:
132
+ files: build/coverage/total/coverage.lcov
133
+ flags: unittests
134
+ name: codecov-umbrella
135
+ fail_ci_if_error: false
136
+ verbose: true
137
+
138
+ - name: Upload coverage artifacts
139
+ uses: actions/upload-artifact@v7
140
+ with:
141
+ name: cmake-coverage-report
142
+ # build/coverage/ is the dashboard root (index.html generated by
143
+ # tests/CMakeLists.txt from coverage_dashboard.html.in), with
144
+ # cpp/, python/, and total/ each holding their own iframe-wrapped
145
+ # report - upload the whole tree so the dashboard's relative
146
+ # links (cpp/index.html, total/coverage.lcov, ...) resolve.
147
+ path: build/coverage/
148
+ retention-days: 5
@@ -0,0 +1,142 @@
1
+ name: Orchestration & Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches: [ master ]
7
+ tags: [ "v*" ]
8
+
9
+ jobs:
10
+ init:
11
+ runs-on: ubuntu-latest
12
+ outputs:
13
+ release_name: ${{ steps.init.outputs.release_name }}
14
+ is_tag: ${{ steps.init.outputs.is_tag }}
15
+ version_string: ${{ steps.init.outputs.version_string }}
16
+ steps:
17
+ - name: Checkout repository
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Initalize
21
+ id: init
22
+ env:
23
+ GH_TOKEN: ${{ github.token }}
24
+ run: |
25
+ export version_string="$(python version.py | tr -d '\n')"
26
+ echo "version_string=${version_string}" | tee -a "$GITHUB_OUTPUT"
27
+ if [[ "${{ github.ref }}" =~ ^refs/tags/v.*$ ]]; then
28
+ TAG_NAME="${GITHUB_REF#refs/tags/}"
29
+ [[ "${version_string}" == "${GITHUB_REF#refs/tags/v}" ]] || (echo "❌ Version mismatch!" && exit 1)
30
+ export release_name="$TAG_NAME"
31
+ export is_tag="true"
32
+ else
33
+ gh api repos/${{ github.repository }}/releases/tags/__beta__ --jq '.assets[].id' 2>/dev/null | xargs -r -I {} gh api repos/${{ github.repository }}/releases/assets/{} -X DELETE 2>/dev/null || true
34
+ export release_name="__beta__"
35
+ export is_tag="false"
36
+ fi
37
+ echo "release_name=${release_name}" | tee -a "$GITHUB_OUTPUT"
38
+ echo "is_tag=${is_tag}" | tee -a "$GITHUB_OUTPUT"
39
+ sed -i -e "s/RELEASE_NAME/${release_name}/g" -e "s/VERSION_STRING/${version_string}/g" .github/workflows/release_template.md
40
+
41
+
42
+ - name: Initialize release body
43
+ uses: softprops/action-gh-release@v2
44
+ with:
45
+ tag_name: ${{ steps.init.outputs.release_name }}
46
+ name: ${{ steps.init.outputs.release_name }}
47
+ draft: false
48
+ prerelease: ${{ steps.init.outputs.is_tag == 'false' }}
49
+ token: ${{ secrets.GITHUB_TOKEN }}
50
+ body_path: .github/workflows/release_template.md
51
+
52
+ cmake:
53
+ uses: ./.github/workflows/cmake.yml
54
+ needs: [init]
55
+
56
+ wheel:
57
+ uses: ./.github/workflows/wheels.yml
58
+ needs: [init]
59
+
60
+
61
+ release-wheels:
62
+ needs: [wheel,init]
63
+ runs-on: ubuntu-latest
64
+ steps:
65
+ - name: Download all artifacts
66
+ uses: actions/download-artifact@v4
67
+ with:
68
+ pattern: wheelhouse-*
69
+ path: dist
70
+ merge-multiple: true
71
+
72
+ - name: List dist directory
73
+ run: ls -la dist
74
+
75
+ - name: create release body
76
+ uses: softprops/action-gh-release@v2
77
+ with:
78
+ tag_name: ${{ needs.init.outputs.release_name }}
79
+ name: ${{ needs.init.outputs.release_name }}
80
+ draft: false
81
+ prerelease: ${{ needs.init.outputs.is_tag == 'false' }}
82
+ token: ${{ secrets.GITHUB_TOKEN }}
83
+ files: dist/*
84
+
85
+ - name: Publishing to PyPi
86
+ uses: pypa/gh-action-pypi-publish@release/v1
87
+ if: startsWith(github.ref, 'refs/tags/')
88
+ with:
89
+ password: ${{ secrets.PYPI_PASSWORD }}
90
+ user: ${{ secrets.PYPI_USERNAME }}
91
+
92
+
93
+ deploy-pages:
94
+ needs: [cmake]
95
+ runs-on: ubuntu-latest
96
+ permissions:
97
+ contents: write
98
+ pages: write
99
+ id-token: write
100
+
101
+ steps:
102
+ - name: Checkout repository
103
+ uses: actions/checkout@v4
104
+
105
+ - name: Download documentation artifact
106
+ uses: actions/download-artifact@v4
107
+ with:
108
+ name: cmake-documentation
109
+ path: ./pages
110
+
111
+ - name: Download coverage artifact
112
+ uses: actions/download-artifact@v4
113
+ with:
114
+ name: cmake-coverage-report
115
+ path: ./pages/coverage
116
+
117
+ # Benchmarks are NOT run in CI: the report is generated locally
118
+ # (cmake --build <dir> --target urlparser_benchmarks_report) and committed
119
+ # as benchmarks/results/report.html. CI only publishes it, as /benchmarks/.
120
+ - name: Add benchmark report
121
+ run: |
122
+ if [ ! -f benchmarks/results/report.html ]; then
123
+ echo "::error::benchmarks/results/report.html is missing - generate it locally and commit it"
124
+ exit 1
125
+ fi
126
+ mkdir -p pages/benchmarks
127
+ cp benchmarks/results/report.html pages/benchmarks/index.html
128
+
129
+ - name: List pages directory
130
+ run: find pages -maxdepth 2
131
+
132
+ - name: Setup Pages
133
+ uses: actions/configure-pages@v4
134
+
135
+ - name: Upload artifact
136
+ uses: actions/upload-pages-artifact@v3
137
+ with:
138
+ path: ./pages
139
+
140
+ - name: Deploy to GitHub Pages
141
+ id: deployment
142
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,77 @@
1
+ import argparse
2
+ import re
3
+ from pathlib import Path
4
+
5
+
6
+ def parse_vars(var_list):
7
+ """Parse variables passed as NAME=VALUE into a dictionary."""
8
+ out = {}
9
+ for item in var_list:
10
+ if "=" not in item:
11
+ raise ValueError(f"Invalid variable: {item}")
12
+ k, v = item.split("=", 1)
13
+ out[k] = v
14
+ return out
15
+
16
+
17
+ def replace_vars(text, vars_dict):
18
+ """Replace all variable placeholders in the text."""
19
+ for k, v in vars_dict.items():
20
+ text = text.replace(k, v)
21
+ return text
22
+
23
+
24
+ def main():
25
+ parser = argparse.ArgumentParser(description="Process release template.")
26
+ parser.add_argument("-i", "--input", required=True, help="Input file path")
27
+ parser.add_argument("-o", "--output", help="Output file path (default: overwrite input)")
28
+ parser.add_argument("-s", "--section", required=True, help="Section name (e.g., PYTHON_SECTION)")
29
+ parser.add_argument("-v", "--variable", action="append", required=True, help="Variables in NAME=VALUE format")
30
+
31
+ args = parser.parse_args()
32
+
33
+ input_path = Path(args.input)
34
+ output_path = Path(args.output) if args.output else input_path
35
+
36
+ content = input_path.read_text(encoding="utf-8")
37
+ variables = parse_vars(args.variable)
38
+
39
+ # 1. Locate the full section block:
40
+ # <!--SECTION_BEGIN ... SECTION_END-->
41
+ section_re = re.compile(
42
+ rf"<!--{args.section}_BEGIN(.*?){args.section}_END-->",
43
+ re.DOTALL,
44
+ )
45
+
46
+ match = section_re.search(content)
47
+ if not match:
48
+ raise ValueError(f"Section {args.section} not found")
49
+
50
+ full_section = match.group(0)
51
+ section_body = match.group(1)
52
+
53
+ # 2. Remove everything between:
54
+ # PLACEHOLDER--> ... <!--PLACEHOLDER
55
+ # This deletes the placeholder/warning content entirely
56
+ cleaned_body = re.sub(
57
+ r"PLACEHOLDER-->.*?<!--PLACEHOLDER",
58
+ "",
59
+ section_body,
60
+ flags=re.DOTALL,
61
+ )
62
+
63
+ # Trim extra whitespace
64
+ cleaned_body = cleaned_body.strip()
65
+
66
+ # 3. Replace variables (e.g., RELEASE_NAME, VERSION_STRING)
67
+ cleaned_body = replace_vars(cleaned_body, variables)
68
+
69
+ # 4. Replace the entire section (including comments) with final content
70
+ new_content = content.replace(full_section, cleaned_body)
71
+
72
+ # 5. Write output
73
+ output_path.write_text(new_content, encoding="utf-8")
74
+
75
+
76
+ if __name__ == "__main__":
77
+ main()
@@ -0,0 +1,15 @@
1
+ ## liburlparser VERSION_STRING
2
+
3
+ Prebuilt wheels and the source distribution for this release are attached below,
4
+ and also listed on the [release page](https://github.com/MohammadRaziei/liburlparser/releases/tag/RELEASE_NAME).
5
+
6
+ ```bash
7
+ pip install liburlparser==VERSION_STRING
8
+ ```
9
+
10
+ | Platform | Notes |
11
+ | :--- | :--- |
12
+ | **Windows** (win32 / win_amd64) | See attached `.whl` assets below |
13
+ | **Linux** (manylinux) | See attached `.whl` assets below |
14
+ | **macOS** (universal2) | See attached `.whl` assets below |
15
+ | **Source** | `liburlparser-VERSION_STRING.tar.gz` |
@@ -0,0 +1,74 @@
1
+ name: python build wheels
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ workflow_call:
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ env:
10
+ FORCE_COLOR: 3
11
+
12
+ concurrency:
13
+ group: ${{ github.workflow }}-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ jobs:
17
+ build_sdist:
18
+ name: Build SDist
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - uses: actions/setup-python@v5
24
+ with:
25
+ python-version: "3.11"
26
+ cache: "pip"
27
+
28
+ # - name: Ruff Check
29
+ # run: pipx run ruff check .
30
+
31
+ - name: Build SDist
32
+ run: pipx run build --sdist
33
+
34
+ - name: Check metadata
35
+ run: pipx run twine check dist/*
36
+
37
+ - uses: actions/upload-artifact@v4
38
+ with:
39
+ name: wheelhouse-sdist
40
+ path: dist/*.tar.gz
41
+ overwrite: true
42
+
43
+
44
+ build_wheels:
45
+ name: Wheels on ${{ matrix.os }}
46
+ runs-on: ${{ matrix.os }}
47
+ strategy:
48
+ fail-fast: true
49
+ matrix:
50
+ os: [ubuntu-latest, macos-latest, windows-latest]
51
+
52
+ steps:
53
+ - uses: actions/checkout@v4
54
+
55
+ - name: Build wheels
56
+ uses: pypa/cibuildwheel@v4.2.1
57
+ env:
58
+ MACOSX_DEPLOYMENT_TARGET: "10.13"
59
+ CIBW_ARCHS_MACOS: universal2
60
+ # 3.10-3.11: normal per-version build (nanobind has no stable-ABI
61
+ # support below 3.12, it silently builds a regular extension there,
62
+ # see CMakeLists.txt). 3.12: built once, tagged cp312-abi3 via
63
+ # SKBUILD_WHEEL_PY_API, and that single wheel covers every newer
64
+ # interpreter too - so 3.13+ is skipped here to avoid building a
65
+ # redundant duplicate wheel.
66
+ CIBW_ENVIRONMENT_CP312: "SKBUILD_WHEEL_PY_API=cp312"
67
+ # Disable building PyPy wheels on all platforms
68
+ CIBW_SKIP: pp*
69
+
70
+ - uses: actions/upload-artifact@v4
71
+ with:
72
+ name: wheelhouse-${{ matrix.os }}
73
+ path: wheelhouse/*.whl
74
+ overwrite: false