diff --git a/.github/workflows/dependency-sync.yml b/.github/workflows/dependency-sync.yml new file mode 100644 index 0000000..e859328 --- /dev/null +++ b/.github/workflows/dependency-sync.yml @@ -0,0 +1,25 @@ +name: Dependency sync + +on: + pull_request: + push: + branches: + - main + +jobs: + check-dependency-sync: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Setup uv + uses: astral-sh/setup-uv@v3 + + - name: Check pyproject/requirements synchronization + run: ./scripts/check_requirements_sync.sh diff --git a/README.md b/README.md index ae34fad..cedea52 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,25 @@ Este projeto é um chat em tempo real desenvolvido em Python utilizando a biblio --- -## Requisitos -Antes de executar o projeto, certifique-se de ter o Python instalado e instale as dependências necessárias: +## Dependências (fonte oficial) e travamento de versões +A **única fonte de verdade** das dependências diretas do projeto é o arquivo `pyproject.toml` na seção `[project.dependencies]`. + +### Fluxo oficial +1. **Edite dependências diretas** em `pyproject.toml`. +2. **Regenere o lock de runtime** em `requirements.txt` com: + +```bash +uv pip compile pyproject.toml --python-version 3.10 --no-header -o requirements.txt +``` + +3. **Sincronize o ambiente local** com as versões travadas: ```bash pip install -r requirements.txt ``` +> O arquivo `requirements.txt` é gerado automaticamente a partir do `pyproject.toml` e não deve ser alterado manualmente. + ## Como Executar ### Iniciar o Chat Para iniciar a interface do chat, execute o seguinte comando: diff --git a/pyproject.toml b/pyproject.toml index ecbc516..ddc2b81 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ authors = [ { name = "Marcelo Santos", email = "a79433@ualg.pt" } ] dependencies = [ - "flet==0.27.5" + "flet==0.27.5", ] [tool.flet] @@ -28,14 +28,3 @@ copyright = "Copyright (C) 2025 by Marcelo Santos" [tool.flet.app] path = "src" - -[tool.uv] -dev-dependencies = [ - "flet[all]==0.27.5", -] - -[tool.poetry] -package-mode = false - -[tool.poetry.group.dev.dependencies] -flet = {extras = ["all"], version = "0.27.5"} \ No newline at end of file diff --git a/scripts/check_requirements_sync.sh b/scripts/check_requirements_sync.sh new file mode 100755 index 0000000..6f32d7f --- /dev/null +++ b/scripts/check_requirements_sync.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +set -euo pipefail + +python - <<'PY' +from pathlib import Path +import re + +pyproject_text = Path('pyproject.toml').read_text(encoding='utf-8') + +# Read only [project].dependencies = [ ... ] entries pinned as name==version +in_project = False +in_deps = False +deps = [] +for raw in pyproject_text.splitlines(): + line = raw.strip() + if line.startswith('[') and line.endswith(']'): + in_project = line == '[project]' + if line != '[project]': + in_deps = False + continue + if not in_project: + continue + if line.startswith('dependencies') and '[' in line: + in_deps = True + continue + if in_deps: + if ']' in line: + in_deps = False + continue + m = re.match(r'"([A-Za-z0-9_.-]+)==([^"\s]+)"\s*,?$', line) + if m: + deps.append((m.group(1), m.group(2))) + +pattern = re.compile(r'^\s*([A-Za-z0-9_.-]+)==([^\s#]+)\s*$') +req_bytes = Path('requirements.txt').read_bytes() +for enc in ('utf-8', 'utf-16', 'utf-16-le', 'utf-16-be'): + try: + req_text = req_bytes.decode(enc) + break + except UnicodeDecodeError: + continue +else: + raise SystemExit('Não foi possível decodificar requirements.txt (UTF-8/UTF-16).') + +req_pins = {} +for line in req_text.splitlines(): + m = pattern.match(line) + if m: + req_pins[m.group(1).lower().replace('_', '-').replace('.', '-')] = m.group(2) + +missing, mismatch = [], [] +for name, exp in deps: + key = name.lower().replace('_', '-').replace('.', '-') + got = req_pins.get(key) + if got is None: + missing.append(name) + elif got != exp: + mismatch.append((name, exp, got)) + +if missing or mismatch: + if missing: + print('Dependências diretas ausentes em requirements.txt:', ', '.join(missing)) + for name, exp, got in mismatch: + print(f'Versão divergente para {name}: pyproject={exp}, requirements={got}') + raise SystemExit(1) + +print('Dependências diretas de pyproject.toml estão sincronizadas em requirements.txt.') +PY