Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup code #177

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,27 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
# Reference for SVG and Pixbuf on Ubuntu 24.04: https://github.com/dino/dino/issues/1024
- name: Install Ubuntu dependencies
run: |
sudo apt-get update -q
sudo apt-get install --no-install-recommends -y xvfb gir1.2-gtk-3.0 libgirepository1.0-dev libcairo2-dev gir1.2-gstreamer-1.0 intltool enchant-2
sudo apt-get install --no-install-recommends -y xvfb gir1.2-gtk-3.0 libgirepository1.0-dev libcairo2-dev gir1.2-gstreamer-1.0 intltool enchant-2 librsvg2-common librsvg2-2

- name: Install build dependencies
run: |
pip install --upgrade pip setuptools wheel

- name: Install Gourmand
run: pip install -r development.in
run: |
pip install -r development.in
python setup.py build_i18n

- name: Test with pytest
run: LANGUAGE=de_DE.utf-8 xvfb-run -a pytest
run: |
xvfb-run -a python -c "from gourmand import prefs, gglobals; gglobals.gourmanddir.mkdir(parents=True, exist_ok=True); prefs.copy_old_installation_or_initialize(gglobals.gourmanddir)"
LC_ALL=C xvfb-run -a pytest

- name: Check imports ordering
run: >
isort --diff src/**/*.py &&
isort -c src/**/*.py
- name: Check code style
run: |
ruff check src/ tests/ setup.py
if: always()
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ gourmet.desktop
/development.txt

# Test outputs
tests/recipe_files/athenos1.gourmetcleaned.mx2
tests/recipe_files/athenos1.gourmetcleaned.mx2
/Formatted*
/Simple*
/Uni*


# Virtual environments
Expand Down
3 changes: 1 addition & 2 deletions development.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
--editable .[epub-export,pdf-export,spellcheck]
dogtail
flake8
isort
mypy
ruff==0.8.4
pytest
19 changes: 14 additions & 5 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,14 @@ You should now be able to launch and run Gourmand:

## Style

