feat: add --format switch for runtime artifact family filtering
This commit is contained in:
1 parent
9e41900596
commit
d0a3d48c17
12 files changed
+103
-8
No files matched your search
@@ -41,6 +41,7 @@ The library ships a default CLI front-end that is meant to be a convenient start
|
||||
- Output directory.
|
||||
- SVG renderer selection.
|
||||
- **`--only`** (short `-l`): restrict the build to the jobs whose names are given. It accepts one or more names and may be repeated. Jobs that the selected ones depend on are still built as needed, so it is a resource-saving way to rebuild or verify only a subset of an entire icon set.
|
||||
- **`--format`** (short `-f`): restrict the build to the given artifact formats (`freedesktop`, `ico`, `msix`, `icns`). It accepts one or more formats and may be repeated. Sinks and sources of non-selected formats skip themselves at run time, while intermediate jobs (like temporary artifact producers) are unaffected and always run. Defaults to all formats.
|
||||
|
||||
Because Assemblicon is a library, this CLI is not fixed. You can write your own entry point and extend (or replace) the standard argument parser with project-specific options.
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from pathlib import Path
|
||||
from argparse import ArgumentParser, Namespace
|
||||
from dataclasses import dataclass
|
||||
from .lowlevel.artrdr import SvgRenderKind
|
||||
from .highlevel.address import Family
|
||||
|
||||
|
||||
class CliSvgRenderKind(enum.StrEnum):
|
||||
@@ -20,6 +21,26 @@ class CliSvgRenderKind(enum.StrEnum):
|
||||
raise ValueError(f"Unknown CLI-specific SVG render kind: {self}")
|
||||
|
||||
|
||||
class CliArtifactFormat(enum.StrEnum):
|
||||
Freedesktop = "freedesktop"
|
||||
Ico = "ico"
|
||||
Msix = "msix"
|
||||
Icns = "icns"
|
||||
|
||||
def to_assemblicon_type(self) -> Family:
|
||||
match self:
|
||||
case CliArtifactFormat.Freedesktop:
|
||||
return Family.Freedesktop
|
||||
case CliArtifactFormat.Ico:
|
||||
return Family.Ico
|
||||
case CliArtifactFormat.Msix:
|
||||
return Family.Msix
|
||||
case CliArtifactFormat.Icns:
|
||||
return Family.Icns
|
||||
case _:
|
||||
raise ValueError(f"Unknown CLI-specific artifact format: {self}")
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class StdOpts:
|
||||
"""Assemblicon standard command line options"""
|
||||
@@ -32,6 +53,11 @@ class StdOpts:
|
||||
"""The list holding all name of jobs for building."""
|
||||
svg_render: CliSvgRenderKind
|
||||
"""The render kind for SVG file."""
|
||||
format_selection: Optional[list[CliArtifactFormat]]
|
||||
"""
|
||||
The list holding all formats of artifacts for building.
|
||||
``None`` for building artifacts of all formats.
|
||||
"""
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -98,6 +124,16 @@ def create_argparser(setup: StdOptsSetup) -> ArgumentParser:
|
||||
help="The render used for rendering SVG into PNG.",
|
||||
metavar="RENDER",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f",
|
||||
"--format",
|
||||
dest="format_selection",
|
||||
action="extend",
|
||||
nargs="+",
|
||||
type=CliArtifactFormat,
|
||||
help="Only build artifacts of given formats. Repeatable. Default all formats.",
|
||||
metavar="FORMAT",
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
@@ -107,4 +143,5 @@ def parse_standard_opts(cfg: StdOptsSetup, ns: Namespace) -> StdOpts:
|
||||
output_directory=ns.output if cfg.require_output else None,
|
||||
selection=ns.selection,
|
||||
svg_render=ns.svg_render,
|
||||
format_selection=ns.format_selection,
|
||||
)
|
||||
@@ -1,6 +1,19 @@
|
||||
import enum
|
||||
|
||||
|
||||
class Family(enum.StrEnum):
|
||||
"""The family of an output artifact, used by runtime family filtering."""
|
||||
|
||||
Freedesktop = "freedesktop"
|
||||
"""FreeDesktop compatible PNG icons."""
|
||||
Ico = "ico"
|
||||
"""Windows ICO icons."""
|
||||
Msix = "msix"
|
||||
"""Windows MSIX package icons."""
|
||||
Icns = "icns"
|
||||
"""macOS ICNS icons."""
|
||||
|
||||
|
||||
class AddressDomain(enum.IntEnum):
|
||||
Input = enum.auto()
|
||||
Temporary = enum.auto()
|
||||
|
||||
@@ -7,6 +7,7 @@ from pathlib import Path
|
||||
from typing import TypeVar, Generic, Callable
|
||||
from ..lowlevel.environment import Prologue as LowPrologue, Environment as LowEnv
|
||||
from ..lowlevel.artrdr import SvgRenderKind
|
||||
from .address import Family
|
||||
from .utils import (
|
||||
FdContext,
|
||||
IcoCategory,
|
||||
@@ -53,6 +54,16 @@ class Prologue(LowPrologue):
|
||||
The only argument in function is the path to user temporary directory.
|
||||
``None`` for no extra initializer.
|
||||
"""
|
||||
allowed_families: set[Family] | None = None
|
||||
"""
|
||||
The set of artifact families allowed to be generated.
|
||||
Output-family sinks and sources check this at run time and silently
|
||||
skip themselves when their family is not listed, which provides a
|
||||
resource-saving way to only produce a subset of output families.
|
||||
Intermediate artifacts (like temporary ones) have no family and are
|
||||
always produced. ``None`` for no restriction, and an empty set means
|
||||
no output family is allowed.
|
||||
"""
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
super().__post_init__()
|
||||
@@ -70,6 +81,15 @@ class Prologue(LowPrologue):
|
||||
for targetsize in self.msix_ext_targetsizes:
|
||||
check_msix_targetsize(targetsize)
|
||||
|
||||
def allow_family(self, family: Family) -> bool:
|
||||
"""
|
||||
Check whether given artifact family is allowed to be generated.
|
||||
|
||||
:param family: The family to be checked.
|
||||
:returns: ``True`` if this family is allowed to be generated.
|
||||
"""
|
||||
return self.allowed_families is None or family in self.allowed_families
|
||||
|
||||
|
||||
_TEMP_USER_DIR: str = "user"
|
||||
_TEMP_LIB_DIR: str = "assemblicon"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from dataclasses import dataclass
|
||||
from .common import Sink
|
||||
from ..address import Address, AddressDomain
|
||||
from ..address import Address, AddressDomain, Family
|
||||
from ..environment import Environment
|
||||
from ..utils import Artifact, FdContext, check_vart
|
||||
from ...lowlevel import artio, artrdr
|
||||
@@ -26,6 +26,9 @@ class FdArtSink(Sink):
|
||||
return Address(AddressDomain.PosixFdOutput, str(self.__kind), self.__name)
|
||||
|
||||
def push(self, env: Environment, art: Artifact) -> None:
|
||||
if not env.prologue.allow_family(Family.Freedesktop):
|
||||
return
|
||||
|
||||
LOGGER.info(
|
||||
'Saving FreeDesktop artifact with kind "%s" and name "%s".',
|
||||
self.__kind,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from dataclasses import dataclass
|
||||
from .common import Sink
|
||||
from ..address import Address, AddressDomain
|
||||
from ..address import Address, AddressDomain, Family
|
||||
from ..environment import Environment
|
||||
from ..utils import Artifact, IcnsCategory, check_vart
|
||||
from ...lowlevel import artrdr
|
||||
@@ -26,6 +26,9 @@ class IcnsArtSink(Sink):
|
||||
return Address(AddressDomain.MacIcnsOutput, str(self.__kind), self.__name)
|
||||
|
||||
def push(self, env: Environment, art: Artifact) -> None:
|
||||
if not env.prologue.allow_family(Family.Icns):
|
||||
return
|
||||
|
||||
LOGGER.info(
|
||||
'Saving macOS ICNS artifact with kind "%s" and name "%s".',
|
||||
self.__kind,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from dataclasses import dataclass
|
||||
from .common import Sink
|
||||
from ..address import Address, AddressDomain
|
||||
from ..address import Address, AddressDomain, Family
|
||||
from ..environment import Environment
|
||||
from ..utils import Artifact, IcoCategory, check_vart
|
||||
from ...lowlevel import artrdr
|
||||
@@ -26,6 +26,9 @@ class IcoArtSink(Sink):
|
||||
return Address(AddressDomain.WinIcoOutput, str(self.__kind), self.__name)
|
||||
|
||||
def push(self, env: Environment, art: Artifact) -> None:
|
||||
if not env.prologue.allow_family(Family.Ico):
|
||||
return
|
||||
|
||||
LOGGER.info(
|
||||
'Saving Windows ICO artifact with kind "%s" and name "%s".',
|
||||
self.__kind,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from dataclasses import dataclass
|
||||
from .common import Sink
|
||||
from ..address import Address, AddressDomain
|
||||
from ..address import Address, AddressDomain, Family
|
||||
from ..environment import Environment
|
||||
from ..utils import (
|
||||
Artifact,
|
||||
@@ -33,6 +33,9 @@ class MsixArtSink(Sink):
|
||||
return Address(AddressDomain.WinMsixOutput, str(self.__kind), self.__name)
|
||||
|
||||
def push(self, env: Environment, art: Artifact) -> None:
|
||||
if not env.prologue.allow_family(Family.Msix):
|
||||
return
|
||||
|
||||
LOGGER.info(
|
||||
'Saving Windows MSIX artifact with kind "%s" and name "%s".',
|
||||
self.__kind,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from .common import Source
|
||||
from ..address import Address, AddressDomain
|
||||
from ..address import Address, AddressDomain, Family
|
||||
from ..environment import Environment
|
||||
from ..sink.fdart_sink import FdArtSink
|
||||
from ..utils import FdContext
|
||||
@@ -20,6 +20,9 @@ class FdArtSource(Source):
|
||||
return Address(AddressDomain.PosixFdOutput, str(self.__kind), self.__name)
|
||||
|
||||
def link_to(self, env: Environment, fd_sink: FdArtSink) -> None:
|
||||
if not env.prologue.allow_family(Family.Freedesktop):
|
||||
return
|
||||
|
||||
sink_hint = fd_sink.push_hint()
|
||||
LOGGER.info(
|
||||
'Duplicating FreeDesktop artifact from kind "%s" name "%s" to kind "%s" name "%s".',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from .common import Source
|
||||
from ..address import Address, AddressDomain
|
||||
from ..address import Address, AddressDomain, Family
|
||||
from ..environment import Environment
|
||||
from ..sink.icnsart_sink import IcnsArtSink
|
||||
from ..utils import IcnsCategory
|
||||
@@ -20,6 +20,9 @@ class IcnsArtSource(Source):
|
||||
return Address(AddressDomain.MacIcnsOutput, str(self.__kind), self.__name)
|
||||
|
||||
def link_to(self, env: Environment, icns_sink: IcnsArtSink) -> None:
|
||||
if not env.prologue.allow_family(Family.Icns):
|
||||
return
|
||||
|
||||
sink_hint = icns_sink.push_hint()
|
||||
LOGGER.info(
|
||||
'Duplicating macOS ICNS artifact from kind "%s" name "%s" to kind "%s" name "%s".',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from .common import Source
|
||||
from ..address import Address, AddressDomain
|
||||
from ..address import Address, AddressDomain, Family
|
||||
from ..environment import Environment
|
||||
from ..sink.icoart_sink import IcoArtSink
|
||||
from ..utils import IcoCategory
|
||||
@@ -20,6 +20,9 @@ class IcoArtSource(Source):
|
||||
return Address(AddressDomain.WinIcoOutput, str(self.__kind), self.__name)
|
||||
|
||||
def link_to(self, env: Environment, ico_sink: IcoArtSink) -> None:
|
||||
if not env.prologue.allow_family(Family.Ico):
|
||||
return
|
||||
|
||||
sink_hint = ico_sink.push_hint()
|
||||
LOGGER.info(
|
||||
'Duplicating Windows ICO artifact from kind "%s" name "%s" to kind "%s" name "%s".',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from .common import Source
|
||||
from ..address import Address, AddressDomain
|
||||
from ..address import Address, AddressDomain, Family
|
||||
from ..environment import Environment
|
||||
from ..sink.msixart_sink import MsixArtSink, MsixArtSinkHint
|
||||
from ..utils import MsixCategory, MsixAppLogoKind, MsixAppPlatedKind
|
||||
@@ -20,6 +20,9 @@ class MsixArtSource(Source):
|
||||
return Address(AddressDomain.WinMsixOutput, str(self.__kind), self.__name)
|
||||
|
||||
def link_to(self, env: Environment, msix_sink: MsixArtSink) -> None:
|
||||
if not env.prologue.allow_family(Family.Msix):
|
||||
return
|
||||
|
||||
sink_hint = msix_sink.push_hint()
|
||||
LOGGER.info(
|
||||
'Duplicating Windows MSIX artifact from kind "%s" name "%s" to kind "%s" name "%s".',
|
||||
|
||||
Reference in new issue
Block a user