Compare commits

...

2 Commits

Author SHA1 Message Date
Mario Fetka 3f4ba32dbb Imported Upstream version 3.1.0 2023-07-01 11:55:30 +02:00
Mario Fetka 8a6603ece7 Imported Upstream version 3.1.0 2023-07-01 11:54:39 +02:00
18 changed files with 142 additions and 111 deletions

57
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,57 @@
name: CI
on:
pull_request: {}
push: {}
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install tox tox-gh-actions
- run: tox -e lint
check-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install tox tox-gh-actions
- run: tox -e check-docs
test:
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
experimental: [false]
include:
- python-version: "3.12-dev"
experimental: true
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip setuptools
python3 -m pip install tox tox-gh-actions
- run: tox

View File

@ -1,37 +0,0 @@
language: python
dist: xenial
python:
- "3.6"
- "3.7"
- "3.8"
# TODO add 3.9
- "3.9-dev"
install: pip install tox-travis tox tox-venv
# Used by the `test` stage.
script: tox
stages:
- test
- lint
jobs:
allow_failures:
- python: "3.9-dev"
include:
# The `test` stage using the `python` matrix defined above
# is included implicitly.
- stage: lint
name: "Code Linting"
python: "3.7"
script: TOXENV=lint tox
- stage: check-docs
name: "Docs check"
python: "3.7"
script: TOXENV=check-docs tox

View File

@ -9,7 +9,7 @@ lint:
.PHONY: test
test:
coverage run -m py.test
coverage run -m pytest
coverage report
.PHONY: clean
@ -49,15 +49,11 @@ check-docs:
deb-local: clean sdist
docker build -t afancontrol-debuild -f ./Dockerfile.debian .
docker run -it --rm \
-e DEBFULLNAME="`git config --global user.name`" \
-e DEBEMAIL="`git config --global user.email`" \
-v `pwd`/dist:/afancontrol/dist \
-v `pwd`/debian:/afancontrol/debian \
afancontrol-debuild sh -ex -c '\
tar xaf /afancontrol/dist/afancontrol-*.tar.gz --strip 1; \
dch -v `python3 setup.py --version` -b --distribution=unstable; \
debuild -us -uc -b; \
cp debian/changelog /afancontrol/debian/; \
cd ../; \
ls -alh; \
mkdir /afancontrol/dist/debian; \

View File

@ -5,8 +5,8 @@ afancontrol
:target: https://pypi.python.org/pypi/afancontrol/
:alt: Latest Version
.. image:: https://img.shields.io/travis/KostyaEsmukov/afancontrol.svg?style=flat-square
:target: https://travis-ci.org/KostyaEsmukov/afancontrol
.. image:: https://img.shields.io/github/workflow/status/KostyaEsmukov/afancontrol/CI?style=flat-square
:target: https://github.com/KostyaEsmukov/afancontrol/actions
:alt: Build Status
.. image:: https://img.shields.io/github/license/KostyaEsmukov/afancontrol.svg?style=flat-square

16
debian/changelog vendored
View File

