mf4-rs 1.1.2__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 (87) hide show
  1. mf4_rs-1.1.2/.github/workflows/pr-title.yml +40 -0
  2. mf4_rs-1.1.2/.github/workflows/release.yml +367 -0
  3. mf4_rs-1.1.2/.gitignore +121 -0
  4. mf4_rs-1.1.2/CHANGELOG.md +29 -0
  5. mf4_rs-1.1.2/CLAUDE.md +466 -0
  6. mf4_rs-1.1.2/Cargo.lock +457 -0
  7. mf4_rs-1.1.2/Cargo.toml +29 -0
  8. mf4_rs-1.1.2/LICENSE +21 -0
  9. mf4_rs-1.1.2/PKG-INFO +302 -0
  10. mf4_rs-1.1.2/README.md +276 -0
  11. mf4_rs-1.1.2/WASM_FEASIBILITY.md +336 -0
  12. mf4_rs-1.1.2/examples/cut_file.rs +56 -0
  13. mf4_rs-1.1.2/examples/index_operations.rs +171 -0
  14. mf4_rs-1.1.2/examples/merge_files.rs +79 -0
  15. mf4_rs-1.1.2/examples/read_file.rs +88 -0
  16. mf4_rs-1.1.2/examples/visualize_layout.rs +33 -0
  17. mf4_rs-1.1.2/examples/write_file.rs +86 -0
  18. mf4_rs-1.1.2/pyproject.toml +37 -0
  19. mf4_rs-1.1.2/python_examples/README.md +392 -0
  20. mf4_rs-1.1.2/python_examples/index_operations.py +152 -0
  21. mf4_rs-1.1.2/python_examples/pandas_example.py +179 -0
  22. mf4_rs-1.1.2/python_examples/read_file.py +112 -0
  23. mf4_rs-1.1.2/python_examples/visualize_layout.py +63 -0
  24. mf4_rs-1.1.2/python_examples/write_file.py +115 -0
  25. mf4_rs-1.1.2/src/api/channel.rs +223 -0
  26. mf4_rs-1.1.2/src/api/channel_group.rs +87 -0
  27. mf4_rs-1.1.2/src/api/mdf.rs +74 -0
  28. mf4_rs-1.1.2/src/api/mod.rs +9 -0
  29. mf4_rs-1.1.2/src/block_layout.rs +932 -0
  30. mf4_rs-1.1.2/src/blocks/channel_block.rs +319 -0
  31. mf4_rs-1.1.2/src/blocks/channel_group_block.rs +187 -0
  32. mf4_rs-1.1.2/src/blocks/common.rs +244 -0
  33. mf4_rs-1.1.2/src/blocks/conversion/base.rs +354 -0
  34. mf4_rs-1.1.2/src/blocks/conversion/bitfield.rs +80 -0
  35. mf4_rs-1.1.2/src/blocks/conversion/formula.rs +27 -0
  36. mf4_rs-1.1.2/src/blocks/conversion/linear.rs +69 -0
  37. mf4_rs-1.1.2/src/blocks/conversion/logic.rs +43 -0
  38. mf4_rs-1.1.2/src/blocks/conversion/mod.rs +21 -0
  39. mf4_rs-1.1.2/src/blocks/conversion/simple_test.rs +163 -0
  40. mf4_rs-1.1.2/src/blocks/conversion/table_lookup.rs +65 -0
  41. mf4_rs-1.1.2/src/blocks/conversion/test_deep_chains.rs +272 -0
  42. mf4_rs-1.1.2/src/blocks/conversion/text.rs +252 -0
  43. mf4_rs-1.1.2/src/blocks/conversion/types.rs +70 -0
  44. mf4_rs-1.1.2/src/blocks/data_block.rs +48 -0
  45. mf4_rs-1.1.2/src/blocks/data_group_block.rs +137 -0
  46. mf4_rs-1.1.2/src/blocks/data_list_block.rs +165 -0
  47. mf4_rs-1.1.2/src/blocks/header_block.rs +172 -0
  48. mf4_rs-1.1.2/src/blocks/identification_block.rs +192 -0
  49. mf4_rs-1.1.2/src/blocks/metadata_block.rs +35 -0
  50. mf4_rs-1.1.2/src/blocks/mod.rs +14 -0
  51. mf4_rs-1.1.2/src/blocks/signal_data_block.rs +34 -0
  52. mf4_rs-1.1.2/src/blocks/source_block.rs +102 -0
  53. mf4_rs-1.1.2/src/blocks/text_block.rs +153 -0
  54. mf4_rs-1.1.2/src/cut.rs +145 -0
  55. mf4_rs-1.1.2/src/error.rs +42 -0
  56. mf4_rs-1.1.2/src/index.rs +1221 -0
  57. mf4_rs-1.1.2/src/lib.rs +46 -0
  58. mf4_rs-1.1.2/src/merge.rs +125 -0
  59. mf4_rs-1.1.2/src/parsing/decoder.rs +447 -0
  60. mf4_rs-1.1.2/src/parsing/mdf_file.rs +118 -0
  61. mf4_rs-1.1.2/src/parsing/mod.rs +6 -0
  62. mf4_rs-1.1.2/src/parsing/raw_channel.rs +166 -0
  63. mf4_rs-1.1.2/src/parsing/raw_channel_group.rs +8 -0
  64. mf4_rs-1.1.2/src/parsing/raw_data_group.rs +77 -0
  65. mf4_rs-1.1.2/src/parsing/source_info.rs +39 -0
  66. mf4_rs-1.1.2/src/python.rs +1457 -0
  67. mf4_rs-1.1.2/src/writer/mdf_writer/data.rs +768 -0
  68. mf4_rs-1.1.2/src/writer/mdf_writer/init.rs +217 -0
  69. mf4_rs-1.1.2/src/writer/mdf_writer/io.rs +231 -0
  70. mf4_rs-1.1.2/src/writer/mdf_writer/mod.rs +51 -0
  71. mf4_rs-1.1.2/src/writer/mod.rs +8 -0
  72. mf4_rs-1.1.2/tests/api.rs +210 -0
  73. mf4_rs-1.1.2/tests/bench_index_read.rs +334 -0
  74. mf4_rs-1.1.2/tests/bench_python.py +180 -0
  75. mf4_rs-1.1.2/tests/bench_read.rs +324 -0
  76. mf4_rs-1.1.2/tests/bench_write.rs +637 -0
  77. mf4_rs-1.1.2/tests/bench_write_chunked.rs +255 -0
  78. mf4_rs-1.1.2/tests/bench_write_python.py +193 -0
  79. mf4_rs-1.1.2/tests/block_layout.rs +156 -0
  80. mf4_rs-1.1.2/tests/blocks.rs +163 -0
  81. mf4_rs-1.1.2/tests/cross_compatibility.rs +616 -0
  82. mf4_rs-1.1.2/tests/enhanced_index_conversions.rs +307 -0
  83. mf4_rs-1.1.2/tests/index.rs +518 -0
  84. mf4_rs-1.1.2/tests/merge.rs +85 -0
  85. mf4_rs-1.1.2/tests/test_asammdf_interop.py +553 -0
  86. mf4_rs-1.1.2/tests/test_invalidation_bits.rs +257 -0
  87. mf4_rs-1.1.2/uv.lock +8 -0
