jw-pkg/src/python/jw/pkg/cmds/secrets/lib/DistroContext.py

170 lines
6.1 KiB
Python
Raw Normal View History

from __future__ import annotations
import re
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
import sys
lib.ec.secret_store: Add and use framework "jw-pkg secrets install" copies secret material from a GPG-encrypted tar archive to dotenv .jw-secret files on a target host. This commit refactors the underlying code and adds hooks for the inverse copy direction, and for more secret sources and targets. The peers between which secrets are copied are represented by the new abstract secret_store.Base class, and the existing tar blob and host storages, inheriting from that class, are TarGpg and KvFile. Moreover, secret_store.Base is inheriting from FileContext, so all of jw-pkg's file-like operations are available as hooks. Secrets inside instances of two file contexts are addressable as (targpg|kvfile)://target.host.com/path/to/file.conf.jw-secret. The on-host KvFile will look either locally or via SSH for that file, and TarGpg will look inside a tar archive specified in the JW_SECRETS_TARGPG_TAR environment variable. Uris with these schemas can be passed to FileContext.create(), which will return a chrooted file context of the correct type. KvFile.stat("/path/to/file.conf.jw-secret").ftype is FT_SECRET which inherits from FT_COMPOUND - which means that readdir() works on such animals. Not entirely sure if that's a good idea, but it feels pretty generic. Let's see where that takes us. DistroContext.install() after this refactor reads its source through the store interface and writes the landing through the KvFile store. Both secret stores are exercised through the existing unit test of jw-pkg secrets install, and unit tests for both stores are also added by this commit. Signed-off-by: Jan Lindemann <jan@janware.com>
2026-10-03 21:39:32 +02:00
from contextlib import suppress
from pathlib import Path
from typing import TYPE_CHECKING
lib.ec.secret_store: Add and use framework "jw-pkg secrets install" copies secret material from a GPG-encrypted tar archive to dotenv .jw-secret files on a target host. This commit refactors the underlying code and adds hooks for the inverse copy direction, and for more secret sources and targets. The peers between which secrets are copied are represented by the new abstract secret_store.Base class, and the existing tar blob and host storages, inheriting from that class, are TarGpg and KvFile. Moreover, secret_store.Base is inheriting from FileContext, so all of jw-pkg's file-like operations are available as hooks. Secrets inside instances of two file contexts are addressable as (targpg|kvfile)://target.host.com/path/to/file.conf.jw-secret. The on-host KvFile will look either locally or via SSH for that file, and TarGpg will look inside a tar archive specified in the JW_SECRETS_TARGPG_TAR environment variable. Uris with these schemas can be passed to FileContext.create(), which will return a chrooted file context of the correct type. KvFile.stat("/path/to/file.conf.jw-secret").ftype is FT_SECRET which inherits from FT_COMPOUND - which means that readdir() works on such animals. Not entirely sure if that's a good idea, but it feels pretty generic. Let's see where that takes us. DistroContext.install() after this refactor reads its source through the store interface and writes the landing through the KvFile store. Both secret stores are exercised through the existing unit test of jw-pkg secrets install, and unit tests for both stores are also added by this commit. Signed-off-by: Jan Lindemann <jan@janware.com>
2026-10-03 21:39:32 +02:00
from ....lib.ec.secret_store.Base import Base as SecretStore
from ....lib.ec.secret_store.KvFile import KvFile
from ....lib.ec.secret_store.layout import (
DEFAULT_PREFIX,
FT_SECRET,
FT_SECRET_KEY,
SECRET_SUFFIX,
host_prefix,
)
from ....lib.FileContext import FileContext
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
from ....lib.log import DEBUG, NOTICE, WARNING, log
from .FilesContext import FilesContext
if TYPE_CHECKING:
from collections.abc import Collection
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
from ....lib.Distro import Distro
from .base import Attrs
class DistroContext(FilesContext):
def __init__(self, distro: Distro) -> None:
lib.ec.secret_store: Add and use framework "jw-pkg secrets install" copies secret material from a GPG-encrypted tar archive to dotenv .jw-secret files on a target host. This commit refactors the underlying code and adds hooks for the inverse copy direction, and for more secret sources and targets. The peers between which secrets are copied are represented by the new abstract secret_store.Base class, and the existing tar blob and host storages, inheriting from that class, are TarGpg and KvFile. Moreover, secret_store.Base is inheriting from FileContext, so all of jw-pkg's file-like operations are available as hooks. Secrets inside instances of two file contexts are addressable as (targpg|kvfile)://target.host.com/path/to/file.conf.jw-secret. The on-host KvFile will look either locally or via SSH for that file, and TarGpg will look inside a tar archive specified in the JW_SECRETS_TARGPG_TAR environment variable. Uris with these schemas can be passed to FileContext.create(), which will return a chrooted file context of the correct type. KvFile.stat("/path/to/file.conf.jw-secret").ftype is FT_SECRET which inherits from FT_COMPOUND - which means that readdir() works on such animals. Not entirely sure if that's a good idea, but it feels pretty generic. Let's see where that takes us. DistroContext.install() after this refactor reads its source through the store interface and writes the landing through the KvFile store. Both secret stores are exercised through the existing unit test of jw-pkg secrets install, and unit tests for both stores are also added by this commit. Signed-off-by: Jan Lindemann <jan@janware.com>
2026-10-03 21:39:32 +02:00
super().__init__(distro.ctx, distro = distro)
self.__distro = distro
async def match_files(self, pkg_names: Collection[str], pattern: str) -> list[str]:
ret: list[str] = []
for pkg_name in pkg_names:
for path in await self.__distro.pkg_files(pkg_name):
if re.match(pattern, path):
ret.append(path)
return ret
async def list_template_files(self, pkg_names: Collection[str]) -> list[str]:
if not pkg_names:
pkg_names = [p.name for p in await self.__distro.select()]
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
return await self.match_files(pkg_names, pattern = r'.*\.jw-tmpl$')
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
async def list_secret_paths(
self, pkg_names: Collection[str], ignore_missing: bool = False
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
) -> list[str]:
ret = []
for tmpl in await self.list_template_files(pkg_names):
lib.ec.secret_store: Add and use framework "jw-pkg secrets install" copies secret material from a GPG-encrypted tar archive to dotenv .jw-secret files on a target host. This commit refactors the underlying code and adds hooks for the inverse copy direction, and for more secret sources and targets. The peers between which secrets are copied are represented by the new abstract secret_store.Base class, and the existing tar blob and host storages, inheriting from that class, are TarGpg and KvFile. Moreover, secret_store.Base is inheriting from FileContext, so all of jw-pkg's file-like operations are available as hooks. Secrets inside instances of two file contexts are addressable as (targpg|kvfile)://target.host.com/path/to/file.conf.jw-secret. The on-host KvFile will look either locally or via SSH for that file, and TarGpg will look inside a tar archive specified in the JW_SECRETS_TARGPG_TAR environment variable. Uris with these schemas can be passed to FileContext.create(), which will return a chrooted file context of the correct type. KvFile.stat("/path/to/file.conf.jw-secret").ftype is FT_SECRET which inherits from FT_COMPOUND - which means that readdir() works on such animals. Not entirely sure if that's a good idea, but it feels pretty generic. Let's see where that takes us. DistroContext.install() after this refactor reads its source through the store interface and writes the landing through the KvFile store. Both secret stores are exercised through the existing unit test of jw-pkg secrets install, and unit tests for both stores are also added by this commit. Signed-off-by: Jan Lindemann <jan@janware.com>
2026-10-03 21:39:32 +02:00
path = str(Path(tmpl).with_suffix(SECRET_SUFFIX))
if ignore_missing and not await self.ctx.file_exists(path):
continue
ret.append(path)
return ret
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
async def list_compilation_targets(
self, pkg_names: Collection[str], ignore_missing: bool = False
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
) -> list[str]:
ret = []
for tmpl in await self.list_template_files(pkg_names):
path = tmpl.removesuffix('.jw-tmpl')
if ignore_missing and not await self.ctx.file_exists(path):
continue
ret.append(path)
return ret
async def remove_compilation_targets(self, pkg_names: Collection[str]) -> list[str]:
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
ret: list[str] = []
for path in await self.list_compilation_targets(pkg_names):
try:
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
await self.ctx.stat(path)
log(NOTICE, f'Removing {path}')
await self.ctx.unlink(path)
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
ret.append(path)
except FileNotFoundError:
log(DEBUG, f"Compilation target {path} doesn't exist (ignored)")
continue
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
return ret
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
async def compile_template_files(
self, pkg_names: Collection[str], default_attrs: Attrs
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
) -> list[str]:
ret: list[str] = []
missing = 0
for target in await self.list_compilation_targets(pkg_names):
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
if await self.compile_template_file(target, default_attrs):
ret.append(target)
else:
missing += 1
if missing > 0:
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
from ....lib.util import pretty_cmd
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
cmdline = pretty_cmd(sys.argv)
log(
WARNING,
(
f'{missing} missing secrets found. You might want to add them and '
f'run sudo {cmdline} again'
),
)
return ret
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
async def install(
self,
src_uri: str,
pkg_names: Collection[str],
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
only_missing: bool = False,
verbose: bool = False,
) -> None:
if only_missing:
raise NotImplementedError('--only-missing is not yet implemented')
lib.ec.secret_store: Add and use framework "jw-pkg secrets install" copies secret material from a GPG-encrypted tar archive to dotenv .jw-secret files on a target host. This commit refactors the underlying code and adds hooks for the inverse copy direction, and for more secret sources and targets. The peers between which secrets are copied are represented by the new abstract secret_store.Base class, and the existing tar blob and host storages, inheriting from that class, are TarGpg and KvFile. Moreover, secret_store.Base is inheriting from FileContext, so all of jw-pkg's file-like operations are available as hooks. Secrets inside instances of two file contexts are addressable as (targpg|kvfile)://target.host.com/path/to/file.conf.jw-secret. The on-host KvFile will look either locally or via SSH for that file, and TarGpg will look inside a tar archive specified in the JW_SECRETS_TARGPG_TAR environment variable. Uris with these schemas can be passed to FileContext.create(), which will return a chrooted file context of the correct type. KvFile.stat("/path/to/file.conf.jw-secret").ftype is FT_SECRET which inherits from FT_COMPOUND - which means that readdir() works on such animals. Not entirely sure if that's a good idea, but it feels pretty generic. Let's see where that takes us. DistroContext.install() after this refactor reads its source through the store interface and writes the landing through the KvFile store. Both secret stores are exercised through the existing unit test of jw-pkg secrets install, and unit tests for both stores are also added by this commit. Signed-off-by: Jan Lindemann <jan@janware.com>
2026-10-03 21:39:32 +02:00
fc = FileContext.create(src_uri, chroot = True)
await fc.open()
try:
hostname = self.ctx.uri.hostname
if not hostname:
raise Exception('Have no hostname to find secrets in the store')
if isinstance(fc, SecretStore):
if not fc.whole:
raise Exception(
f'src {src_uri} must name the whole store, not a '
f'rooted subtree'
)
src: FileContext = fc
# -- Store candidates: the host tree, then the default
# tree
prefixes: tuple[str, ...] = (host_prefix(hostname), DEFAULT_PREFIX)
jw.pkg: Fix "make check" static code check fallout The previous commits have put rules for linting and formatting via ruff, yapf, mypy and pyright into place. They are checked with the make check target, and this commit adds the fixes for the target to succeed. It does some refactoring where type checking dug up dirty bits, and also adds lots of churn in the Python code. To a good deal, that's owed to mere formatting changes. It would have been better to seperate those from syntax and refactoring fixes into multiple commits, so that the interesting changes don't drown in the formatting nose. However, that would have been a lot of additional work only to be thrown away by later commits, hence this commit has a big diff in one piece. The size of the diff is regrettable but hopefully a one-off: What it buys is automatic format checking for CI and predictble formats for smaller diffs in the future. Rules that "make check" enforces are, in the following order - Syntax checkers: - ruff check . - mypy . - pyright - Format check: - yapf --diff --recursive . The refactoring includes: - Turn the Result class into a more elaborate object, capable of doing more heavy lifting around stderr and stdout decoding, summarizing outcome, and matching error strings. Aside from fixing broken type checks, this also removes lots of boilerplate calling code which is currently used for handling possible call outcome scenarios. Trying to access an inexistent, decoded string should raise a meaningful exception by itself now, which removes lots of code with case distinctions. - Fix Cmd type hierarchy: - Add the AbstractCmd class above Cmd. This is necessary because the checker rightfully complains it can't instantiate a Cmd instance where constructor arguments were needed. They never were, but the type used at the instantiating code's location in jw.pkg.App so claims. - Lots of sub- and sub-subcommands are derived from the base class of the invoking command. That provides some properties shared across the ancestor hierarchy of a command, but is semantically unsound. Fix that by introducing jw.pkg.BaseCmd class as a place to provide basic helpers shared across all commands used in a jw.pkg.App's context, and derive all command classes from that afresh. The parent command is still reachable via a common parent property. Formatting changes are conforming to PEP-8, mostly, with minor tweaks. All in all they include the following changes. - Remove # -*- coding: utf-8 -*- The line was needed by Python 2 which is not supported anylonger. For Python 3, the default encoding is UTF-8, anyway. - Allow to run "make py-format" without having it produce any changes. It's basically "yapf --in-place --recursive ." with some code style settings, see conf/topdir/pyproject.toml. The settings may be debatable. I've had custom tweaks in place on that target, too, but then again, IDEs would have more hassle to integrate that. - Introduce a 88 character line length limit - One import per line, reshuffle them semantically, see [tool.isort] in pyproject.toml. - Hide imports needed for type-checking only behind if TYPE_CHECKING - Spaces around assignments accounts for much churn. Having having no spaces in inline parameter list assignments and default parameter values would arguably be more compact where it's useful. On the other hand, I have not found a code formatter which allows spaces around assignments in parameter lists broken into one per line and that's often better than a wall of text. - Add two spaces before # export, as this seems to be mandated by PEP-8 - Use single quotes by default Signed-off-by: Jan Lindemann <jan@janware.com>
2026-05-27 07:16:05 +02:00
else:
lib.ec.secret_store: Add and use framework "jw-pkg secrets install" copies secret material from a GPG-encrypted tar archive to dotenv .jw-secret files on a target host. This commit refactors the underlying code and adds hooks for the inverse copy direction, and for more secret sources and targets. The peers between which secrets are copied are represented by the new abstract secret_store.Base class, and the existing tar blob and host storages, inheriting from that class, are TarGpg and KvFile. Moreover, secret_store.Base is inheriting from FileContext, so all of jw-pkg's file-like operations are available as hooks. Secrets inside instances of two file contexts are addressable as (targpg|kvfile)://target.host.com/path/to/file.conf.jw-secret. The on-host KvFile will look either locally or via SSH for that file, and TarGpg will look inside a tar archive specified in the JW_SECRETS_TARGPG_TAR environment variable. Uris with these schemas can be passed to FileContext.create(), which will return a chrooted file context of the correct type. KvFile.stat("/path/to/file.conf.jw-secret").ftype is FT_SECRET which inherits from FT_COMPOUND - which means that readdir() works on such animals. Not entirely sure if that's a good idea, but it feels pretty generic. Let's see where that takes us. DistroContext.install() after this refactor reads its source through the store interface and writes the landing through the KvFile store. Both secret stores are exercised through the existing unit test of jw-pkg secrets install, and unit tests for both stores are also added by this commit. Signed-off-by: Jan Lindemann <jan@janware.com>
2026-10-03 21:39:32 +02:00
# -- A file tree in the on-host layout: wrap it in the kvfile store
src = KvFile(fc, distro = self.__distro)
prefixes = ('', )
# -- The store and the kvfile source are alike addressed
# by the on-host file name
suffix = SECRET_SUFFIX
for entry in await self.list_compilation_targets(pkg_names):
# -- A present entry, even an empty one, wins over the
# fallback
entry_rel = f'{entry.lstrip("/")}{suffix}'
addr = entry_rel
keys: list[str] | None = None
for pfx in prefixes:
addr = f'{pfx}/{entry_rel}' if pfx else entry_rel
try:
keys = list(await src.readdir(addr))
break
except FileNotFoundError:
continue
if keys is None:
log(NOTICE, f'not extracted: {entry}')
continue
log(NOTICE, f'extracted: {entry}')
pairs: list[tuple[str, bytes]] = []
for key in keys:
val = await src.get(f'{addr}/{key}')
pairs.append((key, val.stdout))
dst = self.store
with suppress(FileNotFoundError):
await dst.unlink(entry_rel)
await dst.mkdir(entry_rel, ftype = FT_SECRET)
for key, content in pairs:
await dst.put(f'{entry_rel}/{key}', content, ftype = FT_SECRET_KEY)
finally:
await fc.close()