anod.spec

Attributes

__version__

SUPPORTED_API

logger

spec_logger

BUILD_PRIMITIVE

Classes

Anod

Anod base class.

Functions

check_api_version(→ None)

Make sure there are no API mismatch.

parse_command(→ list[str])

Parse a command line formatting each string.

has_primitive(→ bool)

Return True if the primitive name is supported.

fetch_attr(→ Any)

Return an attribute or the default value if missing.

Module Contents

anod.spec.__version__ = '1.4'
anod.spec.SUPPORTED_API
anod.spec.logger
anod.spec.spec_logger
anod.spec.BUILD_PRIMITIVE
anod.spec.check_api_version(version: str) None

Make sure there are no API mismatch.

Raise:

AnodError if the API is not supported

anod.spec.parse_command(command: collections.abc.Sequence[str], build_space: e3.anod.buildspace.BuildSpace) list[str]

Parse a command line formatting each string.

Parameters:
  • command – the command line (a list of string)

  • build_space – a build space object

anod.spec.has_primitive(anod_instance: Anod, name: Literal['download'] | PRIMITIVE) bool

Return True if the primitive name is supported.

Note that download is currently considered as a primitive in that context.

Parameters:
  • anod_instance – an Anod instance

  • name – name of the primitive (‘build’, ‘install’…)

anod.spec.fetch_attr(instance: Any, name: str, default_value: Any) Any

Return an attribute or the default value if missing.

Unlike getattr(instance, name, default_value), this works only on attributes present in the class (so class attributes or properties) and this does not hide AttributeError exceptions that getting an existing attribute might raise.

class anod.spec.Anod(qualifier: str | dict[str, str | bool | Iterable[str]] | None, kind: PRIMITIVE, jobs: int = 1, env: e3.env.BaseEnv | None = None, *, parse_qualifiers: bool = True)

Anod base class.

To write an Anod specification file, you’ll need to subclass Anod. A very basic Anod specification file could be:

from e3.anod.spec import Anod

class MyProduct(Anod):
    pass

All attributes starting with spec_ are reserved by the driver and must not be overwritten.

Several attributes are set when loading the spec:

Variables:
  • api_version – which API version is in use

  • data_files – set of yaml files associated with the spec

  • spec_checksum – the sha1 of the specification file content

  • spec_dir – directory where the specification files are located

  • name – the basename of the specification file (without the .anod extension)

  • sandbox (e3.anod.sandbox.SandBox | None) – e3.anod.sandbox.SandBox object shared by all Anod instances

Some attributes are meant to be overwritten in the specification file:

Variables:

source_pkg_build – a dictionary associating Anod.SourceBuilder to the Anod.Source names

Some attributes are here to simply the writing of specification files. They are part of the Anod API:

Variables:
  • Dependency – the e3.anod.deps.Dependency class

  • Package – the e3.anod.package.Package class

  • Source – the e3.anod.package.Source class

  • SourceBuilder – the e3.anod.package.SourceBuilder class

  • ThirdPartySourceBuilder – the e3.anod.package.ThirdPartySourceBuilder

  • uid (str | None) – unique identifier for the instance, None until the instance has been activated with AnodDriver.activate()

spec_checksum = ''
spec_dir = ''
sandbox: e3.anod.sandbox.SandBox | None = None
name = ''
api_version = '1.4'
data_files: tuple[str, Ellipsis] = ()
Dependency
Package
BuildVar
Source
SharedSource
SourceBuilder
ExternalSourceBuilder
ThirdPartySourceBuilder
deps: dict[str, Anod]
kind
jobs = 1
__build_space: e3.anod.buildspace.BuildSpace | None = None
log
env
uid = ''
_config: dict | None = None
_pre: dict[str, Any] | None = None
property qualifier: str
property enable_name_generator: bool

State if the name generation must be enabled.

If true, then both the ‘component’ and the ‘build_space_name’ are generated.

property readme_info: tuple[str, str] | None

Return readme location and final filename.

Note

This property make sens only if a component is declared.

Returns:

A tuple with a relative path to spec directory where the find the content and the final basename for the readme.

declare_qualifiers_and_components(qualifiers_manager: e3.anod.qualifiers_manager.QualifiersManager) None

Configure all the qualifiers and components.

This method must be overridden in the user spec to actually configure the QualifiersManager.

All the qualifiers must be declared using the declare_tag_qualifier and declare_key_value_qualifier spec_parameter_manager method.

All the components must be declared using the declare_component method of QualifiersManager class.

Parameters:

qualifiers_manager – the QualifiersManager instance to be configured.

property args: dict[str, str | bool | frozenset[str]]

Access to final qualifier values (with defaults set).

property base_name: str

Set the base name used for the name generation.

This method is used to provide the base name to be used by the name generator. By default, this base name is ‘self.name’ (the spec name without .anod).

It can be overloaded in the user spec.

property build_space_name: str

Return an automatic build_space_name.

If the component name is not None (from the component method), it will return the component name for consistency reasons.

