python-rako-2025 0.4.3__tar.gz → 0.5.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 (86) hide show
  1. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/.coveragerc +4 -2
  2. python_rako_2025-0.5.0/.github/workflows/ci.yml +75 -0
  3. python_rako_2025-0.5.0/.github/workflows/release.yml +117 -0
  4. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/.gitignore +0 -1
  5. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/.pre-commit-config.yaml +6 -6
  6. python_rako_2025-0.5.0/CHANGELOG.md +123 -0
  7. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/Makefile +9 -9
  8. python_rako_2025-0.5.0/PKG-INFO +334 -0
  9. python_rako_2025-0.5.0/README.md +293 -0
  10. python_rako_2025-0.5.0/RELEASING.md +153 -0
  11. python_rako_2025-0.5.0/examples/listen_status.py +76 -0
  12. python_rako_2025-0.5.0/examples/state_snapshot.py +87 -0
  13. python_rako_2025-0.5.0/examples/verified_commands.py +65 -0
  14. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/pyproject.toml +10 -5
  15. python_rako_2025-0.5.0/python_rako/__init__.py +150 -0
  16. python_rako_2025-0.5.0/python_rako/__version__.py +1 -0
  17. python_rako_2025-0.5.0/python_rako/bridge.py +791 -0
  18. python_rako_2025-0.5.0/python_rako/commands.py +618 -0
  19. python_rako_2025-0.5.0/python_rako/const.py +111 -0
  20. python_rako_2025-0.5.0/python_rako/exceptions.py +47 -0
  21. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/python_rako/helpers.py +46 -49
  22. python_rako_2025-0.5.0/python_rako/listener.py +449 -0
  23. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/python_rako/model.py +42 -5
  24. python_rako_2025-0.5.0/python_rako/pacing.py +534 -0
  25. python_rako_2025-0.5.0/python_rako/protocol.py +658 -0
  26. python_rako_2025-0.5.0/python_rako/state.py +431 -0
  27. python_rako_2025-0.5.0/scripts/bump_version.py +120 -0
  28. python_rako_2025-0.5.0/scripts/latency.py +201 -0
  29. python_rako_2025-0.5.0/scripts/listen.py +166 -0
  30. python_rako_2025-0.5.0/scripts/measure_interval.py +271 -0
  31. python_rako_2025-0.5.0/scripts/snapshot.py +101 -0
  32. python_rako_2025-0.5.0/tests/README_TESTING.md +138 -0
  33. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/tests/test_async_lock.py +64 -15
  34. python_rako_2025-0.5.0/tests/test_bridge_async_parsing.py +96 -0
  35. python_rako_2025-0.5.0/tests/test_bridge_state.py +278 -0
  36. python_rako_2025-0.5.0/tests/test_command_queue.py +682 -0
  37. python_rako_2025-0.5.0/tests/test_commands.py +670 -0
  38. python_rako_2025-0.5.0/tests/test_discovery.py +104 -0
  39. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/tests/test_helpers.py +37 -1
  40. python_rako_2025-0.5.0/tests/test_listener.py +507 -0
  41. python_rako_2025-0.5.0/tests/test_measure_interval.py +126 -0
  42. python_rako_2025-0.5.0/tests/test_protocol.py +528 -0
  43. python_rako_2025-0.5.0/tests/test_state.py +482 -0
  44. python_rako_2025-0.5.0/tests_integration/conftest.py +151 -0
  45. python_rako_2025-0.5.0/tests_integration/test_bridge_info_live.py +32 -0
  46. python_rako_2025-0.5.0/tests_integration/test_command_live.py +131 -0
  47. python_rako_2025-0.5.0/tests_integration/test_discovery_live.py +40 -0
  48. python_rako_2025-0.5.0/tests_integration/test_listener_live.py +45 -0
  49. python_rako_2025-0.5.0/tests_integration/test_state_live.py +52 -0
  50. python_rako_2025-0.4.3/.claude/settings.local.json +0 -13
  51. python_rako_2025-0.4.3/.github/workflows/ci.yml +0 -54
  52. python_rako_2025-0.4.3/.github/workflows/release.yml +0 -50
  53. python_rako_2025-0.4.3/PKG-INFO +0 -196
  54. python_rako_2025-0.4.3/README.md +0 -157
  55. python_rako_2025-0.4.3/python_rako/__init__.py +0 -69
  56. python_rako_2025-0.4.3/python_rako/__version__.py +0 -1
  57. python_rako_2025-0.4.3/python_rako/bridge.py +0 -355
  58. python_rako_2025-0.4.3/python_rako/const.py +0 -59
  59. python_rako_2025-0.4.3/python_rako/exceptions.py +0 -2
  60. python_rako_2025-0.4.3/tests/README_TESTING.md +0 -46
  61. python_rako_2025-0.4.3/tests_integration/conftest.py +0 -21
  62. python_rako_2025-0.4.3/tests_integration/test_command_live.py +0 -106
  63. python_rako_2025-0.4.3/tests_integration/test_general_live.py +0 -41
  64. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/.editorconfig +0 -0
  65. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/.flake8 +0 -0
  66. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/.gitattributes +0 -0
  67. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/.github/dependabot.yml +0 -0
  68. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/.isort.cfg +0 -0
  69. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/.yamllint +0 -0
  70. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/LICENSE +0 -0
  71. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/catalog-info.yaml +0 -0
  72. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/conftest.py +0 -0
  73. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/doc/accessing-the-rako-bridge.pdf +0 -0
  74. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/examples/discover_all_devices.py +0 -0
  75. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/examples/example.py +0 -0
  76. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/examples/ventilation_example.py +0 -0
  77. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/examples/view_updates.py +0 -0
  78. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/python_rako/py.typed +0 -0
  79. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/tests/resources/rako.xml +0 -0
  80. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/tests/resources/rako2.xml +0 -0
  81. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/tests/resources/rako3.xml +0 -0
  82. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/tests/test_bridge.py +0 -0
  83. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/tests/test_edge_cases.py +0 -0
  84. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/tests/test_model.py +0 -0
  85. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/tests/test_xml_parsing.py +0 -0
  86. {python_rako_2025-0.4.3 → python_rako_2025-0.5.0}/tests_integration/__init__.py +0 -0