@@ -0,0 +1,40 @@
1
+ name: Lint PR Title
2
+
3
+ on:
4
+ pull_request:
5
+ types:
6
+ - opened
7
+ - edited
8
+ - synchronize
9
+ - reopened
10
+
11
+ permissions:
12
+ pull-requests: read
13
+ statuses: write
14
+
15
+ jobs:
16
+ validate:
17
+ name: Validate Conventional Commits format
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: amannn/action-semantic-pull-request@v5
21
+ env:
22
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23
+ with:
24
+ types: |
25
+ feat
26
+ fix
27
+ perf
28
+ chore
29
+ docs
30
+ refactor
31
+ test
32
+ ci
33
+ build
34
+ style
35
+ requireScope: false
36
+ subjectPattern: ^[A-Za-z0-9].+$
37
+ subjectPatternError: |
38
+ The PR title subject (after the colon) must start with an alphanumeric character.
39
+ Example: `feat: add CAN bus extraction`
40
+ wip: true
@@ -0,0 +1,367 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ concurrency:
9
+ group: release-${{ github.ref }}
10
+ cancel-in-progress: false
11
+
12
+ permissions:
13
+ contents: write
14
+
15
+ jobs:
16
+ compute-bump:
17
+ name: Compute SemVer bump from Conventional Commits
18
+ runs-on: ubuntu-latest
19
+ outputs:
20
+ release_needed: ${{ steps.bump.outputs.release_needed }}
21
+ new_version: ${{ steps.bump.outputs.new_version }}
22
+ previous_tag: ${{ steps.bump.outputs.previous_tag }}
23
+ bump: ${{ steps.bump.outputs.bump }}
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ with:
27
+ fetch-depth: 0
28
+
29
+ - id: bump
30
+ name: Determine next version
31
+ shell: python
32
+ run: |
33
+ import os, pathlib, re, subprocess
34
+
35
+ def parse(v):
36
+ return tuple(int(x) for x in v.lstrip("v").split("."))
37
+
38
+ tags = subprocess.check_output(
39
+ ["git", "tag", "--list", "v*", "--sort=-v:refname"], text=True
40
+ ).split()
41
+ last_tag = tags[0] if tags else "v0.0.0"
42
+ range_arg = "HEAD" if last_tag == "v0.0.0" else f"{last_tag}..HEAD"
43
+
44
+ # The bump base is the maximum of the latest v* tag and the
45
+ # version currently declared in Cargo.toml. This way, a manually
46
+ # bumped Cargo.toml version (or a version published to a registry
47
+ # before the workflow was wired up) is honored, and we never
48
+ # downgrade.
49
+ cargo_version = re.search(
50
+ r'^version\s*=\s*"([^"]+)"',
51
+ pathlib.Path("Cargo.toml").read_text(),
52
+ re.M,
53
+ ).group(1)
54
+ base_v = max(parse(last_tag), parse(cargo_version))
55
+ base_label = f"v{'.'.join(str(x) for x in base_v)}"
56
+
57
+ hashes = subprocess.check_output(
58
+ ["git", "log", range_arg, "--format=%H"], text=True
59
+ ).split()
60
+
61
+ TYPE_RE = re.compile(
62
+ r"^(feat|fix|perf|refactor|chore|docs|test|ci|build|style)"
63
+ r"(\([^)]+\))?(!)?:"
64
+ )
65
+ BREAKING_FOOTER = re.compile(r"^BREAKING[ -]CHANGE:", re.M | re.I)
66
+
67
+ rank = {"none": 0, "patch": 1, "minor": 2, "major": 3}
68
+ bump = "none"
69
+
70
+ for h in hashes:
71
+ body = subprocess.check_output(
72
+ ["git", "show", "-s", "--format=%B", h], text=True
73
+ )
74
+ subject = body.splitlines()[0] if body else ""
75
+ m = TYPE_RE.match(subject)
76
+ if (m and m.group(3) == "!") or BREAKING_FOOTER.search(body):
77
+ bump = "major"
78
+ break
79
+ if not m:
80
+ continue
81
+ t = m.group(1)
82
+ if t == "feat" and rank[bump] < rank["minor"]:
83
+ bump = "minor"
84
+ elif t in ("fix", "perf") and rank[bump] < rank["patch"]:
85
+ bump = "patch"
86
+
87
+ major, minor, patch = base_v
88
+ if bump == "major":
89
+ major, minor, patch = major + 1, 0, 0
90
+ elif bump == "minor":
91
+ minor, patch = minor + 1, 0
92
+ elif bump == "patch":
93
+ patch += 1
94
+
95
+ new_version = f"{major}.{minor}.{patch}" if bump != "none" else ""
96
+ release_needed = "true" if bump != "none" else "false"
97
+
98
+ print(f"Latest tag: {last_tag}")
99
+ print(f"Cargo.toml version: {cargo_version}")
100
+ print(f"Bump base: {base_label}")
101
+ print(f"Commits analyzed: {len(hashes)}")
102
+ print(f"Bump: {bump}")
103
+ print(f"New version: {new_version or '(none — skipping release)'}")
104
+
105
+ # previous_tag stays as the actual latest git tag so the
106
+ # changelog step can use it as a `git log <prev>..HEAD` range.
107
+ # bump_base is the synthetic baseline used for SemVer arithmetic.
108
+ with open(os.environ["GITHUB_OUTPUT"], "a") as f:
109
+ f.write(f"previous_tag={last_tag}\n")
110
+ f.write(f"bump_base={base_label}\n")
111
+ f.write(f"new_version={new_version}\n")
112
+ f.write(f"release_needed={release_needed}\n")
113
+ f.write(f"bump={bump}\n")
114
+
115
+ bump-and-tag:
116
+ name: Bump version, update changelog, tag
117
+ needs: compute-bump
118
+ if: needs.compute-bump.outputs.release_needed == 'true'
119
+ runs-on: ubuntu-latest
120
+ outputs:
121
+ new_version: ${{ needs.compute-bump.outputs.new_version }}
122
+ tag: v${{ needs.compute-bump.outputs.new_version }}
123
+ steps:
124
+ - uses: actions/checkout@v4
125
+ with:
126
+ fetch-depth: 0
127
+ token: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
128
+
129
+ - name: Configure git author
130
+ run: |
131
+ git config user.name "github-actions[bot]"
132
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
133
+
134
+ - name: Bump Cargo.toml
135
+ run: |
136
+ sed -i -E 's/^version *= *"[^"]+"/version = "${{ needs.compute-bump.outputs.new_version }}"/' Cargo.toml
137
+ grep '^version' Cargo.toml
138
+
139
+ - name: Bump pyproject.toml
140
+ run: |
141
+ python -c "
142
+ import re, pathlib
143
+ p = pathlib.Path('pyproject.toml')
144
+ new = re.sub(r'^version = \".*\"', 'version = \"${{ needs.compute-bump.outputs.new_version }}\"', p.read_text(), count=1, flags=re.M)
145
+ p.write_text(new)
146
+ "
147
+ grep '^version' pyproject.toml
148
+
149
+ - uses: dtolnay/rust-toolchain@stable
150
+
151
+ - name: Refresh Cargo.lock
152
+ run: cargo update -p mf4-rs
153
+
154
+ - name: Generate changelog entry
155
+ id: changelog
156
+ env:
157
+ PREVIOUS_TAG: ${{ needs.compute-bump.outputs.previous_tag }}
158
+ NEW_VERSION: ${{ needs.compute-bump.outputs.new_version }}
159
+ shell: python
160
+ run: |
161
+ import datetime, os, pathlib, re, subprocess
162
+
163
+ prev = os.environ["PREVIOUS_TAG"]
164
+ new_tag = "v" + os.environ["NEW_VERSION"]
165
+ range_arg = "HEAD" if prev == "v0.0.0" else f"{prev}..HEAD"
166
+
167
+ subjects = subprocess.check_output(
168
+ ["git", "log", range_arg, "--format=%s"], text=True
169
+ ).splitlines()
170
+
171
+ TYPE = re.compile(r"^([a-z]+)(\([^)]+\))?(!)?:\s*(.+)$")
172
+ groups = [
173
+ ("feat", "Features"),
174
+ ("fix", "Fixes"),
175
+ ("perf", "Performance"),
176
+ ("refactor", "Refactors"),
177
+ ("docs", "Docs"),
178
+ ("build", "Build"),
179
+ ("ci", "CI"),
180
+ ]
181
+ breaking = []
182
+ buckets = {t: [] for t, _ in groups}
183
+ for s in subjects:
184
+ m = TYPE.match(s)
185
+ if not m:
186
+ continue
187
+ t, _, bang, desc = m.groups()
188
+ if bang:
189
+ breaking.append(f"- {desc}")
190
+ if t in buckets:
191
+ buckets[t].append(f"- {desc}")
192
+
193
+ today = datetime.date.today().isoformat()
194
+ lines = [f"## {new_tag} — {today}", ""]
195
+ if breaking:
196
+ lines += ["### BREAKING CHANGES", *breaking, ""]
197
+ for t, label in groups:
198
+ if buckets[t]:
199
+ lines += [f"### {label}", *buckets[t], ""]
200
+
201
+ new_section = "\n".join(lines).rstrip() + "\n"
202
+ pathlib.Path("new_section.md").write_text(new_section)
203
+
204
+ changelog = pathlib.Path("CHANGELOG.md")
205
+ if changelog.exists():
206
+ changelog.write_text(new_section + "\n" + changelog.read_text())
207
+ else:
208
+ header = (
209
+ "# Changelog\n\n"
210
+ "All notable changes to mf4-rs are documented in this file. "
211
+ "This project follows Semantic Versioning and Conventional Commits.\n\n"
212
+ )
213
+ changelog.write_text(header + new_section)
214
+
215
+ print("--- generated changelog section ---")
216
+ print(new_section)
217
+
218
+ - name: Commit, tag, and push
219
+ run: |
220
+ set -euo pipefail
221
+ new='v${{ needs.compute-bump.outputs.new_version }}'
222
+ git add Cargo.toml Cargo.lock pyproject.toml CHANGELOG.md
223
+ git commit -m "chore(release): ${new}"
224
+ git tag -a "${new}" -m "Release ${new}"
225
+ git push origin HEAD:main
226
+ git push origin "${new}"
227
+
228
+ - name: Create GitHub Release
229
+ env:
230
+ GH_TOKEN: ${{ github.token }}
231
+ run: |
232
+ gh release create "v${{ needs.compute-bump.outputs.new_version }}" \
233
+ --title "v${{ needs.compute-bump.outputs.new_version }}" \
234
+ --notes-file new_section.md
235
+
236
+ build-wheels-linux:
237
+ name: Build wheels (Linux ${{ matrix.target }})
238
+ needs: bump-and-tag
239
+ runs-on: ubuntu-latest
240
+ strategy:
241
+ fail-fast: false
242
+ matrix:
243
+ target: [x86_64, aarch64]
244
+ steps:
245
+ - uses: actions/checkout@v4
246
+ with:
247
+ ref: ${{ needs.bump-and-tag.outputs.tag }}
248
+ - uses: PyO3/maturin-action@v1
249
+ with:
250
+ target: ${{ matrix.target }}
251
+ args: --release --out dist
252
+ manylinux: auto
253
+ sccache: "true"
254
+ - uses: actions/upload-artifact@v4
255
+ with:
256
+ name: wheels-linux-${{ matrix.target }}
257
+ path: dist
258
+
259
+ build-wheels-macos:
260
+ name: Build wheels (macOS ${{ matrix.target }})
261
+ needs: bump-and-tag
262
+ strategy:
263
+ fail-fast: false
264
+ matrix:
265
+ include:
266
+ - os: macos-14
267
+ target: aarch64
268
+ runs-on: ${{ matrix.os }}
269
+ steps:
270
+ - uses: actions/checkout@v4
271
+ with:
272
+ ref: ${{ needs.bump-and-tag.outputs.tag }}
273
+ - uses: actions/setup-python@v5
274
+ with:
275
+ python-version: "3.12"
276
+ - uses: PyO3/maturin-action@v1
277
+ with:
278
+ target: ${{ matrix.target }}
279
+ args: --release --out dist
280
+ sccache: "true"
281
+ - uses: actions/upload-artifact@v4
282
+ with:
283
+ name: wheels-macos-${{ matrix.target }}
284
+ path: dist
285
+
286
+ build-wheels-windows:
287
+ name: Build wheels (Windows ${{ matrix.target }})
288
+ needs: bump-and-tag
289
+ runs-on: windows-latest
290
+ strategy:
291
+ fail-fast: false
292
+ matrix:
293
+ target: [x64]
294
+ steps:
295
+ - uses: actions/checkout@v4
296
+ with:
297
+ ref: ${{ needs.bump-and-tag.outputs.tag }}
298
+ - uses: actions/setup-python@v5
299
+ with:
300
+ python-version: "3.12"
301
+ - uses: PyO3/maturin-action@v1
302
+ with:
303
+ target: ${{ matrix.target }}
304
+ args: --release --out dist
305
+ sccache: "true"
306
+ - uses: actions/upload-artifact@v4
307
+ with:
308
+ name: wheels-windows-${{ matrix.target }}
309
+ path: dist
310
+
311
+ build-sdist:
312
+ name: Build source distribution
313
+ needs: bump-and-tag
314
+ runs-on: ubuntu-latest
315
+ steps:
316
+ - uses: actions/checkout@v4
317
+ with:
318
+ ref: ${{ needs.bump-and-tag.outputs.tag }}
319
+ - uses: PyO3/maturin-action@v1
320
+ with:
321
+ command: sdist
322
+ args: --out dist
323
+ - uses: actions/upload-artifact@v4
324
+ with:
325
+ name: sdist
326
+ path: dist
327
+
328
+ publish-pypi:
329
+ name: Publish to PyPI
330
+ needs:
331
+ - build-wheels-linux
332
+ - build-wheels-macos
333
+ - build-wheels-windows
334
+ - build-sdist
335
+ runs-on: ubuntu-latest
336
+ environment:
337
+ name: pypi
338
+ url: https://pypi.org/p/mf4-rs
339
+ permissions:
340
+ id-token: write
341
+ steps:
342
+ - uses: actions/download-artifact@v4
343
+ with:
344
+ path: dist
345
+ merge-multiple: true
346
+ - name: List collected artifacts
347
+ run: ls -la dist
348
+ - uses: pypa/gh-action-pypi-publish@release/v1
349
+ with:
350
+ packages-dir: dist
351
+ skip-existing: true
352
+
353
+ publish-crates:
354
+ name: Publish to crates.io
355
+ needs: bump-and-tag
356
+ runs-on: ubuntu-latest
357
+ steps:
358
+ - uses: actions/checkout@v4
359
+ with:
360
+ ref: ${{ needs.bump-and-tag.outputs.tag }}
361
+ - uses: dtolnay/rust-toolchain@stable
362
+ - name: Dry-run publish
363
+ run: cargo publish --dry-run --allow-dirty
364
+ - name: Publish
365
+ env:
366
+ CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
367
+ run: cargo publish --token "$CARGO_REGISTRY_TOKEN"
@@ -0,0 +1,121 @@
1
+ # Generated by Cargo
2
+ # will have compiled files and executables
3
+ debug/
4
+ target/
5
+
6
+ # These are backup files generated by rustfmt
7
+ **/*.rs.bk
8
+
9
+ # MSVC Windows builds of rustc generate these, which store debugging information
10
+ *.pdb
11
+
12
+ # Generated by cargo mutants
13
+ # Contains mutation testing data
14
+ **/mutants.out*/
15
+
16
+ # Python
17
+ # Virtual environments
18
+ .venv/
19
+ venv/
20
+ env/
21
+ __pycache__/
22
+ *.pyc
23
+ *.pyo
24
+ *.pyd
25
+ .Python
26
+ build/
27
+ develop-eggs/
28
+ dist/
29
+ downloads/
30
+ eggs/
31
+ .eggs/
32
+ lib/
33
+ lib64/
34
+ parts/
35
+ sdist/
36
+ var/
37
+ wheels/
38
+ *.egg-info/
39
+ .installed.cfg
40
+ *.egg
41
+
42
+ # MDF Files
43
+ # Test and temporary MDF files
44
+ *.mf4
45
+ *.tmp.mf4
46
+ asammdf_*.mf4
47
+
48
+ # JSON Files
49
+ # Test and temporary JSON files (indexes, configs)
50
+ *.json
51
+ *_index.json
52
+ *_test.json
53
+
54
+ # Benchmark Data
55
+ # Generated test data and results (optional - remove if you want to commit test data)
56
+ benchmarks/data/*.mf4
57
+ benchmarks/data/*.json
58
+ benchmarks/results/latest/
59
+ benchmarks/results/history/
60
+ benchmarks/results/reports/
61
+
62
+ # Documentation PDFs
63
+ *.pdf
64
+
65
+ # Test/Debug Scripts
66
+ # Temporary Python scripts created during development
67
+ debug_*.py
68
+ test_*.py
69
+ *_test.py
70
+ *_debug.py
71
+ temp_*.py
72
+ # Exception: committed interop tests in tests/
73
+ !tests/test_*.py
74
+
75
+ # IDE
76
+ # RustRover
77
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
78
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
79
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
80
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
81
+ #.idea/
82
+ .vscode/
83
+ *.swp
84
+ *.swo
85
+ *~
86
+
87
+ # OS
88
+ # Windows
89
+ Thumbs.db
90
+ ehthumbs.db
91
+ Desktop.ini
92
+ $RECYCLE.BIN/
93
+ *.lnk
94
+
95
+ # macOS
96
+ .DS_Store
97
+ .AppleDouble
98
+ .LSOverride
99
+ Icon
100
+ ._*
101
+ .DocumentRevisions-V100
102
+ .fseventsd
103
+ .Spotlight-V100
104
+ .TemporaryItems
105
+ .Trashes
106
+ .VolumeIcon.icns
107
+ .com.apple.timemachine.donotpresent
108
+
109
+ # Linux
110
+ *~
111
+ .fuse_hidden*
112
+ .directory
113
+ .Trash-*
114
+ .nfs*
115
+
116
+ # Temporary files
117
+ *.tmp
118
+ *.temp
119
+ *.bak
120
+ *.backup
121
+ *.old
@@ -0,0 +1,29 @@
1
+ ## v1.1.2 — 2026-04-25
2
+
3
+ ### Fixes
4
+ - drop Intel Mac wheel build to avoid macos-13 runner queue
5
+
6
+ ## v1.1.1 — 2026-04-25
7
+
8
+ ### Fixes
9
+ - build a single abi3 wheel per OS/arch for Python 3.8+
10
+
11
+ ## v1.1.0 — 2026-04-25
12
+
13
+ ### Features
14
+ - use max of latest tag and Cargo.toml version as bump base (#58)
15
+
16
+ # Changelog
17
+
18
+ All notable changes to mf4-rs are documented in this file. This project follows Semantic Versioning and Conventional Commits.
19
+
20
+ ## v0.1.0 — 2026-04-25
21
+
22
+ ### Features
23
+ - enable automated releases (#57)
24
+
25
+ ### Refactors
26
+ - reuse record gathering logic
27
+
28
+ ### CI
29
+ - add automated SemVer release pipeline driven by Conventional Commits