Skip to content

Commit 4f774c5

Browse files
authored
Merge pull request #446 from JnyJny/uv
The Great UV / GitHub Action Disruption
2 parents ae9841a + 420d56e commit 4f774c5

File tree

13 files changed

+1751
-2831
lines changed

13 files changed

+1751
-2831
lines changed

.github/workflows/pytest-linux.yaml

Lines changed: 0 additions & 37 deletions
This file was deleted.

.github/workflows/pytest-macos.yaml

Lines changed: 0 additions & 32 deletions
This file was deleted.

.github/workflows/pytest-windows.yaml

Lines changed: 0 additions & 34 deletions
This file was deleted.

.github/workflows/release.yaml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: Test and Publish Release
2+
3+
on:
4+
push:
5+
branches:
6+
- testing
7+
tags:
8+
- 'v*-test'
9+
- 'v[0-9]+.[0-9]+.[0-9]+'
10+
workflow_dispatch:
11+
12+
permissions:
13+
contents: read
14+
id-token: write
15+
16+
jobs:
17+
test:
18+
name: Test on Linux/MacOS/Window
19+
runs-on: ${{ matrix.os }}
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
os: [ubuntu-latest, macos-latest, windows-latest]
24+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
25+
26+
steps:
27+
- uses: actions/checkout@v4
28+
29+
- name: Install uv and set Python version.
30+
uses: astral-sh/setup-uv@v5
31+
with:
32+
version: "0.7.5"
33+
python-version: ${{ matrix.python-version }}
34+
35+
- name: Install libusb on Linux.
36+
if: runner.os == 'Linux'
37+
run: |
38+
sudo apt-get update
39+
sudo apt-get install -y libusb-1.0-0-dev libudev-dev
40+
41+
- name: Run tests - ${{ matrix.python-version }} - ${{ matrix.os }}
42+
run: |
43+
uv run --all-extras pytest
44+
45+
publish:
46+
name: Build & Publish
47+
needs: test
48+
if: |
49+
github.ref_type == 'tag' &&
50+
startsWith(github.ref, 'refs/tags/v') &&
51+
!endsWith(github.ref, '-test') &&
52+
success()
53+
runs-on: ubuntu-latest
54+
environment:
55+
name: pypi
56+
url: https://pypi.org/project/busylight-for-humans
57+
58+
steps:
59+
- uses: actions/checkout@v4
60+
61+
- name: Install uv and set Python version.
62+
uses: astral-sh/setup-uv@v5
63+
with:
64+
version: "0.7.5"
65+
python-version: 3.9
66+
67+
- name: Build package.
68+
run: |
69+
uv build
70+
71+
- name: Publish to PyPI
72+
uses: pypa/gh-action-pypi-publish@release/v1

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ tst.py
1212
htmlcov
1313
*token
1414
.python-version
15-
15+
.direnv/
1616
.vscode/
17+
.envrc

README.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,25 +86,33 @@ $ python3 -m pip install busylight-for-humans[webapi]
8686

8787
## Development Install
8888

89-
I use the tool [poetry][poetry-docs] to manage various aspects of this project, including:
90-
- dependencies
89+
I am in the process of switching from [poetry][poetry-docs] to the new hotness [uv][uv-docs].
90+
91+
Like `poetry`, I use `uv` for:
92+
- dependency management
9193
- pytest configuration
9294
- versioning
9395
- optional dependencies
9496
- virtual environment creation
9597
- building packages
9698
- publishing packages to PyPi
9799

100+
98101
```console
99-
$ python3 -m pip install poetry
102+
$ python3 -m pip install uv
100103
$ cd path/to/busylight
101-
$ poetry shell
102-
<venv> $ poetry install -E webapi
104+
$ uv venv .venv
105+
$ source .venv/bin/activate
106+
<venv> $ uv sync --all-extras
103107
<venv> $ which busylight
104108
<venv> $ which busyserve
109+
<venv> $ pytest
105110
```
106111

107-
After installing into the virtual environment, the project is now available in editable mode. Changes made in the source will be reflected in the runtime behavior when running in the poetry initiated shell.
112+
After installing into the virtual environment, the project is now
113+
available in editable mode. Changes made in the source will be
114+
reflected in the runtime behavior when running in the poetry initiated
115+
shell.
108116

109117
## Linux Post-Install Activities
110118

@@ -271,7 +279,6 @@ manager.off()
271279

272280
[0]: https://github.com/JnyJny/busylight
273281