@@ -1,8 +1,10 @@
1
1
  [run]
2
2
  source = python_rako
3
+ # Keep this in step with [tool.coverage.run] in pyproject.toml -- this file
4
+ # takes precedence over it. __init__.py and bridge.py used to be omitted here,
5
+ # which silently excluded the bridge API from the coverage gate.
3
6
  omit =
4
- python_rako/__init__.py
5
- python_rako/bridge.py
7
+ python_rako/__version__.py
6
8
 
7
9
 
8
10
  [report]
@@ -0,0 +1,75 @@
1
+ ---
2
+ name: Continuous Integration
3
+
4
+ on: [push, pull_request]
5
+
6
+ concurrency:
7
+ group: ci-${{ github.workflow }}-${{ github.ref }}
8
+ cancel-in-progress: true
9
+
10
+ jobs:
11
+ linting:
12
+ name: Linting
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checking out code from GitHub
16
+ uses: actions/checkout@v4
17
+ - name: Install uv
18
+ uses: astral-sh/setup-uv@v5
19
+ with:
20
+ enable-cache: true
21
+ - name: Create virtual environment
22
+ run: uv venv .venv --python 3.13
23
+ - name: Install dependencies
24
+ run: uv pip install --python .venv/bin/python -e '.[dev]'
25
+ - name: Run pre-commit on all files
26
+ run: .venv/bin/pre-commit run --all-files --show-diff-on-failure
27
+
28
+ test:
29
+ name: Python ${{ matrix.python }} on ${{ matrix.os }}
30
+ runs-on: ${{ matrix.os }}-latest
31
+ strategy:
32
+ fail-fast: false
33
+ matrix:
34
+ os: [ubuntu]
35
+ python: ["3.12", "3.13"]
36
+ steps:
37
+ - name: Checking out code from GitHub
38
+ uses: actions/checkout@v4
39
+ - name: Install uv
40
+ uses: astral-sh/setup-uv@v5
41
+ with:
42
+ enable-cache: true
43
+ - name: Create virtual environment
44
+ run: uv venv .venv --python ${{ matrix.python }}
45
+ - name: Install dependencies
46
+ run: uv pip install --python .venv/bin/python -e '.[test]'
47
+ - name: Run tests with coverage
48
+ run: .venv/bin/python -m pytest
49
+ - name: Upload coverage to Codecov
50
+ if: matrix.python == '3.12' && matrix.os == 'ubuntu'
51
+ uses: codecov/codecov-action@v5
52
+ with:
53
+ token: ${{ secrets.CODECOV_TOKEN }}
54
+ file: ./coverage.xml
55
+ flags: unittests
56
+ name: codecov-umbrella
57
+
58
+ packaging:
59
+ name: Build & verify distribution
60
+ runs-on: ubuntu-latest
61
+ steps:
62
+ - name: Checking out code from GitHub
63
+ uses: actions/checkout@v4
64
+ - name: Install uv
65
+ uses: astral-sh/setup-uv@v5
66
+ with:
67
+ enable-cache: true
68
+ - name: Create virtual environment
69
+ run: uv venv .venv --python 3.13
70
+ - name: Install build tooling
71
+ run: uv pip install --python .venv/bin/python build twine
72
+ - name: Build sdist and wheel
73
+ run: .venv/bin/python -m build
74
+ - name: Check distribution metadata (twine)
75
+ run: .venv/bin/python -m twine check dist/*
@@ -0,0 +1,117 @@
1
+ ---
2
+ name: Release
3
+
4
+ # Two ways to run this workflow:
5
+ #
6
+ # - "release: published" -> real release. Builds, verifies the tag matches
7
+ # python_rako/__version__.py, and publishes to the real PyPI (environment: pypi).
8
+ #
9
+ # - "workflow_dispatch" -> dry run. Builds and publishes to TestPyPI
10
+ # (environment: testpypi) instead. Safe to run at any time; never touches
11
+ # the real PyPI. Use this to sanity-check the pipeline before cutting a
12
+ # real release.
13
+ #
14
+ # See RELEASING.md for the full maintainer walkthrough and the one-time
15
+ # Trusted Publisher setup this workflow depends on.
16
+
17
+ on:
18
+ release:
19
+ types: [published]
20
+ workflow_dispatch: {}
21
+
22
+ permissions: {}
23
+
24
+ jobs:
25
+ build:
26
+ name: Build & verify distribution
27
+ runs-on: ubuntu-latest
28
+ permissions:
29
+ contents: read
30
+ steps:
31
+ - name: Checking out code from GitHub
32
+ uses: actions/checkout@v4
33
+
34
+ - name: Install uv
35
+ uses: astral-sh/setup-uv@v5
36
+ with:
37
+ enable-cache: true
38
+
39
+ - name: Create virtual environment
40
+ run: uv venv .venv --python 3.13
41
+
42
+ - name: Verify the release tag matches python_rako/__version__.py
43
+ if: github.event_name == 'release'
44
+ run: |
45
+ .venv/bin/python scripts/bump_version.py check "${{ github.event.release.tag_name }}"
46
+
47
+ - name: Install build tooling
48
+ run: uv pip install --python .venv/bin/python build twine
49
+
50
+ - name: Build sdist and wheel
51
+ run: .venv/bin/python -m build
52
+
53
+ - name: Check distribution metadata (twine)
54
+ run: .venv/bin/python -m twine check dist/*
55
+
56
+ - name: Smoke-test the built wheel in a clean venv
57
+ run: |
58
+ uv venv /tmp/smoke-venv --python 3.13
59
+ uv pip install --python /tmp/smoke-venv/bin/python dist/*.whl
60
+ /tmp/smoke-venv/bin/python -c "import python_rako; print('python_rako', python_rako.__version__)"
61
+
62
+ - name: Upload build artifacts
63
+ uses: actions/upload-artifact@v4
64
+ with:
65
+ name: dist
66
+ path: dist/
67
+ if-no-files-found: error
68
+
69
+ publish-testpypi:
70
+ name: Publish to TestPyPI (dry run)
71
+ if: github.event_name == 'workflow_dispatch'
72
+ needs: build
73
+ runs-on: ubuntu-latest
74
+ environment:
75
+ name: testpypi
76
+ url: https://test.pypi.org/p/python-rako-2025
77
+ permissions:
78
+ id-token: write # required for PyPI Trusted Publishing
79
+ attestations: write # required for build provenance attestations
80
+ contents: read
81
+ steps:
82
+ - name: Download build artifacts
83
+ uses: actions/download-artifact@v4
84
+ with:
85
+ name: dist
86
+ path: dist/
87
+
88
+ - name: Publish to TestPyPI
89
+ uses: pypa/gh-action-pypi-publish@release/v1
90
+ with:
91
+ repository-url: https://test.pypi.org/legacy/
92
+ attestations: true
93
+ skip-existing: true # dry runs of an unchanged version must not fail
94
+
95
+ publish-pypi:
96
+ name: Publish to PyPI
97
+ if: github.event_name == 'release'
98
+ needs: build
99
+ runs-on: ubuntu-latest
100
+ environment:
101
+ name: pypi
102
+ url: https://pypi.org/p/python-rako-2025
103
+ permissions:
104
+ id-token: write # required for PyPI Trusted Publishing
105
+ attestations: write # required for build provenance attestations
106
+ contents: read
107
+ steps:
108
+ - name: Download build artifacts
109
+ uses: actions/download-artifact@v4
110
+ with:
111
+ name: dist
112
+ path: dist/
113
+
114
+ - name: Publish to PyPI
115
+ uses: pypa/gh-action-pypi-publish@release/v1
116
+ with:
117
+ attestations: true
@@ -88,7 +88,6 @@ venv
88
88
  .venv
89
89
  Pipfile*
90
90
  share/*
91
- /Scripts/
92
91
 
93
92
  # vimmy stuff
94
93
  *.swp
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  repos:
3
3
  - repo: https://github.com/astral-sh/ruff-pre-commit
4
- rev: v0.1.15
4
+ rev: v0.16.4
5
5
  hooks:
6
- - id: ruff
6
+ - id: ruff-check
7
7
  args: [--fix]
8
8
  - id: ruff-format
9
9
  - repo: https://github.com/pre-commit/pre-commit-hooks
10
- rev: v5.0.0
10
+ rev: v6.0.0
11
11
  hooks:
12
12
  - id: trailing-whitespace
13
13
  - id: end-of-file-fixer
@@ -16,20 +16,20 @@ repos:
16
16
  - id: check-docstring-first
17
17
  - id: check-json
18
18
  - id: check-yaml
19
- - id: check-byte-order-marker
19
+ - id: fix-byte-order-marker
20
20
  - id: check-case-conflict
21
21
  - id: check-executables-have-shebangs
22
22
  - id: check-ast
23
23
  - id: detect-private-key
24
24
  - id: forbid-new-submodules
25
25
  - repo: https://github.com/pre-commit/mirrors-mypy
26
- rev: v1.16.1
26
+ rev: v2.3.1
27
27
  hooks:
28
28
  - id: mypy
29
29
  files: ^python_rako/.+\.py$
30
30
  exclude: ^python_rako/__version__\.py$
31
31
  additional_dependencies: [types-requests]
32
32
  - repo: https://github.com/adrienverge/yamllint.git
33
- rev: v1.37.1
33
+ rev: v1.38.0
34
34
  hooks:
35
35
  - id: yamllint
@@ -0,0 +1,123 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ Nothing yet.
11
+
12
+ ## [0.5.0] - 2026-08-30
13
+
14
+ ### Added
15
+
16
+ - Full UDP status decoder (`python_rako.protocol`): every documented instruction
17
+ (OFF, FADE_UP/DOWN, SC1–SC4, IDENT, LEVEL_SET, STORE, STOP, CUSTOM_232,
18
+ HOLIDAY, SET_SCENE, FADE, SET_LEVEL), the empirically observed undocumented
19
+ 0x33 level-toggle, and a typed `UnknownStatusMessage` for anything else —
20
+ nothing is silently dropped any more. Messages carry a `MessageOrigin`
21
+ (sensor vs control, derived from flags bit 3) and 10-bit room ids.
22
+ - `StatusListener`: supervised broadcast listener with automatic restart and
23
+ backoff, health reporting, a 300 ms duplicate window (the bridge re-sends
24
+ some keypad events ~200 ms apart), and subscriber fan-out.
25
+ - Echo-verified commands: `Bridge.send_command`, `set_room_scene`,
26
+ `set_room_level`, `set_channel_level`, `fade_up`, `fade_down`, `stop_fade`
27
+ wait for the bridge's own status broadcast to confirm the command took
28
+ effect (typically 150–300 ms), retry once on silence, then raise
29
+ `RakoCommandError`. The echoed message is returned so callers update state
30
+ from what the bridge actually did.
31
+ - `BridgeStateSnapshot`: room/channel state with per-channel provenance
32
+ (`StateSource`) and a `reconcile()` rule that never overwrites a fresher
33
+ level broadcast with a stale scene-derived level, nor resurrects a scene for
34
+ a room whose last event was a fade.
35
+ - `Bridge.get_scene_cache_http()` reads the scene cache over HTTP
36
+ (`scenes.htm`) so polling never contends with the UDP listener socket.
37
+ - **Command pacing** (`python_rako.pacing.CommandQueue`): every command now goes
38
+ through a per-bridge FIFO queue that sends no faster than
39
+ `min_command_interval` (default `DEFAULT_MIN_COMMAND_INTERVAL` = 1.25 s —
40
+ measured on a live bridge: 1.0 s spacing was loss-free, 0.75 s silently
41
+ dropped a command; default = fastest clean interval x 1.25 margin) and never
42
+ overlaps a command still waiting
43
+ for its echo. Requests that arrive too fast are queued, never dropped — the
44
+ bridge silently ignores commands sent too close together. Commands for the
45
+ same `(room, channel)` coalesce: a newer one replaces a waiting one in place,
46
+ keeping its queue position, so a slider drag becomes a single send and the
47
+ superseded callers get the echo of the command that actually ran. Diagnostics
48
+ via `bridge.command_queue.stats` (depth, oldest age, sent/coalesced/failed),
49
+ `drain()` for orderly shutdown, `paced=False` on `send_command`/`set_*` as a
50
+ direct escape hatch, and a runtime-settable `bridge.min_command_interval`.
51
+ A fade and its stop are treated as one gesture: the stop for the target of
52
+ the fade just sent skips the queue and the interval (so a short tap stays
53
+ short), neither half can coalesce the other away, and pacing resumes from the
54
+ stop. New exception `RakoQueueClosedError` (a `RakoCommandError`) for
55
+ commands a closed queue will never send.
56
+ - `scripts/measure_interval.py`: live tool that finds the bridge's real minimum
57
+ safe interval by sending echo-verified off/on pairs at decreasing intervals,
58
+ and recommends a `min_interval` from the result.
59
+ - `Bridge` is now an async context manager; `Bridge.close()` releases sockets.
60
+ - `discover_bridge(timeout=5.0)`; new exceptions `RakoDiscoveryError`,
61
+ `RakoUnsupportedCommandError`, `RakoProtocolError`.
62
+ - `tests_integration/` rewritten on the new state/listener/echo-verify API,
63
+ gated behind `RAKO_LIVE=1` (mutating tests additionally behind
64
+ `RAKO_LIVE_MUTATE=1` and an operator-chosen `RAKO_TEST_ROOM`/
65
+ `RAKO_TEST_CHANNEL`) and the `live` pytest marker, so a plain `pytest` run
66
+ never collects them; `tests/test_state.py` gained a full-pipeline regression
67
+ test replaying every Phase-0 capture through `decode_packet` and
68
+ `BridgeStateSnapshot.apply`. New characterisation tools under `scripts/`
69
+ (`listen.py`, `snapshot.py`, `latency.py`) mirror the Phase 0 tooling
70
+ against the new API for exploring a live bridge by hand.
71
+
72
+ ### Changed
73
+
74
+ - **Behaviour change:** `set_*` methods no longer report success on a UDP
75
+ timeout. With a listener attached they raise `RakoCommandError` when the
76
+ bridge does not confirm; without one they return `None` and warn.
77
+ `BridgeCommanderUDP`/`BridgeCommanderHTTP` are deprecated delegates.
78
+ - `rako.xml` parsing runs off the event loop (`asyncio.to_thread`); the
79
+ unnecessary parse lock was removed.
80
+ - Scene-cache parsing now handles extended (10-bit) room ids correctly.
81
+ - Tooling refresh: ruff/mypy/pre-commit pins updated, Python 3.12/3.13 CI matrix.
82
+
83
+ ### Removed
84
+
85
+ - Dead code: `UDPMessageRateLimit`, `get_predicted_channel_brightness`.
86
+
87
+ ### Fixed
88
+
89
+ - Release pipeline: the release workflow no longer overwrites
90
+ `python_rako/__version__.py` with the raw git tag (which produced an
91
+ invalid Python file). It now verifies the release tag matches
92
+ `__version__.py` and fails loudly on mismatch instead of publishing a
93
+ broken build.
94
+ - Release workflow now publishes to PyPI using **Trusted Publishing**
95
+ (OIDC) instead of long-lived API tokens, with build attestations, a
96
+ pre-publish smoke test (build the wheel, install it into a clean venv,
97
+ import it), and a `workflow_dispatch`-triggered TestPyPI dry run.
98
+ - CI now also builds the sdist/wheel and runs `twine check` on every pull
99
+ request, so packaging breakage is caught before release day, not during
100
+ it.
101
+
102
+ <!--
103
+ When cutting a release, move the entries above into a new section here,
104
+ e.g.:
105
+
106
+ ## [0.5.0] - 2026-09-01
107
+
108
+ ### Fixed
109
+
110
+ - ...
111
+ -->
112
+
113
+ [Unreleased]: https://github.com/SimonLeigh/python-rako/compare/v0.5.0...master
114
+ [0.5.0]: https://github.com/SimonLeigh/python-rako/releases/tag/v0.5.0
115
+
116
+ <!--
117
+ Note for the first tagged release under this process: no git tags exist in
118
+ this repository yet (0.4.1 was released without ever tagging the commit).
119
+ Once v0.5.0 (or whichever version comes first) is tagged, switch the link
120
+ above to a compare link, e.g.:
121
+ [Unreleased]: https://github.com/SimonLeigh/python-rako/compare/v0.5.0...HEAD
122
+ [0.5.0]: https://github.com/SimonLeigh/python-rako/releases/tag/v0.5.0
123
+ -->
@@ -107,18 +107,18 @@ install-dev: clean
107
107
 
108
108
  .PHONY: bump-patch
109
109
  bump-patch: ## Bump patch version (x.y.Z) and commit
110
- @python -c "import re; content = open('python_rako/__version__.py').read().strip(); match = re.search(r'(\d+)\.(\d+)\.(\d+)', content); major, minor, patch = match.groups(); new_version = f'{major}.{minor}.{int(patch) + 1}'; open('python_rako/__version__.py', 'w').write(f'__version__ = \"{new_version}\"\n'); print(f'Bumped version to {new_version}')"
111
- @git add python_rako/__version__.py
112
- @git commit -m "Bump version to $$(python -c "import re; content = open('python_rako/__version__.py').read(); match = re.search(r'\"([^\"]+)\"', content); print(match.group(1))")"
110
+ python scripts/bump_version.py bump patch
111
+ git add python_rako/__version__.py
112
+ git commit -m "Bump version to $$(python scripts/bump_version.py current)"
113
113
 
114
114
  .PHONY: bump-minor
115
115
  bump-minor: ## Bump minor version (x.Y.z) and commit
116
- @python -c "import re; content = open('python_rako/__version__.py').read().strip(); match = re.search(r'(\d+)\.(\d+)\.(\d+)', content); major, minor, patch = match.groups(); new_version = f'{major}.{int(minor) + 1}.0'; open('python_rako/__version__.py', 'w').write(f'__version__ = \"{new_version}\"\n'); print(f'Bumped version to {new_version}')"
117
- @git add python_rako/__version__.py
118
- @git commit -m "Bump version to $$(python -c "import re; content = open('python_rako/__version__.py').read(); match = re.search(r'\"([^\"]+)\"', content); print(match.group(1))")"
116
+ python scripts/bump_version.py bump minor
117
+ git add python_rako/__version__.py
118
+ git commit -m "Bump version to $$(python scripts/bump_version.py current)"
119
119
 
120
120
  .PHONY: bump-major
121
121
  bump-major: ## Bump major version (X.y.z) and commit
122
- @python -c "import re; content = open('python_rako/__version__.py').read().strip(); match = re.search(r'(\d+)\.(\d+)\.(\d+)', content); major, minor, patch = match.groups(); new_version = f'{int(major) + 1}.0.0'; open('python_rako/__version__.py', 'w').write(f'__version__ = \"{new_version}\"\n'); print(f'Bumped version to {new_version}')"
123
- @git add python_rako/__version__.py
124
- @git commit -m "Bump version to $$(python -c "import re; content = open('python_rako/__version__.py').read(); match = re.search(r'\"([^\"]+)\"', content); print(match.group(1))")"
122
+ python scripts/bump_version.py bump major
123
+ git add python_rako/__version__.py
124
+ git commit -m "Bump version to $$(python scripts/bump_version.py current)"