Returns:

self.name if the name generator is disabled and the generated build_space name otherwise.

Return type:

str | None

property build_space: e3.anod.buildspace.BuildSpace
property has_package: bool

Return true if the spec defines a binary package.

bind_to_sandbox(sandbox: e3.anod.sandbox.SandBox) None

Bind spec instance to a physical Anod sandbox.

Binding an Anod instance to a sandbox will set the build_space attribute.

check_shared_libraries_closure(prefix: str | None = None, ignored_libs: list[str] | None = None, ldd_output: str | None = None, case_sensitive: bool | None = None) dict[str, list[tuple[str, str]]]

Sanity check the shared library closure.

Make sure that the libraries only depend on authorized system shared libraries.

Raise an error when a problem is detected.

It is possible to use the ldd_output parameter to mimic the ldd call. In that case, the ldd_output should look like:

/a/b/c.so:
        d.so => /e/f/d.so
        g.so => /a/b/g.so
/a/b/h.so:
        g.so => /a/b/g.so

Note

Indented lines above use the TAB character.

Note

This method may be used only on hosts with an ldd tool in the PATH. If the tool may not be found with which(), and ldd_output is not provided, a FileNotFoundError exception is raised.

Parameters:
  • prefix – The path where to find the library to be checked.

  • ignored_libs – The list of additional system libraries authorized in the closure.

  • ldd_output – An ldd command output.

  • case_sensitive – State if the comparison of a library name and the value in ignored_libs should be case-sensitive or not. If None, the comparison is case-sensitive, but on Windows hosts.

Returns:

A dictionary, where keys are the analyzed files, and the values are the shared libraries linked to that file (a tuple made of the file name and its path).

Raises:
  • AnodError – if some of the shared libraries in prefix (or in ldd_output) is not in the same directory as the analysed element.

  • FileNotFoundError – if ldd_output is not provided and ldd application cannot be found in the PATH.

load_config_file(extended: bool = False, suffix: str | None = None, selectors: dict | None = None) Any

Load a YAML config file associated with the current module.

This function looks for a YAML starting with the spec basename. The list of available file is set by the data_files parameter when initializing the spec.

Parameters:
  • suffix – suffix of the configuration file (default is None)

  • extended – if True then a special yaml parser is used with ability to use case statement

  • selectors – additional selectors for extended mode

__getitem__(key: str) Any

Access build_space attributes and pre callback values directly.

Allow accessing all build_space attributes directly by using __getitem__, e.g. self[‘PKG_DIR’] to access self.build_space.pkg_dir values.

Also, directly access items returned by the pre callback.

get_qualifier(qualifier_name: str) str | bool | frozenset[str] | None

Return a qualifier value.

Requires that qualifiers_manager attribute has been initialized and its parse method called.

Returns:

The qualifier value: - A string for key value qualifiers - A bool for tag qualifiers - None if the name_generator is disabled

classmethod primitive(pre: str | None = None, post: str | None = None, version: collections.abc.Callable[Ellipsis, str] | None = None, require: collections.abc.Callable[[Anod], bool] | None = None, post_install: bool = False) collections.abc.Callable

Declare an anod primitive.

Catch all exceptions and raise AnodError with the traceback

Parameters:
  • pre – None or name of method in the spec to call before running the primitive. The method takes a unique parameter self and returns a dict

  • post – None or “install”. This parameter is obsolete and should not be used. Prefer “post_install=True” to achieve the same effect

  • version – None or a callback function returning the version that will be evaluated as a string. This callback is called after running the primitive

  • require – None or a special function to call before running the primitive. The function takes a unique parameter self and returns a boolean

  • post_install – if True call the install primitive after the build primitive. Note that between the two a binary package might be generated depending on the context. This is equivalent to post=”install”

Raise:

AnodError

property package: e3.anod.package.Package | None

Return binary package creation recipe.

If None don’t create a binary package, needs a component name set.

property component: str | None

Return component name.

If None, don’t created a component (nor a binary package). :return: None if the name generator is disabled and the generated name otherwise (possibly None if no component is required)

property module_name: str

For backward compatibility purpose.

property anod_id: str

For backward compatibility purpose.

property source_pkg_build: list[e3.anod.package.SourceBuilder] | None

Return list of SourceBuilder defined in the specification file.

shell(*command: str, parse_shebang: bool = True, output: e3.os.process.DEVNULL_VALUE | e3.os.process.PIPE_VALUE | str | IO | None = None, python_executable: None = None, **kwargs: Any) e3.os.process.Run

Run a subprocess using e3.os.process.Run.

Contrary to what is done in e3.os.process.Run parse_shebang defaults to True and output is by default set to the anod build space log stream.

Note that calling shell() raises an exception when the process returns an exit code that is not 0.

Same options as e3.os.process.Run with some small differences:

Parameters:
  • python_executable – kept for backward compatibility but ignored

  • output – by default set to anod build space log stream

  • parse_shebang – by default set True

Raise:

ShellError