Gourmand is an old code base, consequently its style is not always consistent or
conformant to contemporary tastes.
Please follow [PEP 8](http://www.python.org/dev/peps/pep-0008/) when writing new
code, and when working on old code, please tidy up as you go.
Gourmand uses *ruff* for checking the code style, while trying to closely follow
[PEP 8](http://www.python.org/dev/peps/pep-0008/).

Check the style:

```bash
ruff check src/ tests/ setup.py
```

## Issues and Suggestions

Expand Down Expand Up @@ -134,11 +138,16 @@ Launch Gourmand and check the changes.
Once satisfied, open a pull request with your work.

## Testing

Gourmand have a test suite in the `tests` directory. Patches that expands it are welcome.
It is run with [pytest](https://docs.pytest.org/):

```bash
pytest
LC_ALL=C pytest
```

Most modern python IDEs have support for running the tests usin pytest.

**Warning:** Running the tests will most likely mess with your local configuration and
database file. Please make sure to backup the corresponding directory content manually
BEFORE running the tests.
22 changes: 21 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,24 @@
addopts = "-vv"
testpaths = [
"tests",
]
]

[tool.black]
line-length = 160
# https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#t-target-version
target-version = ["py38", "py39", "py310", "py311", "py312", "py313"]

[tool.ruff]
line-length = 160
target-version = "py38"

[tool.ruff.lint]
extend-select = [
"E", # All pycodestyle errors
"W", # pycodestyle warnings
"PGH004", # blanket-noqa
"I", # isort
# "N", # pep8-naming # TODO: 338 violations in main API as of 2024-12-30.
# "A", # flake8-builtins # TODO: 112 violations in main API as of 2024-12-30.
# "B", # flake8-bugbear # TODO: 122 violations in main API as of 2024-12-30.
]
144 changes: 71 additions & 73 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@
from setuptools import Command, find_packages, setup
from setuptools.command.develop import develop
from setuptools.command.sdist import sdist

from wheel.bdist_wheel import bdist_wheel


PACKAGE = 'gourmand'
PACKAGEDIR = Path('src') / PACKAGE
DATADIR = Path('data')
PODIR = Path('po')
LANGS = sorted(f.stem for f in PODIR.glob('*.po'))
LOCALEDIR = PACKAGEDIR / 'data' / 'locale'
PACKAGE = "gourmand"
PACKAGEDIR = Path("src") / PACKAGE
DATADIR = Path("data")
PODIR = Path("po")
LANGS = sorted(f.stem for f in PODIR.glob("*.po"))
LOCALEDIR = PACKAGEDIR / "data" / "locale"


def get_info(prop: str) -> str:
with open(PACKAGEDIR / '__version__.py') as versfile:
with open(PACKAGEDIR / "__version__.py") as versfile:
content = versfile.read()
match = re.search(r'^{} = "(.+)"'.format(prop), content, re.M)
if match is not None:
Expand All @@ -35,9 +33,9 @@ def refresh_metadata(cmd: Command) -> None:
# 'python setup.py sdist bdist_wheel'). Since package data is dynamically
# built depending on the type of build, we need to ensure that any stale
# metadata is refreshed.
if cmd.distribution.have_run.get('egg_info', 0):
cmd.distribution.reinitialize_command('egg_info')
cmd.run_command('egg_info')
if cmd.distribution.have_run.get("egg_info", 0):
cmd.distribution.reinitialize_command("egg_info")
cmd.run_command("egg_info")


def rmfile(filepath: Union[Path, str]) -> None:
Expand All @@ -62,41 +60,41 @@ def finalize_options(self):
def run(self):
# compile message catalogs to binary format
for lang in LANGS:
pofile = PODIR / f'{lang}.po'
pofile = PODIR / f"{lang}.po"

mofile = LOCALEDIR / lang / 'LC_MESSAGES'
mofile = LOCALEDIR / lang / "LC_MESSAGES"
mofile.mkdir(parents=True, exist_ok=True)
mofile /= f'{PACKAGE}.mo'
mofile /= f"{PACKAGE}.mo"

cmd = f'msgfmt {pofile} -o {mofile}'
cmd = f"msgfmt {pofile} -o {mofile}"
os.system(cmd)

# merge translated strings into various file types
cachefile = PODIR / '.intltool-merge-cache'
cachefile = PODIR / ".intltool-merge-cache"
cmd = f"LC_ALL=C intltool-merge -u -c {cachefile} {PODIR}"

for infile in DATADIR.rglob('*.in'):
for infile in DATADIR.rglob("*.in"):
# trim '.in' extension
outfile = infile.with_suffix('')
outfile = infile.with_suffix("")

extension = outfile.suffix
if 'desktop' in extension:
flag = '-d'
if "desktop" in extension:
flag = "-d"
# TODO: is '.schema' used?
elif 'schema' in extension:
flag = '-s'
elif 'xml' in extension:
flag = '-x'
elif 'gourmet-plugin' in extension:
flag = '-k'
elif "schema" in extension:
flag = "-s"
elif "xml" in extension:
flag = "-x"
elif "gourmet-plugin" in extension:
flag = "-k"
outfile = PACKAGEDIR / outfile.relative_to(DATADIR)
else:
assert False, f'Unknown file type: {infile}'
assert False, f"Unknown file type: {infile}"

os.system(f"{cmd} {flag} {infile} {outfile}")

rmfile(cachefile)
rmfile(f'{cachefile}.lock')
rmfile(f"{cachefile}.lock")


class BuildSource(sdist):
Expand All @@ -106,23 +104,25 @@ def run(self):
# NOTE: We can't use MANIFEST.in for this because these files will then
# also be excluded from built distributions
for lang in LANGS:
mofile = LOCALEDIR / lang / 'LC_MESSAGES' / f'{PACKAGE}.mo'
mofile = LOCALEDIR / lang / "LC_MESSAGES" / f"{PACKAGE}.mo"
rmfile(mofile)

for infile in DATADIR.rglob('*.in'):
for infile in DATADIR.rglob("*.in"):
# trim '.in' extension
outfile = infile.with_suffix('')
outfile = infile.with_suffix("")
extension = outfile.suffix
if ('desktop' in extension
or 'xml' in extension
# TODO: is '.schema' used?
or 'schema' in extension):
if (
"desktop" in extension
or "xml" in extension
# TODO: is '.schema' used?
or "schema" in extension
):
# these files aren't moved after they're built
pass
elif 'gourmet-plugin' in extension:
elif "gourmet-plugin" in extension:
outfile = PACKAGEDIR / outfile.relative_to(DATADIR)
else:
assert False, f'Unknown file type: {infile}'
assert False, f"Unknown file type: {infile}"

rmfile(outfile)

Expand All @@ -133,15 +133,15 @@ def run(self):
class BuildWheel(bdist_wheel):

def run(self):
self.run_command('build_i18n')
self.run_command("build_i18n")
refresh_metadata(self)
super().run()


class Develop(develop):

def run(self):
self.run_command('build_i18n')
self.run_command("build_i18n")
super().run()


Expand All @@ -164,54 +164,52 @@ def run(self):

for lang in LANGS:
self.announce(f"Updating {lang}.po", INFO)
os.system(
f"cd {PODIR};"
f"intltool-update --dist --gettext-package={PACKAGE} {lang}")
os.system(f"cd {PODIR};" f"intltool-update --dist --gettext-package={PACKAGE} {lang}")


setup(
name=PACKAGE,
version=get_info('version'),
description=get_info('description'),
author=get_info('author'),
maintainer=get_info('maintainer'),
maintainer_email=get_info('maintainer_email'),
url=get_info('url'),
license=get_info('license'),
package_dir={'': 'src'},
packages=find_packages('src'),
version=get_info("version"),
description=get_info("description"),
author=get_info("author"),
maintainer=get_info("maintainer"),
maintainer_email=get_info("maintainer_email"),
url=get_info("url"),
license=get_info("license"),
package_dir={"": "src"},
packages=find_packages("src"),
include_package_data=True,
data_files = [
('share/metainfo', ['data/io.github.GourmandRecipeManager.Gourmand.appdata.xml']),
('share/applications', ['data/io.github.GourmandRecipeManager.Gourmand.desktop']),
('share/icons/hicolor/scalable/apps', ['data/io.github.GourmandRecipeManager.Gourmand.svg']),
data_files=[
("share/metainfo", ["data/io.github.GourmandRecipeManager.Gourmand.appdata.xml"]),
("share/applications", ["data/io.github.GourmandRecipeManager.Gourmand.desktop"]),
("share/icons/hicolor/scalable/apps", ["data/io.github.GourmandRecipeManager.Gourmand.svg"]),
],
install_requires=[
'beautifulsoup4>=4.10.0',
"beautifulsoup4>=4.10.0",
'importlib-metadata; python_version<"3.10"',
'lxml>=4.6.3',
'pillow>=8.3.2',
'pygobject>=3.40.1',
'sqlalchemy>=1.4.36,<2',
'tomli_w>=1.0.0',
"lxml>=4.6.3",
"pillow>=8.3.2",
"pygobject>=3.40.1",
"sqlalchemy>=1.4.36,<2",
"tomli_w>=1.0.0",
'toml==0.10.2; python_version<"3.11"',
'recipe-scrapers>=14.27.0,<15',
"recipe-scrapers>=14.27.0,<15",
],
extras_require={
'epub-export': ['ebooklib==0.17.1'],
'pdf-export': ['reportlab<4'],
'spellcheck': ['pyenchant',
'pygtkspellcheck'],
"epub-export": ["ebooklib==0.17.1"],
"pdf-export": ["reportlab<4"],
"spellcheck": ["pyenchant", "pygtkspellcheck"],
},
cmdclass={
'bdist_wheel': BuildWheel,
'build_i18n': BuildI18n,
'develop': Develop,
'sdist': BuildSource,
'update_i18n': UpdateI18n,
"bdist_wheel": BuildWheel,
"build_i18n": BuildI18n,
"develop": Develop,
"sdist": BuildSource,
"update_i18n": UpdateI18n,
},
entry_points={
"gui_scripts": [
"gourmand = gourmand.main:launch_app",
]}
]
},
)
Loading
Loading