@ -1,3 +1,19 @@
afancontrol (3.1.0-1) unstable; urgency=medium
[ Juha Yrjölä ]
* Support glob expansion with fans (#9)
[ Kostya Esmukov ]
* Drop Python 3.6 support, add 3.11
-- Kostya Esmukov <kostya@esmukov.ru> Mon, 28 Nov 2022 00:11:43 +0200
afancontrol (3.0.0-2) unstable; urgency=medium
* Bump debhelper compat to 13
-- Kostya Esmukov <kostya@esmukov.ru> Mon, 02 Aug 2021 19:19:34 +0000
afancontrol (3.0.0-1) unstable; urgency=medium
* Drop support for prometheus-client < 0.1.0 (debian stretch)

1
debian/compat vendored
View File

@ -1 +0,0 @@
9

30
debian/control vendored
View File

@ -2,37 +2,29 @@ Source: afancontrol
Section: utils
Priority: optional
Maintainer: Kostya Esmukov <kostya@esmukov.ru>
Build-Depends: debhelper (>= 9),
Build-Depends: debhelper-compat (= 13),
dh-python,
dh-systemd,
python3-all,
python3-click,
python3-prometheus-client (>= 0.1.0),
python3-pytest,
python3-requests,
python3-serial,
python3-setuptools
Build-Depends-Indep: python3-pytest,
python3-requests,
python3-click,
python3-prometheus-client (>= 0.1.0),
python3-serial
Standards-Version: 3.9.8
Homepage: https://github.com/KostyaEsmukov/afancontrol
X-Python3-Version: >= 3.5
#Vcs-Git: https://anonscm.debian.org/git/python-modules/packages/python3-afancontrol.git
#Vcs-Browser: https://anonscm.debian.org/cgit/python-modules/packages/python3-afancontrol.git/
#Testsuite: autopkgtest-pkg-python
Package: afancontrol
Architecture: all
Depends: ${python3:Depends},
${misc:Depends},
hddtemp,
Depends: hddtemp,
lm-sensors,
python3-click,
python3-pkg-resources,
python3-prometheus-client (>= 0.1.0),
python3-serial
Suggests: freeipmi-tools,
python3-serial,
${misc:Depends},
${python3:Depends}
Suggests: freeipmi-tools
Description: Advanced Fan Control program (Python 3)
afancontrol is an Advanced Fan Control program, which controls PWM
fans according to the current temperatures of the system components.
.
This package installs the library for Python 3.

2
debian/rules vendored Normal file → Executable file
View File

@ -9,4 +9,4 @@ export PYBUILD_TEST_PYTEST=1
export PYBUILD_TEST_ARGS={dir}/tests/
%:
dh $@ --with systemd,python3 --buildsystem=pybuild
dh $@ --with python3 --buildsystem=pybuild

View File

@ -25,13 +25,8 @@ per-file-ignores =
src/afancontrol/config.py:C901
[isort]
; https://github.com/timothycrosley/isort#multi-line-output-modes
multi_line_output = 3
; https://github.com/ambv/black#how-black-wraps-lines
include_trailing_comma = True
force_grid_wrap = 0
combine_as_imports = True
line_length = 88
profile = black
[metadata]
author = Kostya Esmukov
@ -45,10 +40,6 @@ classifier =
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Topic :: System :: Hardware
Topic :: System :: Monitoring
Topic :: System :: Systems Administration
@ -76,7 +67,7 @@ install_requires =
package_dir =
= src
packages = find:
python_requires = >=3.6
python_requires = >=3.7
[options.entry_points]
console_scripts =
@ -88,15 +79,16 @@ arduino =
metrics =
prometheus-client>=0.1.0
dev =
black==20.8b1
coverage==5.3
flake8==3.8.4
isort==5.5.4
mypy==0.782
pytest==6.1.0
black==22.10.0
coverage==6.5.0
flake8==5.0.4
isort==5.10.1
mypy==0.990
pytest==7.2.0
sphinx==4.3.2
vcrpy==4.2.1
requests
sphinx==3.2.1
wheel
types-requests
[options.packages.find]
where = src

View File

@ -1 +1 @@
__version__ = "3.0.0"
__version__ = "3.1.0"

View File

@ -1,4 +1,5 @@
import configparser
import glob
from typing import Any, Generic, Iterator, Optional, Type, TypeVar, Union, overload
T = TypeVar("T", bound=str)
@ -127,3 +128,12 @@ class ConfigParserSection(Generic[T]):
"[%s] %r option is expected to be set" % (self.__section.name, option)
)
return res
def expand_glob(path: str):
matches = glob.glob(path)
if not matches:
return path # a FileNotFoundError will be raised on a first read attempt
if len(matches) == 1:
return matches[0]
raise ValueError("Expected glob to expand to a single path, got %r" % (matches,))

View File

