This commit is contained in:
Alexis Métaireau 2024-11-16 11:55:10 +01:00 committed by GitHub
commit 9bbb91f104
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 1927 additions and 164 deletions

View file

@ -1,26 +0,0 @@
name: Check doc
on:
push:
branches: [ 'master', 'stable-*' ]
pull_request:
branches: [ 'master', 'stable-*' ]
jobs:
test_doc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
cache: 'pip'
cache-dependency-path: '**/pyproject.toml'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install tox
- name: Check we can generate documentation
run: tox -e docs

View file

@ -1,4 +1,4 @@
name: Lint & unit tests name: CI
on: on:
push: push:
@ -15,20 +15,15 @@ jobs:
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:
python-version: "3.11" python-version: "3.11"
cache: 'pip' - name: Install uv
cache-dependency-path: '**/pyproject.toml' run: pip install uv
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install tox
- name: Run Lint - name: Run Lint
run: tox -e lint run: |
make lint
test: test:
# Dependency on linting to avoid running our expensive matrix test for nothing
needs: lint needs: lint
runs-on: ubuntu-latest runs-on: ubuntu-latest
# Use postgresql and MariaDB versions of Debian bookworm
services: services:
postgres: postgres:
image: postgres:15 image: postgres:15
@ -56,7 +51,6 @@ jobs:
python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12"] python-version: [3.7, 3.8, 3.9, "3.10", "3.11", "3.12"]
dependencies: [normal] dependencies: [normal]
database: [sqlite] database: [sqlite]
# Test other databases with only a few versions of Python (Debian bullseye has 3.9, bookworm has 3.11)
include: include:
- python-version: 3.9 - python-version: 3.9
dependencies: normal dependencies: normal
@ -70,7 +64,6 @@ jobs:
- python-version: 3.11 - python-version: 3.11
dependencies: normal dependencies: normal
database: mariadb database: mariadb
# Try a few variants with the minimal versions supported
- python-version: 3.7 - python-version: 3.7
dependencies: minimal dependencies: minimal
database: sqlite database: sqlite
@ -97,30 +90,31 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: - name: Install uv
python-version: ${{ matrix.python-version }} run: pip install uv
cache: 'pip' - name: install python from uv
cache-dependency-path: '**/pyproject.toml'
- name: Change dependencies to minimal supported versions
run: sed -i -e 's/>=/==/g; s/~=.*==\(.*\)/==\1/g; s/~=/==/g;' pyproject.toml
if: matrix.dependencies == 'minimal'
- name: Install dependencies
run: | run: |
python -m pip install --upgrade pip uv python install ${{ matrix.python-version }}
python -m pip install tox uv venv --python ${{ matrix.python-version }} .venv
# Run tox using the version of Python in `PATH` - name: Change dependencies to minimal supported versions
- name: Run Tox with sqlite run: sed -i -e '/requires-python/!s/>=/==/g; /requires-python/!s/~=.*==\(.*\)/==\1/g; /requires-python/!s/~=/==/g;' pyproject.toml
run: tox -e py if: matrix.dependencies == 'minimal'
if: matrix.database == 'sqlite' - name: Run tests
run: |
python --version
make test
env: env:
TESTING_SQLALCHEMY_DATABASE_URI: 'sqlite:///budget.db' TESTING_SQLALCHEMY_DATABASE_URI: ${{ matrix.database == 'sqlite' && 'sqlite:///budget.db' || matrix.database == 'postgresql' && 'postgresql+psycopg2://postgres:ihatemoney@localhost:5432/ihatemoney_ci' || 'mysql+pymysql://root:ihatemoney@localhost:3306/ihatemoney_ci' }}
- name: Run Tox with postgresql
run: tox -e py docs:
if: matrix.database == 'postgresql' runs-on: ubuntu-latest
env: steps:
TESTING_SQLALCHEMY_DATABASE_URI: 'postgresql+psycopg2://postgres:ihatemoney@localhost:5432/ihatemoney_ci' - uses: actions/checkout@v3
- name: Run Tox with mariadb - name: Set up Python
run: tox -e py uses: actions/setup-python@v4
if: matrix.database == 'mariadb' with:
env: python-version: "3.11"
TESTING_SQLALCHEMY_DATABASE_URI: 'mysql+pymysql://root:ihatemoney@localhost:3306/ihatemoney_ci' - name: Install uv
run: pip install uv
- name: Build docs
run: make build-docs

View file