274-
275282
<!-- doc links -->
276283
[2]: https://github.com/JnyJny/busylight/blob/master/docs/devices/agile_innovative.md
277284
[3]: https://github.com/JnyJny/busylight/blob/master/docs/devices/embrava.md
@@ -287,12 +294,15 @@ manager.off()
287294
[HELP]: https://github.com/JnyJny/busylight/blob/master/docs/busylight.1.md
288295
[WEBAPI]: https://github.com/JnyJny/busylight/blob/master/docs/busylight_api.pdf
289296

297+
290298
<!-- [DEMO]: demo/demo-updated.gif -->
291299
[DEMO]: https://github.com/JnyJny/busylight/blob/master/docs/assets/HerdOfLights.png
292300

301+
<!-- Miscellaneous -->
293302
[BASICAUTH]: https://en.wikipedia.org/wiki/Basic_access_authentication
294303
[UDEV]: https://en.wikipedia.org/wiki/Udev
295-
304+
[poetry-docs]: https://python-poetry.org/docs/
305+
[uv-docs]: https://docs.astral.sh/uv/
296306
[todbot]: https://github.com/todbot
297307
[thingm]: https://thingm.com
298308

@@ -304,5 +314,4 @@ manager.off()
304314
[license]: https://img.shields.io/pypi/l/busylight-for-humans
305315
[dependencies]: https://img.shields.io/librariesio/github/JnyJny/busylight
306316
[monthly-downloads]: https://img.shields.io/pypi/dm/busylight-for-humans
307-
[poetry-docs]: https://python-poetry.org/docs/
308317
[visits]: https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2FJnyJny%2Fbusylight&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=Visits&edge_flat=false

busylight/__main__.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
"""Busylight command-line interface
2-
3-
"""
1+
"""Busylight command-line interface"""
42

53
from dataclasses import dataclass, field
64
from os import environ
@@ -65,7 +63,6 @@ def precommand_callback(
6563
False,
6664
"--debug",
6765
"-D",
68-
is_flag=True,
6966
help="Enable debugging output.",
7067
),
7168
targets: str = typer.Option(
@@ -98,7 +95,6 @@ def precommand_callback(
9895
version: bool = typer.Option(
9996
False,
10097
"--version",
101-
is_flag=True,
10298
is_eager=True,
10399
callback=report_version,
104100
),
@@ -208,7 +204,9 @@ def rainbow_lights(
208204
) -> None:
209205
"""Display rainbow colors on specified lights."""
210206
logger.info("applying rainbow effect")
211-
rainbow = Effects.for_name("spectrum")(speed.duty_cycle / 4, scale=ctx.obj.dim, count=count)
207+
rainbow = Effects.for_name("spectrum")(
208+
speed.duty_cycle / 4, scale=ctx.obj.dim, count=count
209+
)
212210

213211
try:
214212
manager.apply_effect(rainbow, ctx.obj.lights, timeout=ctx.obj.timeout)
@@ -296,7 +294,6 @@ def list_available_lights(
296294
False,
297295
"--verbose",
298296
"-v",
299-
is_flag=True,
300297
help="Shows additional information about each light.",
301298
),
302299
) -> None:
@@ -333,7 +330,6 @@ def list_supported_lights(
333330
False,
334331
"--verbose",
335332
"-v",
336-
is_flag=True,
337333
help="Print vendor and product identifiers.",
338334
),
339335
) -> None:
@@ -394,7 +390,7 @@ def generate_udev_rules(
394390

395391
@webcli.command()
396392
def serve_http_api(
397-
debug: bool = typer.Option(False, "--debug", "-D", is_flag=True),
393+
debug: bool = typer.Option(False, "--debug", "-D"),
398394
host: str = typer.Option(
399395
"0.0.0.0",
400396
"--host",

busylight/lights/hid.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
"""
2-
"""
1+
""" """
32

4-
from typing import Dict, List
3+
from typing import Dict, List, Optional
54

65
import hid
76

8-
97
# Why This File Exists.
108
#
119
# The 'apmorton/pyhidapi' package and 'trezor/cython-hidapi' packages both
@@ -45,7 +43,7 @@ def open(
4543
self,
4644
vendor_id: int,
4745
product_id: int,
48-
serial_number: str = None,
46+
serial_number: Optional[str] = None,
4947
) -> None:
5048
"""Open the first device matching vendor_id and product_id or serial number."""
5149
if self._handle:
@@ -69,7 +67,7 @@ def close(self) -> None:
6967
except AttributeError:
7068
raise IOError("device not open") from None
7169

72-
def read(self, nbytes: int, timeout_ms: int = None) -> List[int]:
70+
def read(self, nbytes: int, timeout_ms: Optional[int] = None) -> List[int]:
7371
"""Read nbytes from the device, returns a list of ints."""
7472
try:
7573
return self._handle.read(nbytes, timeout_ms)

0 commit comments

Comments
 (0)