@ -187,7 +187,8 @@ def fantest(
elif fan_type == "arduino":
if not arduino_serial_url:
arduino_serial_url = click.prompt(
"\n%s\nArduino Serial url" % HELP_ARDUINO_SERIAL_URL, type=str
"\n%s\nArduino Serial url" % HELP_ARDUINO_SERIAL_URL,
type=str, # type: ignore
)
# typeshed currently specifies `Optional[str]` for `default`,
@ -197,17 +198,19 @@ def fantest(
# Hence the `type: ignore`.
arduino_baudrate = click.prompt( # type: ignore
"\n%s\nBaudrate" % HELP_ARDUINO_BAUDRATE,
type=int,
type=int, # type: ignore
default=str(arduino_baudrate),
show_default=True,
)
if not arduino_pwm_pin and arduino_pwm_pin != 0:
arduino_pwm_pin = click.prompt(
"\n%s\nArduino PWM pin" % HELP_ARDUINO_PWM_PIN, type=int
"\n%s\nArduino PWM pin" % HELP_ARDUINO_PWM_PIN,
type=int, # type: ignore
)
if not arduino_tacho_pin and arduino_tacho_pin != 0:
arduino_tacho_pin = click.prompt(
"\n%s\nArduino Tachometer pin" % HELP_ARDUINO_TACHO_PIN, type=int
"\n%s\nArduino Tachometer pin" % HELP_ARDUINO_TACHO_PIN,
type=int, # type: ignore
)
assert arduino_serial_url is not None

View File

@ -1,11 +1,13 @@
import abc
from typing import NewType, Type
from typing import NewType, Tuple, Type
PWMValue = NewType("PWMValue", int) # [0..255]
FanValue = NewType("FanValue", int)
class _SlotsReprMixin:
__slots__: Tuple[str, ...]
def __eq__(self, other):
if isinstance(other, type(self)):
for attr in self.__slots__:

View File

@ -1,7 +1,7 @@
from pathlib import Path
from typing import NewType
from afancontrol.configparser import ConfigParserSection
from afancontrol.configparser import ConfigParserSection, expand_glob
from afancontrol.pwmfan.base import (
BaseFanPWMRead,
BaseFanPWMWrite,
@ -18,7 +18,7 @@ class LinuxFanSpeed(BaseFanSpeed):
__slots__ = ("_fan_input",)
def __init__(self, fan_input: FanInputDevice) -> None:
self._fan_input = Path(fan_input)
self._fan_input = Path(expand_glob(fan_input))
@classmethod
def from_configparser(cls, section: ConfigParserSection) -> BaseFanSpeed:
@ -35,7 +35,7 @@ class LinuxFanPWMRead(BaseFanPWMRead):
min_pwm = PWMValue(0)
def __init__(self, pwm: PWMDevice) -> None:
self._pwm = Path(pwm)
self._pwm = Path(expand_glob(pwm))
@classmethod
def from_configparser(cls, section: ConfigParserSection) -> BaseFanPWMRead:
@ -51,8 +51,9 @@ class LinuxFanPWMWrite(BaseFanPWMWrite):
read_cls = LinuxFanPWMRead
def __init__(self, pwm: PWMDevice) -> None:
self._pwm = Path(pwm)
self._pwm_enable = Path(pwm + "_enable")
base = expand_glob(pwm)
self._pwm = Path(base)
self._pwm_enable = Path(base + "_enable")
@classmethod
def from_configparser(cls, section: ConfigParserSection) -> BaseFanPWMWrite:

View File

@ -1,21 +1,11 @@
import glob
import re
from pathlib import Path
from typing import Optional, Tuple
from afancontrol.configparser import ConfigParserSection
from afancontrol.configparser import ConfigParserSection, expand_glob
from afancontrol.temp.base import Temp, TempCelsius
def _expand_glob(path: str):
matches = glob.glob(path)
if not matches:
return path # a FileNotFoundError will be raised on a first read attempt
if len(matches) == 1:
return matches[0]
raise ValueError("Expected glob to expand to a single path, got %r" % (matches,))
class FileTemp(Temp):
def __init__(
self,
@ -33,7 +23,7 @@ class FileTemp(Temp):
# /sys/devices/pci0000:00/0000:00:01.3/[...]/hwmon/hwmon*/temp1_input
# The `hwmon*` might change after reboot, but it is always a single
# directory within the device.
temp_path = _expand_glob(temp_path + "_input")
temp_path = expand_glob(temp_path + "_input")
temp_path = re.sub(r"_input$", "", temp_path)
self._temp_input = Path(temp_path + "_input")

View File

@ -6,7 +6,8 @@ import pytest
from click.testing import CliRunner
from afancontrol import daemon
from afancontrol.daemon import PidFile, Signals, daemon as main
from afancontrol.daemon import PidFile, Signals
from afancontrol.daemon import daemon as main
def test_main_smoke(temp_path):

View File

@ -10,9 +10,9 @@ from afancontrol.fantest import (
CSVMeasurementsOutput,
HumanMeasurementsOutput,
MeasurementsOutput,
fantest as main,
run_fantest,
)
from afancontrol.fantest import fantest as main
from afancontrol.fantest import run_fantest
from afancontrol.pwmfan import (
BaseFanPWMRead,
BaseFanPWMWrite,

11
tox.ini
View File

@ -1,5 +1,5 @@
[tox]
envlist=py{36,37,38,39,310}{,-arduino,-metrics},lint,check-docs
envlist=py{37,38,39,310,311,312}{,-arduino,-metrics},lint,check-docs
[testenv]
extras =
@ -12,6 +12,15 @@ commands = make test
; sources to the working dir by default.
usedevelop = True
[gh-actions]
python =
3.7: py37
3.8: py38
3.9: py39
3.10: py310
3.11: py311
3.12: py312
[testenv:lint]
extras =
arduino