@ -5,7 +5,10 @@ This document describes changes between each past release.
## 6.2.0 (unreleased) ## 6.2.0 (unreleased)
- Add support for python 3.12 (#757) - Add support for python 3.12 (#757)
- Remove support for python 3.7
- Replace the black linter by ruff
- Replace virtualenv and pip by uv
- Remove tox
## 6.1.5 (2024-03-19) ## 6.1.5 (2024-03-19)

View file

@ -1,60 +1,40 @@
VIRTUALENV = python3 -m venv VIRTUALENV = uv venv
SPHINX_BUILDDIR = docs/_build
VENV := $(shell realpath $${VIRTUAL_ENV-.venv}) VENV := $(shell realpath $${VIRTUAL_ENV-.venv})
PYTHON = $(VENV)/bin/python3 BIN := uv tool run
PIP := uv pip
PYTHON = $(BIN)/python3
DEV_STAMP = $(VENV)/.dev_env_installed.stamp DEV_STAMP = $(VENV)/.dev_env_installed.stamp
INSTALL_STAMP = $(VENV)/.install.stamp INSTALL_STAMP = $(VENV)/.install.stamp
TEMPDIR := $(shell mktemp -d) TEMPDIR := $(shell mktemp -d)
ZOPFLIPNG := zopflipng ZOPFLIPNG := zopflipng
MAGICK_MOGRIFY := mogrify MAGICK_MOGRIFY := mogrify
.PHONY: all
all: install ## Alias for install
.PHONY: install
install: virtualenv pyproject.toml $(INSTALL_STAMP) ## Install dependencies
$(INSTALL_STAMP):
$(VENV)/bin/pip install -U pip
$(VENV)/bin/pip install -e .
touch $(INSTALL_STAMP)
.PHONY: virtualenv .PHONY: virtualenv
virtualenv: $(PYTHON) virtualenv: $(PYTHON)
$(PYTHON): $(PYTHON):
$(VIRTUALENV) $(VENV) $(VIRTUALENV) $(VENV)
.PHONY: install-dev
install-dev: virtualenv pyproject.toml $(INSTALL_STAMP) $(DEV_STAMP) ## Install development dependencies
$(DEV_STAMP): $(PYTHON)
$(VENV)/bin/pip install -Ue .[dev]
touch $(DEV_STAMP)
.PHONY: remove-install-stamp
remove-install-stamp:
rm $(INSTALL_STAMP)
.PHONY: update
update: remove-install-stamp install ## Update the dependencies
.PHONY: serve .PHONY: serve
serve: install build-translations ## Run the ihatemoney server serve: build-translations ## Run the ihatemoney server
@echo 'Running ihatemoney on http://localhost:5000' @echo 'Running ihatemoney on http://localhost:5000'
FLASK_DEBUG=1 FLASK_APP=ihatemoney.wsgi $(VENV)/bin/flask run --host=0.0.0.0 FLASK_DEBUG=1 FLASK_APP=ihatemoney.wsgi uv run flask run --host=0.0.0.0
.PHONY: test .PHONY: test
test: install-dev ## Run the tests test:
$(VENV)/bin/tox uv run --extra dev --extra database pytest .
.PHONY: black .PHONY: lint
black: install-dev ## Run the tests lint:
$(VENV)/bin/black --target-version=py37 . uv tool run ruff check .
uv tool run vermin --no-tips --violations -t=3.8- .
.PHONY: isort .PHONY: format
isort: install-dev ## Run the tests format:
$(VENV)/bin/isort . uv tool run ruff format .
.PHONY: release .PHONY: release
release: install-dev ## Release a new version (see https://ihatemoney.readthedocs.io/en/latest/contributing.html#how-to-release) release: # Release a new version (see https://ihatemoney.readthedocs.io/en/latest/contributing.html#how-to-release)
$(VENV)/bin/fullrelease uv run --extra dev fullreleas
.PHONY: compress-showcase .PHONY: compress-showcase
compress-showcase: compress-showcase:
@ -72,27 +52,30 @@ compress-assets: compress-showcase ## Compress static assets
.PHONY: build-translations .PHONY: build-translations
build-translations: ## Build the translations build-translations: ## Build the translations
$(VENV)/bin/pybabel compile -d ihatemoney/translations uv run --extra dev pybabel compile -d ihatemoney/translations
.PHONY: extract-translations .PHONY: extract-translations
extract-translations: ## Extract new translations from source code extract-translations: ## Extract new translations from source code
$(VENV)/bin/pybabel extract --add-comments "I18N:" --strip-comments --omit-header --no-location --mapping-file ihatemoney/babel.cfg -o ihatemoney/messages.pot ihatemoney uv run --extra dev pybabel extract --add-comments "I18N:" --strip-comments --omit-header --no-location --mapping-file ihatemoney/babel.cfg -o ihatemoney/messages.pot ihatemoney
$(VENV)/bin/pybabel update -i ihatemoney/messages.pot -d ihatemoney/translations/ uv run --extra dev pybabel update -i ihatemoney/messages.pot -d ihatemoney/translations/
.PHONY: create-database-revision .PHONY: create-database-revision
create-database-revision: ## Create a new database revision create-database-revision: ## Create a new database revision
@read -p "Please enter a message describing this revision: " rev_message; \ @read -p "Please enter a message describing this revision: " rev_message; \
$(PYTHON) -m ihatemoney.manage db migrate -d ihatemoney/migrations -m "$${rev_message}" uv run python -m ihatemoney.manage db migrate -d ihatemoney/migrations -m "$${rev_message}"
.PHONY: create-empty-database-revision .PHONY: create-empty-database-revision
create-empty-database-revision: ## Create an empty database revision create-empty-database-revision: ## Create an empty database revision
@read -p "Please enter a message describing this revision: " rev_message; \ @read -p "Please enter a message describing this revision: " rev_message; \
$(PYTHON) -m ihatemoney.manage db revision -d ihatemoney/migrations -m "$${rev_message}" uv run python -m ihatemoney.manage db revision -d ihatemoney/migrations -m "$${rev_message}"
.PHONY: clean .PHONY: clean
clean: ## Destroy the virtual environment clean: ## Destroy the virtual environment
rm -rf .venv rm -rf .venv
build-docs:
uv run --extra doc sphinx-build -a -n -b html -d docs/_build/doctrees docs docs/_build/html
.PHONY: help .PHONY: help
help: ## Show the help indications help: ## Show the help indications
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

View file

@ -22,7 +22,7 @@ highly encouraged to do so.
## Requirements ## Requirements
- **Python**: version 3.7 to 3.12. - **Python**: version 3.8 to 3.12.
- **Backends**: SQLite, PostgreSQL, MariaDB (version 10.3.2 or above), - **Backends**: SQLite, PostgreSQL, MariaDB (version 10.3.2 or above),
Memory. Memory.

View file

@ -90,7 +90,6 @@ def get_billform_for(project, set_default=True, **kwargs):
class CommaDecimalField(DecimalField): class CommaDecimalField(DecimalField):
"""A class to deal with comma in Decimal Field""" """A class to deal with comma in Decimal Field"""
def process_formdata(self, value): def process_formdata(self, value):

View file

@ -103,7 +103,7 @@ def validate_configuration(app):
if "MAIL_DEFAULT_SENDER" not in app.config: if "MAIL_DEFAULT_SENDER" not in app.config:
app.config["MAIL_DEFAULT_SENDER"] = default_settings.DEFAULT_MAIL_SENDER app.config["MAIL_DEFAULT_SENDER"] = default_settings.DEFAULT_MAIL_SENDER
if type(app.config["MAIL_DEFAULT_SENDER"]) == tuple: if type(app.config["MAIL_DEFAULT_SENDER"]) is tuple:
(name, address) = app.config["MAIL_DEFAULT_SENDER"] (name, address) = app.config["MAIL_DEFAULT_SENDER"]
app.config["MAIL_DEFAULT_SENDER"] = f"{name} <{address}>" app.config["MAIL_DEFAULT_SENDER"] = f"{name} <{address}>"
warnings.warn( warnings.warn(

View file

@ -9,7 +9,6 @@ from ihatemoney.tests.common.ihatemoney_testcase import IhatemoneyTestCase
class TestAPI(IhatemoneyTestCase): class TestAPI(IhatemoneyTestCase):
"""Tests the API""" """Tests the API"""
def api_create( def api_create(

View file

@ -1030,9 +1030,7 @@ class TestBudget(IhatemoneyTestCase):
assert """<thead> assert """<thead>
<tr> <tr>
<th>Project</th> <th>Project</th>
<th>Number of participants</th>""" in resp.data.decode( <th>Number of participants</th>""" in resp.data.decode("utf-8")
"utf-8"
)
def test_dashboard_project_deletion(self): def test_dashboard_project_deletion(self):
self.post_project("raclette") self.post_project("raclette")

View file

@ -84,7 +84,6 @@ def flash_email_error(error_message, category="danger"):
class Redirect303(HTTPException, RoutingException): class Redirect303(HTTPException, RoutingException):
"""Raise if the map requests a redirect. This is for example the case if """Raise if the map requests a redirect. This is for example the case if
`strict_slashes` are activated and an url that requires a trailing slash. `strict_slashes` are activated and an url that requires a trailing slash.
@ -102,7 +101,6 @@ class Redirect303(HTTPException, RoutingException):
class PrefixedWSGI(object): class PrefixedWSGI(object):
""" """
Wrap the application in this middleware and configure the Wrap the application in this middleware and configure the
front-end server to add these headers, to let you quietly bind front-end server to add these headers, to let you quietly bind

View file

@ -8,6 +8,7 @@ Basically, this blueprint takes care of the authentication and provides
some shortcuts to make your life better when coding (see `pull_project` some shortcuts to make your life better when coding (see `pull_project`
and `add_project_id` for a quick overview) and `add_project_id` for a quick overview)
""" """
import datetime import datetime
from functools import wraps from functools import wraps
import hashlib import hashlib

View file

@ -5,6 +5,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "ihatemoney" name = "ihatemoney"
version = "6.2.0.dev0" version = "6.2.0.dev0"
requires-python = ">=3.8"
description = "A simple shared budget manager web application." description = "A simple shared budget manager web application."
readme = "README.md" readme = "README.md"
license = {file = "LICENSE"} license = {file = "LICENSE"}
@ -15,7 +16,6 @@ keywords = ["web", "budget"]
classifiers = [ classifiers = [
"Programming Language :: Python", "Programming Language :: Python",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.10",
@ -34,7 +34,8 @@ dependencies = [
"Flask-Cors>=3.0.8,<4", "Flask-Cors>=3.0.8,<4",
"Flask-Limiter>=2.6,<3", "Flask-Limiter>=2.6,<3",
"Flask-Mail>=0.9.1,<1", "Flask-Mail>=0.9.1,<1",
"Flask-Migrate>=2.5.3,<5", # Not following semantic versioning (e.g. https://github.com/miguelgrinberg/flask-migrate/commit/1af28ba273de6c88544623b8dc02dd539340294b) # Not following semantic versioning (e.g. https://github.com/miguelgrinberg/flask-migrate/commit/1af28ba273de6c88544623b8dc02dd539340294b)
"Flask-Migrate>=2.5.3,<5",
"Flask-RESTful>=0.3.9,<1", "Flask-RESTful>=0.3.9,<1",
"Flask-SQLAlchemy>=2.4,<3", "Flask-SQLAlchemy>=2.4,<3",
"Flask-Talisman>=0.8,<2", "Flask-Talisman>=0.8,<2",
@ -47,8 +48,10 @@ dependencies = [
"qrcode>=7.1,<8", "qrcode>=7.1,<8",
"requests>=2.25,<3", "requests>=2.25,<3",
"SQLAlchemy-Continuum>=1.3.12,<2", "SQLAlchemy-Continuum>=1.3.12,<2",
"SQLAlchemy>=1.3.0,<1.5", # New 1.4 changes API, see #728 # New 1.4 changes API, see #728
"SQLAlchemy>=1.3.0,<1.5",
"python-dateutil", "python-dateutil",
"pytest-libfaketime[dev]>=0.1.3",
] ]
[project.optional-dependencies] [project.optional-dependencies]
@ -57,19 +60,16 @@ database = [
"psycopg2-binary>=2.9.2,<3", "psycopg2-binary>=2.9.2,<3",
"PyMySQL>=0.9,<1.1", "PyMySQL>=0.9,<1.1",
] ]
dev = [ dev = [
"black==23.3.0", "ruff==0.6.8",
"flake8==5.0.4", "flake8==5.0.4",
"isort==5.11.5", "isort==5.11.5",
"vermin==1.5.2", "vermin==1.5.2",
"pytest>=6.2.5", "pytest>=6.2.5",
"pytest-flask>=1.2.0", "pytest-flask>=1.2.0",
"pytest-libfaketime>=0.1.2",
"tox>=3.14.6",
"zest.releaser>=6.20.1", "zest.releaser>=6.20.1",
"libfaketime>=2.1.0",
] ]
doc = [ doc = [
"Sphinx>=7.0.1,<8", "Sphinx>=7.0.1,<8",
"docutils==0.20.1", "docutils==0.20.1",
@ -107,3 +107,7 @@ include = [
"README.md", "README.md",
"SECURITY.md", "SECURITY.md",
] ]
[tool.ruff]
exclude = ["ihatemoney/migrations"]

41
tox.ini
View file

@ -1,41 +0,0 @@
[tox]
isolated_build = true
envlist = py312,py311,py310,py39,py38,py37,lint,docs
skip_missing_interpreters = True
[testenv]
passenv = TESTING_SQLALCHEMY_DATABASE_URI
commands =
python --version
py.test --pyargs ihatemoney.tests {posargs}
deps =
-e.[database,dev]
# To be sure we are importing ihatemoney pkg from pip-installed version
changedir = /tmp
[testenv:lint]
commands =
black --check --target-version=py37 .
isort --check --profile black .
flake8 ihatemoney
vermin --no-tips --violations -t=3.7- .
deps =
-e.[dev]
changedir = {toxinidir}
[testenv:docs]
commands =
sphinx-build -a -n -b html -d docs/_build/doctrees docs docs/_build/html
deps =
-e.[doc]
changedir = {toxinidir}
[flake8]
exclude = migrations
max_line_length = 100
extend-ignore =
# See https://github.com/PyCQA/pycodestyle/issues/373
E203,

1851
uv.lock Normal file

File diff suppressed because it is too large Load diff