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.
|
- Output directory.
|
||||||
- SVG renderer selection.
|
- 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.
|
- **`--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.
|
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 argparse import ArgumentParser, Namespace
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from .lowlevel.artrdr import SvgRenderKind
|
from .lowlevel.artrdr import SvgRenderKind
|
||||||
|
from .highlevel.address import Family
|
||||||
|
|
||||||
|
|
||||||
class CliSvgRenderKind(enum.StrEnum):
|
class CliSvgRenderKind(enum.StrEnum):
|
||||||
@@ -20,6 +21,26 @@ class CliSvgRenderKind(enum.StrEnum):
|
|||||||
raise ValueError(f"Unknown CLI-specific SVG render kind: {self}")
|
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)
|
@dataclass(frozen=True)
|
||||||
class StdOpts:
|
class StdOpts:
|
||||||
"""Assemblicon standard command line options"""
|
"""Assemblicon standard command line options"""
|
||||||
@@ -32,6 +53,11 @@ class StdOpts:
|
|||||||
"""The list holding all name of jobs for building."""
|
"""The list holding all name of jobs for building."""
|
||||||
svg_render: CliSvgRenderKind
|
svg_render: CliSvgRenderKind
|
||||||
"""The render kind for SVG file."""
|
"""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)
|
@dataclass(frozen=True)
|
||||||
@@ -98,6 +124,16 @@ def create_argparser(setup: StdOptsSetup) -> ArgumentParser:
|
|||||||
help="The render used for rendering SVG into PNG.",
|
help="The render used for rendering SVG into PNG.",
|
||||||
metavar="RENDER",
|
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
|
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,
|
output_directory=ns.output if cfg.require_output else None,
|
||||||
selection=ns.selection,
|
selection=ns.selection,
|
||||||
svg_render=ns.svg_render,
|
svg_render=ns.svg_render,
|
||||||
|
format_selection=ns.format_selection,
|
||||||
)
|
)
|
||||||
@@ -1,6 +1,19 @@
|
|||||||
import enum
|
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):
|
class AddressDomain(enum.IntEnum):
|
||||||
Input = enum.auto()
|
Input = enum.auto()
|
||||||
Temporary = enum.auto()
|
Temporary = enum.auto()
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from pathlib import Path
|
|||||||
from typing import TypeVar, Generic, Callable
|
from typing import TypeVar, Generic, Callable
|
||||||
from ..lowlevel.environment import Prologue as LowPrologue, Environment as LowEnv
|
from ..lowlevel.environment import Prologue as LowPrologue, Environment as LowEnv
|
||||||
from ..lowlevel.artrdr import SvgRenderKind
|
from ..lowlevel.artrdr import SvgRenderKind
|
||||||
|
from .address import Family
|
||||||
from .utils import (
|
from .utils import (
|
||||||
FdContext,
|
FdContext,
|
||||||
IcoCategory,
|
IcoCategory,
|
||||||
@@ -53,6 +54,16 @@ class Prologue(LowPrologue):
|
|||||||
The only argument in function is the path to user temporary directory.
|
The only argument in function is the path to user temporary directory.
|
||||||
``None`` for no extra initializer.
|
``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:
|
def __post_init__(self) -> None:
|
||||||
super().__post_init__()
|
super().__post_init__()
|
||||||
@@ -70,6 +81,15 @@ class Prologue(LowPrologue):
|
|||||||
for targetsize in self.msix_ext_targetsizes:
|
for targetsize in self.msix_ext_targetsizes:
|
||||||
check_msix_targetsize(targetsize)
|
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_USER_DIR: str = "user"
|
||||||
_TEMP_LIB_DIR: str = "assemblicon"
|
_TEMP_LIB_DIR: str = "assemblicon"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from .common import Sink
|
from .common import Sink
|
||||||
from ..address import Address, AddressDomain
|
from ..address import Address, AddressDomain, Family
|
||||||
from ..environment import Environment
|
from ..environment import Environment
|
||||||
from ..utils import Artifact, FdContext, check_vart
|
from ..utils import Artifact, FdContext, check_vart
|
||||||
from ...lowlevel import artio, artrdr
|
from ...lowlevel import artio, artrdr
|
||||||
@@ -26,6 +26,9 @@ class FdArtSink(Sink):
|
|||||||
return Address(AddressDomain.PosixFdOutput, str(self.__kind), self.__name)
|
return Address(AddressDomain.PosixFdOutput, str(self.__kind), self.__name)
|
||||||
|
|
||||||
def push(self, env: Environment, art: Artifact) -> None:
|
def push(self, env: Environment, art: Artifact) -> None:
|
||||||
|
if not env.prologue.allow_family(Family.Freedesktop):
|
||||||
|
return
|
||||||
|
|
||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
'Saving FreeDesktop artifact with kind "%s" and name "%s".',
|
'Saving FreeDesktop artifact with kind "%s" and name "%s".',
|
||||||
self.__kind,
|
self.__kind,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from .common import Sink
|
from .common import Sink
|
||||||
from ..address import Address, AddressDomain
|
from ..address import Address, AddressDomain, Family
|
||||||
from ..environment import Environment
|
from ..environment import Environment
|
||||||
from ..utils import Artifact, IcnsCategory, check_vart
|
from ..utils import Artifact, IcnsCategory, check_vart
|
||||||
from ...lowlevel import artrdr
|
from ...lowlevel import artrdr
|
||||||
@@ -26,6 +26,9 @@ class IcnsArtSink(Sink):
|
|||||||
return Address(AddressDomain.MacIcnsOutput, str(self.__kind), self.__name)
|
return Address(AddressDomain.MacIcnsOutput, str(self.__kind), self.__name)
|
||||||
|
|
||||||
def push(self, env: Environment, art: Artifact) -> None:
|
def push(self, env: Environment, art: Artifact) -> None:
|
||||||
|
if not env.prologue.allow_family(Family.Icns):
|
||||||
|
return
|
||||||
|
|
||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
'Saving macOS ICNS artifact with kind "%s" and name "%s".',
|
'Saving macOS ICNS artifact with kind "%s" and name "%s".',
|
||||||
self.__kind,
|
self.__kind,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from .common import Sink
|
from .common import Sink
|
||||||
from ..address import Address, AddressDomain
|
from ..address import Address, AddressDomain, Family
|
||||||
from ..environment import Environment
|
from ..environment import Environment
|
||||||
from ..utils import Artifact, IcoCategory, check_vart
|
from ..utils import Artifact, IcoCategory, check_vart
|
||||||
from ...lowlevel import artrdr
|
from ...lowlevel import artrdr
|
||||||
@@ -26,6 +26,9 @@ class IcoArtSink(Sink):
|
|||||||
return Address(AddressDomain.WinIcoOutput, str(self.__kind), self.__name)
|
return Address(AddressDomain.WinIcoOutput, str(self.__kind), self.__name)
|
||||||
|
|
||||||
def push(self, env: Environment, art: Artifact) -> None:
|
def push(self, env: Environment, art: Artifact) -> None:
|
||||||
|
if not env.prologue.allow_family(Family.Ico):
|
||||||
|
return
|
||||||
|
|
||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
'Saving Windows ICO artifact with kind "%s" and name "%s".',
|
'Saving Windows ICO artifact with kind "%s" and name "%s".',
|
||||||
self.__kind,
|
self.__kind,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from .common import Sink
|
from .common import Sink
|
||||||
from ..address import Address, AddressDomain
|
from ..address import Address, AddressDomain, Family
|
||||||
from ..environment import Environment
|
from ..environment import Environment
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
Artifact,
|
Artifact,
|
||||||
@@ -33,6 +33,9 @@ class MsixArtSink(Sink):
|
|||||||
return Address(AddressDomain.WinMsixOutput, str(self.__kind), self.__name)
|
return Address(AddressDomain.WinMsixOutput, str(self.__kind), self.__name)
|
||||||
|
|
||||||
def push(self, env: Environment, art: Artifact) -> None:
|
def push(self, env: Environment, art: Artifact) -> None:
|
||||||
|
if not env.prologue.allow_family(Family.Msix):
|
||||||
|
return
|
||||||
|
|
||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
'Saving Windows MSIX artifact with kind "%s" and name "%s".',
|
'Saving Windows MSIX artifact with kind "%s" and name "%s".',
|
||||||
self.__kind,
|
self.__kind,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from .common import Source
|
from .common import Source
|
||||||
from ..address import Address, AddressDomain
|
from ..address import Address, AddressDomain, Family
|
||||||
from ..environment import Environment
|
from ..environment import Environment
|
||||||
from ..sink.fdart_sink import FdArtSink
|
from ..sink.fdart_sink import FdArtSink
|
||||||
from ..utils import FdContext
|
from ..utils import FdContext
|
||||||
@@ -20,6 +20,9 @@ class FdArtSource(Source):
|
|||||||
return Address(AddressDomain.PosixFdOutput, str(self.__kind), self.__name)
|
return Address(AddressDomain.PosixFdOutput, str(self.__kind), self.__name)
|
||||||
|
|
||||||
def link_to(self, env: Environment, fd_sink: FdArtSink) -> None:
|
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()
|
sink_hint = fd_sink.push_hint()
|
||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
'Duplicating FreeDesktop artifact from kind "%s" name "%s" to kind "%s" name "%s".',
|
'Duplicating FreeDesktop artifact from kind "%s" name "%s" to kind "%s" name "%s".',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from .common import Source
|
from .common import Source
|
||||||
from ..address import Address, AddressDomain
|
from ..address import Address, AddressDomain, Family
|
||||||
from ..environment import Environment
|
from ..environment import Environment
|
||||||
from ..sink.icnsart_sink import IcnsArtSink
|
from ..sink.icnsart_sink import IcnsArtSink
|
||||||
from ..utils import IcnsCategory
|
from ..utils import IcnsCategory
|
||||||
@@ -20,6 +20,9 @@ class IcnsArtSource(Source):
|
|||||||
return Address(AddressDomain.MacIcnsOutput, str(self.__kind), self.__name)
|
return Address(AddressDomain.MacIcnsOutput, str(self.__kind), self.__name)
|
||||||
|
|
||||||
def link_to(self, env: Environment, icns_sink: IcnsArtSink) -> None:
|
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()
|
sink_hint = icns_sink.push_hint()
|
||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
'Duplicating macOS ICNS artifact from kind "%s" name "%s" to kind "%s" name "%s".',
|
'Duplicating macOS ICNS artifact from kind "%s" name "%s" to kind "%s" name "%s".',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from .common import Source
|
from .common import Source
|
||||||
from ..address import Address, AddressDomain
|
from ..address import Address, AddressDomain, Family
|
||||||
from ..environment import Environment
|
from ..environment import Environment
|
||||||
from ..sink.icoart_sink import IcoArtSink
|
from ..sink.icoart_sink import IcoArtSink
|
||||||
from ..utils import IcoCategory
|
from ..utils import IcoCategory
|
||||||
@@ -20,6 +20,9 @@ class IcoArtSource(Source):
|
|||||||
return Address(AddressDomain.WinIcoOutput, str(self.__kind), self.__name)
|
return Address(AddressDomain.WinIcoOutput, str(self.__kind), self.__name)
|
||||||
|
|
||||||
def link_to(self, env: Environment, ico_sink: IcoArtSink) -> None:
|
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()
|
sink_hint = ico_sink.push_hint()
|
||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
'Duplicating Windows ICO artifact from kind "%s" name "%s" to kind "%s" name "%s".',
|
'Duplicating Windows ICO artifact from kind "%s" name "%s" to kind "%s" name "%s".',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from .common import Source
|
from .common import Source
|
||||||
from ..address import Address, AddressDomain
|
from ..address import Address, AddressDomain, Family
|
||||||
from ..environment import Environment
|
from ..environment import Environment
|
||||||
from ..sink.msixart_sink import MsixArtSink, MsixArtSinkHint
|
from ..sink.msixart_sink import MsixArtSink, MsixArtSinkHint
|
||||||
from ..utils import MsixCategory, MsixAppLogoKind, MsixAppPlatedKind
|
from ..utils import MsixCategory, MsixAppLogoKind, MsixAppPlatedKind
|
||||||
@@ -20,6 +20,9 @@ class MsixArtSource(Source):
|
|||||||
return Address(AddressDomain.WinMsixOutput, str(self.__kind), self.__name)
|
return Address(AddressDomain.WinMsixOutput, str(self.__kind), self.__name)
|
||||||
|
|
||||||
def link_to(self, env: Environment, msix_sink: MsixArtSink) -> None:
|
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()
|
sink_hint = msix_sink.push_hint()
|
||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
'Duplicating Windows MSIX artifact from kind "%s" name "%s" to kind "%s" name "%s".',
|
'Duplicating Windows MSIX artifact from kind "%s" name "%s" to kind "%s" name "%s".',
|
||||||
|
|||||||
Reference in new issue
Block a user