This commit is contained in:
Salamandar 2024-05-17 13:53:58 +02:00 committed by GitHub
commit 6c63fd4707
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 124 additions and 72 deletions

View file

@ -1,35 +0,0 @@
name: Check / auto apply Black
on:
push:
branches:
- master
jobs:
black:
name: Check / auto apply black
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check files using the black formatter
uses: psf/black@stable
id: black
with:
options: "."
continue-on-error: true
- shell: pwsh
id: check_files_changed
run: |
# Diff HEAD with the previous commit
$diff = git diff
$HasDiff = $diff.Length -gt 0
Write-Host "::set-output name=files_changed::$HasDiff"
- name: Create Pull Request
if: steps.check_files_changed.outputs.files_changed == 'true'
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
title: "Format Python code with Black"
commit-message: ":art: Format Python code with Black"
body: |
This pull request uses the [psf/black](https://github.com/psf/black) formatter.
base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch
branch: actions/black

28
.github/workflows/python-check.yml vendored Normal file
View file

@ -0,0 +1,28 @@
name: Python Lint with Ruff and Mypy
on:
pull_request:
push:
branches: [master]
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.9"
- name: Install Ruff and Mypy
run: pip install ruff mypy
- name: Ruff check
run: |
ruff check .
- name: Mypy install types
run: yes | mypy . --install-types || true
- name: Mypy check
run: mypy .

34
.github/workflows/python-format.yml vendored Normal file
View file

@ -0,0 +1,34 @@
name: Python formatting with Black and Ruff
on:
push:
branches: [master]
jobs:
format:
name: Formatting with Black and Ruff
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check files using the black formatter
uses: psf/black@stable
id: black
with:
options: "."
continue-on-error: true
- uses: actions/setup-python@v5
with:
python-version: "3.9"
- name: Install Ruff
run: pip install ruff
- name: Ruff check and fix
run: |
ruff check .
ruff check --fix .
- uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 'Python formatting fixes from Black and Ruff'

View file

@ -2,6 +2,7 @@ name: Run Shellcheck on push and PR
on: on:
push: push:
branches: [master]
pull_request: pull_request:
jobs: jobs:
@ -9,7 +10,7 @@ jobs:
name: Shellcheck name: Shellcheck
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Run ShellCheck - name: Run ShellCheck
uses: ludeeus/action-shellcheck@master uses: ludeeus/action-shellcheck@master
with: with:

5
.gitignore vendored
View file

@ -16,3 +16,8 @@ ssowat
# Folders # Folders
apps apps
backup backup
__pycache__/
.mypy_cache/
.ruff_cache/

View file

@ -1,17 +1,18 @@
#!/usr/bin/python3 #!/usr/bin/python3
import sys
import os
import json import json
import toml import os
import yaml import sys
import time import time
from collections import OrderedDict from collections import OrderedDict
from pathlib import Path
from typing import Any
CATALOG_LIST_PATH = "/etc/yunohost/apps_catalog.yml" import toml
assert os.path.exists( import yaml
CATALOG_LIST_PATH
), f"Catalog list yaml file '{CATALOG_LIST_PATH} does not exists" CATALOG_LIST_PATH = Path("/etc/yunohost/apps_catalog.yml").resolve()
assert CATALOG_LIST_PATH.exists(), f"Catalog list yaml file '{CATALOG_LIST_PATH} does not exists"
now = time.time() now = time.time()
my_env = os.environ.copy() my_env = os.environ.copy()
@ -21,13 +22,14 @@ DEFAULT_APPS_FOLDER = "/ynh-dev/custom-catalog/"
DEFAULT_APP_BRANCH = "master" DEFAULT_APP_BRANCH = "master"
def build(folder=DEFAULT_APPS_FOLDER): def build(folder: Path | str = DEFAULT_APPS_FOLDER) -> None:
assert os.path.exists(folder), f"'{folder}' doesn't exists." folder = Path(folder)
assert folder.exists(), f"'{folder}' doesn't exists."
app_list_path = os.path.join(folder, "apps.json") app_list_path = folder / "apps.json"
assert os.path.exists(app_list_path), "no 'apps.json' app list found." assert app_list_path.exists(), "no 'apps.json' app list found."
with open(app_list_path) as f: with app_list_path.open() as f:
app_list = json.load(f) app_list = json.load(f)
apps = {} apps = {}
@ -44,37 +46,38 @@ def build(folder=DEFAULT_APPS_FOLDER):
apps[app_dict["id"]] = app_dict apps[app_dict["id"]] = app_dict
# We also remove the app install question and resources parts which aint needed anymore by webadmin etc (or at least we think ;P) # We also remove the app install question and resources parts which aint needed
# anymore by webadmin etc (or at least we think ;P)
for app in apps.values(): for app in apps.values():
if "manifest" in app and "install" in app["manifest"]: if "manifest" in app and "install" in app["manifest"]:
del app["manifest"]["install"] del app["manifest"]["install"]
if "manifest" in app and "resources" in app["manifest"]: if "manifest" in app and "resources" in app["manifest"]:
del app["manifest"]["resources"] del app["manifest"]["resources"]
output_file = os.path.join(folder, "catalog.json") output_file = folder / "catalog.json"
data = { data = {
"apps": apps, "apps": apps,
"from_api_version": 3, "from_api_version": 3,
} }
with open(output_file, "w") as f: with output_file.open("w") as f:
f.write(json.dumps(data, sort_keys=True, indent=2)) f.write(json.dumps(data, sort_keys=True, indent=2))
if fail: if fail:
sys.exit(1) sys.exit(1)
def build_app_dict(app, infos, folder): def build_app_dict(app: str, infos: dict[str, Any], folder: Path) -> dict[str, Any]:
app_folder = os.path.join(folder, app + "_ynh") app_folder = folder / f"{app}_ynh"
# Build the dict with all the infos # Build the dict with all the infos
manifest_toml = os.path.join(app_folder, "manifest.toml") manifest_toml = app_folder / "manifest.toml"
manifest_json = os.path.join(app_folder, "manifest.json") manifest_json = app_folder / "manifest.json"
if os.path.exists(manifest_toml): if manifest_toml.exists():
with open(manifest_toml) as f: with manifest_toml.open() as f:
manifest = toml.load(f, _dict=OrderedDict) manifest = toml.load(f, _dict=OrderedDict)
else: else:
with open(manifest_json) as f: with manifest_json.open() as f:
manifest = json.load(f, _dict=OrderedDict) manifest = json.load(f, _dict=OrderedDict)
return { return {
@ -94,32 +97,27 @@ def build_app_dict(app, infos, folder):
"category": infos.get("category", None), "category": infos.get("category", None),
"subtags": infos.get("subtags", []), "subtags": infos.get("subtags", []),
"potential_alternative_to": infos.get("potential_alternative_to", []), "potential_alternative_to": infos.get("potential_alternative_to", []),
"antifeatures": list( "antifeatures": list(set(list(manifest.get("antifeatures", {}).keys()) + infos.get("antifeatures", []))),
set(
list(manifest.get("antifeatures", {}).keys())
+ infos.get("antifeatures", [])
)
),
} }
def reset(): def reset() -> None:
with open(CATALOG_LIST_PATH, "w") as f: with CATALOG_LIST_PATH.open("w") as f:
catalog_list = [{"id": "default", "url": "https://app.yunohost.org/default/"}] catalog_list = [{"id": "default", "url": "https://app.yunohost.org/default/"}]
yaml.safe_dump(catalog_list, f, default_flow_style=False) yaml.safe_dump(catalog_list, f, default_flow_style=False)
def add(): def add() -> None:
with open(CATALOG_LIST_PATH) as f: with CATALOG_LIST_PATH.open("r") as f:
catalog_list = yaml.load(f, Loader=yaml.FullLoader) catalog_list = yaml.load(f, Loader=yaml.FullLoader)
ids = [catalog["id"] for catalog in catalog_list] ids = [catalog["id"] for catalog in catalog_list]
if "custom" not in ids: if "custom" not in ids:
catalog_list.append({"id": "custom", "url": None}) catalog_list.append({"id": "custom", "url": None})
with open(CATALOG_LIST_PATH, "w") as f: with CATALOG_LIST_PATH.open("w") as f:
yaml.safe_dump(catalog_list, f, default_flow_style=False) yaml.safe_dump(catalog_list, f, default_flow_style=False)
def override(): def override() -> None:
with open(CATALOG_LIST_PATH, "w") as f: with CATALOG_LIST_PATH.open("w") as f:
catalog_list = [{"id": "custom", "url": None}] catalog_list = [{"id": "custom", "url": None}]
yaml.safe_dump(catalog_list, f, default_flow_style=False) yaml.safe_dump(catalog_list, f, default_flow_style=False)

21
pyproject.toml Normal file
View file

@ -0,0 +1,21 @@
[tool.black]
line-length = 120
[tool.ruff]
line-length = 120
[tool.ruff.lint]
select = [
"F", # pyflakes
"E", # pycodestyle
"W", # pycodestyle
"I", # isort
"N", # pep8-naming
"B", # flake8-ubgbear
"ANN", # flake8-annotations
"Q", # flake8-quotes
"PTH", # flake8-use-pathlib
"UP", # pyupgrade,
]
[tool.mypy]