From 800206f3d2f2fbcc51447b4d0f42bff0df3a5386 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Fri, 28 Feb 2025 16:16:03 +0100 Subject: [PATCH 001/138] Crude schema migration to Pydantic model and JSON Schema --- constructor/construct.py | 1285 +++++++++++----------- constructor/data/constructor.schema.json | 454 ++++++++ 2 files changed, 1105 insertions(+), 634 deletions(-) create mode 100644 constructor/data/constructor.schema.json diff --git a/constructor/construct.py b/constructor/construct.py index a4393a619..9be9f0191 100644 --- a/constructor/construct.py +++ b/constructor/construct.py @@ -4,12 +4,14 @@ # constructor is distributed under the terms of the BSD 3-clause license. # Consult LICENSE.txt or http://opensource.org/licenses/BSD-3-Clause. +import json import logging import re import sys from functools import partial from os.path import dirname +from pydantic import BaseModel, ConfigDict from ruamel.yaml import YAMLError from constructor.exceptions import UnableToParse, UnableToParseMissingJinja2, YamlParsingError @@ -20,636 +22,648 @@ "signtool", ] -# list of tuples (key name, required, type, description) -KEYS = [ - ('name', True, str, ''' -Name of the installer. Names may be composed of letters, numbers, -underscores, dashes, and periods, but may not begin or end with a -dash or period. -'''), - - ('version', True, str, ''' -Version of the installer. Versions may be composed of letters, numbers, -underscores, dashes, and periods, but may not begin or end with a -dash or period. -'''), - - ('channels', False, list, ''' -The conda channels from which packages are retrieved. At least one channel must -be supplied, either in `channels` or `channels_remap`. - -See notes in `channels_remap` for details about local channels. -'''), - - ('channels_remap', False, list, ''' -A list of `src/dest` channel URL pairs. When building the installer, conda will -use the `src` channels to solve and fetch the packages. However, the resulting -installation will see the packages as coming from the `dest` equivalent. -This allows an installer to be built against a different set of channels than -will be present when the installer is actually used. Example use: - -```yaml -channels_remap: - - src: file:///tmp/a3/conda-bld # [unix] - dest: https://repo.anaconda.com/pkgs/main # [unix] - - src: file:///D:/tmp/a3/conda-bld # [win] - dest: https://repo.anaconda.com/pkgs/main # [unix] -``` - -At least one channel must be supplied, either in `channels` or `channels_remap`. -'''), - - ('specs', False, (list, str), ''' -A list of package specifications; e.g. `python 2.7*`, `pyzmq` or `numpy >=1.8`. -The specifications are identical in form and purpose to those that would be -included in a `conda create --file` command. Packages may also be specified -by an exact URL; e.g., -`https://repo.anaconda.com/pkgs/main/osx-64/openssl-1.0.2o-h26aff7b_0.tar.bz2`. -This key can also take a `str` pointing to a requirements file with the same syntax. - -Note: `constructor` relies on `conda`'s Python API to solve the passed -specifications. You can still set the `CONDA_SOLVER` environment variable -to override system-wide settings for `constructor`. If you are using -`constructor` from a non-`base` environment, make sure the -configured solver plugin is also installed in that environment. -'''), - - ('user_requested_specs', False, (list, str), ''' -A list of package specifications to be recorded as "user-requested" for the -initial environment in conda's history file. This information is used by newer -versions of conda to better filter its package choices on subsequent installs; -for example, if `python=3.6` is included, then conda will always seek versions -of packages compatible with Python 3.6. If this is option is not provided, it -will be set equal to the value of `specs`. -'''), - - ('virtual_specs', False, list, ''' -A list of virtual packages that must be satisfied at install time. Virtual -packages must start with `__`. For example, `__osx>=11` or `__glibc>=2.24`. -These specs are dry-run solved offline by the bundled `--conda-exe` binary. -In SH installers, `__glibc>=x.y` and `__osx>=x.y` specs can be checked with -Bash only. The detected version can be overriden with environment variables -`CONDA_OVERRIDE_GLIBC` and `CONDA_OVERRIDE_OSX`, respectively. In PKG -installers, `__osx` specs can be checked natively without the solver being -involved as long as only `>=`, `<` or `,` are used. -'''), - - ('exclude', False, list, ''' -A list of package names to be excluded after the `specs` have been resolved. -For example, you can say that `readline` should be excluded, even though it -is contained as a result of resolving the specs for `python 2.7`. -'''), - - ('menu_packages', False, list, ''' -A list of packages with menu items to be installed. The packages must have -necessary metadata in `Menu/.json`). By default, all menu items -found in the installation will be created; supplying this list allows a -subset to be selected instead. If an empty list is supplied, no shortcuts will -be created. - -If all environments (`extra_envs` included) set `menu_packages` to an empty list, -no UI options about shortcuts will be offered to the user. - -Note: This option is not fully implemented when `micromamba` is used as -the `--conda-exe` binary. The only accepted value is an empty list (`[]`). -'''), - - ('ignore_duplicate_files', False, bool, ''' -By default, constructor will warn you when adding packages with duplicate -files in them. Setting this option to false will raise an error instead. -'''), - - ('install_in_dependency_order', False, (bool, str), ''' -_Obsolete_. The current version of constructor relies on the standalone -conda executable for its installation behavior. This option is now -ignored with a warning. -'''), - - ('environment', False, str, ''' -Name of the environment to construct from. If this option is present, the -`specs` argument will be ignored. Using this option allows the user to -curate the enviromment interactively using standard `conda` commands, and -run constructor with full confidence that the exact environment will be -reproduced. -'''), - - ('environment_file', False, str, ''' -Path to an environment file (TXT or YAML) to construct from. If this option -is present, the `specs` argument will be ignored. Instead, constructor will -call conda to create a temporary environment, constructor will build and -installer from that, and the temporary environment will be removed. -This ensures that constructor is using the precise local conda configuration -to discover and install the packages. The created environment MUST include -`python`. - -Read notes about the solver in the `specs` field. -'''), - - ('transmute_file_type', False, str, ''' -File type extension for the files to be transmuted into. Currently supports -only '.conda'. See conda-package-handling for supported extension names. -If left empty, no transmuting is done. -'''), - - ('conda_default_channels', False, list, ''' -If this value is provided as well as `write_condarc`, then the channels -in this list will be included as the value of the `default_channels:` -option in the environment's `.condarc` file. This will have an impact -only if `conda` is included in the environmnent. -'''), - ('conda_channel_alias', False, str, ''' -The channel alias that would be assumed for the created installer -(only useful if it includes conda). -'''), - - ('extra_envs', False, (dict,), ''' -Create more environments in addition to the default `base` provided by `specs`, -`environment` or `environment_file`. This should be a map of `str` (environment -name) to a dictionary of options: -- `specs` (list of str): which packages to install in that environment -- `environment` (str): same as global option, for this env -- `environment_file` (str): same as global option, for this env -- `channels` (list of str): using these channels; if not provided, the global - value is used. To override inheritance, set it to an empty list. -- `channels_remap` (list of str): same as global option, for this env; - if not provided, the global value is used. To override inheritance, set it to - an empty list. -- `user_requested_specs` (list of str): same as the global option, but for this env; - if not provided, global value is _not_ used -- `menu_packages` (list of str): same as the global option, for this env; - if not provided, the global value is _not_ used. - -Notes: -- `ignore_duplicate_files` will always be considered `True` if `extra_envs` is in use. -- `conda` needs to be present in the `base` environment (via `specs`) -- If a global `exclude` option is used, it will have an effect on the environments created - by `extra_envs` too. For example, if the global environment excludes `tk`, none of the - extra environments will have it either. Unlike the global option, an error will not be - thrown if the excluded package is not found in the packages required by the extra environment. - To override the global `exclude` value, use an empty list `[]`. -'''), - - ('register_envs', False, bool, ''' -Whether to register the environments created by the installer (both `base` and `extra_envs`) -in `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. Defaults to `True`. -'''), - - ('installer_filename', False, str, ''' -The filename of the installer being created. If not supplied, a reasonable -default will determined by the `name`, `version`, platform, and installer type. -'''), - - ('installer_type', False, (str, list), ''' -The type of the installer being created. Possible values are: -- `sh`: shell-based installer for Linux or macOS; -- `pkg`: macOS GUI installer built with Apple's `pkgbuild` -- `exe`: Windows GUI installer built with NSIS - -The default type is `sh` on Linux and macOS, and `exe` on Windows. A special -value of `all` builds _both_ `sh` and `pkg` installers on macOS, as well -as `sh` on Linux and `exe` on Windows. - -Notes for silent mode `/S` on Windows EXEs: -- NSIS Silent mode will not print any error message, but will silently abort the installation. - If needed, [NSIS log-builds][nsis-log] can be used to print to `%PREFIX%\\install.log`, which - can be searched for `::error::` strings. Pre- and post- install scripts will only throw an error - if the environment variable `NSIS_SCRIPTS_RAISE_ERRORS` is set. -- The `/D` flag can be used to specify the target location. It must be the last argument in - the command and should NEVER be quoted, even if it contains spaces. For example: - `CMD.EXE /C START /WAIT myproject.exe /S /D=C:\\path with spaces\\my project`. - -[nsis-log]: https://nsis.sourceforge.io/Special_Builds -'''), - - ('license_file', False, str, ''' -Path to the license file being displayed by the installer during the install -process. It must be plain text (.txt) for shell-based installers. On PKG, -.txt, .rtf and .html are supported. On Windows, .txt and .rtf are supported. -'''), - - ('keep_pkgs', False, bool, ''' -If `False` (default), the package cache in the `pkgs` subdirectory is removed -when the installation process is complete. If `True`, this subdirectory and -its contents are preserved. If `keep_pkgs` is `False`, Unix `.sh` and Windows `.msi` -installers offer a command-line option (`-k` and `/KeepPkgCache`, respectively) -to preserve the package cache. -'''), - - ('batch_mode', False, bool, ''' -Only affects ``.sh`` installers. If ``False`` (default), the installer launches -an interactive wizard guiding the user through the available options. If -``True``, the installer runs automatically as if ``-b`` was passed. -'''), - - ('signing_identity_name', False, str, ''' -By default, the MacOS pkg installer isn't signed. If an identity name is specified -using this option, it will be used to sign the installer with Apple's `productsign`. -Note that you will need to have a certificate (usually an "Installer certificate") -and the corresponding private key, together called an 'identity', in one of your -accessible keychains. Common values for this option follow this format -`Developer ID Installer: Name of the owner (XXXXXX)`. -'''), - - ('notarization_identity_name', False, str, ''' -If the pkg installer is going to be signed with `signing_identity_name`, you -can also prepare the bundle for notarization. This will use Apple's `codesign` -to sign `conda.exe`. For this, you need an "Application certificate" (different from the -"Installer certificate" mentioned above). Common values for this option follow the format -`Developer ID Application: Name of the owner (XXXXXX)`. -'''), - - ('windows_signing_tool', False, str, f''' -The tool used to sign Windows installers. Must be one of: {", ".join(WIN_SIGNTOOLS)}. -Some tools require `signing_certificate` to be set. -Defaults to `signtool` if `signing_certificate` is set. -Additional environment variables may need to be used to configure signing. -See the documentation for details: -https://conda.github.io/constructor/howto/#signing-exe-installers -'''), - - ('signing_certificate', False, str, ''' -On Windows only, set this key to the path of the certificate file to be used -with the `windows_signing_tool`. -'''), - - ('attempt_hardlinks', False, (bool, str), ''' -_Obsolete_. The current version of constructor relies on the standalone -conda executable for its installation behavior. This option is now -ignored with a warning. -'''), - - ('write_condarc', False, bool, ''' -By default, no `.condarc` file is written. If set, a `.condarc` file is written to -the base environment if there are any channels or conda_default_channels is set. -'''), - - ('condarc', False, (dict, str), ''' -If set, a `.condarc` file is written to the base environment containing the contents -of this value. The value can either be a string (likely a multi-line string) or -a dictionary, which will be converted to a YAML string for writing. _Note:_ if this -option is used, then all other options related to the construction of a `.condarc` -file (`write_condarc`, `conda_default_channels`, etc.) are ignored. -'''), - - ('company', False, str, ''' -Name of the company/entity who is responsible for the installer. -'''), - - ('reverse_domain_identifier', False, str, ''' -Unique identifier for this package, formatted with reverse domain notation. This is -used internally in the PKG installers to handle future updates and others. If not -provided, it will default to `io.continuum`. (MacOS only) -'''), - - ('uninstall_name', False, str, ''' -Application name in the Windows "Programs and Features" control panel. -Defaults to `${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})`. -'''), - - ('script_env_variables', False, (dict,), ''' -Dictionary of additional environment variables to be made available to -the pre_install and post_install scripts, in the form of VAR:VALUE -pairs. These environment variables are in addition to those in the -`post_install` section above and take precedence in the case of name -collisions. - -On Unix the variable values are automatically single quoted, allowing -you to supply strings with spaces, without needing to worry about -escaping. As a consequence, string interpolation is disabled: if you -need string interpolation, you can apply it in the -pre_install/post_install script(s). If you need to include single quotes -in your value, you can escape them by replacing each single quote with -`'\''`. - -On Windows, single quotes and double quotes are not supported. - -Note that the # (hash) character cannot be used as it denotes yaml -comments for all platforms. -'''), - ('pre_install', False, str, ''' -Path to a pre-install script, run after the package cache has been set, but -before the files are linked to their final locations. As a result, you should -only rely on tools known to be available on most systems (e.g. `bash`, `cmd`, -etc). See `post_install` for information about available environment variables. -'''), - - ('pre_install_desc', False, str, ''' -A description of the purpose of the supplied `pre_install` script. If this -string is supplied and non-empty, then the Windows and macOS GUI installers -will display it along with checkbox to enable or disable the execution of the -script. If this string is not supplied, it is assumed that the script -is compulsory and the option to disable it will not be offered. - -This option has no effect on `SH` installers. -'''), - - ('post_install', False, str, ''' -Path to a post-install script. Some notes: - -- For Unix `.sh` installers, the shebang line is respected if present; - otherwise, the script is run by the POSIX shell `sh`. Note that the use - of a shebang can reduce the portability of the installer. The - installation path is available as `${PREFIX}`. Installer metadata is - available in the `${INSTALLER_NAME}`, `${INSTALLER_VER}`, `${INSTALLER_PLAT}` - environment variables. `${INSTALLER_TYPE}` is set to `SH`. - `${INSTALLER_UNATTENDED}` will be `"1"` in batch mode (`-b`), `"0"` otherwise. -- For PKG installers, the shebang line is respected if present; - otherwise, `bash` is used. The same variables mentioned for `sh` - installers are available here. `${INSTALLER_TYPE}` is set to `PKG`. - `${INSTALLER_UNATTENDED}` will be `"1"` for command line installs, `"0"` otherwise. -- For Windows `.exe` installers, the script must be a `.bat` file. - Installation path is available as `%PREFIX%`. Metadata about - the installer can be found in the `%INSTALLER_NAME%`, `%INSTALLER_VER%`, - `%INSTALLER_PLAT%` environment variables. `%INSTALLER_TYPE%` is set to `EXE`. - `%INSTALLER_UNATTENDED%` will be `"1"` in silent mode (`/S`), `"0"` otherwise. - -If necessary, you can activate the installed `base` environment like this: - -- Unix: `source "$PREFIX/etc/profile.d/conda.sh" && conda activate "$PREFIX"` -- Windows: `call "%PREFIX%\\Scripts\\activate.bat"` -'''), - - ('post_install_desc', False, str, ''' -A description of the purpose of the supplied `post_install` script. If this -string is supplied and non-empty, then the Windows and macOS GUI installers -will display it along with checkbox to enable or disable the execution of the -script. If this string is not supplied, it is assumed that the script -is compulsory and the option to disable it will not be offered. - -This option has no effect on `SH` installers. -'''), - - ('pre_uninstall', False, str, ''' -Path to a pre uninstall script. This is only supported for on Windows, -and must be a `.bat` file. Installation path is available as `%PREFIX%`. -Metadata about the installer can be found in the `%INSTALLER_NAME%`, -`%INSTALLER_VER%`, `%INSTALLER_PLAT%` environment variables. -`%INSTALLER_TYPE%` is set to `EXE`. -'''), - - ('default_prefix', False, str, r''' -Set default install prefix. On Linux, if not provided, the default prefix -is `${HOME}/` (or, if `HOME` is not set, `/opt/`). On Windows, -this is used only for "Just Me" installation; for "All Users" installation, -use the `default_prefix_all_users` key. If not provided, the default prefix -is `%USERPROFILE%\`. Environment variables will be expanded at -installation time. -'''), # noqa - - ('default_prefix_domain_user', False, str, r''' -Set default installation prefix for domain user. If not provided, the -installation prefix for domain user will be `%LOCALAPPDATA%\`. -By default, it is different from the `default_prefix` value to avoid installing -the distribution in the roaming profile. Environment variables will be expanded -at installation time. Windows only. -'''), # noqa - - ('default_prefix_all_users', False, str, r''' -Set default installation prefix for All Users installation. If not provided, -the installation prefix for all users installation will be -`%ALLUSERSPROFILE%\`. Environment variables will be expanded at installation -time. Windows only. -'''), # noqa - - ('default_location_pkg', False, str, ''' -Default installation subdirectory in the chosen volume. In PKG installers, -default installation locations are configured differently. The user can choose -between a "Just me" installation (which would result in `~/`) or another -volume (which defaults to `/`). If you want a different default, -you can add a middle component with this option, let's call it `location`. It would -result in these default values: `~//` for "Just me", -`//` for custom volumes. For example, setting this option -to `/Library` in a "Just me" installation will give you `~/Library/`. -Internally, this is passed to `pkgbuild --install-location`. -macOS only. -'''), - - ('pkg_domains', False, dict, ''' -The domains the package can be installed into. For a detailed explanation, see: -https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html -constructor defaults to `enable_anywhere=true` and `enable_currentUserHome=true`. -`enable_localSystem` should not be set to true unless `default_location_pkg` is set as well. -macOS only. -'''), - - ('pkg_name', False, str, ''' -Internal identifier for the installer. This is used in the build prefix and will -determine part of the default location path. Combine with `default_location_pkg` -for more flexibility. If not provided, the value of `name` will be used. (MacOS only) -'''), - - ('install_path_exists_error_text', False, str, ''' -Error message that will be shown if the installation path already exists. -You cannot use double quotes or newlines. The placeholder `{CHOSEN_PATH}` is -available and set to the destination causing the error. Defaults to: - -> '{CHOSEN_PATH}' already exists. Please, relaunch the installer and -> choose another location in the Destination Select step. - -(MacOS only) -'''), - - ('progress_notifications', False, bool, ''' -Whether to show UI notifications on PKG installers. On large installations, -the progress bar reaches ~90% very quickly and stays there for a long time. -This might look like the installer froze. This option enables UI notifications -so the user receives updates after each command executed by the installer. -(macOS only) -'''), - - ('welcome_image', False, str, ''' -Path to an image in any common image format (`.png`, `.jpg`, `.tif`, etc.) -to be used as the welcome image for the Windows and PKG installers. -The image is re-sized to 164 x 314 pixels on Windows and 1227 x 600 on Macos. -By default, an image is automatically generated on Windows. On MacOS, Anaconda's -logo is shown if this key is not provided. If you don't want a background on -PKG installers, set this key to `""` (empty string). -'''), - - ('header_image', False, str, ''' -Like `welcome_image` for Windows, re-sized to 150 x 57 pixels. -'''), - - ('icon_image', False, str, ''' -Like `welcome_image` for Windows, re-sized to 256 x 256 pixels. -'''), - - ('default_image_color', False, str, ''' -The color of the default images (when not providing explicit image files) -used on Windows. Possible values are `red`, `green`, `blue`, `yellow`. -The default is `blue`. -'''), - - ('welcome_image_text', False, str, ''' -If `welcome_image` is not provided, use this text when generating the image -(Windows and PKG only). Defaults to `name` on Windows. -'''), - - ('header_image_text', False, str, ''' -If `header_image` is not provided, use this text when generating the image -(Windows only). Defaults to `name`. -'''), - - ('initialize_conda', False, bool, ''' -Add an option to the installer so the user can choose whether to run `conda init` -after the install. See also `initialize_by_default`. -'''), - - ('initialize_by_default', False, bool, ''' -Whether to add the installation to the PATH environment variable. The default -is true for GUI installers (msi, pkg) and False for shell installers. The user -is able to change the default during interactive installation. NOTE: For Windows, -`AddToPath` is disabled when `InstallationType=AllUsers`. -'''), - - ('register_python', False, bool, ''' -Whether to offer the user an option to register the installed Python instance as the -system's default Python. (Windows only) -'''), - - ('register_python_default', False, bool, ''' -Default choice for whether to register the installed Python instance as the -system's default Python. The user is still able to change this during -interactive installation. (Windows only). -'''), - - ('check_path_length', False, bool, ''' -Check the length of the path where the distribution is installed to ensure nodejs -can be installed. Raise a message to request shorter path (less than 46 character) -or enable long path on windows > 10 (require admin right). Default is True. (Windows only). - -Read notes about the particularities of Windows silent mode `/S` in the -`installer_type` documentation. -'''), - - ('check_path_spaces', False, bool, ''' -Check if the path where the distribution is installed contains spaces. Default is True. -To allow installations with spaces, change to False. Note that: - -- A recent conda-standalone (>=22.11.1) or equivalent is needed for full support. -- `conda` cannot be present in the `base` environment - -Read notes about the particularities of Windows silent mode `/S` in the -`installer_type` documentation. -'''), - - ('nsis_template', False, str, ''' -If `nsis_template` is not provided, constructor uses its default -NSIS template. For more complete customization for the installation experience, -provide an NSIS template file. (Windows only). -'''), - - ('welcome_file', False, str, ''' -If `installer_type` is `pkg` on MacOS, this message will be -shown before the license information, right after the introduction. -File can be plain text (.txt), rich text (.rtf) or HTML (.html). If -both `welcome_file` and `welcome_text` are provided, `welcome_file` takes precedence. -(MacOS only). - -If the installer is for windows and welcome file type is nsi, -it will use the nsi script to add in extra pages before the installer -begins the installation process. -'''), - - ('welcome_text', False, str, ''' -If `installer_type` is `pkg` on MacOS, this message will be -shown before the license information, right after the introduction. -If this key is missing, it defaults to a message about Anaconda Cloud. -You can disable it altogether so it defaults to the system message -if you set this key to `""` (empty string). -(MacOS only). -'''), - - ('readme_file', False, str, ''' -If `installer_type` is `pkg` on MacOS, this message will be -shown before the license information, right after the welcome screen. -File can be plain text (.txt), rich text (.rtf) or HTML (.html). If -both `readme_file` and `readme_text` are provided, `readme_file` takes precedence. -(MacOS only). -'''), - - ('readme_text', False, str, ''' -If `installer_type` is `pkg` on MacOS, this message will be -shown before the license information, right after the welcome screen. -If this key is missing, it defaults to a message about Anaconda Cloud. -You can disable it altogether if you set this key to `""` (empty string). -(MacOS only). -'''), - - ('post_install_pages', False, (list, str), ''' -Adds extra pages to the installers to be shown after installation. - -For PKG installers, these can be compiled `installer` plug-ins or -directories containing an Xcode project. In the latter case, -constructor will try and compile the project file using `xcodebuild`. - -For Windows, the extra pages must be `.nsi` files. -They will be inserted as-is before the conclusion page. -'''), - - ('conclusion_file', False, str, ''' -If `installer_type` is `pkg` on MacOS, this message will be -shown at the end of the installer upon success. File can be -plain text (.txt), rich text (.rtf) or HTML (.html). If both -`conclusion_file` and `conclusion_text` are provided, -`conclusion_file` takes precedence. (MacOS only). - -If the installer is for Windows, the file type must be nsi. -'''), - - ('conclusion_text', False, str, ''' -A message that will be shown at the end of the installer upon success. -The behaviour is slightly different across installer types: -- PKG: If this key is missing, it defaults to a message about Anaconda Cloud. - You can disable it altogether so it defaults to the system message if you set this - key to `""` (empty string). -- EXE: The first line will be used as a title. The following lines will be used as text. -(macOS PKG and Windows only). -'''), - - ('extra_files', False, list, ''' -Extra, non-packaged files that should be added to the installer. If provided as relative -paths, they will be considered relative to the directory where `construct.yaml` is. -This setting can be passed as a list of: -- `str`: each found file will be copied to the root prefix -- `Mapping[str, str]`: map of path in disk to path in prefix. -'''), - - ('temp_extra_files', False, list, ''' -Temporary files that could be referenced in the installation process (i.e. customized -`welcome_file` and `conclusion_file` (see above)) . Should be a list of -file paths, relative to the directory where `construct.yaml` is. In Windows, these -files will be copied into a temporary folder, the NSIS `$PLUGINSDIR`, during -install process (Windows only). - -Supports the same values as `extra_files`. -'''), - - ('build_outputs', False, list, ''' -Additional artifacts to be produced after building the installer. -It expects either a list of strings or single-key dictionaries: -Allowed keys are: -- `hash`: The hash of the installer files. - - `algorithm` (str or list): The hash algorithm. Must be among `hashlib`'s available algorithms: - https://docs.python.org/3/library/hashlib.html#hashlib.algorithms_available -- `info.json`: The internal `info` object, serialized to JSON. Takes no options. -- `pkgs_list`: The list of packages contained in a given environment. Options: - - `env` (optional, default=`base`): Name of an environment in `extra_envs` to export. -- `lockfile`: An `@EXPLICIT` lockfile for a given environment. Options: - - `env` (optional, default=`base`): Name of an environment in `extra_envs` to export. -- `licenses`: Generate a JSON file with the licensing details of all included packages. Options: - - `include_text` (optional bool, default=`False`): Whether to dump the license text in the JSON. - If false, only the path will be included. - - `text_errors` (optional str, default=`None`): How to handle decoding errors when reading the - license text. Only relevant if include_text is True. Any str accepted by open()'s 'errors' - argument is valid. See https://docs.python.org/3/library/functions.html#open. -'''), - - ('uninstall_with_conda_exe', False, bool, ''' -Use the standalone binary to perform the uninstallation. -Requires conda-standalone 24.11.0 or newer. -'''), -] + +class ConstructorConfiguration(BaseModel): + """ + Schema for constructor.yaml input files. + """ + model_config: ConfigDict = ConfigDict( + extra="forbid", + use_attribute_docstrings=True, + ) + + name: str = ... + """ + Name of the installer. Names may be composed of letters, numbers, + underscores, dashes, and periods, but may not begin or end with a + dash or period. + """ + version: str = ... + """ + Version of the installer. Versions may be composed of letters, numbers, + underscores, dashes, and periods, but may not begin or end with a + dash or period. + """ + channels: list = list() + """ + The conda channels from which packages are retrieved. At least one channel must + be supplied, either in `channels` or `channels_remap`. + + See notes in `channels_remap` for details about local channels. + """ + channels_remap: list = list() + """ + A list of `src/dest` channel URL pairs. When building the installer, conda will + use the `src` channels to solve and fetch the packages. However, the resulting + installation will see the packages as coming from the `dest` equivalent. + This allows an installer to be built against a different set of channels than + will be present when the installer is actually used. Example use: + + ```yaml + channels_remap: + - src: file:///tmp/a3/conda-bld # [unix] + dest: https://repo.anaconda.com/pkgs/main # [unix] + - src: file:///D:/tmp/a3/conda-bld # [win] + dest: https://repo.anaconda.com/pkgs/main # [unix] + ``` + + At least one channel must be supplied, either in `channels` or `channels_remap`. + """ + specs: tuple = tuple() + """ + A list of package specifications; e.g. `python 2.7*`, `pyzmq` or `numpy >=1.8`. + The specifications are identical in form and purpose to those that would be + included in a `conda create --file` command. Packages may also be specified + by an exact URL; e.g., + `https://repo.anaconda.com/pkgs/main/osx-64/openssl-1.0.2o-h26aff7b_0.tar.bz2`. + This key can also take a `str` pointing to a requirements file with the same syntax. + + Note: `constructor` relies on `conda`'s Python API to solve the passed + specifications. You can still set the `CONDA_SOLVER` environment variable + to override system-wide settings for `constructor`. If you are using + `constructor` from a non-`base` environment, make sure the + configured solver plugin is also installed in that environment. + """ + user_requested_specs: tuple = tuple() + """ + A list of package specifications to be recorded as "user-requested" for the + initial environment in conda's history file. This information is used by newer + versions of conda to better filter its package choices on subsequent installs; + for example, if `python=3.6` is included, then conda will always seek versions + of packages compatible with Python 3.6. If this is option is not provided, it + will be set equal to the value of `specs`. + """ + virtual_specs: list = list() + """ + A list of virtual packages that must be satisfied at install time. Virtual + packages must start with `__`. For example, `__osx>=11` or `__glibc>=2.24`. + These specs are dry-run solved offline by the bundled `--conda-exe` binary. + In SH installers, `__glibc>=x.y` and `__osx>=x.y` specs can be checked with + Bash only. The detected version can be overriden with environment variables + `CONDA_OVERRIDE_GLIBC` and `CONDA_OVERRIDE_OSX`, respectively. In PKG + installers, `__osx` specs can be checked natively without the solver being + involved as long as only `>=`, `<` or `,` are used. + """ + exclude: list = list() + """ + A list of package names to be excluded after the `specs` have been resolved. + For example, you can say that `readline` should be excluded, even though it + is contained as a result of resolving the specs for `python 2.7`. + """ + menu_packages: list = list() + """ + A list of packages with menu items to be installed. The packages must have + necessary metadata in `Menu/.json`). By default, all menu items + found in the installation will be created; supplying this list allows a + subset to be selected instead. If an empty list is supplied, no shortcuts will + be created. + + If all environments (`extra_envs` included) set `menu_packages` to an empty list, + no UI options about shortcuts will be offered to the user. + + Note: This option is not fully implemented when `micromamba` is used as + the `--conda-exe` binary. The only accepted value is an empty list (`[]`). + """ + ignore_duplicate_files: bool = bool() + """ + By default, constructor will warn you when adding packages with duplicate + files in them. Setting this option to false will raise an error instead. + """ + install_in_dependency_order: tuple = tuple() + """ + _Obsolete_. The current version of constructor relies on the standalone + conda executable for its installation behavior. This option is now + ignored with a warning. + """ + environment: str = str() + """ + Name of the environment to construct from. If this option is present, the + `specs` argument will be ignored. Using this option allows the user to + curate the enviromment interactively using standard `conda` commands, and + run constructor with full confidence that the exact environment will be + reproduced. + """ + environment_file: str = str() + """ + Path to an environment file (TXT or YAML) to construct from. If this option + is present, the `specs` argument will be ignored. Instead, constructor will + call conda to create a temporary environment, constructor will build and + installer from that, and the temporary environment will be removed. + This ensures that constructor is using the precise local conda configuration + to discover and install the packages. The created environment MUST include + `python`. + + Read notes about the solver in the `specs` field. + """ + transmute_file_type: str = str() + """ + File type extension for the files to be transmuted into. Currently supports + only '.conda'. See conda-package-handling for supported extension names. + If left empty, no transmuting is done. + """ + conda_default_channels: list = list() + """ + If this value is provided as well as `write_condarc`, then the channels + in this list will be included as the value of the `default_channels:` + option in the environment's `.condarc` file. This will have an impact + only if `conda` is included in the environmnent. + """ + conda_channel_alias: str = str() + """ + The channel alias that would be assumed for the created installer + (only useful if it includes conda). + """ + extra_envs: tuple = tuple() + """ + Create more environments in addition to the default `base` provided by `specs`, + `environment` or `environment_file`. This should be a map of `str` (environment + name) to a dictionary of options: + - `specs` (list of str): which packages to install in that environment + - `environment` (str): same as global option, for this env + - `environment_file` (str): same as global option, for this env + - `channels` (list of str): using these channels; if not provided, the global + value is used. To override inheritance, set it to an empty list. + - `channels_remap` (list of str): same as global option, for this env; + if not provided, the global value is used. To override inheritance, set it to + an empty list. + - `user_requested_specs` (list of str): same as the global option, but for this env; + if not provided, global value is _not_ used + - `menu_packages` (list of str): same as the global option, for this env; + if not provided, the global value is _not_ used. + + Notes: + - `ignore_duplicate_files` will always be considered `True` if `extra_envs` is in use. + - `conda` needs to be present in the `base` environment (via `specs`) + - If a global `exclude` option is used, it will have an effect on the environments created + by `extra_envs` too. For example, if the global environment excludes `tk`, none of the + extra environments will have it either. Unlike the global option, an error will not be + thrown if the excluded package is not found in the packages required by the extra environment. + To override the global `exclude` value, use an empty list `[]`. + """ + register_envs: bool = bool() + """ + Whether to register the environments created by the installer (both `base` and `extra_envs`) + in `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. Defaults to `True`. + """ + installer_filename: str = str() + """ + The filename of the installer being created. If not supplied, a reasonable + default will determined by the `name`, `version`, platform, and installer type. + """ + installer_type: tuple = tuple() + """ + The type of the installer being created. Possible values are: + - `sh`: shell-based installer for Linux or macOS; + - `pkg`: macOS GUI installer built with Apple's `pkgbuild` + - `exe`: Windows GUI installer built with NSIS + + The default type is `sh` on Linux and macOS, and `exe` on Windows. A special + value of `all` builds _both_ `sh` and `pkg` installers on macOS, as well + as `sh` on Linux and `exe` on Windows. + + Notes for silent mode `/S` on Windows EXEs: + - NSIS Silent mode will not print any error message, but will silently abort the installation. + If needed, [NSIS log-builds][nsis-log] can be used to print to `%PREFIX%\\install.log`, which + can be searched for `::error::` strings. Pre- and post- install scripts will only throw an error + if the environment variable `NSIS_SCRIPTS_RAISE_ERRORS` is set. + - The `/D` flag can be used to specify the target location. It must be the last argument in + the command and should NEVER be quoted, even if it contains spaces. For example: + `CMD.EXE /C START /WAIT myproject.exe /S /D=C:\\path with spaces\\my project`. + + [nsis-log]: https://nsis.sourceforge.io/Special_Builds + """ + license_file: str = str() + """ + Path to the license file being displayed by the installer during the install + process. It must be plain text (.txt) for shell-based installers. On PKG, + .txt, .rtf and .html are supported. On Windows, .txt and .rtf are supported. + """ + keep_pkgs: bool = bool() + """ + If `False` (default), the package cache in the `pkgs` subdirectory is removed + when the installation process is complete. If `True`, this subdirectory and + its contents are preserved. If `keep_pkgs` is `False`, Unix `.sh` and Windows `.msi` + installers offer a command-line option (`-k` and `/KeepPkgCache`, respectively) + to preserve the package cache. + """ + batch_mode: bool = bool() + """ + Only affects ``.sh`` installers. If ``False`` (default), the installer launches + an interactive wizard guiding the user through the available options. If + ``True``, the installer runs automatically as if ``-b`` was passed. + """ + signing_identity_name: str = str() + """ + By default, the MacOS pkg installer isn't signed. If an identity name is specified + using this option, it will be used to sign the installer with Apple's `productsign`. + Note that you will need to have a certificate (usually an "Installer certificate") + and the corresponding private key, together called an 'identity', in one of your + accessible keychains. Common values for this option follow this format + `Developer ID Installer: Name of the owner (XXXXXX)`. + """ + notarization_identity_name: str = str() + """ + If the pkg installer is going to be signed with `signing_identity_name`, you + can also prepare the bundle for notarization. This will use Apple's `codesign` + to sign `conda.exe`. For this, you need an "Application certificate" (different from the + "Installer certificate" mentioned above). Common values for this option follow the format + `Developer ID Application: Name of the owner (XXXXXX)`. + """ + windows_signing_tool: str = str() + """ + The tool used to sign Windows installers. Must be one of: azuresigntool, signtool. + Some tools require `signing_certificate` to be set. + Defaults to `signtool` if `signing_certificate` is set. + Additional environment variables may need to be used to configure signing. + See the documentation for details: + https://conda.github.io/constructor/howto/#signing-exe-installers + """ + signing_certificate: str = str() + """ + On Windows only, set this key to the path of the certificate file to be used + with the `windows_signing_tool`. + """ + attempt_hardlinks: tuple = tuple() + """ + _Obsolete_. The current version of constructor relies on the standalone + conda executable for its installation behavior. This option is now + ignored with a warning. + """ + write_condarc: bool = bool() + """ + By default, no `.condarc` file is written. If set, a `.condarc` file is written to + the base environment if there are any channels or conda_default_channels is set. + """ + condarc: tuple = tuple() + """ + If set, a `.condarc` file is written to the base environment containing the contents + of this value. The value can either be a string (likely a multi-line string) or + a dictionary, which will be converted to a YAML string for writing. _Note:_ if this + option is used, then all other options related to the construction of a `.condarc` + file (`write_condarc`, `conda_default_channels`, etc.) are ignored. + """ + company: str = str() + """ + Name of the company/entity who is responsible for the installer. + """ + reverse_domain_identifier: str = str() + """ + Unique identifier for this package, formatted with reverse domain notation. This is + used internally in the PKG installers to handle future updates and others. If not + provided, it will default to `io.continuum`. (MacOS only) + """ + uninstall_name: str = str() + """ + Application name in the Windows "Programs and Features" control panel. + Defaults to `${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})`. + """ + script_env_variables: tuple = tuple() + """ + Dictionary of additional environment variables to be made available to + the pre_install and post_install scripts, in the form of VAR:VALUE + pairs. These environment variables are in addition to those in the + `post_install` section above and take precedence in the case of name + collisions. + + On Unix the variable values are automatically single quoted, allowing + you to supply strings with spaces, without needing to worry about + escaping. As a consequence, string interpolation is disabled: if you + need string interpolation, you can apply it in the + pre_install/post_install script(s). If you need to include single quotes + in your value, you can escape them by replacing each single quote with + `'''`. + + On Windows, single quotes and double quotes are not supported. + + Note that the # (hash) character cannot be used as it denotes yaml + comments for all platforms. + """ + pre_install: str = str() + """ + Path to a pre-install script, run after the package cache has been set, but + before the files are linked to their final locations. As a result, you should + only rely on tools known to be available on most systems (e.g. `bash`, `cmd`, + etc). See `post_install` for information about available environment variables. + """ + pre_install_desc: str = str() + """ + A description of the purpose of the supplied `pre_install` script. If this + string is supplied and non-empty, then the Windows and macOS GUI installers + will display it along with checkbox to enable or disable the execution of the + script. If this string is not supplied, it is assumed that the script + is compulsory and the option to disable it will not be offered. + + This option has no effect on `SH` installers. + """ + post_install: str = str() + """ + Path to a post-install script. Some notes: + + - For Unix `.sh` installers, the shebang line is respected if present; + otherwise, the script is run by the POSIX shell `sh`. Note that the use + of a shebang can reduce the portability of the installer. The + installation path is available as `${PREFIX}`. Installer metadata is + available in the `${INSTALLER_NAME}`, `${INSTALLER_VER}`, `${INSTALLER_PLAT}` + environment variables. `${INSTALLER_TYPE}` is set to `SH`. + `${INSTALLER_UNATTENDED}` will be `"1"` in batch mode (`-b`), `"0"` otherwise. + - For PKG installers, the shebang line is respected if present; + otherwise, `bash` is used. The same variables mentioned for `sh` + installers are available here. `${INSTALLER_TYPE}` is set to `PKG`. + `${INSTALLER_UNATTENDED}` will be `"1"` for command line installs, `"0"` otherwise. + - For Windows `.exe` installers, the script must be a `.bat` file. + Installation path is available as `%PREFIX%`. Metadata about + the installer can be found in the `%INSTALLER_NAME%`, `%INSTALLER_VER%`, + `%INSTALLER_PLAT%` environment variables. `%INSTALLER_TYPE%` is set to `EXE`. + `%INSTALLER_UNATTENDED%` will be `"1"` in silent mode (`/S`), `"0"` otherwise. + + If necessary, you can activate the installed `base` environment like this: + + - Unix: `source "$PREFIX/etc/profile.d/conda.sh" && conda activate "$PREFIX"` + - Windows: `call "%PREFIX%\\Scripts\\activate.bat"` + """ + post_install_desc: str = str() + """ + A description of the purpose of the supplied `post_install` script. If this + string is supplied and non-empty, then the Windows and macOS GUI installers + will display it along with checkbox to enable or disable the execution of the + script. If this string is not supplied, it is assumed that the script + is compulsory and the option to disable it will not be offered. + + This option has no effect on `SH` installers. + """ + pre_uninstall: str = str() + """ + Path to a pre uninstall script. This is only supported for on Windows, + and must be a `.bat` file. Installation path is available as `%PREFIX%`. + Metadata about the installer can be found in the `%INSTALLER_NAME%`, + `%INSTALLER_VER%`, `%INSTALLER_PLAT%` environment variables. + `%INSTALLER_TYPE%` is set to `EXE`. + """ + default_prefix: str = str() + """ + Set default install prefix. On Linux, if not provided, the default prefix + is `${HOME}/` (or, if `HOME` is not set, `/opt/`). On Windows, + this is used only for "Just Me" installation; for "All Users" installation, + use the `default_prefix_all_users` key. If not provided, the default prefix + is `%USERPROFILE%\\`. Environment variables will be expanded at + installation time. + """ + default_prefix_domain_user: str = str() + """ + Set default installation prefix for domain user. If not provided, the + installation prefix for domain user will be `%LOCALAPPDATA%\\`. + By default, it is different from the `default_prefix` value to avoid installing + the distribution in the roaming profile. Environment variables will be expanded + at installation time. Windows only. + """ + default_prefix_all_users: str = str() + """ + Set default installation prefix for All Users installation. If not provided, + the installation prefix for all users installation will be + `%ALLUSERSPROFILE%\\`. Environment variables will be expanded at installation + time. Windows only. + """ + default_location_pkg: str = str() + """ + Default installation subdirectory in the chosen volume. In PKG installers, + default installation locations are configured differently. The user can choose + between a "Just me" installation (which would result in `~/`) or another + volume (which defaults to `/`). If you want a different default, + you can add a middle component with this option, let's call it `location`. It would + result in these default values: `~//` for "Just me", + `//` for custom volumes. For example, setting this option + to `/Library` in a "Just me" installation will give you `~/Library/`. + Internally, this is passed to `pkgbuild --install-location`. + macOS only. + """ + pkg_domains: dict = dict() + """ + The domains the package can be installed into. For a detailed explanation, see: + https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html + constructor defaults to `enable_anywhere=true` and `enable_currentUserHome=true`. + `enable_localSystem` should not be set to true unless `default_location_pkg` is set as well. + macOS only. + """ + pkg_name: str = str() + """ + Internal identifier for the installer. This is used in the build prefix and will + determine part of the default location path. Combine with `default_location_pkg` + for more flexibility. If not provided, the value of `name` will be used. (MacOS only) + """ + install_path_exists_error_text: str = str() + """ + Error message that will be shown if the installation path already exists. + You cannot use double quotes or newlines. The placeholder `{CHOSEN_PATH}` is + available and set to the destination causing the error. Defaults to: + + > '{CHOSEN_PATH}' already exists. Please, relaunch the installer and + > choose another location in the Destination Select step. + + (MacOS only) + """ + progress_notifications: bool = bool() + """ + Whether to show UI notifications on PKG installers. On large installations, + the progress bar reaches ~90% very quickly and stays there for a long time. + This might look like the installer froze. This option enables UI notifications + so the user receives updates after each command executed by the installer. + (macOS only) + """ + welcome_image: str = str() + """ + Path to an image in any common image format (`.png`, `.jpg`, `.tif`, etc.) + to be used as the welcome image for the Windows and PKG installers. + The image is re-sized to 164 x 314 pixels on Windows and 1227 x 600 on Macos. + By default, an image is automatically generated on Windows. On MacOS, Anaconda's + logo is shown if this key is not provided. If you don't want a background on + PKG installers, set this key to `""` (empty string). + """ + header_image: str = str() + """ + Like `welcome_image` for Windows, re-sized to 150 x 57 pixels. + """ + icon_image: str = str() + """ + Like `welcome_image` for Windows, re-sized to 256 x 256 pixels. + """ + default_image_color: str = str() + """ + The color of the default images (when not providing explicit image files) + used on Windows. Possible values are `red`, `green`, `blue`, `yellow`. + The default is `blue`. + """ + welcome_image_text: str = str() + """ + If `welcome_image` is not provided, use this text when generating the image + (Windows and PKG only). Defaults to `name` on Windows. + """ + header_image_text: str = str() + """ + If `header_image` is not provided, use this text when generating the image + (Windows only). Defaults to `name`. + """ + initialize_conda: bool = bool() + """ + Add an option to the installer so the user can choose whether to run `conda init` + after the install. See also `initialize_by_default`. + """ + initialize_by_default: bool = bool() + """ + Whether to add the installation to the PATH environment variable. The default + is true for GUI installers (msi, pkg) and False for shell installers. The user + is able to change the default during interactive installation. NOTE: For Windows, + `AddToPath` is disabled when `InstallationType=AllUsers`. + """ + register_python: bool = bool() + """ + Whether to offer the user an option to register the installed Python instance as the + system's default Python. (Windows only) + """ + register_python_default: bool = bool() + """ + Default choice for whether to register the installed Python instance as the + system's default Python. The user is still able to change this during + interactive installation. (Windows only). + """ + check_path_length: bool = bool() + """ + Check the length of the path where the distribution is installed to ensure nodejs + can be installed. Raise a message to request shorter path (less than 46 character) + or enable long path on windows > 10 (require admin right). Default is True. (Windows only). + + Read notes about the particularities of Windows silent mode `/S` in the + `installer_type` documentation. + """ + check_path_spaces: bool = bool() + """ + Check if the path where the distribution is installed contains spaces. Default is True. + To allow installations with spaces, change to False. Note that: + + - A recent conda-standalone (>=22.11.1) or equivalent is needed for full support. + - `conda` cannot be present in the `base` environment + + Read notes about the particularities of Windows silent mode `/S` in the + `installer_type` documentation. + """ + nsis_template: str = str() + """ + If `nsis_template` is not provided, constructor uses its default + NSIS template. For more complete customization for the installation experience, + provide an NSIS template file. (Windows only). + """ + welcome_file: str = str() + """ + If `installer_type` is `pkg` on MacOS, this message will be + shown before the license information, right after the introduction. + File can be plain text (.txt), rich text (.rtf) or HTML (.html). If + both `welcome_file` and `welcome_text` are provided, `welcome_file` takes precedence. + (MacOS only). + + If the installer is for windows and welcome file type is nsi, + it will use the nsi script to add in extra pages before the installer + begins the installation process. + """ + welcome_text: str = str() + """ + If `installer_type` is `pkg` on MacOS, this message will be + shown before the license information, right after the introduction. + If this key is missing, it defaults to a message about Anaconda Cloud. + You can disable it altogether so it defaults to the system message + if you set this key to `""` (empty string). + (MacOS only). + """ + readme_file: str = str() + """ + If `installer_type` is `pkg` on MacOS, this message will be + shown before the license information, right after the welcome screen. + File can be plain text (.txt), rich text (.rtf) or HTML (.html). If + both `readme_file` and `readme_text` are provided, `readme_file` takes precedence. + (MacOS only). + """ + readme_text: str = str() + """ + If `installer_type` is `pkg` on MacOS, this message will be + shown before the license information, right after the welcome screen. + If this key is missing, it defaults to a message about Anaconda Cloud. + You can disable it altogether if you set this key to `""` (empty string). + (MacOS only). + """ + post_install_pages: tuple = tuple() + """ + Adds extra pages to the installers to be shown after installation. + + For PKG installers, these can be compiled `installer` plug-ins or + directories containing an Xcode project. In the latter case, + constructor will try and compile the project file using `xcodebuild`. + + For Windows, the extra pages must be `.nsi` files. + They will be inserted as-is before the conclusion page. + """ + conclusion_file: str = str() + """ + If `installer_type` is `pkg` on MacOS, this message will be + shown at the end of the installer upon success. File can be + plain text (.txt), rich text (.rtf) or HTML (.html). If both + `conclusion_file` and `conclusion_text` are provided, + `conclusion_file` takes precedence. (MacOS only). + + If the installer is for Windows, the file type must be nsi. + """ + conclusion_text: str = str() + """ + A message that will be shown at the end of the installer upon success. + The behaviour is slightly different across installer types: + - PKG: If this key is missing, it defaults to a message about Anaconda Cloud. + You can disable it altogether so it defaults to the system message if you set this + key to `""` (empty string). + - EXE: The first line will be used as a title. The following lines will be used as text. + (macOS PKG and Windows only). + """ + extra_files: list = list() + """ + Extra, non-packaged files that should be added to the installer. If provided as relative + paths, they will be considered relative to the directory where `construct.yaml` is. + This setting can be passed as a list of: + - `str`: each found file will be copied to the root prefix + - `Mapping[str, str]`: map of path in disk to path in prefix. + """ + temp_extra_files: list = list() + """ + Temporary files that could be referenced in the installation process (i.e. customized + `welcome_file` and `conclusion_file` (see above)) . Should be a list of + file paths, relative to the directory where `construct.yaml` is. In Windows, these + files will be copied into a temporary folder, the NSIS `$PLUGINSDIR`, during + install process (Windows only). + + Supports the same values as `extra_files`. + """ + build_outputs: list = list() + """ + Additional artifacts to be produced after building the installer. + It expects either a list of strings or single-key dictionaries: + Allowed keys are: + - `hash`: The hash of the installer files. + - `algorithm` (str or list): The hash algorithm. Must be among `hashlib`'s available algorithms: + https://docs.python.org/3/library/hashlib.html#hashlib.algorithms_available + - `info.json`: The internal `info` object, serialized to JSON. Takes no options. + - `pkgs_list`: The list of packages contained in a given environment. Options: + - `env` (optional, default=`base`): Name of an environment in `extra_envs` to export. + - `lockfile`: An `@EXPLICIT` lockfile for a given environment. Options: + - `env` (optional, default=`base`): Name of an environment in `extra_envs` to export. + - `licenses`: Generate a JSON file with the licensing details of all included packages. Options: + - `include_text` (optional bool, default=`False`): Whether to dump the license text in the JSON. + If false, only the path will be included. + - `text_errors` (optional str, default=`None`): How to handle decoding errors when reading the + license text. Only relevant if include_text is True. Any str accepted by open()'s 'errors' + argument is valid. See https://docs.python.org/3/library/functions.html#open. + """ + uninstall_with_conda_exe: bool = bool() + """ + Use the standalone binary to perform the uninstallation. + Requires conda-standalone 24.11.0 or newer. + """ + + _EXTRA_ENVS_SCHEMA = { @@ -845,10 +859,13 @@ def verify(info): sys.exit(f"The signing tool {signtool} requires 'signing_certificate' to be set.") -def generate_doc(): - logger.error('generate_doc() is deprecated. Use scripts/make_docs.py instead') - sys.exit(1) +def dump_schema(): + model = ConstructorModel(name="...", version="...") + obj = model.model_json_schema() + obj["$schema"] = "https://json-schema.org/draft/2020-12/schema" + (HERE / "data" / "constructor.schema.json").write_text(json.dumps(obj, indent=2)) + print(json.dumps(obj, indent=2)) if __name__ == '__main__': - generate_doc() + dump_schema() diff --git a/constructor/data/constructor.schema.json b/constructor/data/constructor.schema.json new file mode 100644 index 000000000..f6c559ee8 --- /dev/null +++ b/constructor/data/constructor.schema.json @@ -0,0 +1,454 @@ +{ + "additionalProperties": false, + "properties": { + "name": { + "description": "Name of the installer. Names may be composed of letters, numbers,\nunderscores, dashes, and periods, but may not begin or end with a\ndash or period.", + "title": "Name", + "type": "string" + }, + "version": { + "description": "Version of the installer. Versions may be composed of letters, numbers,\nunderscores, dashes, and periods, but may not begin or end with a\ndash or period.", + "title": "Version", + "type": "string" + }, + "channels": { + "default": [], + "description": "The conda channels from which packages are retrieved. At least one channel must\nbe supplied, either in `channels` or `channels_remap`.\n\nSee notes in `channels_remap` for details about local channels.", + "items": {}, + "title": "Channels", + "type": "array" + }, + "channels_remap": { + "default": [], + "description": "A list of `src/dest` channel URL pairs. When building the installer, conda will\nuse the `src` channels to solve and fetch the packages. However, the resulting\ninstallation will see the packages as coming from the `dest` equivalent.\nThis allows an installer to be built against a different set of channels than\nwill be present when the installer is actually used. Example use:\n\n```yaml\nchannels_remap:\n - src: file:///tmp/a3/conda-bld # [unix]\n dest: https://repo.anaconda.com/pkgs/main # [unix]\n - src: file:///D:/tmp/a3/conda-bld # [win]\n dest: https://repo.anaconda.com/pkgs/main # [unix]\n```\n\nAt least one channel must be supplied, either in `channels` or `channels_remap`.", + "items": {}, + "title": "Channels Remap", + "type": "array" + }, + "specs": { + "default": [], + "description": "A list of package specifications; e.g. `python 2.7*`, `pyzmq` or `numpy >=1.8`.\nThe specifications are identical in form and purpose to those that would be\nincluded in a `conda create --file` command. Packages may also be specified\nby an exact URL; e.g.,\n`https://repo.anaconda.com/pkgs/main/osx-64/openssl-1.0.2o-h26aff7b_0.tar.bz2`.\nThis key can also take a `str` pointing to a requirements file with the same syntax.\n\nNote: `constructor` relies on `conda`'s Python API to solve the passed\nspecifications. You can still set the `CONDA_SOLVER` environment variable\nto override system-wide settings for `constructor`. If you are using\n`constructor` from a non-`base` environment, make sure the\nconfigured solver plugin is also installed in that environment.", + "items": {}, + "title": "Specs", + "type": "array" + }, + "user_requested_specs": { + "default": [], + "description": "A list of package specifications to be recorded as \"user-requested\" for the\ninitial environment in conda's history file. This information is used by newer\nversions of conda to better filter its package choices on subsequent installs;\nfor example, if `python=3.6` is included, then conda will always seek versions\nof packages compatible with Python 3.6. If this is option is not provided, it\nwill be set equal to the value of `specs`.", + "items": {}, + "title": "User Requested Specs", + "type": "array" + }, + "virtual_specs": { + "default": [], + "description": "A list of virtual packages that must be satisfied at install time. Virtual\npackages must start with `__`. For example, `__osx>=11` or `__glibc>=2.24`.\nThese specs are dry-run solved offline by the bundled `--conda-exe` binary.\nIn SH installers, `__glibc>=x.y` and `__osx>=x.y` specs can be checked with\nBash only. The detected version can be overriden with environment variables\n`CONDA_OVERRIDE_GLIBC` and `CONDA_OVERRIDE_OSX`, respectively. In PKG\ninstallers, `__osx` specs can be checked natively without the solver being\ninvolved as long as only `>=`, `<` or `,` are used.", + "items": {}, + "title": "Virtual Specs", + "type": "array" + }, + "exclude": { + "default": [], + "description": "A list of package names to be excluded after the `specs` have been resolved.\nFor example, you can say that `readline` should be excluded, even though it\nis contained as a result of resolving the specs for `python 2.7`.", + "items": {}, + "title": "Exclude", + "type": "array" + }, + "menu_packages": { + "default": [], + "description": "A list of packages with menu items to be installed. The packages must have\nnecessary metadata in `Menu/.json`). By default, all menu items\nfound in the installation will be created; supplying this list allows a\nsubset to be selected instead. If an empty list is supplied, no shortcuts will\nbe created.\n\nIf all environments (`extra_envs` included) set `menu_packages` to an empty list,\nno UI options about shortcuts will be offered to the user.\n\nNote: This option is not fully implemented when `micromamba` is used as\nthe `--conda-exe` binary. The only accepted value is an empty list (`[]`).", + "items": {}, + "title": "Menu Packages", + "type": "array" + }, + "ignore_duplicate_files": { + "default": false, + "description": "By default, constructor will warn you when adding packages with duplicate\nfiles in them. Setting this option to false will raise an error instead.", + "title": "Ignore Duplicate Files", + "type": "boolean" + }, + "install_in_dependency_order": { + "default": [], + "description": "_Obsolete_. The current version of constructor relies on the standalone\nconda executable for its installation behavior. This option is now\nignored with a warning.", + "items": {}, + "title": "Install In Dependency Order", + "type": "array" + }, + "environment": { + "default": "", + "description": "Name of the environment to construct from. If this option is present, the\n`specs` argument will be ignored. Using this option allows the user to\ncurate the enviromment interactively using standard `conda` commands, and\nrun constructor with full confidence that the exact environment will be\nreproduced.", + "title": "Environment", + "type": "string" + }, + "environment_file": { + "default": "", + "description": "Path to an environment file (TXT or YAML) to construct from. If this option\nis present, the `specs` argument will be ignored. Instead, constructor will\ncall conda to create a temporary environment, constructor will build and\ninstaller from that, and the temporary environment will be removed.\nThis ensures that constructor is using the precise local conda configuration\nto discover and install the packages. The created environment MUST include\n`python`.\n\nRead notes about the solver in the `specs` field.", + "title": "Environment File", + "type": "string" + }, + "transmute_file_type": { + "default": "", + "description": "File type extension for the files to be transmuted into. Currently supports\nonly '.conda'. See conda-package-handling for supported extension names.\nIf left empty, no transmuting is done.", + "title": "Transmute File Type", + "type": "string" + }, + "conda_default_channels": { + "default": [], + "description": "If this value is provided as well as `write_condarc`, then the channels\nin this list will be included as the value of the `default_channels:`\noption in the environment's `.condarc` file. This will have an impact\nonly if `conda` is included in the environmnent.", + "items": {}, + "title": "Conda Default Channels", + "type": "array" + }, + "conda_channel_alias": { + "default": "", + "description": "The channel alias that would be assumed for the created installer\n(only useful if it includes conda).", + "title": "Conda Channel Alias", + "type": "string" + }, + "extra_envs": { + "default": [], + "description": "Create more environments in addition to the default `base` provided by `specs`,\n`environment` or `environment_file`. This should be a map of `str` (environment\nname) to a dictionary of options:\n- `specs` (list of str): which packages to install in that environment\n- `environment` (str): same as global option, for this env\n- `environment_file` (str): same as global option, for this env\n- `channels` (list of str): using these channels; if not provided, the global\n value is used. To override inheritance, set it to an empty list.\n- `channels_remap` (list of str): same as global option, for this env;\n if not provided, the global value is used. To override inheritance, set it to\n an empty list.\n- `user_requested_specs` (list of str): same as the global option, but for this env;\n if not provided, global value is _not_ used\n- `menu_packages` (list of str): same as the global option, for this env;\n if not provided, the global value is _not_ used.\n\nNotes:\n- `ignore_duplicate_files` will always be considered `True` if `extra_envs` is in use.\n- `conda` needs to be present in the `base` environment (via `specs`)\n- If a global `exclude` option is used, it will have an effect on the environments created\n by `extra_envs` too. For example, if the global environment excludes `tk`, none of the\n extra environments will have it either. Unlike the global option, an error will not be\n thrown if the excluded package is not found in the packages required by the extra environment.\n To override the global `exclude` value, use an empty list `[]`.", + "items": {}, + "title": "Extra Envs", + "type": "array" + }, + "register_envs": { + "default": false, + "description": "Whether to register the environments created by the installer (both `base` and `extra_envs`)\nin `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. Defaults to `True`.", + "title": "Register Envs", + "type": "boolean" + }, + "installer_filename": { + "default": "", + "description": "The filename of the installer being created. If not supplied, a reasonable\ndefault will determined by the `name`, `version`, platform, and installer type.", + "title": "Installer Filename", + "type": "string" + }, + "installer_type": { + "default": [], + "description": "The type of the installer being created. Possible values are:\n- `sh`: shell-based installer for Linux or macOS;\n- `pkg`: macOS GUI installer built with Apple's `pkgbuild`\n- `exe`: Windows GUI installer built with NSIS\n\nThe default type is `sh` on Linux and macOS, and `exe` on Windows. A special\nvalue of `all` builds _both_ `sh` and `pkg` installers on macOS, as well\nas `sh` on Linux and `exe` on Windows.\n\nNotes for silent mode `/S` on Windows EXEs:\n- NSIS Silent mode will not print any error message, but will silently abort the installation.\n If needed, [NSIS log-builds][nsis-log] can be used to print to `%PREFIX%\\install.log`, which\n can be searched for `::error::` strings. Pre- and post- install scripts will only throw an error\n if the environment variable `NSIS_SCRIPTS_RAISE_ERRORS` is set.\n- The `/D` flag can be used to specify the target location. It must be the last argument in\n the command and should NEVER be quoted, even if it contains spaces. For example:\n `CMD.EXE /C START /WAIT myproject.exe /S /D=C:\\path with spaces\\my project`.\n\n[nsis-log]: https://nsis.sourceforge.io/Special_Builds", + "items": {}, + "title": "Installer Type", + "type": "array" + }, + "license_file": { + "default": "", + "description": "Path to the license file being displayed by the installer during the install\nprocess. It must be plain text (.txt) for shell-based installers. On PKG,\n.txt, .rtf and .html are supported. On Windows, .txt and .rtf are supported.", + "title": "License File", + "type": "string" + }, + "keep_pkgs": { + "default": false, + "description": "If `False` (default), the package cache in the `pkgs` subdirectory is removed\nwhen the installation process is complete. If `True`, this subdirectory and\nits contents are preserved. If `keep_pkgs` is `False`, Unix `.sh` and Windows `.msi`\ninstallers offer a command-line option (`-k` and `/KeepPkgCache`, respectively)\nto preserve the package cache.", + "title": "Keep Pkgs", + "type": "boolean" + }, + "batch_mode": { + "default": false, + "description": "Only affects ``.sh`` installers. If ``False`` (default), the installer launches\nan interactive wizard guiding the user through the available options. If\n``True``, the installer runs automatically as if ``-b`` was passed.", + "title": "Batch Mode", + "type": "boolean" + }, + "signing_identity_name": { + "default": "", + "description": "By default, the MacOS pkg installer isn't signed. If an identity name is specified\nusing this option, it will be used to sign the installer with Apple's `productsign`.\nNote that you will need to have a certificate (usually an \"Installer certificate\")\nand the corresponding private key, together called an 'identity', in one of your\naccessible keychains. Common values for this option follow this format\n`Developer ID Installer: Name of the owner (XXXXXX)`.", + "title": "Signing Identity Name", + "type": "string" + }, + "notarization_identity_name": { + "default": "", + "description": "If the pkg installer is going to be signed with `signing_identity_name`, you\ncan also prepare the bundle for notarization. This will use Apple's `codesign`\nto sign `conda.exe`. For this, you need an \"Application certificate\" (different from the\n\"Installer certificate\" mentioned above). Common values for this option follow the format\n`Developer ID Application: Name of the owner (XXXXXX)`.", + "title": "Notarization Identity Name", + "type": "string" + }, + "windows_signing_tool": { + "default": "", + "description": "The tool used to sign Windows installers. Must be one of: azuresigntool, signtool.\nSome tools require `signing_certificate` to be set.\nDefaults to `signtool` if `signing_certificate` is set.\nAdditional environment variables may need to be used to configure signing.\nSee the documentation for details:\nhttps://conda.github.io/constructor/howto/#signing-exe-installers", + "title": "Windows Signing Tool", + "type": "string" + }, + "signing_certificate": { + "default": "", + "description": "On Windows only, set this key to the path of the certificate file to be used\nwith the `windows_signing_tool`.", + "title": "Signing Certificate", + "type": "string" + }, + "attempt_hardlinks": { + "default": [], + "description": "_Obsolete_. The current version of constructor relies on the standalone\nconda executable for its installation behavior. This option is now\nignored with a warning.", + "items": {}, + "title": "Attempt Hardlinks", + "type": "array" + }, + "write_condarc": { + "default": false, + "description": "By default, no `.condarc` file is written. If set, a `.condarc` file is written to\nthe base environment if there are any channels or conda_default_channels is set.", + "title": "Write Condarc", + "type": "boolean" + }, + "condarc": { + "default": [], + "description": "If set, a `.condarc` file is written to the base environment containing the contents\nof this value. The value can either be a string (likely a multi-line string) or\na dictionary, which will be converted to a YAML string for writing. _Note:_ if this\noption is used, then all other options related to the construction of a `.condarc`\nfile (`write_condarc`, `conda_default_channels`, etc.) are ignored.", + "items": {}, + "title": "Condarc", + "type": "array" + }, + "company": { + "default": "", + "description": "Name of the company/entity who is responsible for the installer.", + "title": "Company", + "type": "string" + }, + "reverse_domain_identifier": { + "default": "", + "description": "Unique identifier for this package, formatted with reverse domain notation. This is\nused internally in the PKG installers to handle future updates and others. If not\nprovided, it will default to `io.continuum`. (MacOS only)", + "title": "Reverse Domain Identifier", + "type": "string" + }, + "uninstall_name": { + "default": "", + "description": "Application name in the Windows \"Programs and Features\" control panel.\nDefaults to `${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})`.", + "title": "Uninstall Name", + "type": "string" + }, + "script_env_variables": { + "default": [], + "description": "Dictionary of additional environment variables to be made available to\nthe pre_install and post_install scripts, in the form of VAR:VALUE\npairs. These environment variables are in addition to those in the\n`post_install` section above and take precedence in the case of name\ncollisions.\n\nOn Unix the variable values are automatically single quoted, allowing\nyou to supply strings with spaces, without needing to worry about\nescaping. As a consequence, string interpolation is disabled: if you\nneed string interpolation, you can apply it in the\npre_install/post_install script(s). If you need to include single quotes\nin your value, you can escape them by replacing each single quote with\n`'''`.\n\nOn Windows, single quotes and double quotes are not supported.\n\nNote that the # (hash) character cannot be used as it denotes yaml\ncomments for all platforms.", + "items": {}, + "title": "Script Env Variables", + "type": "array" + }, + "pre_install": { + "default": "", + "description": "Path to a pre-install script, run after the package cache has been set, but\nbefore the files are linked to their final locations. As a result, you should\nonly rely on tools known to be available on most systems (e.g. `bash`, `cmd`,\netc). See `post_install` for information about available environment variables.", + "title": "Pre Install", + "type": "string" + }, + "pre_install_desc": { + "default": "", + "description": "A description of the purpose of the supplied `pre_install` script. If this\nstring is supplied and non-empty, then the Windows and macOS GUI installers\nwill display it along with checkbox to enable or disable the execution of the\nscript. If this string is not supplied, it is assumed that the script\nis compulsory and the option to disable it will not be offered.\n\nThis option has no effect on `SH` installers.", + "title": "Pre Install Desc", + "type": "string" + }, + "post_install": { + "default": "", + "description": "Path to a post-install script. Some notes:\n\n- For Unix `.sh` installers, the shebang line is respected if present;\n otherwise, the script is run by the POSIX shell `sh`. Note that the use\n of a shebang can reduce the portability of the installer. The\n installation path is available as `${PREFIX}`. Installer metadata is\n available in the `${INSTALLER_NAME}`, `${INSTALLER_VER}`, `${INSTALLER_PLAT}`\n environment variables. `${INSTALLER_TYPE}` is set to `SH`.\n `${INSTALLER_UNATTENDED}` will be `\"1\"` in batch mode (`-b`), `\"0\"` otherwise.\n- For PKG installers, the shebang line is respected if present;\n otherwise, `bash` is used. The same variables mentioned for `sh`\n installers are available here. `${INSTALLER_TYPE}` is set to `PKG`.\n `${INSTALLER_UNATTENDED}` will be `\"1\"` for command line installs, `\"0\"` otherwise.\n- For Windows `.exe` installers, the script must be a `.bat` file.\n Installation path is available as `%PREFIX%`. Metadata about\n the installer can be found in the `%INSTALLER_NAME%`, `%INSTALLER_VER%`,\n `%INSTALLER_PLAT%` environment variables. `%INSTALLER_TYPE%` is set to `EXE`.\n `%INSTALLER_UNATTENDED%` will be `\"1\"` in silent mode (`/S`), `\"0\"` otherwise.\n\nIf necessary, you can activate the installed `base` environment like this:\n\n- Unix: `source \"$PREFIX/etc/profile.d/conda.sh\" && conda activate \"$PREFIX\"`\n- Windows: `call \"%PREFIX%\\Scripts\\activate.bat\"`", + "title": "Post Install", + "type": "string" + }, + "post_install_desc": { + "default": "", + "description": "A description of the purpose of the supplied `post_install` script. If this\nstring is supplied and non-empty, then the Windows and macOS GUI installers\nwill display it along with checkbox to enable or disable the execution of the\nscript. If this string is not supplied, it is assumed that the script\nis compulsory and the option to disable it will not be offered.\n\nThis option has no effect on `SH` installers.", + "title": "Post Install Desc", + "type": "string" + }, + "pre_uninstall": { + "default": "", + "description": "Path to a pre uninstall script. This is only supported for on Windows,\nand must be a `.bat` file. Installation path is available as `%PREFIX%`.\nMetadata about the installer can be found in the `%INSTALLER_NAME%`,\n`%INSTALLER_VER%`, `%INSTALLER_PLAT%` environment variables.\n`%INSTALLER_TYPE%` is set to `EXE`.", + "title": "Pre Uninstall", + "type": "string" + }, + "default_prefix": { + "default": "", + "description": "Set default install prefix. On Linux, if not provided, the default prefix\nis `${HOME}/` (or, if `HOME` is not set, `/opt/`). On Windows,\nthis is used only for \"Just Me\" installation; for \"All Users\" installation,\nuse the `default_prefix_all_users` key. If not provided, the default prefix\nis `%USERPROFILE%\\`. Environment variables will be expanded at\ninstallation time.", + "title": "Default Prefix", + "type": "string" + }, + "default_prefix_domain_user": { + "default": "", + "description": "Set default installation prefix for domain user. If not provided, the\ninstallation prefix for domain user will be `%LOCALAPPDATA%\\`.\nBy default, it is different from the `default_prefix` value to avoid installing\nthe distribution in the roaming profile. Environment variables will be expanded\nat installation time. Windows only.", + "title": "Default Prefix Domain User", + "type": "string" + }, + "default_prefix_all_users": { + "default": "", + "description": "Set default installation prefix for All Users installation. If not provided,\nthe installation prefix for all users installation will be\n`%ALLUSERSPROFILE%\\`. Environment variables will be expanded at installation\ntime. Windows only.", + "title": "Default Prefix All Users", + "type": "string" + }, + "default_location_pkg": { + "default": "", + "description": "Default installation subdirectory in the chosen volume. In PKG installers,\ndefault installation locations are configured differently. The user can choose\nbetween a \"Just me\" installation (which would result in `~/`) or another\nvolume (which defaults to `/`). If you want a different default,\nyou can add a middle component with this option, let's call it `location`. It would\nresult in these default values: `~//` for \"Just me\",\n`//` for custom volumes. For example, setting this option\nto `/Library` in a \"Just me\" installation will give you `~/Library/`.\nInternally, this is passed to `pkgbuild --install-location`.\nmacOS only.", + "title": "Default Location Pkg", + "type": "string" + }, + "pkg_domains": { + "default": {}, + "description": "The domains the package can be installed into. For a detailed explanation, see:\nhttps://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html\nconstructor defaults to `enable_anywhere=true` and `enable_currentUserHome=true`.\n`enable_localSystem` should not be set to true unless `default_location_pkg` is set as well.\nmacOS only.", + "title": "Pkg Domains", + "type": "object" + }, + "pkg_name": { + "default": "", + "description": "Internal identifier for the installer. This is used in the build prefix and will\ndetermine part of the default location path. Combine with `default_location_pkg`\nfor more flexibility. If not provided, the value of `name` will be used. (MacOS only)", + "title": "Pkg Name", + "type": "string" + }, + "install_path_exists_error_text": { + "default": "", + "description": "Error message that will be shown if the installation path already exists.\nYou cannot use double quotes or newlines. The placeholder `{CHOSEN_PATH}` is\navailable and set to the destination causing the error. Defaults to:\n\n> '{CHOSEN_PATH}' already exists. Please, relaunch the installer and\n> choose another location in the Destination Select step.\n\n(MacOS only)", + "title": "Install Path Exists Error Text", + "type": "string" + }, + "progress_notifications": { + "default": false, + "description": "Whether to show UI notifications on PKG installers. On large installations,\nthe progress bar reaches ~90% very quickly and stays there for a long time.\nThis might look like the installer froze. This option enables UI notifications\nso the user receives updates after each command executed by the installer.\n(macOS only)", + "title": "Progress Notifications", + "type": "boolean" + }, + "welcome_image": { + "default": "", + "description": "Path to an image in any common image format (`.png`, `.jpg`, `.tif`, etc.)\nto be used as the welcome image for the Windows and PKG installers.\nThe image is re-sized to 164 x 314 pixels on Windows and 1227 x 600 on Macos.\nBy default, an image is automatically generated on Windows. On MacOS, Anaconda's\nlogo is shown if this key is not provided. If you don't want a background on\nPKG installers, set this key to `\"\"` (empty string).", + "title": "Welcome Image", + "type": "string" + }, + "header_image": { + "default": "", + "description": "Like `welcome_image` for Windows, re-sized to 150 x 57 pixels.", + "title": "Header Image", + "type": "string" + }, + "icon_image": { + "default": "", + "description": "Like `welcome_image` for Windows, re-sized to 256 x 256 pixels.", + "title": "Icon Image", + "type": "string" + }, + "default_image_color": { + "default": "", + "description": "The color of the default images (when not providing explicit image files)\nused on Windows. Possible values are `red`, `green`, `blue`, `yellow`.\nThe default is `blue`.", + "title": "Default Image Color", + "type": "string" + }, + "welcome_image_text": { + "default": "", + "description": "If `welcome_image` is not provided, use this text when generating the image\n(Windows and PKG only). Defaults to `name` on Windows.", + "title": "Welcome Image Text", + "type": "string" + }, + "header_image_text": { + "default": "", + "description": "If `header_image` is not provided, use this text when generating the image\n(Windows only). Defaults to `name`.", + "title": "Header Image Text", + "type": "string" + }, + "initialize_conda": { + "default": false, + "description": "Add an option to the installer so the user can choose whether to run `conda init`\nafter the install. See also `initialize_by_default`.", + "title": "Initialize Conda", + "type": "boolean" + }, + "initialize_by_default": { + "default": false, + "description": "Whether to add the installation to the PATH environment variable. The default\nis true for GUI installers (msi, pkg) and False for shell installers. The user\nis able to change the default during interactive installation. NOTE: For Windows,\n`AddToPath` is disabled when `InstallationType=AllUsers`.", + "title": "Initialize By Default", + "type": "boolean" + }, + "register_python": { + "default": false, + "description": "Whether to offer the user an option to register the installed Python instance as the\nsystem's default Python. (Windows only)", + "title": "Register Python", + "type": "boolean" + }, + "register_python_default": { + "default": false, + "description": "Default choice for whether to register the installed Python instance as the\nsystem's default Python. The user is still able to change this during\ninteractive installation. (Windows only).", + "title": "Register Python Default", + "type": "boolean" + }, + "check_path_length": { + "default": false, + "description": "Check the length of the path where the distribution is installed to ensure nodejs\ncan be installed. Raise a message to request shorter path (less than 46 character)\nor enable long path on windows > 10 (require admin right). Default is True. (Windows only).\n\nRead notes about the particularities of Windows silent mode `/S` in the\n`installer_type` documentation.", + "title": "Check Path Length", + "type": "boolean" + }, + "check_path_spaces": { + "default": false, + "description": "Check if the path where the distribution is installed contains spaces. Default is True.\nTo allow installations with spaces, change to False. Note that:\n\n- A recent conda-standalone (>=22.11.1) or equivalent is needed for full support.\n- `conda` cannot be present in the `base` environment\n\nRead notes about the particularities of Windows silent mode `/S` in the\n`installer_type` documentation.", + "title": "Check Path Spaces", + "type": "boolean" + }, + "nsis_template": { + "default": "", + "description": "If `nsis_template` is not provided, constructor uses its default\nNSIS template. For more complete customization for the installation experience,\nprovide an NSIS template file. (Windows only).", + "title": "Nsis Template", + "type": "string" + }, + "welcome_file": { + "default": "", + "description": "If `installer_type` is `pkg` on MacOS, this message will be\nshown before the license information, right after the introduction.\nFile can be plain text (.txt), rich text (.rtf) or HTML (.html). If\nboth `welcome_file` and `welcome_text` are provided, `welcome_file` takes precedence.\n(MacOS only).\n\nIf the installer is for windows and welcome file type is nsi,\nit will use the nsi script to add in extra pages before the installer\nbegins the installation process.", + "title": "Welcome File", + "type": "string" + }, + "welcome_text": { + "default": "", + "description": "If `installer_type` is `pkg` on MacOS, this message will be\nshown before the license information, right after the introduction.\nIf this key is missing, it defaults to a message about Anaconda Cloud.\nYou can disable it altogether so it defaults to the system message\nif you set this key to `\"\"` (empty string).\n(MacOS only).", + "title": "Welcome Text", + "type": "string" + }, + "readme_file": { + "default": "", + "description": "If `installer_type` is `pkg` on MacOS, this message will be\nshown before the license information, right after the welcome screen.\nFile can be plain text (.txt), rich text (.rtf) or HTML (.html). If\nboth `readme_file` and `readme_text` are provided, `readme_file` takes precedence.\n(MacOS only).", + "title": "Readme File", + "type": "string" + }, + "readme_text": { + "default": "", + "description": "If `installer_type` is `pkg` on MacOS, this message will be\nshown before the license information, right after the welcome screen.\nIf this key is missing, it defaults to a message about Anaconda Cloud.\nYou can disable it altogether if you set this key to `\"\"` (empty string).\n(MacOS only).", + "title": "Readme Text", + "type": "string" + }, + "post_install_pages": { + "default": [], + "description": "Adds extra pages to the installers to be shown after installation.\n\nFor PKG installers, these can be compiled `installer` plug-ins or\ndirectories containing an Xcode project. In the latter case,\nconstructor will try and compile the project file using `xcodebuild`.\n\nFor Windows, the extra pages must be `.nsi` files.\nThey will be inserted as-is before the conclusion page.", + "items": {}, + "title": "Post Install Pages", + "type": "array" + }, + "conclusion_file": { + "default": "", + "description": "If `installer_type` is `pkg` on MacOS, this message will be\nshown at the end of the installer upon success. File can be\nplain text (.txt), rich text (.rtf) or HTML (.html). If both\n`conclusion_file` and `conclusion_text` are provided,\n`conclusion_file` takes precedence. (MacOS only).\n\nIf the installer is for Windows, the file type must be nsi.", + "title": "Conclusion File", + "type": "string" + }, + "conclusion_text": { + "default": "", + "description": "A message that will be shown at the end of the installer upon success.\nThe behaviour is slightly different across installer types:\n- PKG: If this key is missing, it defaults to a message about Anaconda Cloud.\n You can disable it altogether so it defaults to the system message if you set this\n key to `\"\"` (empty string).\n- EXE: The first line will be used as a title. The following lines will be used as text.\n(macOS PKG and Windows only).", + "title": "Conclusion Text", + "type": "string" + }, + "extra_files": { + "default": [], + "description": "Extra, non-packaged files that should be added to the installer. If provided as relative\npaths, they will be considered relative to the directory where `construct.yaml` is.\nThis setting can be passed as a list of:\n- `str`: each found file will be copied to the root prefix\n- `Mapping[str, str]`: map of path in disk to path in prefix.", + "items": {}, + "title": "Extra Files", + "type": "array" + }, + "temp_extra_files": { + "default": [], + "description": "Temporary files that could be referenced in the installation process (i.e. customized\n`welcome_file` and `conclusion_file` (see above)) . Should be a list of\nfile paths, relative to the directory where `construct.yaml` is. In Windows, these\nfiles will be copied into a temporary folder, the NSIS `$PLUGINSDIR`, during\ninstall process (Windows only).\n\nSupports the same values as `extra_files`.", + "items": {}, + "title": "Temp Extra Files", + "type": "array" + }, + "build_outputs": { + "default": [], + "description": "Additional artifacts to be produced after building the installer.\nIt expects either a list of strings or single-key dictionaries:\nAllowed keys are:\n- `hash`: The hash of the installer files.\n - `algorithm` (str or list): The hash algorithm. Must be among `hashlib`'s available algorithms:\n https://docs.python.org/3/library/hashlib.html#hashlib.algorithms_available\n- `info.json`: The internal `info` object, serialized to JSON. Takes no options.\n- `pkgs_list`: The list of packages contained in a given environment. Options:\n - `env` (optional, default=`base`): Name of an environment in `extra_envs` to export.\n- `lockfile`: An `@EXPLICIT` lockfile for a given environment. Options:\n - `env` (optional, default=`base`): Name of an environment in `extra_envs` to export.\n- `licenses`: Generate a JSON file with the licensing details of all included packages. Options:\n - `include_text` (optional bool, default=`False`): Whether to dump the license text in the JSON.\n If false, only the path will be included.\n - `text_errors` (optional str, default=`None`): How to handle decoding errors when reading the\n license text. Only relevant if include_text is True. Any str accepted by open()'s 'errors'\n argument is valid. See https://docs.python.org/3/library/functions.html#open.", + "items": {}, + "title": "Build Outputs", + "type": "array" + }, + "uninstall_with_conda_exe": { + "default": false, + "description": "Use the standalone binary to perform the uninstallation.\nRequires conda-standalone 24.11.0 or newer.", + "title": "Uninstall With Conda Exe", + "type": "boolean" + } + }, + "required": [ + "name", + "version" + ], + "title": "ConstructorModel", + "type": "object", + "$schema": "https://json-schema.org/draft/2020-12/schema" +} From 500f97cf3e547fc91921629026624154be76079b Mon Sep 17 00:00:00 2001 From: jaimergp Date: Fri, 28 Feb 2025 16:16:15 +0100 Subject: [PATCH 002/138] add $schema path in examples --- examples/azure_signtool/construct.yaml | 1 + examples/custom_nsis_template/construct.yaml | 2 ++ examples/customize_controls/construct.yaml | 2 ++ examples/customized_welcome_conclusion/construct.yaml | 2 ++ examples/exe_extra_pages/construct.yaml | 2 ++ examples/extra_envs/construct.yaml | 2 ++ examples/extra_files/construct.yaml | 2 ++ examples/from_env_txt/construct.yaml | 2 ++ examples/from_env_yaml/construct.yaml | 2 ++ examples/from_existing_env/construct.yaml | 2 ++ examples/from_explicit/construct.yaml | 2 ++ examples/grin/construct.yaml | 2 ++ examples/jetsonconda/construct.yaml | 2 ++ examples/miniconda/construct.yaml | 2 ++ examples/miniforge-mamba2/construct.yaml | 2 ++ examples/miniforge/construct.yaml | 2 ++ examples/newchan/construct.yaml | 2 ++ examples/noconda/constructor_input.yaml | 2 ++ examples/osxpkg/construct.yaml | 2 ++ examples/osxpkg_extra_pages/construct.yaml | 2 ++ examples/register_envs/construct.yaml | 2 ++ examples/regressions/construct.yaml | 2 ++ examples/scripts/construct.yaml | 2 ++ examples/shortcuts/construct.yaml | 2 ++ examples/signing/construct.yaml | 2 ++ examples/use_channel_remap/construct.yaml | 2 ++ examples/virtual_specs_failed/construct.yaml | 2 ++ examples/virtual_specs_ok/construct.yaml | 2 ++ 28 files changed, 55 insertions(+) diff --git a/examples/azure_signtool/construct.yaml b/examples/azure_signtool/construct.yaml index 37b3c1744..1901bc291 100644 --- a/examples/azure_signtool/construct.yaml +++ b/examples/azure_signtool/construct.yaml @@ -1,3 +1,4 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json name: Signed_AzureSignTool version: X installer_type: exe diff --git a/examples/custom_nsis_template/construct.yaml b/examples/custom_nsis_template/construct.yaml index 59bf7f503..0206e4d1c 100644 --- a/examples/custom_nsis_template/construct.yaml +++ b/examples/custom_nsis_template/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: custom version: X ignore_duplicate_files: True diff --git a/examples/customize_controls/construct.yaml b/examples/customize_controls/construct.yaml index aae91d0fa..5075fde07 100644 --- a/examples/customize_controls/construct.yaml +++ b/examples/customize_controls/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: NoCondaOptions version: X installer_type: all diff --git a/examples/customized_welcome_conclusion/construct.yaml b/examples/customized_welcome_conclusion/construct.yaml index 6a4de2591..caa389271 100644 --- a/examples/customized_welcome_conclusion/construct.yaml +++ b/examples/customized_welcome_conclusion/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: CustomizedWelcomeConclusion version: X installer_type: all diff --git a/examples/exe_extra_pages/construct.yaml b/examples/exe_extra_pages/construct.yaml index a7987b4e9..c1e959af1 100644 --- a/examples/exe_extra_pages/construct.yaml +++ b/examples/exe_extra_pages/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + {% if os.environ.get("POST_INSTALL_PAGES_LIST") %} {% set name = "extraPages" %} {% else %} diff --git a/examples/extra_envs/construct.yaml b/examples/extra_envs/construct.yaml index b839b9239..78f4d139a 100644 --- a/examples/extra_envs/construct.yaml +++ b/examples/extra_envs/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: ExtraEnvs version: X installer_type: all diff --git a/examples/extra_files/construct.yaml b/examples/extra_files/construct.yaml index 1d248235e..3220faf84 100644 --- a/examples/extra_files/construct.yaml +++ b/examples/extra_files/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: ExtraFiles version: X installer_type: all diff --git a/examples/from_env_txt/construct.yaml b/examples/from_env_txt/construct.yaml index 5a6f0aa2f..b9b6fd7f0 100644 --- a/examples/from_env_txt/construct.yaml +++ b/examples/from_env_txt/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: EnvironmentTXT version: X installer_type: all diff --git a/examples/from_env_yaml/construct.yaml b/examples/from_env_yaml/construct.yaml index 7c792e204..63c80cc04 100644 --- a/examples/from_env_yaml/construct.yaml +++ b/examples/from_env_yaml/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: EnvironmentYAML version: X installer_type: all diff --git a/examples/from_existing_env/construct.yaml b/examples/from_existing_env/construct.yaml index 33fe9fc32..18f3aba96 100644 --- a/examples/from_existing_env/construct.yaml +++ b/examples/from_existing_env/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: Existing version: X installer_type: all diff --git a/examples/from_explicit/construct.yaml b/examples/from_explicit/construct.yaml index 67e3f6e46..d9b29188d 100644 --- a/examples/from_explicit/construct.yaml +++ b/examples/from_explicit/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: Explicit version: X installer_type: all diff --git a/examples/grin/construct.yaml b/examples/grin/construct.yaml index 2bb45f6aa..47ea78bd0 100644 --- a/examples/grin/construct.yaml +++ b/examples/grin/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + # name and version (required) name: test version: 3 diff --git a/examples/jetsonconda/construct.yaml b/examples/jetsonconda/construct.yaml index d9eb5f9a4..7941008f0 100644 --- a/examples/jetsonconda/construct.yaml +++ b/examples/jetsonconda/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: JetsonConda version: 0.1 diff --git a/examples/miniconda/construct.yaml b/examples/miniconda/construct.yaml index 8fe996cd6..5491fbce1 100644 --- a/examples/miniconda/construct.yaml +++ b/examples/miniconda/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: MinicondaX version: X installer_type: all diff --git a/examples/miniforge-mamba2/construct.yaml b/examples/miniforge-mamba2/construct.yaml index 24eb4a512..d2a0a0bfa 100644 --- a/examples/miniforge-mamba2/construct.yaml +++ b/examples/miniforge-mamba2/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: Miniforge3-mamba2 version: 25.0.0-2 company: conda-forge diff --git a/examples/miniforge/construct.yaml b/examples/miniforge/construct.yaml index 040f111a0..fb55fd313 100644 --- a/examples/miniforge/construct.yaml +++ b/examples/miniforge/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: Miniforge3 version: 25.0.0-1 company: conda-forge diff --git a/examples/newchan/construct.yaml b/examples/newchan/construct.yaml index 05a1b668b..1f0c349ef 100644 --- a/examples/newchan/construct.yaml +++ b/examples/newchan/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: Funnychan version: 2.5.5 diff --git a/examples/noconda/constructor_input.yaml b/examples/noconda/constructor_input.yaml index 5a522cea2..45fcfb0a3 100644 --- a/examples/noconda/constructor_input.yaml +++ b/examples/noconda/constructor_input.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: NoConda version: X installer_type: all diff --git a/examples/osxpkg/construct.yaml b/examples/osxpkg/construct.yaml index b749fa6ec..b7d9a64b9 100644 --- a/examples/osxpkg/construct.yaml +++ b/examples/osxpkg/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: osxpkgtest version: 1.2.3 diff --git a/examples/osxpkg_extra_pages/construct.yaml b/examples/osxpkg_extra_pages/construct.yaml index 36f47f00d..b86aa14f6 100644 --- a/examples/osxpkg_extra_pages/construct.yaml +++ b/examples/osxpkg_extra_pages/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: osxpkgtest version: 1.2.3 diff --git a/examples/register_envs/construct.yaml b/examples/register_envs/construct.yaml index 5db921d2f..d76ac40ea 100644 --- a/examples/register_envs/construct.yaml +++ b/examples/register_envs/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: RegisterEnvs version: X installer_type: all diff --git a/examples/regressions/construct.yaml b/examples/regressions/construct.yaml index ceda1fd05..48a8e1e53 100644 --- a/examples/regressions/construct.yaml +++ b/examples/regressions/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: regressions version: 0.0.1 diff --git a/examples/scripts/construct.yaml b/examples/scripts/construct.yaml index e57bdffa0..108548450 100644 --- a/examples/scripts/construct.yaml +++ b/examples/scripts/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: Scripts version: X installer_type: all diff --git a/examples/shortcuts/construct.yaml b/examples/shortcuts/construct.yaml index e22d46d97..a936a805c 100644 --- a/examples/shortcuts/construct.yaml +++ b/examples/shortcuts/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: MinicondaWithShortcuts version: X installer_type: all diff --git a/examples/signing/construct.yaml b/examples/signing/construct.yaml index 5deb48f42..17d64accc 100644 --- a/examples/signing/construct.yaml +++ b/examples/signing/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: Signed version: X installer_type: all diff --git a/examples/use_channel_remap/construct.yaml b/examples/use_channel_remap/construct.yaml index 2fd86f0ff..eb9bae7fa 100644 --- a/examples/use_channel_remap/construct.yaml +++ b/examples/use_channel_remap/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: use_channel_remap version: 0.0.1 diff --git a/examples/virtual_specs_failed/construct.yaml b/examples/virtual_specs_failed/construct.yaml index 0b8eae288..51e031ea6 100644 --- a/examples/virtual_specs_failed/construct.yaml +++ b/examples/virtual_specs_failed/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: virtual_specs_failed version: 0.0.1 diff --git a/examples/virtual_specs_ok/construct.yaml b/examples/virtual_specs_ok/construct.yaml index e92e61f49..4af22e653 100644 --- a/examples/virtual_specs_ok/construct.yaml +++ b/examples/virtual_specs_ok/construct.yaml @@ -1,3 +1,5 @@ +# yaml-language-server: $schema=../../constructor/data/constructor.schema.json + name: virtual_specs_ok version: 0.0.1 From e3aa238d2d2329f4ff5e1756e8f43c18c32f5deb Mon Sep 17 00:00:00 2001 From: jaimergp Date: Fri, 28 Feb 2025 16:29:46 +0100 Subject: [PATCH 003/138] Add pydantic to dependencies, small fixes --- constructor/construct.py | 78 ++++++++++++++++++++-------------------- dev/environment.yml | 1 + pyproject.toml | 1 + 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/constructor/construct.py b/constructor/construct.py index 9be9f0191..2ff524493 100644 --- a/constructor/construct.py +++ b/constructor/construct.py @@ -10,6 +10,7 @@ import sys from functools import partial from os.path import dirname +from pathlib import Path from pydantic import BaseModel, ConfigDict from ruamel.yaml import YAMLError @@ -21,6 +22,7 @@ "azuresigntool", "signtool", ] +HERE = Path(__file__).parent class ConstructorConfiguration(BaseModel): @@ -135,7 +137,7 @@ class ConstructorConfiguration(BaseModel): conda executable for its installation behavior. This option is now ignored with a warning. """ - environment: str = str() + environment: str = '' """ Name of the environment to construct from. If this option is present, the `specs` argument will be ignored. Using this option allows the user to @@ -143,7 +145,7 @@ class ConstructorConfiguration(BaseModel): run constructor with full confidence that the exact environment will be reproduced. """ - environment_file: str = str() + environment_file: str = '' """ Path to an environment file (TXT or YAML) to construct from. If this option is present, the `specs` argument will be ignored. Instead, constructor will @@ -155,7 +157,7 @@ class ConstructorConfiguration(BaseModel): Read notes about the solver in the `specs` field. """ - transmute_file_type: str = str() + transmute_file_type: str = '' """ File type extension for the files to be transmuted into. Currently supports only '.conda'. See conda-package-handling for supported extension names. @@ -168,7 +170,7 @@ class ConstructorConfiguration(BaseModel): option in the environment's `.condarc` file. This will have an impact only if `conda` is included in the environmnent. """ - conda_channel_alias: str = str() + conda_channel_alias: str = '' """ The channel alias that would be assumed for the created installer (only useful if it includes conda). @@ -205,7 +207,7 @@ class ConstructorConfiguration(BaseModel): Whether to register the environments created by the installer (both `base` and `extra_envs`) in `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. Defaults to `True`. """ - installer_filename: str = str() + installer_filename: str = '' """ The filename of the installer being created. If not supplied, a reasonable default will determined by the `name`, `version`, platform, and installer type. @@ -232,7 +234,7 @@ class ConstructorConfiguration(BaseModel): [nsis-log]: https://nsis.sourceforge.io/Special_Builds """ - license_file: str = str() + license_file: str = '' """ Path to the license file being displayed by the installer during the install process. It must be plain text (.txt) for shell-based installers. On PKG, @@ -252,7 +254,7 @@ class ConstructorConfiguration(BaseModel): an interactive wizard guiding the user through the available options. If ``True``, the installer runs automatically as if ``-b`` was passed. """ - signing_identity_name: str = str() + signing_identity_name: str = '' """ By default, the MacOS pkg installer isn't signed. If an identity name is specified using this option, it will be used to sign the installer with Apple's `productsign`. @@ -261,7 +263,7 @@ class ConstructorConfiguration(BaseModel): accessible keychains. Common values for this option follow this format `Developer ID Installer: Name of the owner (XXXXXX)`. """ - notarization_identity_name: str = str() + notarization_identity_name: str = '' """ If the pkg installer is going to be signed with `signing_identity_name`, you can also prepare the bundle for notarization. This will use Apple's `codesign` @@ -269,7 +271,7 @@ class ConstructorConfiguration(BaseModel): "Installer certificate" mentioned above). Common values for this option follow the format `Developer ID Application: Name of the owner (XXXXXX)`. """ - windows_signing_tool: str = str() + windows_signing_tool: str = '' """ The tool used to sign Windows installers. Must be one of: azuresigntool, signtool. Some tools require `signing_certificate` to be set. @@ -278,7 +280,7 @@ class ConstructorConfiguration(BaseModel): See the documentation for details: https://conda.github.io/constructor/howto/#signing-exe-installers """ - signing_certificate: str = str() + signing_certificate: str = '' """ On Windows only, set this key to the path of the certificate file to be used with the `windows_signing_tool`. @@ -302,17 +304,17 @@ class ConstructorConfiguration(BaseModel): option is used, then all other options related to the construction of a `.condarc` file (`write_condarc`, `conda_default_channels`, etc.) are ignored. """ - company: str = str() + company: str = '' """ Name of the company/entity who is responsible for the installer. """ - reverse_domain_identifier: str = str() + reverse_domain_identifier: str = '' """ Unique identifier for this package, formatted with reverse domain notation. This is used internally in the PKG installers to handle future updates and others. If not provided, it will default to `io.continuum`. (MacOS only) """ - uninstall_name: str = str() + uninstall_name: str = '' """ Application name in the Windows "Programs and Features" control panel. Defaults to `${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})`. @@ -338,14 +340,14 @@ class ConstructorConfiguration(BaseModel): Note that the # (hash) character cannot be used as it denotes yaml comments for all platforms. """ - pre_install: str = str() + pre_install: str = '' """ Path to a pre-install script, run after the package cache has been set, but before the files are linked to their final locations. As a result, you should only rely on tools known to be available on most systems (e.g. `bash`, `cmd`, etc). See `post_install` for information about available environment variables. """ - pre_install_desc: str = str() + pre_install_desc: str = '' """ A description of the purpose of the supplied `pre_install` script. If this string is supplied and non-empty, then the Windows and macOS GUI installers @@ -355,7 +357,7 @@ class ConstructorConfiguration(BaseModel): This option has no effect on `SH` installers. """ - post_install: str = str() + post_install: str = '' """ Path to a post-install script. Some notes: @@ -381,7 +383,7 @@ class ConstructorConfiguration(BaseModel): - Unix: `source "$PREFIX/etc/profile.d/conda.sh" && conda activate "$PREFIX"` - Windows: `call "%PREFIX%\\Scripts\\activate.bat"` """ - post_install_desc: str = str() + post_install_desc: str = '' """ A description of the purpose of the supplied `post_install` script. If this string is supplied and non-empty, then the Windows and macOS GUI installers @@ -391,7 +393,7 @@ class ConstructorConfiguration(BaseModel): This option has no effect on `SH` installers. """ - pre_uninstall: str = str() + pre_uninstall: str = '' """ Path to a pre uninstall script. This is only supported for on Windows, and must be a `.bat` file. Installation path is available as `%PREFIX%`. @@ -399,7 +401,7 @@ class ConstructorConfiguration(BaseModel): `%INSTALLER_VER%`, `%INSTALLER_PLAT%` environment variables. `%INSTALLER_TYPE%` is set to `EXE`. """ - default_prefix: str = str() + default_prefix: str = '' """ Set default install prefix. On Linux, if not provided, the default prefix is `${HOME}/` (or, if `HOME` is not set, `/opt/`). On Windows, @@ -408,7 +410,7 @@ class ConstructorConfiguration(BaseModel): is `%USERPROFILE%\\`. Environment variables will be expanded at installation time. """ - default_prefix_domain_user: str = str() + default_prefix_domain_user: str = '' """ Set default installation prefix for domain user. If not provided, the installation prefix for domain user will be `%LOCALAPPDATA%\\`. @@ -416,14 +418,14 @@ class ConstructorConfiguration(BaseModel): the distribution in the roaming profile. Environment variables will be expanded at installation time. Windows only. """ - default_prefix_all_users: str = str() + default_prefix_all_users: str = '' """ Set default installation prefix for All Users installation. If not provided, the installation prefix for all users installation will be `%ALLUSERSPROFILE%\\`. Environment variables will be expanded at installation time. Windows only. """ - default_location_pkg: str = str() + default_location_pkg: str = '' """ Default installation subdirectory in the chosen volume. In PKG installers, default installation locations are configured differently. The user can choose @@ -444,13 +446,13 @@ class ConstructorConfiguration(BaseModel): `enable_localSystem` should not be set to true unless `default_location_pkg` is set as well. macOS only. """ - pkg_name: str = str() + pkg_name: str = '' """ Internal identifier for the installer. This is used in the build prefix and will determine part of the default location path. Combine with `default_location_pkg` for more flexibility. If not provided, the value of `name` will be used. (MacOS only) """ - install_path_exists_error_text: str = str() + install_path_exists_error_text: str = '' """ Error message that will be shown if the installation path already exists. You cannot use double quotes or newlines. The placeholder `{CHOSEN_PATH}` is @@ -469,7 +471,7 @@ class ConstructorConfiguration(BaseModel): so the user receives updates after each command executed by the installer. (macOS only) """ - welcome_image: str = str() + welcome_image: str = '' """ Path to an image in any common image format (`.png`, `.jpg`, `.tif`, etc.) to be used as the welcome image for the Windows and PKG installers. @@ -478,26 +480,26 @@ class ConstructorConfiguration(BaseModel): logo is shown if this key is not provided. If you don't want a background on PKG installers, set this key to `""` (empty string). """ - header_image: str = str() + header_image: str = '' """ Like `welcome_image` for Windows, re-sized to 150 x 57 pixels. """ - icon_image: str = str() + icon_image: str = '' """ Like `welcome_image` for Windows, re-sized to 256 x 256 pixels. """ - default_image_color: str = str() + default_image_color: str = '' """ The color of the default images (when not providing explicit image files) used on Windows. Possible values are `red`, `green`, `blue`, `yellow`. The default is `blue`. """ - welcome_image_text: str = str() + welcome_image_text: str = '' """ If `welcome_image` is not provided, use this text when generating the image (Windows and PKG only). Defaults to `name` on Windows. """ - header_image_text: str = str() + header_image_text: str = '' """ If `header_image` is not provided, use this text when generating the image (Windows only). Defaults to `name`. @@ -545,13 +547,13 @@ class ConstructorConfiguration(BaseModel): Read notes about the particularities of Windows silent mode `/S` in the `installer_type` documentation. """ - nsis_template: str = str() + nsis_template: str = '' """ If `nsis_template` is not provided, constructor uses its default NSIS template. For more complete customization for the installation experience, provide an NSIS template file. (Windows only). """ - welcome_file: str = str() + welcome_file: str = '' """ If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the introduction. @@ -563,7 +565,7 @@ class ConstructorConfiguration(BaseModel): it will use the nsi script to add in extra pages before the installer begins the installation process. """ - welcome_text: str = str() + welcome_text: str = '' """ If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the introduction. @@ -572,7 +574,7 @@ class ConstructorConfiguration(BaseModel): if you set this key to `""` (empty string). (MacOS only). """ - readme_file: str = str() + readme_file: str = '' """ If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the welcome screen. @@ -580,7 +582,7 @@ class ConstructorConfiguration(BaseModel): both `readme_file` and `readme_text` are provided, `readme_file` takes precedence. (MacOS only). """ - readme_text: str = str() + readme_text: str = '' """ If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the welcome screen. @@ -599,7 +601,7 @@ class ConstructorConfiguration(BaseModel): For Windows, the extra pages must be `.nsi` files. They will be inserted as-is before the conclusion page. """ - conclusion_file: str = str() + conclusion_file: str = '' """ If `installer_type` is `pkg` on MacOS, this message will be shown at the end of the installer upon success. File can be @@ -609,7 +611,7 @@ class ConstructorConfiguration(BaseModel): If the installer is for Windows, the file type must be nsi. """ - conclusion_text: str = str() + conclusion_text: str = '' """ A message that will be shown at the end of the installer upon success. The behaviour is slightly different across installer types: @@ -860,7 +862,7 @@ def verify(info): def dump_schema(): - model = ConstructorModel(name="...", version="...") + model = ConstructorConfiguration(name="...", version="...") obj = model.model_json_schema() obj["$schema"] = "https://json-schema.org/draft/2020-12/schema" (HERE / "data" / "constructor.schema.json").write_text(json.dumps(obj, indent=2)) diff --git a/dev/environment.yml b/dev/environment.yml index 721e3419c..4a3e30aa3 100644 --- a/dev/environment.yml +++ b/dev/environment.yml @@ -8,3 +8,4 @@ dependencies: - conda-standalone # >=23.11.0 - pillow >=3.1 # [osx or win] - jinja2 + - pydantic >=2 diff --git a/pyproject.toml b/pyproject.toml index 6c80b2811..d3108ce53 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,7 @@ dependencies = [ "ruamel.yaml >=0.11.14,<0.19", "pillow >=3.1 ; platform_system=='Windows' or platform_system=='Darwin'", "jinja2", + "pydantic >=2" ] [project.scripts] From 1ecaa7b4b7ddbf395dc008daa8e2f1b0b6c2b870 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Fri, 28 Feb 2025 18:27:46 +0100 Subject: [PATCH 004/138] Refine types --- constructor/construct.py | 338 ++++---- constructor/data/constructor.schema.json | 972 ++++++++++++++++++----- 2 files changed, 983 insertions(+), 327 deletions(-) diff --git a/constructor/construct.py b/constructor/construct.py index 2ff524493..07fc2631c 100644 --- a/constructor/construct.py +++ b/constructor/construct.py @@ -11,8 +11,9 @@ from functools import partial from os.path import dirname from pathlib import Path +from typing import Annotated, Any, Literal -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field from ruamel.yaml import YAMLError from constructor.exceptions import UnableToParse, UnableToParseMissingJinja2, YamlParsingError @@ -23,37 +24,82 @@ "signtool", ] HERE = Path(__file__).parent +# TODO: lookarounds are not supported, we need to add (?=1.8`. The specifications are identical in form and purpose to those that would be @@ -86,7 +132,7 @@ class ConstructorConfiguration(BaseModel): `constructor` from a non-`base` environment, make sure the configured solver plugin is also installed in that environment. """ - user_requested_specs: tuple = tuple() + user_requested_specs: list[NonEmptyStr] = [] """ A list of package specifications to be recorded as "user-requested" for the initial environment in conda's history file. This information is used by newer @@ -95,7 +141,7 @@ class ConstructorConfiguration(BaseModel): of packages compatible with Python 3.6. If this is option is not provided, it will be set equal to the value of `specs`. """ - virtual_specs: list = list() + virtual_specs: list[NonEmptyStr] = [] """ A list of virtual packages that must be satisfied at install time. Virtual packages must start with `__`. For example, `__osx>=11` or `__glibc>=2.24`. @@ -106,13 +152,13 @@ class ConstructorConfiguration(BaseModel): installers, `__osx` specs can be checked natively without the solver being involved as long as only `>=`, `<` or `,` are used. """ - exclude: list = list() + exclude: list[NonEmptyStr] = [] """ A list of package names to be excluded after the `specs` have been resolved. For example, you can say that `readline` should be excluded, even though it is contained as a result of resolving the specs for `python 2.7`. """ - menu_packages: list = list() + menu_packages: list[NonEmptyStr] | None = None """ A list of packages with menu items to be installed. The packages must have necessary metadata in `Menu/.json`). By default, all menu items @@ -126,18 +172,20 @@ class ConstructorConfiguration(BaseModel): Note: This option is not fully implemented when `micromamba` is used as the `--conda-exe` binary. The only accepted value is an empty list (`[]`). """ - ignore_duplicate_files: bool = bool() + ignore_duplicate_files: bool = True """ By default, constructor will warn you when adding packages with duplicate files in them. Setting this option to false will raise an error instead. """ - install_in_dependency_order: tuple = tuple() + install_in_dependency_order: ( + Annotated[bool, Field(deprecated=True)] | Annotated[str, Field(deprecated=True)] + ) = True """ _Obsolete_. The current version of constructor relies on the standalone conda executable for its installation behavior. This option is now ignored with a warning. """ - environment: str = '' + environment: NonEmptyStr | None = None """ Name of the environment to construct from. If this option is present, the `specs` argument will be ignored. Using this option allows the user to @@ -145,7 +193,7 @@ class ConstructorConfiguration(BaseModel): run constructor with full confidence that the exact environment will be reproduced. """ - environment_file: str = '' + environment_file: NonEmptyStr | None = None """ Path to an environment file (TXT or YAML) to construct from. If this option is present, the `specs` argument will be ignored. Instead, constructor will @@ -157,41 +205,28 @@ class ConstructorConfiguration(BaseModel): Read notes about the solver in the `specs` field. """ - transmute_file_type: str = '' + transmute_file_type: Literal[".conda"] | None = None """ File type extension for the files to be transmuted into. Currently supports only '.conda'. See conda-package-handling for supported extension names. If left empty, no transmuting is done. """ - conda_default_channels: list = list() + conda_default_channels: list[NonEmptyStr] = [] """ If this value is provided as well as `write_condarc`, then the channels in this list will be included as the value of the `default_channels:` option in the environment's `.condarc` file. This will have an impact only if `conda` is included in the environmnent. """ - conda_channel_alias: str = '' + conda_channel_alias: NonEmptyStr | None = None """ The channel alias that would be assumed for the created installer - (only useful if it includes conda). + (only useful if it includes `conda`). """ - extra_envs: tuple = tuple() + extra_envs: dict[NonEmptyStr, ExtraEnv] = {} """ Create more environments in addition to the default `base` provided by `specs`, - `environment` or `environment_file`. This should be a map of `str` (environment - name) to a dictionary of options: - - `specs` (list of str): which packages to install in that environment - - `environment` (str): same as global option, for this env - - `environment_file` (str): same as global option, for this env - - `channels` (list of str): using these channels; if not provided, the global - value is used. To override inheritance, set it to an empty list. - - `channels_remap` (list of str): same as global option, for this env; - if not provided, the global value is used. To override inheritance, set it to - an empty list. - - `user_requested_specs` (list of str): same as the global option, but for this env; - if not provided, global value is _not_ used - - `menu_packages` (list of str): same as the global option, for this env; - if not provided, the global value is _not_ used. + `environment` or `environment_file`. Notes: - `ignore_duplicate_files` will always be considered `True` if `extra_envs` is in use. @@ -202,17 +237,17 @@ class ConstructorConfiguration(BaseModel): thrown if the excluded package is not found in the packages required by the extra environment. To override the global `exclude` value, use an empty list `[]`. """ - register_envs: bool = bool() + register_envs: bool = True """ Whether to register the environments created by the installer (both `base` and `extra_envs`) - in `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. Defaults to `True`. + in `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. """ - installer_filename: str = '' + installer_filename: NonEmptyStr | None = None """ The filename of the installer being created. If not supplied, a reasonable default will determined by the `name`, `version`, platform, and installer type. """ - installer_type: tuple = tuple() + installer_type: NonEmptyStr | list[NonEmptyStr] | None = None """ The type of the installer being created. Possible values are: - `sh`: shell-based installer for Linux or macOS; @@ -226,21 +261,21 @@ class ConstructorConfiguration(BaseModel): Notes for silent mode `/S` on Windows EXEs: - NSIS Silent mode will not print any error message, but will silently abort the installation. If needed, [NSIS log-builds][nsis-log] can be used to print to `%PREFIX%\\install.log`, which - can be searched for `::error::` strings. Pre- and post- install scripts will only throw an error - if the environment variable `NSIS_SCRIPTS_RAISE_ERRORS` is set. + can be searched for `::error::` strings. Pre- and post- install scripts will only throw + an error if the environment variable `NSIS_SCRIPTS_RAISE_ERRORS` is set. - The `/D` flag can be used to specify the target location. It must be the last argument in the command and should NEVER be quoted, even if it contains spaces. For example: `CMD.EXE /C START /WAIT myproject.exe /S /D=C:\\path with spaces\\my project`. [nsis-log]: https://nsis.sourceforge.io/Special_Builds """ - license_file: str = '' + license_file: NonEmptyStr | None = None """ Path to the license file being displayed by the installer during the install process. It must be plain text (.txt) for shell-based installers. On PKG, .txt, .rtf and .html are supported. On Windows, .txt and .rtf are supported. """ - keep_pkgs: bool = bool() + keep_pkgs: bool = False """ If `False` (default), the package cache in the `pkgs` subdirectory is removed when the installation process is complete. If `True`, this subdirectory and @@ -248,13 +283,13 @@ class ConstructorConfiguration(BaseModel): installers offer a command-line option (`-k` and `/KeepPkgCache`, respectively) to preserve the package cache. """ - batch_mode: bool = bool() + batch_mode: bool = False """ - Only affects ``.sh`` installers. If ``False`` (default), the installer launches + Only affects `.sh` installers. If `False` (default), the installer launches an interactive wizard guiding the user through the available options. If - ``True``, the installer runs automatically as if ``-b`` was passed. + `True`, the installer runs automatically as if `-b` was passed. """ - signing_identity_name: str = '' + signing_identity_name: NonEmptyStr | None = None """ By default, the MacOS pkg installer isn't signed. If an identity name is specified using this option, it will be used to sign the installer with Apple's `productsign`. @@ -263,7 +298,7 @@ class ConstructorConfiguration(BaseModel): accessible keychains. Common values for this option follow this format `Developer ID Installer: Name of the owner (XXXXXX)`. """ - notarization_identity_name: str = '' + notarization_identity_name: NonEmptyStr | None = None """ If the pkg installer is going to be signed with `signing_identity_name`, you can also prepare the bundle for notarization. This will use Apple's `codesign` @@ -271,7 +306,7 @@ class ConstructorConfiguration(BaseModel): "Installer certificate" mentioned above). Common values for this option follow the format `Developer ID Application: Name of the owner (XXXXXX)`. """ - windows_signing_tool: str = '' + windows_signing_tool: NonEmptyStr | None = None """ The tool used to sign Windows installers. Must be one of: azuresigntool, signtool. Some tools require `signing_certificate` to be set. @@ -280,23 +315,25 @@ class ConstructorConfiguration(BaseModel): See the documentation for details: https://conda.github.io/constructor/howto/#signing-exe-installers """ - signing_certificate: str = '' + signing_certificate: NonEmptyStr | None = None """ On Windows only, set this key to the path of the certificate file to be used with the `windows_signing_tool`. """ - attempt_hardlinks: tuple = tuple() + attempt_hardlinks: ( + Annotated[bool, Field(deprecated=True)] | Annotated[str, Field(deprecated=True)] + ) = True """ _Obsolete_. The current version of constructor relies on the standalone conda executable for its installation behavior. This option is now ignored with a warning. """ - write_condarc: bool = bool() + write_condarc: bool = False """ By default, no `.condarc` file is written. If set, a `.condarc` file is written to - the base environment if there are any channels or conda_default_channels is set. + the base environment if there are any channels or `conda_default_channels` is set. """ - condarc: tuple = tuple() + condarc: NonEmptyStr | dict | None = None """ If set, a `.condarc` file is written to the base environment containing the contents of this value. The value can either be a string (likely a multi-line string) or @@ -304,22 +341,22 @@ class ConstructorConfiguration(BaseModel): option is used, then all other options related to the construction of a `.condarc` file (`write_condarc`, `conda_default_channels`, etc.) are ignored. """ - company: str = '' + company: NonEmptyStr | None = None """ Name of the company/entity who is responsible for the installer. """ - reverse_domain_identifier: str = '' + reverse_domain_identifier: NonEmptyStr | None = None """ Unique identifier for this package, formatted with reverse domain notation. This is used internally in the PKG installers to handle future updates and others. If not provided, it will default to `io.continuum`. (MacOS only) """ - uninstall_name: str = '' + uninstall_name: NonEmptyStr | None = None """ Application name in the Windows "Programs and Features" control panel. Defaults to `${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})`. """ - script_env_variables: tuple = tuple() + script_env_variables: dict[NonEmptyStr, str] = {} """ Dictionary of additional environment variables to be made available to the pre_install and post_install scripts, in the form of VAR:VALUE @@ -340,14 +377,14 @@ class ConstructorConfiguration(BaseModel): Note that the # (hash) character cannot be used as it denotes yaml comments for all platforms. """ - pre_install: str = '' + pre_install: NonEmptyStr | None = None """ Path to a pre-install script, run after the package cache has been set, but before the files are linked to their final locations. As a result, you should only rely on tools known to be available on most systems (e.g. `bash`, `cmd`, etc). See `post_install` for information about available environment variables. """ - pre_install_desc: str = '' + pre_install_desc: NonEmptyStr | None = None """ A description of the purpose of the supplied `pre_install` script. If this string is supplied and non-empty, then the Windows and macOS GUI installers @@ -357,7 +394,7 @@ class ConstructorConfiguration(BaseModel): This option has no effect on `SH` installers. """ - post_install: str = '' + post_install: NonEmptyStr | None = None """ Path to a post-install script. Some notes: @@ -383,7 +420,7 @@ class ConstructorConfiguration(BaseModel): - Unix: `source "$PREFIX/etc/profile.d/conda.sh" && conda activate "$PREFIX"` - Windows: `call "%PREFIX%\\Scripts\\activate.bat"` """ - post_install_desc: str = '' + post_install_desc: NonEmptyStr | None = None """ A description of the purpose of the supplied `post_install` script. If this string is supplied and non-empty, then the Windows and macOS GUI installers @@ -393,7 +430,7 @@ class ConstructorConfiguration(BaseModel): This option has no effect on `SH` installers. """ - pre_uninstall: str = '' + pre_uninstall: NonEmptyStr | None = None """ Path to a pre uninstall script. This is only supported for on Windows, and must be a `.bat` file. Installation path is available as `%PREFIX%`. @@ -401,7 +438,7 @@ class ConstructorConfiguration(BaseModel): `%INSTALLER_VER%`, `%INSTALLER_PLAT%` environment variables. `%INSTALLER_TYPE%` is set to `EXE`. """ - default_prefix: str = '' + default_prefix: NonEmptyStr | None = None """ Set default install prefix. On Linux, if not provided, the default prefix is `${HOME}/` (or, if `HOME` is not set, `/opt/`). On Windows, @@ -410,7 +447,7 @@ class ConstructorConfiguration(BaseModel): is `%USERPROFILE%\\`. Environment variables will be expanded at installation time. """ - default_prefix_domain_user: str = '' + default_prefix_domain_user: NonEmptyStr | None = None """ Set default installation prefix for domain user. If not provided, the installation prefix for domain user will be `%LOCALAPPDATA%\\`. @@ -418,14 +455,14 @@ class ConstructorConfiguration(BaseModel): the distribution in the roaming profile. Environment variables will be expanded at installation time. Windows only. """ - default_prefix_all_users: str = '' + default_prefix_all_users: NonEmptyStr | None = None """ Set default installation prefix for All Users installation. If not provided, the installation prefix for all users installation will be `%ALLUSERSPROFILE%\\`. Environment variables will be expanded at installation time. Windows only. """ - default_location_pkg: str = '' + default_location_pkg: NonEmptyStr | None = None """ Default installation subdirectory in the chosen volume. In PKG installers, default installation locations are configured differently. The user can choose @@ -438,7 +475,7 @@ class ConstructorConfiguration(BaseModel): Internally, this is passed to `pkgbuild --install-location`. macOS only. """ - pkg_domains: dict = dict() + pkg_domains: dict[NonEmptyStr, Any] = {} """ The domains the package can be installed into. For a detailed explanation, see: https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html @@ -446,13 +483,13 @@ class ConstructorConfiguration(BaseModel): `enable_localSystem` should not be set to true unless `default_location_pkg` is set as well. macOS only. """ - pkg_name: str = '' + pkg_name: NonEmptyStr | None = None """ Internal identifier for the installer. This is used in the build prefix and will determine part of the default location path. Combine with `default_location_pkg` for more flexibility. If not provided, the value of `name` will be used. (MacOS only) """ - install_path_exists_error_text: str = '' + install_path_exists_error_text: NonEmptyStr | None = None """ Error message that will be shown if the installation path already exists. You cannot use double quotes or newlines. The placeholder `{CHOSEN_PATH}` is @@ -463,7 +500,7 @@ class ConstructorConfiguration(BaseModel): (MacOS only) """ - progress_notifications: bool = bool() + progress_notifications: bool = False """ Whether to show UI notifications on PKG installers. On large installations, the progress bar reaches ~90% very quickly and stays there for a long time. @@ -471,7 +508,7 @@ class ConstructorConfiguration(BaseModel): so the user receives updates after each command executed by the installer. (macOS only) """ - welcome_image: str = '' + welcome_image: str | None = None """ Path to an image in any common image format (`.png`, `.jpg`, `.tif`, etc.) to be used as the welcome image for the Windows and PKG installers. @@ -480,54 +517,54 @@ class ConstructorConfiguration(BaseModel): logo is shown if this key is not provided. If you don't want a background on PKG installers, set this key to `""` (empty string). """ - header_image: str = '' + header_image: str | None = None """ Like `welcome_image` for Windows, re-sized to 150 x 57 pixels. """ - icon_image: str = '' + icon_image: str | None = None """ Like `welcome_image` for Windows, re-sized to 256 x 256 pixels. """ - default_image_color: str = '' + default_image_color: Literal["red", "green", "blue", "yellow"] = "blue" """ The color of the default images (when not providing explicit image files) - used on Windows. Possible values are `red`, `green`, `blue`, `yellow`. + used on Windows. Possible values are `red`, `green`, `blue`, `yellow`. The default is `blue`. """ - welcome_image_text: str = '' + welcome_image_text: NonEmptyStr | None = None """ If `welcome_image` is not provided, use this text when generating the image (Windows and PKG only). Defaults to `name` on Windows. """ - header_image_text: str = '' + header_image_text: NonEmptyStr | None = None """ If `header_image` is not provided, use this text when generating the image (Windows only). Defaults to `name`. """ - initialize_conda: bool = bool() + initialize_conda: bool = True """ Add an option to the installer so the user can choose whether to run `conda init` after the install. See also `initialize_by_default`. """ - initialize_by_default: bool = bool() + initialize_by_default: bool | None = None """ Whether to add the installation to the PATH environment variable. The default is true for GUI installers (msi, pkg) and False for shell installers. The user is able to change the default during interactive installation. NOTE: For Windows, `AddToPath` is disabled when `InstallationType=AllUsers`. """ - register_python: bool = bool() + register_python: bool = True """ Whether to offer the user an option to register the installed Python instance as the system's default Python. (Windows only) """ - register_python_default: bool = bool() + register_python_default: bool | None = False """ Default choice for whether to register the installed Python instance as the system's default Python. The user is still able to change this during interactive installation. (Windows only). """ - check_path_length: bool = bool() + check_path_length: bool | None = None """ Check the length of the path where the distribution is installed to ensure nodejs can be installed. Raise a message to request shorter path (less than 46 character) @@ -536,7 +573,7 @@ class ConstructorConfiguration(BaseModel): Read notes about the particularities of Windows silent mode `/S` in the `installer_type` documentation. """ - check_path_spaces: bool = bool() + check_path_spaces: bool = True """ Check if the path where the distribution is installed contains spaces. Default is True. To allow installations with spaces, change to False. Note that: @@ -547,13 +584,13 @@ class ConstructorConfiguration(BaseModel): Read notes about the particularities of Windows silent mode `/S` in the `installer_type` documentation. """ - nsis_template: str = '' + nsis_template: NonEmptyStr | None = None """ If `nsis_template` is not provided, constructor uses its default NSIS template. For more complete customization for the installation experience, provide an NSIS template file. (Windows only). """ - welcome_file: str = '' + welcome_file: NonEmptyStr | None = None """ If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the introduction. @@ -565,7 +602,7 @@ class ConstructorConfiguration(BaseModel): it will use the nsi script to add in extra pages before the installer begins the installation process. """ - welcome_text: str = '' + welcome_text: str | None = None """ If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the introduction. @@ -574,7 +611,7 @@ class ConstructorConfiguration(BaseModel): if you set this key to `""` (empty string). (MacOS only). """ - readme_file: str = '' + readme_file: NonEmptyStr | None = None """ If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the welcome screen. @@ -582,7 +619,7 @@ class ConstructorConfiguration(BaseModel): both `readme_file` and `readme_text` are provided, `readme_file` takes precedence. (MacOS only). """ - readme_text: str = '' + readme_text: str | None = None """ If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the welcome screen. @@ -590,7 +627,7 @@ class ConstructorConfiguration(BaseModel): You can disable it altogether if you set this key to `""` (empty string). (MacOS only). """ - post_install_pages: tuple = tuple() + post_install_pages: NonEmptyStr | list[NonEmptyStr] | None = None """ Adds extra pages to the installers to be shown after installation. @@ -601,7 +638,7 @@ class ConstructorConfiguration(BaseModel): For Windows, the extra pages must be `.nsi` files. They will be inserted as-is before the conclusion page. """ - conclusion_file: str = '' + conclusion_file: NonEmptyStr | None = None """ If `installer_type` is `pkg` on MacOS, this message will be shown at the end of the installer upon success. File can be @@ -611,7 +648,7 @@ class ConstructorConfiguration(BaseModel): If the installer is for Windows, the file type must be nsi. """ - conclusion_text: str = '' + conclusion_text: str | None = None """ A message that will be shown at the end of the installer upon success. The behaviour is slightly different across installer types: @@ -621,7 +658,7 @@ class ConstructorConfiguration(BaseModel): - EXE: The first line will be used as a title. The following lines will be used as text. (macOS PKG and Windows only). """ - extra_files: list = list() + extra_files: list[NonEmptyStr] | list[dict[NonEmptyStr, NonEmptyStr]] = [] """ Extra, non-packaged files that should be added to the installer. If provided as relative paths, they will be considered relative to the directory where `construct.yaml` is. @@ -629,7 +666,7 @@ class ConstructorConfiguration(BaseModel): - `str`: each found file will be copied to the root prefix - `Mapping[str, str]`: map of path in disk to path in prefix. """ - temp_extra_files: list = list() + temp_extra_files: list[NonEmptyStr] | list[dict[NonEmptyStr, NonEmptyStr]] = [] """ Temporary files that could be referenced in the installation process (i.e. customized `welcome_file` and `conclusion_file` (see above)) . Should be a list of @@ -639,13 +676,14 @@ class ConstructorConfiguration(BaseModel): Supports the same values as `extra_files`. """ - build_outputs: list = list() + build_outputs: list[NonEmptyStr | dict[NonEmptyStr, Any]] = [] """ Additional artifacts to be produced after building the installer. It expects either a list of strings or single-key dictionaries: Allowed keys are: - `hash`: The hash of the installer files. - - `algorithm` (str or list): The hash algorithm. Must be among `hashlib`'s available algorithms: + - `algorithm` (str or list): The hash algorithm. Must be among `hashlib`'s available + algorithms: https://docs.python.org/3/library/hashlib.html#hashlib.algorithms_available - `info.json`: The internal `info` object, serialized to JSON. Takes no options. - `pkgs_list`: The list of packages contained in a given environment. Options: @@ -653,21 +691,19 @@ class ConstructorConfiguration(BaseModel): - `lockfile`: An `@EXPLICIT` lockfile for a given environment. Options: - `env` (optional, default=`base`): Name of an environment in `extra_envs` to export. - `licenses`: Generate a JSON file with the licensing details of all included packages. Options: - - `include_text` (optional bool, default=`False`): Whether to dump the license text in the JSON. - If false, only the path will be included. - - `text_errors` (optional str, default=`None`): How to handle decoding errors when reading the - license text. Only relevant if include_text is True. Any str accepted by open()'s 'errors' - argument is valid. See https://docs.python.org/3/library/functions.html#open. + - `include_text` (optional bool, default=`False`): Whether to dump the license text in the + JSON. If false, only the path will be included. + - `text_errors` (optional str, default=`None`): How to handle decoding errors when reading + the license text. Only relevant if include_text is True. Any str accepted by open()'s + 'errors' argument is valid. See https://docs.python.org/3/library/functions.html#open. """ - uninstall_with_conda_exe: bool = bool() + uninstall_with_conda_exe: bool | None = None """ Use the standalone binary to perform the uninstallation. Requires conda-standalone 24.11.0 or newer. """ - - _EXTRA_ENVS_SCHEMA = { "specs": (list, tuple), "environment": (str,), @@ -685,15 +721,15 @@ class ConstructorConfiguration(BaseModel): def generate_key_info_list(): key_info_list = [] for key_info in KEYS: - type_names = {str: 'string', list: 'list', dict: 'dictionary', bool: 'boolean'} + type_names = {str: "string", list: "list", dict: "dictionary", bool: "boolean"} key_types = key_info[2] if not isinstance(key_types, (tuple, list)): - key_types = key_types, - plural = 's' if len(key_types) > 1 else '' - key_types = ', '.join(type_names.get(k, '') for k in key_types) - required = 'yes' if key_info[1] else 'no' + key_types = (key_types,) + plural = "s" if len(key_types) > 1 else "" + key_types = ", ".join(type_names.get(k, "") for k in key_types) + required = "yes" if key_info[1] else "no" - if key_info[3] == 'XXX': + if key_info[3] == "XXX": logger.info("Not including %s because the skip sentinel ('XXX') is set", key_info[0]) continue @@ -704,28 +740,28 @@ def generate_key_info_list(): def ns_platform(platform): p = platform return dict( - linux=p.startswith('linux-'), - linux32=bool(p == 'linux-32'), - linux64=bool(p == 'linux-64'), - armv7l=bool(p == 'linux-armv7l'), - aarch64=bool(p == 'linux-aarch64'), - ppc64le=bool(p == 'linux-ppc64le'), - arm64=bool(p == 'osx-arm64'), - s390x=bool(p == 'linux-s390x'), - x86=p.endswith(('-32', '-64')), - x86_64=p.endswith('-64'), - osx=p.startswith('osx-'), - unix=p.startswith(('linux-', 'osx-')), - win=p.startswith('win-'), - win32=bool(p == 'win-32'), - win64=bool(p == 'win-64'), + linux=p.startswith("linux-"), + linux32=bool(p == "linux-32"), + linux64=bool(p == "linux-64"), + armv7l=bool(p == "linux-armv7l"), + aarch64=bool(p == "linux-aarch64"), + ppc64le=bool(p == "linux-ppc64le"), + arm64=bool(p == "osx-arm64"), + s390x=bool(p == "linux-s390x"), + x86=p.endswith(("-32", "-64")), + x86_64=p.endswith("-64"), + osx=p.startswith("osx-"), + unix=p.startswith(("linux-", "osx-")), + win=p.startswith("win-"), + win32=bool(p == "win-32"), + win64=bool(p == "win-64"), ) # This regex is taken from https://github.com/conda/conda_build/metadata.py # The following function "select_lines" is also a slightly modified version of # the function of the same name from conda_build/metadata.py -sel_pat = re.compile(r'(.+?)\s*(#.*)?\[([^\[\]]+)\](?(2)[^\(\)]*)$') +sel_pat = re.compile(r"(.+?)\s*(#.*)?\[([^\[\]]+)\](?(2)[^\(\)]*)$") def select_lines(data, namespace): @@ -738,7 +774,7 @@ def select_lines(data, namespace): if line and line[-1] in ("'", '"'): trailing_quote = line[-1] - if line.lstrip().startswith('#'): + if line.lstrip().startswith("#"): # Don't bother with comment only lines continue m = sel_pat.match(line) @@ -748,16 +784,19 @@ def select_lines(data, namespace): if eval(cond, namespace, {}): lines.append(m.group(1) + trailing_quote) except Exception as e: - sys.exit('''\ + sys.exit( + """\ Error: Invalid selector in meta.yaml line %d: offending line: %s exception: %s -''' % (i + 1, line, str(e))) +""" + % (i + 1, line, str(e)) + ) else: lines.append(line) - return '\n'.join(lines) + '\n' + return "\n".join(lines) + "\n" # adapted from conda-build @@ -766,7 +805,7 @@ def yamlize(data, directory, content_filter): try: return yaml.load(data) except YAMLError as e: - if ('{{' not in data) and ('{%' not in data): + if ("{{" not in data) and ("{%" not in data): raise UnableToParse(original=e) try: from constructor.jinja import render_jinja_for_input_file @@ -790,7 +829,7 @@ def parse(path, platform): sys.exit(e.error_msg()) try: - res['version'] = str(res['version']) + res["version"] = str(res["version"]) except KeyError: pass @@ -809,7 +848,7 @@ def verify(info): types_key[key] = types if required: required_keys.add(key) - if 'Obsolete' in descr: + if "Obsolete" in descr: obsolete_keys.add(key) for key in info: @@ -817,26 +856,25 @@ def verify(info): sys.exit("Error: unknown key '%s' in construct.yaml" % key) elt = info[key] if key in obsolete_keys: - logger.warning("key '%s' is obsolete." - " Its value '%s' is being ignored.", key, elt) + logger.warning("key '%s' is obsolete." " Its value '%s' is being ignored.", key, elt) types = types_key[key] if not isinstance(elt, types): - sys.exit("Error: key '%s' points to %s,\n" - " expected %s" % (key, type(elt), types)) + sys.exit( + "Error: key '%s' points to %s,\n" " expected %s" % (key, type(elt), types) + ) for key in required_keys: if key not in info: - sys.exit("Error: Required key '%s' not found in construct.yaml" % - key) + sys.exit("Error: Required key '%s' not found in construct.yaml" % key) - pat = re.compile(r'[\w][\w\-\.]*$') - for key in 'name', 'version': + pat = re.compile(r"[\w][\w\-\.]*$") + for key in "name", "version": value = info[key] - if not pat.match(value) or value.endswith(('.', '-')): + if not pat.match(value) or value.endswith((".", "-")): sys.exit("Error: invalid %s '%s'" % (key, value)) for env_name, env_data in info.get("extra_envs", {}).items(): - disallowed = ('/', ' ', ':', '#') + disallowed = ("/", " ", ":", "#") if any(character in env_name for character in disallowed): sys.exit( f"Environment names (keys in 'extra_envs') cannot contain any of {disallowed}. " @@ -848,8 +886,10 @@ def verify(info): types = _EXTRA_ENVS_SCHEMA[key] if not isinstance(value, types): types_str = " or ".join([type_.__name__ for type_ in types]) - sys.exit(f"Value for 'extra_envs.{env_name}.{key}' " - f"must be an instance of {types_str}") + sys.exit( + f"Value for 'extra_envs.{env_name}.{key}' " + f"must be an instance of {types_str}" + ) if signtool := info.get("windows_signing_tool"): if signtool.lower().replace(".exe", "") not in WIN_SIGNTOOLS: sys.exit( @@ -862,12 +902,12 @@ def verify(info): def dump_schema(): - model = ConstructorConfiguration(name="...", version="...") + model = ConstructorConfiguration(name="doesnotmatter", version="0.0.0") obj = model.model_json_schema() obj["$schema"] = "https://json-schema.org/draft/2020-12/schema" (HERE / "data" / "constructor.schema.json").write_text(json.dumps(obj, indent=2)) print(json.dumps(obj, indent=2)) -if __name__ == '__main__': +if __name__ == "__main__": dump_schema() diff --git a/constructor/data/constructor.schema.json b/constructor/data/constructor.schema.json index f6c559ee8..4ecafe5c5 100644 --- a/constructor/data/constructor.schema.json +++ b/constructor/data/constructor.schema.json @@ -1,140 +1,395 @@ { + "$defs": { + "ChannelRemap": { + "additionalProperties": false, + "properties": { + "src": { + "description": "Source channel, before being mapped", + "minLength": 1, + "title": "Src", + "type": "string" + }, + "dest": { + "description": "Target channel, after being mapped", + "minLength": 1, + "title": "Dest", + "type": "string" + } + }, + "required": [ + "src", + "dest" + ], + "title": "ChannelRemap", + "type": "object" + }, + "ExtraEnv": { + "additionalProperties": false, + "properties": { + "specs": { + "default": [], + "description": "Which packages to install in this environment", + "items": { + "minLength": 1, + "type": "string" + }, + "title": "Specs", + "type": "array" + }, + "environment": { + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Same as global option, for this environment", + "title": "Environment" + }, + "environment_file": { + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Same as global option, for this environment", + "title": "Environment File" + }, + "channels": { + "anyOf": [ + { + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Solve specs using these channels; if not provided, the global\nvalue is used. To override inheritance, set it to an empty list.", + "title": "Channels" + }, + "channels_remap": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ChannelRemap" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Same as global option, for this env; if not provided, the global \nvalue is used. To override inheritance, set it to an empty list.", + "title": "Channels Remap" + }, + "user_requested_specs": { + "anyOf": [ + { + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Same as the global option, but for this env.\nIf not provided, global value is _not_ used", + "title": "User Requested Specs" + }, + "menu_packages": { + "anyOf": [ + { + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Same as the global option, but for this env.\nIf not provided, global value is _not_ used", + "title": "Menu Packages" + } + }, + "title": "ExtraEnv", + "type": "object" + } + }, "additionalProperties": false, + "description": "Schema for constructor.yaml input files.", "properties": { "name": { "description": "Name of the installer. Names may be composed of letters, numbers,\nunderscores, dashes, and periods, but may not begin or end with a\ndash or period.", + "minLength": 1, + "pattern": "^[A-z0-9_][A-z0-9_\\-\\.]*$", "title": "Name", "type": "string" }, "version": { "description": "Version of the installer. Versions may be composed of letters, numbers,\nunderscores, dashes, and periods, but may not begin or end with a\ndash or period.", + "minLength": 1, + "pattern": "^[A-z0-9_][A-z0-9_\\-\\.]*$", "title": "Version", "type": "string" }, "channels": { "default": [], "description": "The conda channels from which packages are retrieved. At least one channel must\nbe supplied, either in `channels` or `channels_remap`.\n\nSee notes in `channels_remap` for details about local channels.", - "items": {}, + "items": { + "minLength": 1, + "type": "string" + }, "title": "Channels", "type": "array" }, "channels_remap": { "default": [], "description": "A list of `src/dest` channel URL pairs. When building the installer, conda will\nuse the `src` channels to solve and fetch the packages. However, the resulting\ninstallation will see the packages as coming from the `dest` equivalent.\nThis allows an installer to be built against a different set of channels than\nwill be present when the installer is actually used. Example use:\n\n```yaml\nchannels_remap:\n - src: file:///tmp/a3/conda-bld # [unix]\n dest: https://repo.anaconda.com/pkgs/main # [unix]\n - src: file:///D:/tmp/a3/conda-bld # [win]\n dest: https://repo.anaconda.com/pkgs/main # [unix]\n```\n\nAt least one channel must be supplied, either in `channels` or `channels_remap`.", - "items": {}, + "items": { + "$ref": "#/$defs/ChannelRemap" + }, "title": "Channels Remap", "type": "array" }, "specs": { + "anyOf": [ + { + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + { + "minLength": 1, + "type": "string" + } + ], "default": [], "description": "A list of package specifications; e.g. `python 2.7*`, `pyzmq` or `numpy >=1.8`.\nThe specifications are identical in form and purpose to those that would be\nincluded in a `conda create --file` command. Packages may also be specified\nby an exact URL; e.g.,\n`https://repo.anaconda.com/pkgs/main/osx-64/openssl-1.0.2o-h26aff7b_0.tar.bz2`.\nThis key can also take a `str` pointing to a requirements file with the same syntax.\n\nNote: `constructor` relies on `conda`'s Python API to solve the passed\nspecifications. You can still set the `CONDA_SOLVER` environment variable\nto override system-wide settings for `constructor`. If you are using\n`constructor` from a non-`base` environment, make sure the\nconfigured solver plugin is also installed in that environment.", - "items": {}, - "title": "Specs", - "type": "array" + "title": "Specs" }, "user_requested_specs": { "default": [], "description": "A list of package specifications to be recorded as \"user-requested\" for the\ninitial environment in conda's history file. This information is used by newer\nversions of conda to better filter its package choices on subsequent installs;\nfor example, if `python=3.6` is included, then conda will always seek versions\nof packages compatible with Python 3.6. If this is option is not provided, it\nwill be set equal to the value of `specs`.", - "items": {}, + "items": { + "minLength": 1, + "type": "string" + }, "title": "User Requested Specs", "type": "array" }, "virtual_specs": { "default": [], "description": "A list of virtual packages that must be satisfied at install time. Virtual\npackages must start with `__`. For example, `__osx>=11` or `__glibc>=2.24`.\nThese specs are dry-run solved offline by the bundled `--conda-exe` binary.\nIn SH installers, `__glibc>=x.y` and `__osx>=x.y` specs can be checked with\nBash only. The detected version can be overriden with environment variables\n`CONDA_OVERRIDE_GLIBC` and `CONDA_OVERRIDE_OSX`, respectively. In PKG\ninstallers, `__osx` specs can be checked natively without the solver being\ninvolved as long as only `>=`, `<` or `,` are used.", - "items": {}, + "items": { + "minLength": 1, + "type": "string" + }, "title": "Virtual Specs", "type": "array" }, "exclude": { "default": [], "description": "A list of package names to be excluded after the `specs` have been resolved.\nFor example, you can say that `readline` should be excluded, even though it\nis contained as a result of resolving the specs for `python 2.7`.", - "items": {}, + "items": { + "minLength": 1, + "type": "string" + }, "title": "Exclude", "type": "array" }, "menu_packages": { - "default": [], + "anyOf": [ + { + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, "description": "A list of packages with menu items to be installed. The packages must have\nnecessary metadata in `Menu/.json`). By default, all menu items\nfound in the installation will be created; supplying this list allows a\nsubset to be selected instead. If an empty list is supplied, no shortcuts will\nbe created.\n\nIf all environments (`extra_envs` included) set `menu_packages` to an empty list,\nno UI options about shortcuts will be offered to the user.\n\nNote: This option is not fully implemented when `micromamba` is used as\nthe `--conda-exe` binary. The only accepted value is an empty list (`[]`).", - "items": {}, - "title": "Menu Packages", - "type": "array" + "title": "Menu Packages" }, "ignore_duplicate_files": { - "default": false, + "default": true, "description": "By default, constructor will warn you when adding packages with duplicate\nfiles in them. Setting this option to false will raise an error instead.", "title": "Ignore Duplicate Files", "type": "boolean" }, "install_in_dependency_order": { - "default": [], + "anyOf": [ + { + "deprecated": true, + "type": "boolean" + }, + { + "deprecated": true, + "type": "string" + } + ], + "default": true, "description": "_Obsolete_. The current version of constructor relies on the standalone\nconda executable for its installation behavior. This option is now\nignored with a warning.", - "items": {}, - "title": "Install In Dependency Order", - "type": "array" + "title": "Install In Dependency Order" }, "environment": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Name of the environment to construct from. If this option is present, the\n`specs` argument will be ignored. Using this option allows the user to\ncurate the enviromment interactively using standard `conda` commands, and\nrun constructor with full confidence that the exact environment will be\nreproduced.", - "title": "Environment", - "type": "string" + "title": "Environment" }, "environment_file": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Path to an environment file (TXT or YAML) to construct from. If this option\nis present, the `specs` argument will be ignored. Instead, constructor will\ncall conda to create a temporary environment, constructor will build and\ninstaller from that, and the temporary environment will be removed.\nThis ensures that constructor is using the precise local conda configuration\nto discover and install the packages. The created environment MUST include\n`python`.\n\nRead notes about the solver in the `specs` field.", - "title": "Environment File", - "type": "string" + "title": "Environment File" }, "transmute_file_type": { - "default": "", + "anyOf": [ + { + "const": ".conda", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "File type extension for the files to be transmuted into. Currently supports\nonly '.conda'. See conda-package-handling for supported extension names.\nIf left empty, no transmuting is done.", - "title": "Transmute File Type", - "type": "string" + "title": "Transmute File Type" }, "conda_default_channels": { "default": [], "description": "If this value is provided as well as `write_condarc`, then the channels\nin this list will be included as the value of the `default_channels:`\noption in the environment's `.condarc` file. This will have an impact\nonly if `conda` is included in the environmnent.", - "items": {}, + "items": { + "minLength": 1, + "type": "string" + }, "title": "Conda Default Channels", "type": "array" }, "conda_channel_alias": { - "default": "", - "description": "The channel alias that would be assumed for the created installer\n(only useful if it includes conda).", - "title": "Conda Channel Alias", - "type": "string" + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "The channel alias that would be assumed for the created installer\n(only useful if it includes `conda`).", + "title": "Conda Channel Alias" }, "extra_envs": { - "default": [], - "description": "Create more environments in addition to the default `base` provided by `specs`,\n`environment` or `environment_file`. This should be a map of `str` (environment\nname) to a dictionary of options:\n- `specs` (list of str): which packages to install in that environment\n- `environment` (str): same as global option, for this env\n- `environment_file` (str): same as global option, for this env\n- `channels` (list of str): using these channels; if not provided, the global\n value is used. To override inheritance, set it to an empty list.\n- `channels_remap` (list of str): same as global option, for this env;\n if not provided, the global value is used. To override inheritance, set it to\n an empty list.\n- `user_requested_specs` (list of str): same as the global option, but for this env;\n if not provided, global value is _not_ used\n- `menu_packages` (list of str): same as the global option, for this env;\n if not provided, the global value is _not_ used.\n\nNotes:\n- `ignore_duplicate_files` will always be considered `True` if `extra_envs` is in use.\n- `conda` needs to be present in the `base` environment (via `specs`)\n- If a global `exclude` option is used, it will have an effect on the environments created\n by `extra_envs` too. For example, if the global environment excludes `tk`, none of the\n extra environments will have it either. Unlike the global option, an error will not be\n thrown if the excluded package is not found in the packages required by the extra environment.\n To override the global `exclude` value, use an empty list `[]`.", - "items": {}, + "additionalProperties": { + "$ref": "#/$defs/ExtraEnv" + }, + "default": {}, + "description": "Create more environments in addition to the default `base` provided by `specs`,\n`environment` or `environment_file`.\n\nNotes:\n- `ignore_duplicate_files` will always be considered `True` if `extra_envs` is in use.\n- `conda` needs to be present in the `base` environment (via `specs`)\n- If a global `exclude` option is used, it will have an effect on the environments created\n by `extra_envs` too. For example, if the global environment excludes `tk`, none of the\n extra environments will have it either. Unlike the global option, an error will not be\n thrown if the excluded package is not found in the packages required by the extra environment.\n To override the global `exclude` value, use an empty list `[]`.", + "propertyNames": { + "minLength": 1 + }, "title": "Extra Envs", - "type": "array" + "type": "object" }, "register_envs": { - "default": false, - "description": "Whether to register the environments created by the installer (both `base` and `extra_envs`)\nin `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. Defaults to `True`.", + "default": true, + "description": "Whether to register the environments created by the installer (both `base` and `extra_envs`)\nin `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9.", "title": "Register Envs", "type": "boolean" }, "installer_filename": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "The filename of the installer being created. If not supplied, a reasonable\ndefault will determined by the `name`, `version`, platform, and installer type.", - "title": "Installer Filename", - "type": "string" + "title": "Installer Filename" }, "installer_type": { - "default": [], + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, "description": "The type of the installer being created. Possible values are:\n- `sh`: shell-based installer for Linux or macOS;\n- `pkg`: macOS GUI installer built with Apple's `pkgbuild`\n- `exe`: Windows GUI installer built with NSIS\n\nThe default type is `sh` on Linux and macOS, and `exe` on Windows. A special\nvalue of `all` builds _both_ `sh` and `pkg` installers on macOS, as well\nas `sh` on Linux and `exe` on Windows.\n\nNotes for silent mode `/S` on Windows EXEs:\n- NSIS Silent mode will not print any error message, but will silently abort the installation.\n If needed, [NSIS log-builds][nsis-log] can be used to print to `%PREFIX%\\install.log`, which\n can be searched for `::error::` strings. Pre- and post- install scripts will only throw an error\n if the environment variable `NSIS_SCRIPTS_RAISE_ERRORS` is set.\n- The `/D` flag can be used to specify the target location. It must be the last argument in\n the command and should NEVER be quoted, even if it contains spaces. For example:\n `CMD.EXE /C START /WAIT myproject.exe /S /D=C:\\path with spaces\\my project`.\n\n[nsis-log]: https://nsis.sourceforge.io/Special_Builds", - "items": {}, - "title": "Installer Type", - "type": "array" + "title": "Installer Type" }, "license_file": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Path to the license file being displayed by the installer during the install\nprocess. It must be plain text (.txt) for shell-based installers. On PKG,\n.txt, .rtf and .html are supported. On Windows, .txt and .rtf are supported.", - "title": "License File", - "type": "string" + "title": "License File" }, "keep_pkgs": { "default": false, @@ -144,150 +399,320 @@ }, "batch_mode": { "default": false, - "description": "Only affects ``.sh`` installers. If ``False`` (default), the installer launches\nan interactive wizard guiding the user through the available options. If\n``True``, the installer runs automatically as if ``-b`` was passed.", + "description": "Only affects `.sh` installers. If `False` (default), the installer launches\nan interactive wizard guiding the user through the available options. If\n`True`, the installer runs automatically as if `-b` was passed.", "title": "Batch Mode", "type": "boolean" }, "signing_identity_name": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "By default, the MacOS pkg installer isn't signed. If an identity name is specified\nusing this option, it will be used to sign the installer with Apple's `productsign`.\nNote that you will need to have a certificate (usually an \"Installer certificate\")\nand the corresponding private key, together called an 'identity', in one of your\naccessible keychains. Common values for this option follow this format\n`Developer ID Installer: Name of the owner (XXXXXX)`.", - "title": "Signing Identity Name", - "type": "string" + "title": "Signing Identity Name" }, "notarization_identity_name": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "If the pkg installer is going to be signed with `signing_identity_name`, you\ncan also prepare the bundle for notarization. This will use Apple's `codesign`\nto sign `conda.exe`. For this, you need an \"Application certificate\" (different from the\n\"Installer certificate\" mentioned above). Common values for this option follow the format\n`Developer ID Application: Name of the owner (XXXXXX)`.", - "title": "Notarization Identity Name", - "type": "string" + "title": "Notarization Identity Name" }, "windows_signing_tool": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "The tool used to sign Windows installers. Must be one of: azuresigntool, signtool.\nSome tools require `signing_certificate` to be set.\nDefaults to `signtool` if `signing_certificate` is set.\nAdditional environment variables may need to be used to configure signing.\nSee the documentation for details:\nhttps://conda.github.io/constructor/howto/#signing-exe-installers", - "title": "Windows Signing Tool", - "type": "string" + "title": "Windows Signing Tool" }, "signing_certificate": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "On Windows only, set this key to the path of the certificate file to be used\nwith the `windows_signing_tool`.", - "title": "Signing Certificate", - "type": "string" + "title": "Signing Certificate" }, "attempt_hardlinks": { - "default": [], + "anyOf": [ + { + "deprecated": true, + "type": "boolean" + }, + { + "deprecated": true, + "type": "string" + } + ], + "default": true, "description": "_Obsolete_. The current version of constructor relies on the standalone\nconda executable for its installation behavior. This option is now\nignored with a warning.", - "items": {}, - "title": "Attempt Hardlinks", - "type": "array" + "title": "Attempt Hardlinks" }, "write_condarc": { "default": false, - "description": "By default, no `.condarc` file is written. If set, a `.condarc` file is written to\nthe base environment if there are any channels or conda_default_channels is set.", + "description": "By default, no `.condarc` file is written. If set, a `.condarc` file is written to\nthe base environment if there are any channels or `conda_default_channels` is set.", "title": "Write Condarc", "type": "boolean" }, "condarc": { - "default": [], + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, "description": "If set, a `.condarc` file is written to the base environment containing the contents\nof this value. The value can either be a string (likely a multi-line string) or\na dictionary, which will be converted to a YAML string for writing. _Note:_ if this\noption is used, then all other options related to the construction of a `.condarc`\nfile (`write_condarc`, `conda_default_channels`, etc.) are ignored.", - "items": {}, - "title": "Condarc", - "type": "array" + "title": "Condarc" }, "company": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Name of the company/entity who is responsible for the installer.", - "title": "Company", - "type": "string" + "title": "Company" }, "reverse_domain_identifier": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Unique identifier for this package, formatted with reverse domain notation. This is\nused internally in the PKG installers to handle future updates and others. If not\nprovided, it will default to `io.continuum`. (MacOS only)", - "title": "Reverse Domain Identifier", - "type": "string" + "title": "Reverse Domain Identifier" }, "uninstall_name": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Application name in the Windows \"Programs and Features\" control panel.\nDefaults to `${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})`.", - "title": "Uninstall Name", - "type": "string" + "title": "Uninstall Name" }, "script_env_variables": { - "default": [], + "additionalProperties": { + "type": "string" + }, + "default": {}, "description": "Dictionary of additional environment variables to be made available to\nthe pre_install and post_install scripts, in the form of VAR:VALUE\npairs. These environment variables are in addition to those in the\n`post_install` section above and take precedence in the case of name\ncollisions.\n\nOn Unix the variable values are automatically single quoted, allowing\nyou to supply strings with spaces, without needing to worry about\nescaping. As a consequence, string interpolation is disabled: if you\nneed string interpolation, you can apply it in the\npre_install/post_install script(s). If you need to include single quotes\nin your value, you can escape them by replacing each single quote with\n`'''`.\n\nOn Windows, single quotes and double quotes are not supported.\n\nNote that the # (hash) character cannot be used as it denotes yaml\ncomments for all platforms.", - "items": {}, + "propertyNames": { + "minLength": 1 + }, "title": "Script Env Variables", - "type": "array" + "type": "object" }, "pre_install": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Path to a pre-install script, run after the package cache has been set, but\nbefore the files are linked to their final locations. As a result, you should\nonly rely on tools known to be available on most systems (e.g. `bash`, `cmd`,\netc). See `post_install` for information about available environment variables.", - "title": "Pre Install", - "type": "string" + "title": "Pre Install" }, "pre_install_desc": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "A description of the purpose of the supplied `pre_install` script. If this\nstring is supplied and non-empty, then the Windows and macOS GUI installers\nwill display it along with checkbox to enable or disable the execution of the\nscript. If this string is not supplied, it is assumed that the script\nis compulsory and the option to disable it will not be offered.\n\nThis option has no effect on `SH` installers.", - "title": "Pre Install Desc", - "type": "string" + "title": "Pre Install Desc" }, "post_install": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Path to a post-install script. Some notes:\n\n- For Unix `.sh` installers, the shebang line is respected if present;\n otherwise, the script is run by the POSIX shell `sh`. Note that the use\n of a shebang can reduce the portability of the installer. The\n installation path is available as `${PREFIX}`. Installer metadata is\n available in the `${INSTALLER_NAME}`, `${INSTALLER_VER}`, `${INSTALLER_PLAT}`\n environment variables. `${INSTALLER_TYPE}` is set to `SH`.\n `${INSTALLER_UNATTENDED}` will be `\"1\"` in batch mode (`-b`), `\"0\"` otherwise.\n- For PKG installers, the shebang line is respected if present;\n otherwise, `bash` is used. The same variables mentioned for `sh`\n installers are available here. `${INSTALLER_TYPE}` is set to `PKG`.\n `${INSTALLER_UNATTENDED}` will be `\"1\"` for command line installs, `\"0\"` otherwise.\n- For Windows `.exe` installers, the script must be a `.bat` file.\n Installation path is available as `%PREFIX%`. Metadata about\n the installer can be found in the `%INSTALLER_NAME%`, `%INSTALLER_VER%`,\n `%INSTALLER_PLAT%` environment variables. `%INSTALLER_TYPE%` is set to `EXE`.\n `%INSTALLER_UNATTENDED%` will be `\"1\"` in silent mode (`/S`), `\"0\"` otherwise.\n\nIf necessary, you can activate the installed `base` environment like this:\n\n- Unix: `source \"$PREFIX/etc/profile.d/conda.sh\" && conda activate \"$PREFIX\"`\n- Windows: `call \"%PREFIX%\\Scripts\\activate.bat\"`", - "title": "Post Install", - "type": "string" + "title": "Post Install" }, "post_install_desc": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "A description of the purpose of the supplied `post_install` script. If this\nstring is supplied and non-empty, then the Windows and macOS GUI installers\nwill display it along with checkbox to enable or disable the execution of the\nscript. If this string is not supplied, it is assumed that the script\nis compulsory and the option to disable it will not be offered.\n\nThis option has no effect on `SH` installers.", - "title": "Post Install Desc", - "type": "string" + "title": "Post Install Desc" }, "pre_uninstall": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Path to a pre uninstall script. This is only supported for on Windows,\nand must be a `.bat` file. Installation path is available as `%PREFIX%`.\nMetadata about the installer can be found in the `%INSTALLER_NAME%`,\n`%INSTALLER_VER%`, `%INSTALLER_PLAT%` environment variables.\n`%INSTALLER_TYPE%` is set to `EXE`.", - "title": "Pre Uninstall", - "type": "string" + "title": "Pre Uninstall" }, "default_prefix": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Set default install prefix. On Linux, if not provided, the default prefix\nis `${HOME}/` (or, if `HOME` is not set, `/opt/`). On Windows,\nthis is used only for \"Just Me\" installation; for \"All Users\" installation,\nuse the `default_prefix_all_users` key. If not provided, the default prefix\nis `%USERPROFILE%\\`. Environment variables will be expanded at\ninstallation time.", - "title": "Default Prefix", - "type": "string" + "title": "Default Prefix" }, "default_prefix_domain_user": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Set default installation prefix for domain user. If not provided, the\ninstallation prefix for domain user will be `%LOCALAPPDATA%\\`.\nBy default, it is different from the `default_prefix` value to avoid installing\nthe distribution in the roaming profile. Environment variables will be expanded\nat installation time. Windows only.", - "title": "Default Prefix Domain User", - "type": "string" + "title": "Default Prefix Domain User" }, "default_prefix_all_users": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Set default installation prefix for All Users installation. If not provided,\nthe installation prefix for all users installation will be\n`%ALLUSERSPROFILE%\\`. Environment variables will be expanded at installation\ntime. Windows only.", - "title": "Default Prefix All Users", - "type": "string" + "title": "Default Prefix All Users" }, "default_location_pkg": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Default installation subdirectory in the chosen volume. In PKG installers,\ndefault installation locations are configured differently. The user can choose\nbetween a \"Just me\" installation (which would result in `~/`) or another\nvolume (which defaults to `/`). If you want a different default,\nyou can add a middle component with this option, let's call it `location`. It would\nresult in these default values: `~//` for \"Just me\",\n`//` for custom volumes. For example, setting this option\nto `/Library` in a \"Just me\" installation will give you `~/Library/`.\nInternally, this is passed to `pkgbuild --install-location`.\nmacOS only.", - "title": "Default Location Pkg", - "type": "string" + "title": "Default Location Pkg" }, "pkg_domains": { "default": {}, "description": "The domains the package can be installed into. For a detailed explanation, see:\nhttps://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html\nconstructor defaults to `enable_anywhere=true` and `enable_currentUserHome=true`.\n`enable_localSystem` should not be set to true unless `default_location_pkg` is set as well.\nmacOS only.", + "propertyNames": { + "minLength": 1 + }, "title": "Pkg Domains", "type": "object" }, "pkg_name": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Internal identifier for the installer. This is used in the build prefix and will\ndetermine part of the default location path. Combine with `default_location_pkg`\nfor more flexibility. If not provided, the value of `name` will be used. (MacOS only)", - "title": "Pkg Name", - "type": "string" + "title": "Pkg Name" }, "install_path_exists_error_text": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Error message that will be shown if the installation path already exists.\nYou cannot use double quotes or newlines. The placeholder `{CHOSEN_PATH}` is\navailable and set to the destination causing the error. Defaults to:\n\n> '{CHOSEN_PATH}' already exists. Please, relaunch the installer and\n> choose another location in the Destination Select step.\n\n(MacOS only)", - "title": "Install Path Exists Error Text", - "type": "string" + "title": "Install Path Exists Error Text" }, "progress_notifications": { "default": false, @@ -296,159 +721,350 @@ "type": "boolean" }, "welcome_image": { - "default": "", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Path to an image in any common image format (`.png`, `.jpg`, `.tif`, etc.)\nto be used as the welcome image for the Windows and PKG installers.\nThe image is re-sized to 164 x 314 pixels on Windows and 1227 x 600 on Macos.\nBy default, an image is automatically generated on Windows. On MacOS, Anaconda's\nlogo is shown if this key is not provided. If you don't want a background on\nPKG installers, set this key to `\"\"` (empty string).", - "title": "Welcome Image", - "type": "string" + "title": "Welcome Image" }, "header_image": { - "default": "", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Like `welcome_image` for Windows, re-sized to 150 x 57 pixels.", - "title": "Header Image", - "type": "string" + "title": "Header Image" }, "icon_image": { - "default": "", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "Like `welcome_image` for Windows, re-sized to 256 x 256 pixels.", - "title": "Icon Image", - "type": "string" + "title": "Icon Image" }, "default_image_color": { - "default": "", - "description": "The color of the default images (when not providing explicit image files)\nused on Windows. Possible values are `red`, `green`, `blue`, `yellow`.\nThe default is `blue`.", + "default": "blue", + "description": "The color of the default images (when not providing explicit image files)\nused on Windows. Possible values are `red`, `green`, `blue`, `yellow`.\nThe default is `blue`.", + "enum": [ + "red", + "green", + "blue", + "yellow" + ], "title": "Default Image Color", "type": "string" }, "welcome_image_text": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "If `welcome_image` is not provided, use this text when generating the image\n(Windows and PKG only). Defaults to `name` on Windows.", - "title": "Welcome Image Text", - "type": "string" + "title": "Welcome Image Text" }, "header_image_text": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "If `header_image` is not provided, use this text when generating the image\n(Windows only). Defaults to `name`.", - "title": "Header Image Text", - "type": "string" + "title": "Header Image Text" }, "initialize_conda": { - "default": false, + "default": true, "description": "Add an option to the installer so the user can choose whether to run `conda init`\nafter the install. See also `initialize_by_default`.", "title": "Initialize Conda", "type": "boolean" }, "initialize_by_default": { - "default": false, + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, "description": "Whether to add the installation to the PATH environment variable. The default\nis true for GUI installers (msi, pkg) and False for shell installers. The user\nis able to change the default during interactive installation. NOTE: For Windows,\n`AddToPath` is disabled when `InstallationType=AllUsers`.", - "title": "Initialize By Default", - "type": "boolean" + "title": "Initialize By Default" }, "register_python": { - "default": false, + "default": true, "description": "Whether to offer the user an option to register the installed Python instance as the\nsystem's default Python. (Windows only)", "title": "Register Python", "type": "boolean" }, "register_python_default": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], "default": false, "description": "Default choice for whether to register the installed Python instance as the\nsystem's default Python. The user is still able to change this during\ninteractive installation. (Windows only).", - "title": "Register Python Default", - "type": "boolean" + "title": "Register Python Default" }, "check_path_length": { - "default": false, + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, "description": "Check the length of the path where the distribution is installed to ensure nodejs\ncan be installed. Raise a message to request shorter path (less than 46 character)\nor enable long path on windows > 10 (require admin right). Default is True. (Windows only).\n\nRead notes about the particularities of Windows silent mode `/S` in the\n`installer_type` documentation.", - "title": "Check Path Length", - "type": "boolean" + "title": "Check Path Length" }, "check_path_spaces": { - "default": false, + "default": true, "description": "Check if the path where the distribution is installed contains spaces. Default is True.\nTo allow installations with spaces, change to False. Note that:\n\n- A recent conda-standalone (>=22.11.1) or equivalent is needed for full support.\n- `conda` cannot be present in the `base` environment\n\nRead notes about the particularities of Windows silent mode `/S` in the\n`installer_type` documentation.", "title": "Check Path Spaces", "type": "boolean" }, "nsis_template": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "If `nsis_template` is not provided, constructor uses its default\nNSIS template. For more complete customization for the installation experience,\nprovide an NSIS template file. (Windows only).", - "title": "Nsis Template", - "type": "string" + "title": "Nsis Template" }, "welcome_file": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "If `installer_type` is `pkg` on MacOS, this message will be\nshown before the license information, right after the introduction.\nFile can be plain text (.txt), rich text (.rtf) or HTML (.html). If\nboth `welcome_file` and `welcome_text` are provided, `welcome_file` takes precedence.\n(MacOS only).\n\nIf the installer is for windows and welcome file type is nsi,\nit will use the nsi script to add in extra pages before the installer\nbegins the installation process.", - "title": "Welcome File", - "type": "string" + "title": "Welcome File" }, "welcome_text": { - "default": "", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "If `installer_type` is `pkg` on MacOS, this message will be\nshown before the license information, right after the introduction.\nIf this key is missing, it defaults to a message about Anaconda Cloud.\nYou can disable it altogether so it defaults to the system message\nif you set this key to `\"\"` (empty string).\n(MacOS only).", - "title": "Welcome Text", - "type": "string" + "title": "Welcome Text" }, "readme_file": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "If `installer_type` is `pkg` on MacOS, this message will be\nshown before the license information, right after the welcome screen.\nFile can be plain text (.txt), rich text (.rtf) or HTML (.html). If\nboth `readme_file` and `readme_text` are provided, `readme_file` takes precedence.\n(MacOS only).", - "title": "Readme File", - "type": "string" + "title": "Readme File" }, "readme_text": { - "default": "", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "If `installer_type` is `pkg` on MacOS, this message will be\nshown before the license information, right after the welcome screen.\nIf this key is missing, it defaults to a message about Anaconda Cloud.\nYou can disable it altogether if you set this key to `\"\"` (empty string).\n(MacOS only).", - "title": "Readme Text", - "type": "string" + "title": "Readme Text" }, "post_install_pages": { - "default": [], + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, "description": "Adds extra pages to the installers to be shown after installation.\n\nFor PKG installers, these can be compiled `installer` plug-ins or\ndirectories containing an Xcode project. In the latter case,\nconstructor will try and compile the project file using `xcodebuild`.\n\nFor Windows, the extra pages must be `.nsi` files.\nThey will be inserted as-is before the conclusion page.", - "items": {}, - "title": "Post Install Pages", - "type": "array" + "title": "Post Install Pages" }, "conclusion_file": { - "default": "", + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "If `installer_type` is `pkg` on MacOS, this message will be\nshown at the end of the installer upon success. File can be\nplain text (.txt), rich text (.rtf) or HTML (.html). If both\n`conclusion_file` and `conclusion_text` are provided,\n`conclusion_file` takes precedence. (MacOS only).\n\nIf the installer is for Windows, the file type must be nsi.", - "title": "Conclusion File", - "type": "string" + "title": "Conclusion File" }, "conclusion_text": { - "default": "", + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, "description": "A message that will be shown at the end of the installer upon success.\nThe behaviour is slightly different across installer types:\n- PKG: If this key is missing, it defaults to a message about Anaconda Cloud.\n You can disable it altogether so it defaults to the system message if you set this\n key to `\"\"` (empty string).\n- EXE: The first line will be used as a title. The following lines will be used as text.\n(macOS PKG and Windows only).", - "title": "Conclusion Text", - "type": "string" + "title": "Conclusion Text" }, "extra_files": { + "anyOf": [ + { + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + { + "items": { + "additionalProperties": { + "minLength": 1, + "type": "string" + }, + "propertyNames": { + "minLength": 1 + }, + "type": "object" + }, + "type": "array" + } + ], "default": [], "description": "Extra, non-packaged files that should be added to the installer. If provided as relative\npaths, they will be considered relative to the directory where `construct.yaml` is.\nThis setting can be passed as a list of:\n- `str`: each found file will be copied to the root prefix\n- `Mapping[str, str]`: map of path in disk to path in prefix.", - "items": {}, - "title": "Extra Files", - "type": "array" + "title": "Extra Files" }, "temp_extra_files": { + "anyOf": [ + { + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + { + "items": { + "additionalProperties": { + "minLength": 1, + "type": "string" + }, + "propertyNames": { + "minLength": 1 + }, + "type": "object" + }, + "type": "array" + } + ], "default": [], "description": "Temporary files that could be referenced in the installation process (i.e. customized\n`welcome_file` and `conclusion_file` (see above)) . Should be a list of\nfile paths, relative to the directory where `construct.yaml` is. In Windows, these\nfiles will be copied into a temporary folder, the NSIS `$PLUGINSDIR`, during\ninstall process (Windows only).\n\nSupports the same values as `extra_files`.", - "items": {}, - "title": "Temp Extra Files", - "type": "array" + "title": "Temp Extra Files" }, "build_outputs": { "default": [], "description": "Additional artifacts to be produced after building the installer.\nIt expects either a list of strings or single-key dictionaries:\nAllowed keys are:\n- `hash`: The hash of the installer files.\n - `algorithm` (str or list): The hash algorithm. Must be among `hashlib`'s available algorithms:\n https://docs.python.org/3/library/hashlib.html#hashlib.algorithms_available\n- `info.json`: The internal `info` object, serialized to JSON. Takes no options.\n- `pkgs_list`: The list of packages contained in a given environment. Options:\n - `env` (optional, default=`base`): Name of an environment in `extra_envs` to export.\n- `lockfile`: An `@EXPLICIT` lockfile for a given environment. Options:\n - `env` (optional, default=`base`): Name of an environment in `extra_envs` to export.\n- `licenses`: Generate a JSON file with the licensing details of all included packages. Options:\n - `include_text` (optional bool, default=`False`): Whether to dump the license text in the JSON.\n If false, only the path will be included.\n - `text_errors` (optional str, default=`None`): How to handle decoding errors when reading the\n license text. Only relevant if include_text is True. Any str accepted by open()'s 'errors'\n argument is valid. See https://docs.python.org/3/library/functions.html#open.", - "items": {}, + "items": { + "anyOf": [ + { + "minLength": 1, + "type": "string" + }, + { + "propertyNames": { + "minLength": 1 + }, + "type": "object" + } + ] + }, "title": "Build Outputs", "type": "array" }, "uninstall_with_conda_exe": { - "default": false, + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, "description": "Use the standalone binary to perform the uninstallation.\nRequires conda-standalone 24.11.0 or newer.", - "title": "Uninstall With Conda Exe", - "type": "boolean" + "title": "Uninstall With Conda Exe" } }, "required": [ "name", "version" ], - "title": "ConstructorModel", + "title": "ConstructorConfiguration", "type": "object", "$schema": "https://json-schema.org/draft/2020-12/schema" } From 4d870ec8a98e05050350d1554eae63a714fe22dd Mon Sep 17 00:00:00 2001 From: jaimergp Date: Wed, 5 Mar 2025 19:27:06 +0100 Subject: [PATCH 005/138] Generate documentation from Pydantic model --- CONSTRUCT.md | 196 +++++----------------------------- constructor/construct.py | 31 +----- constructor/main.py | 49 +-------- docs/source/construct-yaml.md | 196 +++++----------------------------- scripts/make_docs.py | 11 +- 5 files changed, 61 insertions(+), 422 deletions(-) diff --git a/CONSTRUCT.md b/CONSTRUCT.md index a130dbabb..a0e45929b 100644 --- a/CONSTRUCT.md +++ b/CONSTRUCT.md @@ -34,19 +34,20 @@ are not available here. > Note: This content is also available in the CLI as `constructor --help-construct` ## Available keys -### `name` -_required:_ yes
-_type:_ string
+> This is only a name and description render of the `constructor` JSON Schema. +> For more details, consider using an online viewer like [json-schema.app](https://json-schema.app/view/%23?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjaimergp%2Fconstructor%2Frefs%2Fheads%2Fpydantic-schema%2Fconstructor%2Fdata%2Fconstructor.schema.json) + + +### `name` +_required_ Name of the installer. Names may be composed of letters, numbers, underscores, dashes, and periods, but may not begin or end with a dash or period. ### `version` - -_required:_ yes
-_type:_ string
+_required_ Version of the installer. Versions may be composed of letters, numbers, underscores, dashes, and periods, but may not begin or end with a @@ -54,8 +55,6 @@ dash or period. ### `channels` -_required:_ no
-_type:_ list
The conda channels from which packages are retrieved. At least one channel must be supplied, either in `channels` or `channels_remap`. @@ -64,8 +63,6 @@ See notes in `channels_remap` for details about local channels. ### `channels_remap` -_required:_ no
-_type:_ list
A list of `src/dest` channel URL pairs. When building the installer, conda will use the `src` channels to solve and fetch the packages. However, the resulting @@ -85,8 +82,6 @@ At least one channel must be supplied, either in `channels` or `channels_remap`. ### `specs` -_required:_ no
-_types:_ list, string
A list of package specifications; e.g. `python 2.7*`, `pyzmq` or `numpy >=1.8`. The specifications are identical in form and purpose to those that would be @@ -103,8 +98,6 @@ configured solver plugin is also installed in that environment. ### `user_requested_specs` -_required:_ no
-_types:_ list, string
A list of package specifications to be recorded as "user-requested" for the initial environment in conda's history file. This information is used by newer @@ -115,8 +108,6 @@ will be set equal to the value of `specs`. ### `virtual_specs` -_required:_ no
-_type:_ list
A list of virtual packages that must be satisfied at install time. Virtual packages must start with `__`. For example, `__osx>=11` or `__glibc>=2.24`. @@ -129,8 +120,6 @@ involved as long as only `>=`, `<` or `,` are used. ### `exclude` -_required:_ no
-_type:_ list
A list of package names to be excluded after the `specs` have been resolved. For example, you can say that `readline` should be excluded, even though it @@ -138,8 +127,6 @@ is contained as a result of resolving the specs for `python 2.7`. ### `menu_packages` -_required:_ no
-_type:_ list
A list of packages with menu items to be installed. The packages must have necessary metadata in `Menu/.json`). By default, all menu items @@ -155,16 +142,12 @@ the `--conda-exe` binary. The only accepted value is an empty list (`[]`). ### `ignore_duplicate_files` -_required:_ no
-_type:_ boolean
By default, constructor will warn you when adding packages with duplicate files in them. Setting this option to false will raise an error instead. ### `install_in_dependency_order` -_required:_ no
-_types:_ boolean, string
_Obsolete_. The current version of constructor relies on the standalone conda executable for its installation behavior. This option is now @@ -172,8 +155,6 @@ ignored with a warning. ### `environment` -_required:_ no
-_type:_ string
Name of the environment to construct from. If this option is present, the `specs` argument will be ignored. Using this option allows the user to @@ -183,8 +164,6 @@ reproduced. ### `environment_file` -_required:_ no
-_type:_ string
Path to an environment file (TXT or YAML) to construct from. If this option is present, the `specs` argument will be ignored. Instead, constructor will @@ -198,8 +177,6 @@ Read notes about the solver in the `specs` field. ### `transmute_file_type` -_required:_ no
-_type:_ string
File type extension for the files to be transmuted into. Currently supports only '.conda'. See conda-package-handling for supported extension names. @@ -207,8 +184,6 @@ If left empty, no transmuting is done. ### `conda_default_channels` -_required:_ no
-_type:_ list
If this value is provided as well as `write_condarc`, then the channels in this list will be included as the value of the `default_channels:` @@ -217,32 +192,15 @@ only if `conda` is included in the environmnent. ### `conda_channel_alias` -_required:_ no
-_type:_ string
The channel alias that would be assumed for the created installer -(only useful if it includes conda). +(only useful if it includes `conda`). ### `extra_envs` -_required:_ no
-_type:_ dictionary
Create more environments in addition to the default `base` provided by `specs`, -`environment` or `environment_file`. This should be a map of `str` (environment -name) to a dictionary of options: -- `specs` (list of str): which packages to install in that environment -- `environment` (str): same as global option, for this env -- `environment_file` (str): same as global option, for this env -- `channels` (list of str): using these channels; if not provided, the global - value is used. To override inheritance, set it to an empty list. -- `channels_remap` (list of str): same as global option, for this env; - if not provided, the global value is used. To override inheritance, set it to - an empty list. -- `user_requested_specs` (list of str): same as the global option, but for this env; - if not provided, global value is _not_ used -- `menu_packages` (list of str): same as the global option, for this env; - if not provided, the global value is _not_ used. +`environment` or `environment_file`. Notes: - `ignore_duplicate_files` will always be considered `True` if `extra_envs` is in use. @@ -255,24 +213,18 @@ Notes: ### `register_envs` -_required:_ no
-_type:_ boolean
Whether to register the environments created by the installer (both `base` and `extra_envs`) -in `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. Defaults to `True`. +in `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. ### `installer_filename` -_required:_ no
-_type:_ string
The filename of the installer being created. If not supplied, a reasonable default will determined by the `name`, `version`, platform, and installer type. ### `installer_type` -_required:_ no
-_types:_ string, list
The type of the installer being created. Possible values are: - `sh`: shell-based installer for Linux or macOS; @@ -286,8 +238,8 @@ as `sh` on Linux and `exe` on Windows. Notes for silent mode `/S` on Windows EXEs: - NSIS Silent mode will not print any error message, but will silently abort the installation. If needed, [NSIS log-builds][nsis-log] can be used to print to `%PREFIX%\install.log`, which - can be searched for `::error::` strings. Pre- and post- install scripts will only throw an error - if the environment variable `NSIS_SCRIPTS_RAISE_ERRORS` is set. + can be searched for `::error::` strings. Pre- and post- install scripts will only throw + an error if the environment variable `NSIS_SCRIPTS_RAISE_ERRORS` is set. - The `/D` flag can be used to specify the target location. It must be the last argument in the command and should NEVER be quoted, even if it contains spaces. For example: `CMD.EXE /C START /WAIT myproject.exe /S /D=C:\path with spaces\my project`. @@ -296,8 +248,6 @@ Notes for silent mode `/S` on Windows EXEs: ### `license_file` -_required:_ no
-_type:_ string
Path to the license file being displayed by the installer during the install process. It must be plain text (.txt) for shell-based installers. On PKG, @@ -305,8 +255,6 @@ process. It must be plain text (.txt) for shell-based installers. On PKG, ### `keep_pkgs` -_required:_ no
-_type:_ boolean
If `False` (default), the package cache in the `pkgs` subdirectory is removed when the installation process is complete. If `True`, this subdirectory and @@ -316,17 +264,13 @@ to preserve the package cache. ### `batch_mode` -_required:_ no
-_type:_ boolean
-Only affects ``.sh`` installers. If ``False`` (default), the installer launches +Only affects `.sh` installers. If `False` (default), the installer launches an interactive wizard guiding the user through the available options. If -``True``, the installer runs automatically as if ``-b`` was passed. +`True`, the installer runs automatically as if `-b` was passed. ### `signing_identity_name` -_required:_ no
-_type:_ string
By default, the MacOS pkg installer isn't signed. If an identity name is specified using this option, it will be used to sign the installer with Apple's `productsign`. @@ -337,8 +281,6 @@ accessible keychains. Common values for this option follow this format ### `notarization_identity_name` -_required:_ no
-_type:_ string
If the pkg installer is going to be signed with `signing_identity_name`, you can also prepare the bundle for notarization. This will use Apple's `codesign` @@ -348,8 +290,6 @@ to sign `conda.exe`. For this, you need an "Application certificate" (different ### `windows_signing_tool` -_required:_ no
-_type:_ string
The tool used to sign Windows installers. Must be one of: azuresigntool, signtool. Some tools require `signing_certificate` to be set. @@ -360,16 +300,12 @@ https://conda.github.io/constructor/howto/#signing-exe-installers ### `signing_certificate` -_required:_ no
-_type:_ string
On Windows only, set this key to the path of the certificate file to be used with the `windows_signing_tool`. ### `attempt_hardlinks` -_required:_ no
-_types:_ boolean, string
_Obsolete_. The current version of constructor relies on the standalone conda executable for its installation behavior. This option is now @@ -377,16 +313,12 @@ ignored with a warning. ### `write_condarc` -_required:_ no
-_type:_ boolean
By default, no `.condarc` file is written. If set, a `.condarc` file is written to -the base environment if there are any channels or conda_default_channels is set. +the base environment if there are any channels or `conda_default_channels` is set. ### `condarc` -_required:_ no
-_types:_ dictionary, string
If set, a `.condarc` file is written to the base environment containing the contents of this value. The value can either be a string (likely a multi-line string) or @@ -396,15 +328,11 @@ file (`write_condarc`, `conda_default_channels`, etc.) are ignored. ### `company` -_required:_ no
-_type:_ string
Name of the company/entity who is responsible for the installer. ### `reverse_domain_identifier` -_required:_ no
-_type:_ string
Unique identifier for this package, formatted with reverse domain notation. This is used internally in the PKG installers to handle future updates and others. If not @@ -412,16 +340,12 @@ provided, it will default to `io.continuum`. (MacOS only) ### `uninstall_name` -_required:_ no
-_type:_ string
Application name in the Windows "Programs and Features" control panel. Defaults to `${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})`. ### `script_env_variables` -_required:_ no
-_type:_ dictionary
Dictionary of additional environment variables to be made available to the pre_install and post_install scripts, in the form of VAR:VALUE @@ -444,8 +368,6 @@ comments for all platforms. ### `pre_install` -_required:_ no
-_type:_ string
Path to a pre-install script, run after the package cache has been set, but before the files are linked to their final locations. As a result, you should @@ -454,8 +376,6 @@ etc). See `post_install` for information about available environment variables. ### `pre_install_desc` -_required:_ no
-_type:_ string
A description of the purpose of the supplied `pre_install` script. If this string is supplied and non-empty, then the Windows and macOS GUI installers @@ -467,8 +387,6 @@ This option has no effect on `SH` installers. ### `post_install` -_required:_ no
-_type:_ string
Path to a post-install script. Some notes: @@ -496,8 +414,6 @@ If necessary, you can activate the installed `base` environment like this: ### `post_install_desc` -_required:_ no
-_type:_ string
A description of the purpose of the supplied `post_install` script. If this string is supplied and non-empty, then the Windows and macOS GUI installers @@ -509,8 +425,6 @@ This option has no effect on `SH` installers. ### `pre_uninstall` -_required:_ no
-_type:_ string
Path to a pre uninstall script. This is only supported for on Windows, and must be a `.bat` file. Installation path is available as `%PREFIX%`. @@ -520,8 +434,6 @@ Metadata about the installer can be found in the `%INSTALLER_NAME%`, ### `default_prefix` -_required:_ no
-_type:_ string
Set default install prefix. On Linux, if not provided, the default prefix is `${HOME}/` (or, if `HOME` is not set, `/opt/`). On Windows, @@ -532,8 +444,6 @@ installation time. ### `default_prefix_domain_user` -_required:_ no
-_type:_ string
Set default installation prefix for domain user. If not provided, the installation prefix for domain user will be `%LOCALAPPDATA%\`. @@ -543,8 +453,6 @@ at installation time. Windows only. ### `default_prefix_all_users` -_required:_ no
-_type:_ string
Set default installation prefix for All Users installation. If not provided, the installation prefix for all users installation will be @@ -553,8 +461,6 @@ time. Windows only. ### `default_location_pkg` -_required:_ no
-_type:_ string
Default installation subdirectory in the chosen volume. In PKG installers, default installation locations are configured differently. The user can choose @@ -569,8 +475,6 @@ macOS only. ### `pkg_domains` -_required:_ no
-_type:_ dictionary
The domains the package can be installed into. For a detailed explanation, see: https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html @@ -580,8 +484,6 @@ macOS only. ### `pkg_name` -_required:_ no
-_type:_ string
Internal identifier for the installer. This is used in the build prefix and will determine part of the default location path. Combine with `default_location_pkg` @@ -589,8 +491,6 @@ for more flexibility. If not provided, the value of `name` will be used. (MacOS ### `install_path_exists_error_text` -_required:_ no
-_type:_ string
Error message that will be shown if the installation path already exists. You cannot use double quotes or newlines. The placeholder `{CHOSEN_PATH}` is @@ -603,8 +503,6 @@ available and set to the destination causing the error. Defaults to: ### `progress_notifications` -_required:_ no
-_type:_ boolean
Whether to show UI notifications on PKG installers. On large installations, the progress bar reaches ~90% very quickly and stays there for a long time. @@ -614,8 +512,6 @@ so the user receives updates after each command executed by the installer. ### `welcome_image` -_required:_ no
-_type:_ string
Path to an image in any common image format (`.png`, `.jpg`, `.tif`, etc.) to be used as the welcome image for the Windows and PKG installers. @@ -626,55 +522,41 @@ PKG installers, set this key to `""` (empty string). ### `header_image` -_required:_ no
-_type:_ string
Like `welcome_image` for Windows, re-sized to 150 x 57 pixels. ### `icon_image` -_required:_ no
-_type:_ string
Like `welcome_image` for Windows, re-sized to 256 x 256 pixels. ### `default_image_color` -_required:_ no
-_type:_ string
The color of the default images (when not providing explicit image files) -used on Windows. Possible values are `red`, `green`, `blue`, `yellow`. +used on Windows. Possible values are `red`, `green`, `blue`, `yellow`. The default is `blue`. ### `welcome_image_text` -_required:_ no
-_type:_ string
If `welcome_image` is not provided, use this text when generating the image (Windows and PKG only). Defaults to `name` on Windows. ### `header_image_text` -_required:_ no
-_type:_ string
If `header_image` is not provided, use this text when generating the image (Windows only). Defaults to `name`. ### `initialize_conda` -_required:_ no
-_type:_ boolean
Add an option to the installer so the user can choose whether to run `conda init` after the install. See also `initialize_by_default`. ### `initialize_by_default` -_required:_ no
-_type:_ boolean
Whether to add the installation to the PATH environment variable. The default is true for GUI installers (msi, pkg) and False for shell installers. The user @@ -683,16 +565,12 @@ is able to change the default during interactive installation. NOTE: For Windows ### `register_python` -_required:_ no
-_type:_ boolean
Whether to offer the user an option to register the installed Python instance as the system's default Python. (Windows only) ### `register_python_default` -_required:_ no
-_type:_ boolean
Default choice for whether to register the installed Python instance as the system's default Python. The user is still able to change this during @@ -700,8 +578,6 @@ interactive installation. (Windows only). ### `check_path_length` -_required:_ no
-_type:_ boolean
Check the length of the path where the distribution is installed to ensure nodejs can be installed. Raise a message to request shorter path (less than 46 character) @@ -712,8 +588,6 @@ Read notes about the particularities of Windows silent mode `/S` in the ### `check_path_spaces` -_required:_ no
-_type:_ boolean
Check if the path where the distribution is installed contains spaces. Default is True. To allow installations with spaces, change to False. Note that: @@ -726,8 +600,6 @@ Read notes about the particularities of Windows silent mode `/S` in the ### `nsis_template` -_required:_ no
-_type:_ string
If `nsis_template` is not provided, constructor uses its default NSIS template. For more complete customization for the installation experience, @@ -735,8 +607,6 @@ provide an NSIS template file. (Windows only). ### `welcome_file` -_required:_ no
-_type:_ string
If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the introduction. @@ -750,8 +620,6 @@ begins the installation process. ### `welcome_text` -_required:_ no
-_type:_ string
If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the introduction. @@ -762,8 +630,6 @@ if you set this key to `""` (empty string). ### `readme_file` -_required:_ no
-_type:_ string
If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the welcome screen. @@ -773,8 +639,6 @@ both `readme_file` and `readme_text` are provided, `readme_file` takes precedenc ### `readme_text` -_required:_ no
-_type:_ string
If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the welcome screen. @@ -784,8 +648,6 @@ You can disable it altogether if you set this key to `""` (empty string). ### `post_install_pages` -_required:_ no
-_types:_ list, string
Adds extra pages to the installers to be shown after installation. @@ -798,8 +660,6 @@ They will be inserted as-is before the conclusion page. ### `conclusion_file` -_required:_ no
-_type:_ string
If `installer_type` is `pkg` on MacOS, this message will be shown at the end of the installer upon success. File can be @@ -811,8 +671,6 @@ If the installer is for Windows, the file type must be nsi. ### `conclusion_text` -_required:_ no
-_type:_ string
A message that will be shown at the end of the installer upon success. The behaviour is slightly different across installer types: @@ -824,8 +682,6 @@ The behaviour is slightly different across installer types: ### `extra_files` -_required:_ no
-_type:_ list
Extra, non-packaged files that should be added to the installer. If provided as relative paths, they will be considered relative to the directory where `construct.yaml` is. @@ -835,8 +691,6 @@ This setting can be passed as a list of: ### `temp_extra_files` -_required:_ no
-_type:_ list
Temporary files that could be referenced in the installation process (i.e. customized `welcome_file` and `conclusion_file` (see above)) . Should be a list of @@ -848,14 +702,13 @@ Supports the same values as `extra_files`. ### `build_outputs` -_required:_ no
-_type:_ list
Additional artifacts to be produced after building the installer. It expects either a list of strings or single-key dictionaries: Allowed keys are: - `hash`: The hash of the installer files. - - `algorithm` (str or list): The hash algorithm. Must be among `hashlib`'s available algorithms: + - `algorithm` (str or list): The hash algorithm. Must be among `hashlib`'s available + algorithms: https://docs.python.org/3/library/hashlib.html#hashlib.algorithms_available - `info.json`: The internal `info` object, serialized to JSON. Takes no options. - `pkgs_list`: The list of packages contained in a given environment. Options: @@ -863,21 +716,20 @@ Allowed keys are: - `lockfile`: An `@EXPLICIT` lockfile for a given environment. Options: - `env` (optional, default=`base`): Name of an environment in `extra_envs` to export. - `licenses`: Generate a JSON file with the licensing details of all included packages. Options: - - `include_text` (optional bool, default=`False`): Whether to dump the license text in the JSON. - If false, only the path will be included. - - `text_errors` (optional str, default=`None`): How to handle decoding errors when reading the - license text. Only relevant if include_text is True. Any str accepted by open()'s 'errors' - argument is valid. See https://docs.python.org/3/library/functions.html#open. + - `include_text` (optional bool, default=`False`): Whether to dump the license text in the + JSON. If false, only the path will be included. + - `text_errors` (optional str, default=`None`): How to handle decoding errors when reading + the license text. Only relevant if include_text is True. Any str accepted by open()'s + 'errors' argument is valid. See https://docs.python.org/3/library/functions.html#open. ### `uninstall_with_conda_exe` -_required:_ no
-_type:_ boolean
Use the standalone binary to perform the uninstallation. Requires conda-standalone 24.11.0 or newer. + ## Available selectors - `aarch64` - `arm64` diff --git a/constructor/construct.py b/constructor/construct.py index 07fc2631c..eaf491621 100644 --- a/constructor/construct.py +++ b/constructor/construct.py @@ -703,37 +703,16 @@ class ConstructorConfiguration(BaseModel): Requires conda-standalone 24.11.0 or newer. """ - -_EXTRA_ENVS_SCHEMA = { - "specs": (list, tuple), - "environment": (str,), - "environment_file": (str,), - "channels": (list, tuple), - "channels_remap": (list, tuple), - "user_requested_specs": (list, tuple), - "exclude": (list, tuple), - "menu_packages": (list, tuple), -} - logger = logging.getLogger(__name__) def generate_key_info_list(): key_info_list = [] - for key_info in KEYS: - type_names = {str: "string", list: "list", dict: "dictionary", bool: "boolean"} - key_types = key_info[2] - if not isinstance(key_types, (tuple, list)): - key_types = (key_types,) - plural = "s" if len(key_types) > 1 else "" - key_types = ", ".join(type_names.get(k, "") for k in key_types) - required = "yes" if key_info[1] else "no" - - if key_info[3] == "XXX": - logger.info("Not including %s because the skip sentinel ('XXX') is set", key_info[0]) - continue - - key_info_list.append((key_info[0], required, key_types, key_info[3], plural)) + for name, field in ConstructorConfiguration.model_fields.items(): + type_ = getattr(field.annotation, "__name__", field.annotation.__class__.__name__) + if type_ in ("Optional", "Union", "UnionType"): + type_ = f"`{field.annotation.__args__}`" + key_info_list.append((name, field.is_required(), type_, field.description, "" )) return key_info_list diff --git a/constructor/main.py b/constructor/main.py index e4d8c8975..f75699574 100644 --- a/constructor/main.py +++ b/constructor/main.py @@ -312,54 +312,7 @@ def __call__(self, parser, namespace, values, option_string=None): parser.exit() def _build_message(self): - msg = dedent( - """ - The 'construct.yaml' specification - ================================== - - constructor version {version} - - The `construct.yaml` file is the primary mechanism for controlling - the output of the Constructor package. The file contains a list of - key/value pairs in the standard YAML format. - - Available keys - -------------- - - {available_keys} - - Available selectors - ------------------- - - Constructor can use the same Selector enhancement of the YAML format - used in conda-build ('# [selector]'). Available keywords are: - - {available_selectors} - """ - ) - available_keys_list = [] - for key, required, key_types, help_msg, plural in generate_key_info_list(): - available_keys_list.append( - "\n".join( - [ - key, - "·" * len(key), - indent( - f"Required: {required}, type{plural}: {key_types}", " " - ), - indent(help_msg.strip(), " "), - "", - ] - ) - ) - available_selectors_list = [ - f"- {sel}" for sel in sorted(ns_platform(sys.platform).keys()) - ] - return msg.format( - version=__version__, - available_keys="\n".join(available_keys_list), - available_selectors="\n".join(available_selectors_list), - ) + return "Please refer to https://conda.github.io/constructor/construct-yaml/." def main(): diff --git a/docs/source/construct-yaml.md b/docs/source/construct-yaml.md index a130dbabb..a0e45929b 100644 --- a/docs/source/construct-yaml.md +++ b/docs/source/construct-yaml.md @@ -34,19 +34,20 @@ are not available here. > Note: This content is also available in the CLI as `constructor --help-construct` ## Available keys -### `name` -_required:_ yes
-_type:_ string
+> This is only a name and description render of the `constructor` JSON Schema. +> For more details, consider using an online viewer like [json-schema.app](https://json-schema.app/view/%23?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjaimergp%2Fconstructor%2Frefs%2Fheads%2Fpydantic-schema%2Fconstructor%2Fdata%2Fconstructor.schema.json) + + +### `name` +_required_ Name of the installer. Names may be composed of letters, numbers, underscores, dashes, and periods, but may not begin or end with a dash or period. ### `version` - -_required:_ yes
-_type:_ string
+_required_ Version of the installer. Versions may be composed of letters, numbers, underscores, dashes, and periods, but may not begin or end with a @@ -54,8 +55,6 @@ dash or period. ### `channels` -_required:_ no
-_type:_ list
The conda channels from which packages are retrieved. At least one channel must be supplied, either in `channels` or `channels_remap`. @@ -64,8 +63,6 @@ See notes in `channels_remap` for details about local channels. ### `channels_remap` -_required:_ no
-_type:_ list
A list of `src/dest` channel URL pairs. When building the installer, conda will use the `src` channels to solve and fetch the packages. However, the resulting @@ -85,8 +82,6 @@ At least one channel must be supplied, either in `channels` or `channels_remap`. ### `specs` -_required:_ no
-_types:_ list, string
A list of package specifications; e.g. `python 2.7*`, `pyzmq` or `numpy >=1.8`. The specifications are identical in form and purpose to those that would be @@ -103,8 +98,6 @@ configured solver plugin is also installed in that environment. ### `user_requested_specs` -_required:_ no
-_types:_ list, string
A list of package specifications to be recorded as "user-requested" for the initial environment in conda's history file. This information is used by newer @@ -115,8 +108,6 @@ will be set equal to the value of `specs`. ### `virtual_specs` -_required:_ no
-_type:_ list
A list of virtual packages that must be satisfied at install time. Virtual packages must start with `__`. For example, `__osx>=11` or `__glibc>=2.24`. @@ -129,8 +120,6 @@ involved as long as only `>=`, `<` or `,` are used. ### `exclude` -_required:_ no
-_type:_ list
A list of package names to be excluded after the `specs` have been resolved. For example, you can say that `readline` should be excluded, even though it @@ -138,8 +127,6 @@ is contained as a result of resolving the specs for `python 2.7`. ### `menu_packages` -_required:_ no
-_type:_ list
A list of packages with menu items to be installed. The packages must have necessary metadata in `Menu/.json`). By default, all menu items @@ -155,16 +142,12 @@ the `--conda-exe` binary. The only accepted value is an empty list (`[]`). ### `ignore_duplicate_files` -_required:_ no
-_type:_ boolean
By default, constructor will warn you when adding packages with duplicate files in them. Setting this option to false will raise an error instead. ### `install_in_dependency_order` -_required:_ no
-_types:_ boolean, string
_Obsolete_. The current version of constructor relies on the standalone conda executable for its installation behavior. This option is now @@ -172,8 +155,6 @@ ignored with a warning. ### `environment` -_required:_ no
-_type:_ string
Name of the environment to construct from. If this option is present, the `specs` argument will be ignored. Using this option allows the user to @@ -183,8 +164,6 @@ reproduced. ### `environment_file` -_required:_ no
-_type:_ string
Path to an environment file (TXT or YAML) to construct from. If this option is present, the `specs` argument will be ignored. Instead, constructor will @@ -198,8 +177,6 @@ Read notes about the solver in the `specs` field. ### `transmute_file_type` -_required:_ no
-_type:_ string
File type extension for the files to be transmuted into. Currently supports only '.conda'. See conda-package-handling for supported extension names. @@ -207,8 +184,6 @@ If left empty, no transmuting is done. ### `conda_default_channels` -_required:_ no
-_type:_ list
If this value is provided as well as `write_condarc`, then the channels in this list will be included as the value of the `default_channels:` @@ -217,32 +192,15 @@ only if `conda` is included in the environmnent. ### `conda_channel_alias` -_required:_ no
-_type:_ string
The channel alias that would be assumed for the created installer -(only useful if it includes conda). +(only useful if it includes `conda`). ### `extra_envs` -_required:_ no
-_type:_ dictionary
Create more environments in addition to the default `base` provided by `specs`, -`environment` or `environment_file`. This should be a map of `str` (environment -name) to a dictionary of options: -- `specs` (list of str): which packages to install in that environment -- `environment` (str): same as global option, for this env -- `environment_file` (str): same as global option, for this env -- `channels` (list of str): using these channels; if not provided, the global - value is used. To override inheritance, set it to an empty list. -- `channels_remap` (list of str): same as global option, for this env; - if not provided, the global value is used. To override inheritance, set it to - an empty list. -- `user_requested_specs` (list of str): same as the global option, but for this env; - if not provided, global value is _not_ used -- `menu_packages` (list of str): same as the global option, for this env; - if not provided, the global value is _not_ used. +`environment` or `environment_file`. Notes: - `ignore_duplicate_files` will always be considered `True` if `extra_envs` is in use. @@ -255,24 +213,18 @@ Notes: ### `register_envs` -_required:_ no
-_type:_ boolean
Whether to register the environments created by the installer (both `base` and `extra_envs`) -in `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. Defaults to `True`. +in `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. ### `installer_filename` -_required:_ no
-_type:_ string
The filename of the installer being created. If not supplied, a reasonable default will determined by the `name`, `version`, platform, and installer type. ### `installer_type` -_required:_ no
-_types:_ string, list
The type of the installer being created. Possible values are: - `sh`: shell-based installer for Linux or macOS; @@ -286,8 +238,8 @@ as `sh` on Linux and `exe` on Windows. Notes for silent mode `/S` on Windows EXEs: - NSIS Silent mode will not print any error message, but will silently abort the installation. If needed, [NSIS log-builds][nsis-log] can be used to print to `%PREFIX%\install.log`, which - can be searched for `::error::` strings. Pre- and post- install scripts will only throw an error - if the environment variable `NSIS_SCRIPTS_RAISE_ERRORS` is set. + can be searched for `::error::` strings. Pre- and post- install scripts will only throw + an error if the environment variable `NSIS_SCRIPTS_RAISE_ERRORS` is set. - The `/D` flag can be used to specify the target location. It must be the last argument in the command and should NEVER be quoted, even if it contains spaces. For example: `CMD.EXE /C START /WAIT myproject.exe /S /D=C:\path with spaces\my project`. @@ -296,8 +248,6 @@ Notes for silent mode `/S` on Windows EXEs: ### `license_file` -_required:_ no
-_type:_ string
Path to the license file being displayed by the installer during the install process. It must be plain text (.txt) for shell-based installers. On PKG, @@ -305,8 +255,6 @@ process. It must be plain text (.txt) for shell-based installers. On PKG, ### `keep_pkgs` -_required:_ no
-_type:_ boolean
If `False` (default), the package cache in the `pkgs` subdirectory is removed when the installation process is complete. If `True`, this subdirectory and @@ -316,17 +264,13 @@ to preserve the package cache. ### `batch_mode` -_required:_ no
-_type:_ boolean
-Only affects ``.sh`` installers. If ``False`` (default), the installer launches +Only affects `.sh` installers. If `False` (default), the installer launches an interactive wizard guiding the user through the available options. If -``True``, the installer runs automatically as if ``-b`` was passed. +`True`, the installer runs automatically as if `-b` was passed. ### `signing_identity_name` -_required:_ no
-_type:_ string
By default, the MacOS pkg installer isn't signed. If an identity name is specified using this option, it will be used to sign the installer with Apple's `productsign`. @@ -337,8 +281,6 @@ accessible keychains. Common values for this option follow this format ### `notarization_identity_name` -_required:_ no
-_type:_ string
If the pkg installer is going to be signed with `signing_identity_name`, you can also prepare the bundle for notarization. This will use Apple's `codesign` @@ -348,8 +290,6 @@ to sign `conda.exe`. For this, you need an "Application certificate" (different ### `windows_signing_tool` -_required:_ no
-_type:_ string
The tool used to sign Windows installers. Must be one of: azuresigntool, signtool. Some tools require `signing_certificate` to be set. @@ -360,16 +300,12 @@ https://conda.github.io/constructor/howto/#signing-exe-installers ### `signing_certificate` -_required:_ no
-_type:_ string
On Windows only, set this key to the path of the certificate file to be used with the `windows_signing_tool`. ### `attempt_hardlinks` -_required:_ no
-_types:_ boolean, string
_Obsolete_. The current version of constructor relies on the standalone conda executable for its installation behavior. This option is now @@ -377,16 +313,12 @@ ignored with a warning. ### `write_condarc` -_required:_ no
-_type:_ boolean
By default, no `.condarc` file is written. If set, a `.condarc` file is written to -the base environment if there are any channels or conda_default_channels is set. +the base environment if there are any channels or `conda_default_channels` is set. ### `condarc` -_required:_ no
-_types:_ dictionary, string
If set, a `.condarc` file is written to the base environment containing the contents of this value. The value can either be a string (likely a multi-line string) or @@ -396,15 +328,11 @@ file (`write_condarc`, `conda_default_channels`, etc.) are ignored. ### `company` -_required:_ no
-_type:_ string
Name of the company/entity who is responsible for the installer. ### `reverse_domain_identifier` -_required:_ no
-_type:_ string
Unique identifier for this package, formatted with reverse domain notation. This is used internally in the PKG installers to handle future updates and others. If not @@ -412,16 +340,12 @@ provided, it will default to `io.continuum`. (MacOS only) ### `uninstall_name` -_required:_ no
-_type:_ string
Application name in the Windows "Programs and Features" control panel. Defaults to `${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})`. ### `script_env_variables` -_required:_ no
-_type:_ dictionary
Dictionary of additional environment variables to be made available to the pre_install and post_install scripts, in the form of VAR:VALUE @@ -444,8 +368,6 @@ comments for all platforms. ### `pre_install` -_required:_ no
-_type:_ string
Path to a pre-install script, run after the package cache has been set, but before the files are linked to their final locations. As a result, you should @@ -454,8 +376,6 @@ etc). See `post_install` for information about available environment variables. ### `pre_install_desc` -_required:_ no
-_type:_ string
A description of the purpose of the supplied `pre_install` script. If this string is supplied and non-empty, then the Windows and macOS GUI installers @@ -467,8 +387,6 @@ This option has no effect on `SH` installers. ### `post_install` -_required:_ no
-_type:_ string
Path to a post-install script. Some notes: @@ -496,8 +414,6 @@ If necessary, you can activate the installed `base` environment like this: ### `post_install_desc` -_required:_ no
-_type:_ string
A description of the purpose of the supplied `post_install` script. If this string is supplied and non-empty, then the Windows and macOS GUI installers @@ -509,8 +425,6 @@ This option has no effect on `SH` installers. ### `pre_uninstall` -_required:_ no
-_type:_ string
Path to a pre uninstall script. This is only supported for on Windows, and must be a `.bat` file. Installation path is available as `%PREFIX%`. @@ -520,8 +434,6 @@ Metadata about the installer can be found in the `%INSTALLER_NAME%`, ### `default_prefix` -_required:_ no
-_type:_ string
Set default install prefix. On Linux, if not provided, the default prefix is `${HOME}/` (or, if `HOME` is not set, `/opt/`). On Windows, @@ -532,8 +444,6 @@ installation time. ### `default_prefix_domain_user` -_required:_ no
-_type:_ string
Set default installation prefix for domain user. If not provided, the installation prefix for domain user will be `%LOCALAPPDATA%\`. @@ -543,8 +453,6 @@ at installation time. Windows only. ### `default_prefix_all_users` -_required:_ no
-_type:_ string
Set default installation prefix for All Users installation. If not provided, the installation prefix for all users installation will be @@ -553,8 +461,6 @@ time. Windows only. ### `default_location_pkg` -_required:_ no
-_type:_ string
Default installation subdirectory in the chosen volume. In PKG installers, default installation locations are configured differently. The user can choose @@ -569,8 +475,6 @@ macOS only. ### `pkg_domains` -_required:_ no
-_type:_ dictionary
The domains the package can be installed into. For a detailed explanation, see: https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html @@ -580,8 +484,6 @@ macOS only. ### `pkg_name` -_required:_ no
-_type:_ string
Internal identifier for the installer. This is used in the build prefix and will determine part of the default location path. Combine with `default_location_pkg` @@ -589,8 +491,6 @@ for more flexibility. If not provided, the value of `name` will be used. (MacOS ### `install_path_exists_error_text` -_required:_ no
-_type:_ string
Error message that will be shown if the installation path already exists. You cannot use double quotes or newlines. The placeholder `{CHOSEN_PATH}` is @@ -603,8 +503,6 @@ available and set to the destination causing the error. Defaults to: ### `progress_notifications` -_required:_ no
-_type:_ boolean
Whether to show UI notifications on PKG installers. On large installations, the progress bar reaches ~90% very quickly and stays there for a long time. @@ -614,8 +512,6 @@ so the user receives updates after each command executed by the installer. ### `welcome_image` -_required:_ no
-_type:_ string
Path to an image in any common image format (`.png`, `.jpg`, `.tif`, etc.) to be used as the welcome image for the Windows and PKG installers. @@ -626,55 +522,41 @@ PKG installers, set this key to `""` (empty string). ### `header_image` -_required:_ no
-_type:_ string
Like `welcome_image` for Windows, re-sized to 150 x 57 pixels. ### `icon_image` -_required:_ no
-_type:_ string
Like `welcome_image` for Windows, re-sized to 256 x 256 pixels. ### `default_image_color` -_required:_ no
-_type:_ string
The color of the default images (when not providing explicit image files) -used on Windows. Possible values are `red`, `green`, `blue`, `yellow`. +used on Windows. Possible values are `red`, `green`, `blue`, `yellow`. The default is `blue`. ### `welcome_image_text` -_required:_ no
-_type:_ string
If `welcome_image` is not provided, use this text when generating the image (Windows and PKG only). Defaults to `name` on Windows. ### `header_image_text` -_required:_ no
-_type:_ string
If `header_image` is not provided, use this text when generating the image (Windows only). Defaults to `name`. ### `initialize_conda` -_required:_ no
-_type:_ boolean
Add an option to the installer so the user can choose whether to run `conda init` after the install. See also `initialize_by_default`. ### `initialize_by_default` -_required:_ no
-_type:_ boolean
Whether to add the installation to the PATH environment variable. The default is true for GUI installers (msi, pkg) and False for shell installers. The user @@ -683,16 +565,12 @@ is able to change the default during interactive installation. NOTE: For Windows ### `register_python` -_required:_ no
-_type:_ boolean
Whether to offer the user an option to register the installed Python instance as the system's default Python. (Windows only) ### `register_python_default` -_required:_ no
-_type:_ boolean
Default choice for whether to register the installed Python instance as the system's default Python. The user is still able to change this during @@ -700,8 +578,6 @@ interactive installation. (Windows only). ### `check_path_length` -_required:_ no
-_type:_ boolean
Check the length of the path where the distribution is installed to ensure nodejs can be installed. Raise a message to request shorter path (less than 46 character) @@ -712,8 +588,6 @@ Read notes about the particularities of Windows silent mode `/S` in the ### `check_path_spaces` -_required:_ no
-_type:_ boolean
Check if the path where the distribution is installed contains spaces. Default is True. To allow installations with spaces, change to False. Note that: @@ -726,8 +600,6 @@ Read notes about the particularities of Windows silent mode `/S` in the ### `nsis_template` -_required:_ no
-_type:_ string
If `nsis_template` is not provided, constructor uses its default NSIS template. For more complete customization for the installation experience, @@ -735,8 +607,6 @@ provide an NSIS template file. (Windows only). ### `welcome_file` -_required:_ no
-_type:_ string
If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the introduction. @@ -750,8 +620,6 @@ begins the installation process. ### `welcome_text` -_required:_ no
-_type:_ string
If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the introduction. @@ -762,8 +630,6 @@ if you set this key to `""` (empty string). ### `readme_file` -_required:_ no
-_type:_ string
If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the welcome screen. @@ -773,8 +639,6 @@ both `readme_file` and `readme_text` are provided, `readme_file` takes precedenc ### `readme_text` -_required:_ no
-_type:_ string
If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the welcome screen. @@ -784,8 +648,6 @@ You can disable it altogether if you set this key to `""` (empty string). ### `post_install_pages` -_required:_ no
-_types:_ list, string
Adds extra pages to the installers to be shown after installation. @@ -798,8 +660,6 @@ They will be inserted as-is before the conclusion page. ### `conclusion_file` -_required:_ no
-_type:_ string
If `installer_type` is `pkg` on MacOS, this message will be shown at the end of the installer upon success. File can be @@ -811,8 +671,6 @@ If the installer is for Windows, the file type must be nsi. ### `conclusion_text` -_required:_ no
-_type:_ string
A message that will be shown at the end of the installer upon success. The behaviour is slightly different across installer types: @@ -824,8 +682,6 @@ The behaviour is slightly different across installer types: ### `extra_files` -_required:_ no
-_type:_ list
Extra, non-packaged files that should be added to the installer. If provided as relative paths, they will be considered relative to the directory where `construct.yaml` is. @@ -835,8 +691,6 @@ This setting can be passed as a list of: ### `temp_extra_files` -_required:_ no
-_type:_ list
Temporary files that could be referenced in the installation process (i.e. customized `welcome_file` and `conclusion_file` (see above)) . Should be a list of @@ -848,14 +702,13 @@ Supports the same values as `extra_files`. ### `build_outputs` -_required:_ no
-_type:_ list
Additional artifacts to be produced after building the installer. It expects either a list of strings or single-key dictionaries: Allowed keys are: - `hash`: The hash of the installer files. - - `algorithm` (str or list): The hash algorithm. Must be among `hashlib`'s available algorithms: + - `algorithm` (str or list): The hash algorithm. Must be among `hashlib`'s available + algorithms: https://docs.python.org/3/library/hashlib.html#hashlib.algorithms_available - `info.json`: The internal `info` object, serialized to JSON. Takes no options. - `pkgs_list`: The list of packages contained in a given environment. Options: @@ -863,21 +716,20 @@ Allowed keys are: - `lockfile`: An `@EXPLICIT` lockfile for a given environment. Options: - `env` (optional, default=`base`): Name of an environment in `extra_envs` to export. - `licenses`: Generate a JSON file with the licensing details of all included packages. Options: - - `include_text` (optional bool, default=`False`): Whether to dump the license text in the JSON. - If false, only the path will be included. - - `text_errors` (optional str, default=`None`): How to handle decoding errors when reading the - license text. Only relevant if include_text is True. Any str accepted by open()'s 'errors' - argument is valid. See https://docs.python.org/3/library/functions.html#open. + - `include_text` (optional bool, default=`False`): Whether to dump the license text in the + JSON. If false, only the path will be included. + - `text_errors` (optional str, default=`None`): How to handle decoding errors when reading + the license text. Only relevant if include_text is True. Any str accepted by open()'s + 'errors' argument is valid. See https://docs.python.org/3/library/functions.html#open. ### `uninstall_with_conda_exe` -_required:_ no
-_type:_ boolean
Use the standalone binary to perform the uninstallation. Requires conda-standalone 24.11.0 or newer. + ## Available selectors - `aarch64` - `arm64` diff --git a/scripts/make_docs.py b/scripts/make_docs.py index 323842ac9..f9770653f 100644 --- a/scripts/make_docs.py +++ b/scripts/make_docs.py @@ -50,13 +50,16 @@ ## Available keys -{%- for key_info in keys %} +> This is only a name and description render of the `constructor` JSON Schema. +> For more details, consider using an online viewer like [json-schema.app](https://json-schema.app/view/%23?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjaimergp%2Fconstructor%2Frefs%2Fheads%2Fpydantic-schema%2Fconstructor%2Fdata%2Fconstructor.schema.json) + +{% for key_info in keys %} ### `{{key_info[0]}}` +{{ '_required_' if key_info[1] else '' }} -_required:_ {{key_info[1]}}
-_type{{key_info[4]}}:_ {{key_info[2]}}
{{key_info[3]}} -{%- endfor %} +{% endfor %} + ## Available selectors From 0014436291b16ad0f628429049988d74b5aae246 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Wed, 5 Mar 2025 21:54:34 +0100 Subject: [PATCH 006/138] Adjust documentation generation pipeline --- CONSTRUCT.md | 72 ----------------------------------- constructor/main.py | 2 - docs/source/construct-yaml.md | 72 ----------------------------------- scripts/make_docs.py | 22 ++++++----- 4 files changed, 13 insertions(+), 155 deletions(-) diff --git a/CONSTRUCT.md b/CONSTRUCT.md index a0e45929b..4b667a8a8 100644 --- a/CONSTRUCT.md +++ b/CONSTRUCT.md @@ -40,14 +40,12 @@ are not available here. ### `name` -_required_ Name of the installer. Names may be composed of letters, numbers, underscores, dashes, and periods, but may not begin or end with a dash or period. ### `version` -_required_ Version of the installer. Versions may be composed of letters, numbers, underscores, dashes, and periods, but may not begin or end with a @@ -55,7 +53,6 @@ dash or period. ### `channels` - The conda channels from which packages are retrieved. At least one channel must be supplied, either in `channels` or `channels_remap`. @@ -63,7 +60,6 @@ See notes in `channels_remap` for details about local channels. ### `channels_remap` - A list of `src/dest` channel URL pairs. When building the installer, conda will use the `src` channels to solve and fetch the packages. However, the resulting installation will see the packages as coming from the `dest` equivalent. @@ -82,7 +78,6 @@ At least one channel must be supplied, either in `channels` or `channels_remap`. ### `specs` - A list of package specifications; e.g. `python 2.7*`, `pyzmq` or `numpy >=1.8`. The specifications are identical in form and purpose to those that would be included in a `conda create --file` command. Packages may also be specified @@ -98,7 +93,6 @@ configured solver plugin is also installed in that environment. ### `user_requested_specs` - A list of package specifications to be recorded as "user-requested" for the initial environment in conda's history file. This information is used by newer versions of conda to better filter its package choices on subsequent installs; @@ -108,7 +102,6 @@ will be set equal to the value of `specs`. ### `virtual_specs` - A list of virtual packages that must be satisfied at install time. Virtual packages must start with `__`. For example, `__osx>=11` or `__glibc>=2.24`. These specs are dry-run solved offline by the bundled `--conda-exe` binary. @@ -120,14 +113,12 @@ involved as long as only `>=`, `<` or `,` are used. ### `exclude` - A list of package names to be excluded after the `specs` have been resolved. For example, you can say that `readline` should be excluded, even though it is contained as a result of resolving the specs for `python 2.7`. ### `menu_packages` - A list of packages with menu items to be installed. The packages must have necessary metadata in `Menu/.json`). By default, all menu items found in the installation will be created; supplying this list allows a @@ -142,20 +133,17 @@ the `--conda-exe` binary. The only accepted value is an empty list (`[]`). ### `ignore_duplicate_files` - By default, constructor will warn you when adding packages with duplicate files in them. Setting this option to false will raise an error instead. ### `install_in_dependency_order` - _Obsolete_. The current version of constructor relies on the standalone conda executable for its installation behavior. This option is now ignored with a warning. ### `environment` - Name of the environment to construct from. If this option is present, the `specs` argument will be ignored. Using this option allows the user to curate the enviromment interactively using standard `conda` commands, and @@ -164,7 +152,6 @@ reproduced. ### `environment_file` - Path to an environment file (TXT or YAML) to construct from. If this option is present, the `specs` argument will be ignored. Instead, constructor will call conda to create a temporary environment, constructor will build and @@ -177,14 +164,12 @@ Read notes about the solver in the `specs` field. ### `transmute_file_type` - File type extension for the files to be transmuted into. Currently supports only '.conda'. See conda-package-handling for supported extension names. If left empty, no transmuting is done. ### `conda_default_channels` - If this value is provided as well as `write_condarc`, then the channels in this list will be included as the value of the `default_channels:` option in the environment's `.condarc` file. This will have an impact @@ -192,13 +177,11 @@ only if `conda` is included in the environmnent. ### `conda_channel_alias` - The channel alias that would be assumed for the created installer (only useful if it includes `conda`). ### `extra_envs` - Create more environments in addition to the default `base` provided by `specs`, `environment` or `environment_file`. @@ -213,19 +196,16 @@ Notes: ### `register_envs` - Whether to register the environments created by the installer (both `base` and `extra_envs`) in `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. ### `installer_filename` - The filename of the installer being created. If not supplied, a reasonable default will determined by the `name`, `version`, platform, and installer type. ### `installer_type` - The type of the installer being created. Possible values are: - `sh`: shell-based installer for Linux or macOS; - `pkg`: macOS GUI installer built with Apple's `pkgbuild` @@ -248,14 +228,12 @@ Notes for silent mode `/S` on Windows EXEs: ### `license_file` - Path to the license file being displayed by the installer during the install process. It must be plain text (.txt) for shell-based installers. On PKG, .txt, .rtf and .html are supported. On Windows, .txt and .rtf are supported. ### `keep_pkgs` - If `False` (default), the package cache in the `pkgs` subdirectory is removed when the installation process is complete. If `True`, this subdirectory and its contents are preserved. If `keep_pkgs` is `False`, Unix `.sh` and Windows `.msi` @@ -264,14 +242,12 @@ to preserve the package cache. ### `batch_mode` - Only affects `.sh` installers. If `False` (default), the installer launches an interactive wizard guiding the user through the available options. If `True`, the installer runs automatically as if `-b` was passed. ### `signing_identity_name` - By default, the MacOS pkg installer isn't signed. If an identity name is specified using this option, it will be used to sign the installer with Apple's `productsign`. Note that you will need to have a certificate (usually an "Installer certificate") @@ -281,7 +257,6 @@ accessible keychains. Common values for this option follow this format ### `notarization_identity_name` - If the pkg installer is going to be signed with `signing_identity_name`, you can also prepare the bundle for notarization. This will use Apple's `codesign` to sign `conda.exe`. For this, you need an "Application certificate" (different from the @@ -290,7 +265,6 @@ to sign `conda.exe`. For this, you need an "Application certificate" (different ### `windows_signing_tool` - The tool used to sign Windows installers. Must be one of: azuresigntool, signtool. Some tools require `signing_certificate` to be set. Defaults to `signtool` if `signing_certificate` is set. @@ -300,26 +274,22 @@ https://conda.github.io/constructor/howto/#signing-exe-installers ### `signing_certificate` - On Windows only, set this key to the path of the certificate file to be used with the `windows_signing_tool`. ### `attempt_hardlinks` - _Obsolete_. The current version of constructor relies on the standalone conda executable for its installation behavior. This option is now ignored with a warning. ### `write_condarc` - By default, no `.condarc` file is written. If set, a `.condarc` file is written to the base environment if there are any channels or `conda_default_channels` is set. ### `condarc` - If set, a `.condarc` file is written to the base environment containing the contents of this value. The value can either be a string (likely a multi-line string) or a dictionary, which will be converted to a YAML string for writing. _Note:_ if this @@ -328,25 +298,21 @@ file (`write_condarc`, `conda_default_channels`, etc.) are ignored. ### `company` - Name of the company/entity who is responsible for the installer. ### `reverse_domain_identifier` - Unique identifier for this package, formatted with reverse domain notation. This is used internally in the PKG installers to handle future updates and others. If not provided, it will default to `io.continuum`. (MacOS only) ### `uninstall_name` - Application name in the Windows "Programs and Features" control panel. Defaults to `${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})`. ### `script_env_variables` - Dictionary of additional environment variables to be made available to the pre_install and post_install scripts, in the form of VAR:VALUE pairs. These environment variables are in addition to those in the @@ -368,7 +334,6 @@ comments for all platforms. ### `pre_install` - Path to a pre-install script, run after the package cache has been set, but before the files are linked to their final locations. As a result, you should only rely on tools known to be available on most systems (e.g. `bash`, `cmd`, @@ -376,7 +341,6 @@ etc). See `post_install` for information about available environment variables. ### `pre_install_desc` - A description of the purpose of the supplied `pre_install` script. If this string is supplied and non-empty, then the Windows and macOS GUI installers will display it along with checkbox to enable or disable the execution of the @@ -387,7 +351,6 @@ This option has no effect on `SH` installers. ### `post_install` - Path to a post-install script. Some notes: - For Unix `.sh` installers, the shebang line is respected if present; @@ -414,7 +377,6 @@ If necessary, you can activate the installed `base` environment like this: ### `post_install_desc` - A description of the purpose of the supplied `post_install` script. If this string is supplied and non-empty, then the Windows and macOS GUI installers will display it along with checkbox to enable or disable the execution of the @@ -425,7 +387,6 @@ This option has no effect on `SH` installers. ### `pre_uninstall` - Path to a pre uninstall script. This is only supported for on Windows, and must be a `.bat` file. Installation path is available as `%PREFIX%`. Metadata about the installer can be found in the `%INSTALLER_NAME%`, @@ -434,7 +395,6 @@ Metadata about the installer can be found in the `%INSTALLER_NAME%`, ### `default_prefix` - Set default install prefix. On Linux, if not provided, the default prefix is `${HOME}/` (or, if `HOME` is not set, `/opt/`). On Windows, this is used only for "Just Me" installation; for "All Users" installation, @@ -444,7 +404,6 @@ installation time. ### `default_prefix_domain_user` - Set default installation prefix for domain user. If not provided, the installation prefix for domain user will be `%LOCALAPPDATA%\`. By default, it is different from the `default_prefix` value to avoid installing @@ -453,7 +412,6 @@ at installation time. Windows only. ### `default_prefix_all_users` - Set default installation prefix for All Users installation. If not provided, the installation prefix for all users installation will be `%ALLUSERSPROFILE%\`. Environment variables will be expanded at installation @@ -461,7 +419,6 @@ time. Windows only. ### `default_location_pkg` - Default installation subdirectory in the chosen volume. In PKG installers, default installation locations are configured differently. The user can choose between a "Just me" installation (which would result in `~/`) or another @@ -475,7 +432,6 @@ macOS only. ### `pkg_domains` - The domains the package can be installed into. For a detailed explanation, see: https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html constructor defaults to `enable_anywhere=true` and `enable_currentUserHome=true`. @@ -484,14 +440,12 @@ macOS only. ### `pkg_name` - Internal identifier for the installer. This is used in the build prefix and will determine part of the default location path. Combine with `default_location_pkg` for more flexibility. If not provided, the value of `name` will be used. (MacOS only) ### `install_path_exists_error_text` - Error message that will be shown if the installation path already exists. You cannot use double quotes or newlines. The placeholder `{CHOSEN_PATH}` is available and set to the destination causing the error. Defaults to: @@ -503,7 +457,6 @@ available and set to the destination causing the error. Defaults to: ### `progress_notifications` - Whether to show UI notifications on PKG installers. On large installations, the progress bar reaches ~90% very quickly and stays there for a long time. This might look like the installer froze. This option enables UI notifications @@ -512,7 +465,6 @@ so the user receives updates after each command executed by the installer. ### `welcome_image` - Path to an image in any common image format (`.png`, `.jpg`, `.tif`, etc.) to be used as the welcome image for the Windows and PKG installers. The image is re-sized to 164 x 314 pixels on Windows and 1227 x 600 on Macos. @@ -522,42 +474,35 @@ PKG installers, set this key to `""` (empty string). ### `header_image` - Like `welcome_image` for Windows, re-sized to 150 x 57 pixels. ### `icon_image` - Like `welcome_image` for Windows, re-sized to 256 x 256 pixels. ### `default_image_color` - The color of the default images (when not providing explicit image files) used on Windows. Possible values are `red`, `green`, `blue`, `yellow`. The default is `blue`. ### `welcome_image_text` - If `welcome_image` is not provided, use this text when generating the image (Windows and PKG only). Defaults to `name` on Windows. ### `header_image_text` - If `header_image` is not provided, use this text when generating the image (Windows only). Defaults to `name`. ### `initialize_conda` - Add an option to the installer so the user can choose whether to run `conda init` after the install. See also `initialize_by_default`. ### `initialize_by_default` - Whether to add the installation to the PATH environment variable. The default is true for GUI installers (msi, pkg) and False for shell installers. The user is able to change the default during interactive installation. NOTE: For Windows, @@ -565,20 +510,17 @@ is able to change the default during interactive installation. NOTE: For Windows ### `register_python` - Whether to offer the user an option to register the installed Python instance as the system's default Python. (Windows only) ### `register_python_default` - Default choice for whether to register the installed Python instance as the system's default Python. The user is still able to change this during interactive installation. (Windows only). ### `check_path_length` - Check the length of the path where the distribution is installed to ensure nodejs can be installed. Raise a message to request shorter path (less than 46 character) or enable long path on windows > 10 (require admin right). Default is True. (Windows only). @@ -588,7 +530,6 @@ Read notes about the particularities of Windows silent mode `/S` in the ### `check_path_spaces` - Check if the path where the distribution is installed contains spaces. Default is True. To allow installations with spaces, change to False. Note that: @@ -600,14 +541,12 @@ Read notes about the particularities of Windows silent mode `/S` in the ### `nsis_template` - If `nsis_template` is not provided, constructor uses its default NSIS template. For more complete customization for the installation experience, provide an NSIS template file. (Windows only). ### `welcome_file` - If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the introduction. File can be plain text (.txt), rich text (.rtf) or HTML (.html). If @@ -620,7 +559,6 @@ begins the installation process. ### `welcome_text` - If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the introduction. If this key is missing, it defaults to a message about Anaconda Cloud. @@ -630,7 +568,6 @@ if you set this key to `""` (empty string). ### `readme_file` - If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the welcome screen. File can be plain text (.txt), rich text (.rtf) or HTML (.html). If @@ -639,7 +576,6 @@ both `readme_file` and `readme_text` are provided, `readme_file` takes precedenc ### `readme_text` - If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the welcome screen. If this key is missing, it defaults to a message about Anaconda Cloud. @@ -648,7 +584,6 @@ You can disable it altogether if you set this key to `""` (empty string). ### `post_install_pages` - Adds extra pages to the installers to be shown after installation. For PKG installers, these can be compiled `installer` plug-ins or @@ -660,7 +595,6 @@ They will be inserted as-is before the conclusion page. ### `conclusion_file` - If `installer_type` is `pkg` on MacOS, this message will be shown at the end of the installer upon success. File can be plain text (.txt), rich text (.rtf) or HTML (.html). If both @@ -671,7 +605,6 @@ If the installer is for Windows, the file type must be nsi. ### `conclusion_text` - A message that will be shown at the end of the installer upon success. The behaviour is slightly different across installer types: - PKG: If this key is missing, it defaults to a message about Anaconda Cloud. @@ -682,7 +615,6 @@ The behaviour is slightly different across installer types: ### `extra_files` - Extra, non-packaged files that should be added to the installer. If provided as relative paths, they will be considered relative to the directory where `construct.yaml` is. This setting can be passed as a list of: @@ -691,7 +623,6 @@ This setting can be passed as a list of: ### `temp_extra_files` - Temporary files that could be referenced in the installation process (i.e. customized `welcome_file` and `conclusion_file` (see above)) . Should be a list of file paths, relative to the directory where `construct.yaml` is. In Windows, these @@ -702,7 +633,6 @@ Supports the same values as `extra_files`. ### `build_outputs` - Additional artifacts to be produced after building the installer. It expects either a list of strings or single-key dictionaries: Allowed keys are: @@ -724,12 +654,10 @@ Allowed keys are: ### `uninstall_with_conda_exe` - Use the standalone binary to perform the uninstallation. Requires conda-standalone 24.11.0 or newer. - ## Available selectors - `aarch64` - `arm64` diff --git a/constructor/main.py b/constructor/main.py index f75699574..ba2074673 100644 --- a/constructor/main.py +++ b/constructor/main.py @@ -10,14 +10,12 @@ import os import sys from os.path import abspath, expanduser, isdir, join -from textwrap import dedent, indent from . import __version__ from .build_outputs import process_build_outputs from .conda_interface import SUPPORTED_PLATFORMS from .conda_interface import VersionOrder as Version from .conda_interface import cc_platform -from .construct import generate_key_info_list, ns_platform from .construct import parse as construct_parse from .construct import verify as construct_verify from .fcp import main as fcp_main diff --git a/docs/source/construct-yaml.md b/docs/source/construct-yaml.md index a0e45929b..4b667a8a8 100644 --- a/docs/source/construct-yaml.md +++ b/docs/source/construct-yaml.md @@ -40,14 +40,12 @@ are not available here. ### `name` -_required_ Name of the installer. Names may be composed of letters, numbers, underscores, dashes, and periods, but may not begin or end with a dash or period. ### `version` -_required_ Version of the installer. Versions may be composed of letters, numbers, underscores, dashes, and periods, but may not begin or end with a @@ -55,7 +53,6 @@ dash or period. ### `channels` - The conda channels from which packages are retrieved. At least one channel must be supplied, either in `channels` or `channels_remap`. @@ -63,7 +60,6 @@ See notes in `channels_remap` for details about local channels. ### `channels_remap` - A list of `src/dest` channel URL pairs. When building the installer, conda will use the `src` channels to solve and fetch the packages. However, the resulting installation will see the packages as coming from the `dest` equivalent. @@ -82,7 +78,6 @@ At least one channel must be supplied, either in `channels` or `channels_remap`. ### `specs` - A list of package specifications; e.g. `python 2.7*`, `pyzmq` or `numpy >=1.8`. The specifications are identical in form and purpose to those that would be included in a `conda create --file` command. Packages may also be specified @@ -98,7 +93,6 @@ configured solver plugin is also installed in that environment. ### `user_requested_specs` - A list of package specifications to be recorded as "user-requested" for the initial environment in conda's history file. This information is used by newer versions of conda to better filter its package choices on subsequent installs; @@ -108,7 +102,6 @@ will be set equal to the value of `specs`. ### `virtual_specs` - A list of virtual packages that must be satisfied at install time. Virtual packages must start with `__`. For example, `__osx>=11` or `__glibc>=2.24`. These specs are dry-run solved offline by the bundled `--conda-exe` binary. @@ -120,14 +113,12 @@ involved as long as only `>=`, `<` or `,` are used. ### `exclude` - A list of package names to be excluded after the `specs` have been resolved. For example, you can say that `readline` should be excluded, even though it is contained as a result of resolving the specs for `python 2.7`. ### `menu_packages` - A list of packages with menu items to be installed. The packages must have necessary metadata in `Menu/.json`). By default, all menu items found in the installation will be created; supplying this list allows a @@ -142,20 +133,17 @@ the `--conda-exe` binary. The only accepted value is an empty list (`[]`). ### `ignore_duplicate_files` - By default, constructor will warn you when adding packages with duplicate files in them. Setting this option to false will raise an error instead. ### `install_in_dependency_order` - _Obsolete_. The current version of constructor relies on the standalone conda executable for its installation behavior. This option is now ignored with a warning. ### `environment` - Name of the environment to construct from. If this option is present, the `specs` argument will be ignored. Using this option allows the user to curate the enviromment interactively using standard `conda` commands, and @@ -164,7 +152,6 @@ reproduced. ### `environment_file` - Path to an environment file (TXT or YAML) to construct from. If this option is present, the `specs` argument will be ignored. Instead, constructor will call conda to create a temporary environment, constructor will build and @@ -177,14 +164,12 @@ Read notes about the solver in the `specs` field. ### `transmute_file_type` - File type extension for the files to be transmuted into. Currently supports only '.conda'. See conda-package-handling for supported extension names. If left empty, no transmuting is done. ### `conda_default_channels` - If this value is provided as well as `write_condarc`, then the channels in this list will be included as the value of the `default_channels:` option in the environment's `.condarc` file. This will have an impact @@ -192,13 +177,11 @@ only if `conda` is included in the environmnent. ### `conda_channel_alias` - The channel alias that would be assumed for the created installer (only useful if it includes `conda`). ### `extra_envs` - Create more environments in addition to the default `base` provided by `specs`, `environment` or `environment_file`. @@ -213,19 +196,16 @@ Notes: ### `register_envs` - Whether to register the environments created by the installer (both `base` and `extra_envs`) in `~/.conda/environments.txt`. Only compatible with conda-standalone >=23.9. ### `installer_filename` - The filename of the installer being created. If not supplied, a reasonable default will determined by the `name`, `version`, platform, and installer type. ### `installer_type` - The type of the installer being created. Possible values are: - `sh`: shell-based installer for Linux or macOS; - `pkg`: macOS GUI installer built with Apple's `pkgbuild` @@ -248,14 +228,12 @@ Notes for silent mode `/S` on Windows EXEs: ### `license_file` - Path to the license file being displayed by the installer during the install process. It must be plain text (.txt) for shell-based installers. On PKG, .txt, .rtf and .html are supported. On Windows, .txt and .rtf are supported. ### `keep_pkgs` - If `False` (default), the package cache in the `pkgs` subdirectory is removed when the installation process is complete. If `True`, this subdirectory and its contents are preserved. If `keep_pkgs` is `False`, Unix `.sh` and Windows `.msi` @@ -264,14 +242,12 @@ to preserve the package cache. ### `batch_mode` - Only affects `.sh` installers. If `False` (default), the installer launches an interactive wizard guiding the user through the available options. If `True`, the installer runs automatically as if `-b` was passed. ### `signing_identity_name` - By default, the MacOS pkg installer isn't signed. If an identity name is specified using this option, it will be used to sign the installer with Apple's `productsign`. Note that you will need to have a certificate (usually an "Installer certificate") @@ -281,7 +257,6 @@ accessible keychains. Common values for this option follow this format ### `notarization_identity_name` - If the pkg installer is going to be signed with `signing_identity_name`, you can also prepare the bundle for notarization. This will use Apple's `codesign` to sign `conda.exe`. For this, you need an "Application certificate" (different from the @@ -290,7 +265,6 @@ to sign `conda.exe`. For this, you need an "Application certificate" (different ### `windows_signing_tool` - The tool used to sign Windows installers. Must be one of: azuresigntool, signtool. Some tools require `signing_certificate` to be set. Defaults to `signtool` if `signing_certificate` is set. @@ -300,26 +274,22 @@ https://conda.github.io/constructor/howto/#signing-exe-installers ### `signing_certificate` - On Windows only, set this key to the path of the certificate file to be used with the `windows_signing_tool`. ### `attempt_hardlinks` - _Obsolete_. The current version of constructor relies on the standalone conda executable for its installation behavior. This option is now ignored with a warning. ### `write_condarc` - By default, no `.condarc` file is written. If set, a `.condarc` file is written to the base environment if there are any channels or `conda_default_channels` is set. ### `condarc` - If set, a `.condarc` file is written to the base environment containing the contents of this value. The value can either be a string (likely a multi-line string) or a dictionary, which will be converted to a YAML string for writing. _Note:_ if this @@ -328,25 +298,21 @@ file (`write_condarc`, `conda_default_channels`, etc.) are ignored. ### `company` - Name of the company/entity who is responsible for the installer. ### `reverse_domain_identifier` - Unique identifier for this package, formatted with reverse domain notation. This is used internally in the PKG installers to handle future updates and others. If not provided, it will default to `io.continuum`. (MacOS only) ### `uninstall_name` - Application name in the Windows "Programs and Features" control panel. Defaults to `${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})`. ### `script_env_variables` - Dictionary of additional environment variables to be made available to the pre_install and post_install scripts, in the form of VAR:VALUE pairs. These environment variables are in addition to those in the @@ -368,7 +334,6 @@ comments for all platforms. ### `pre_install` - Path to a pre-install script, run after the package cache has been set, but before the files are linked to their final locations. As a result, you should only rely on tools known to be available on most systems (e.g. `bash`, `cmd`, @@ -376,7 +341,6 @@ etc). See `post_install` for information about available environment variables. ### `pre_install_desc` - A description of the purpose of the supplied `pre_install` script. If this string is supplied and non-empty, then the Windows and macOS GUI installers will display it along with checkbox to enable or disable the execution of the @@ -387,7 +351,6 @@ This option has no effect on `SH` installers. ### `post_install` - Path to a post-install script. Some notes: - For Unix `.sh` installers, the shebang line is respected if present; @@ -414,7 +377,6 @@ If necessary, you can activate the installed `base` environment like this: ### `post_install_desc` - A description of the purpose of the supplied `post_install` script. If this string is supplied and non-empty, then the Windows and macOS GUI installers will display it along with checkbox to enable or disable the execution of the @@ -425,7 +387,6 @@ This option has no effect on `SH` installers. ### `pre_uninstall` - Path to a pre uninstall script. This is only supported for on Windows, and must be a `.bat` file. Installation path is available as `%PREFIX%`. Metadata about the installer can be found in the `%INSTALLER_NAME%`, @@ -434,7 +395,6 @@ Metadata about the installer can be found in the `%INSTALLER_NAME%`, ### `default_prefix` - Set default install prefix. On Linux, if not provided, the default prefix is `${HOME}/` (or, if `HOME` is not set, `/opt/`). On Windows, this is used only for "Just Me" installation; for "All Users" installation, @@ -444,7 +404,6 @@ installation time. ### `default_prefix_domain_user` - Set default installation prefix for domain user. If not provided, the installation prefix for domain user will be `%LOCALAPPDATA%\`. By default, it is different from the `default_prefix` value to avoid installing @@ -453,7 +412,6 @@ at installation time. Windows only. ### `default_prefix_all_users` - Set default installation prefix for All Users installation. If not provided, the installation prefix for all users installation will be `%ALLUSERSPROFILE%\`. Environment variables will be expanded at installation @@ -461,7 +419,6 @@ time. Windows only. ### `default_location_pkg` - Default installation subdirectory in the chosen volume. In PKG installers, default installation locations are configured differently. The user can choose between a "Just me" installation (which would result in `~/`) or another @@ -475,7 +432,6 @@ macOS only. ### `pkg_domains` - The domains the package can be installed into. For a detailed explanation, see: https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html constructor defaults to `enable_anywhere=true` and `enable_currentUserHome=true`. @@ -484,14 +440,12 @@ macOS only. ### `pkg_name` - Internal identifier for the installer. This is used in the build prefix and will determine part of the default location path. Combine with `default_location_pkg` for more flexibility. If not provided, the value of `name` will be used. (MacOS only) ### `install_path_exists_error_text` - Error message that will be shown if the installation path already exists. You cannot use double quotes or newlines. The placeholder `{CHOSEN_PATH}` is available and set to the destination causing the error. Defaults to: @@ -503,7 +457,6 @@ available and set to the destination causing the error. Defaults to: ### `progress_notifications` - Whether to show UI notifications on PKG installers. On large installations, the progress bar reaches ~90% very quickly and stays there for a long time. This might look like the installer froze. This option enables UI notifications @@ -512,7 +465,6 @@ so the user receives updates after each command executed by the installer. ### `welcome_image` - Path to an image in any common image format (`.png`, `.jpg`, `.tif`, etc.) to be used as the welcome image for the Windows and PKG installers. The image is re-sized to 164 x 314 pixels on Windows and 1227 x 600 on Macos. @@ -522,42 +474,35 @@ PKG installers, set this key to `""` (empty string). ### `header_image` - Like `welcome_image` for Windows, re-sized to 150 x 57 pixels. ### `icon_image` - Like `welcome_image` for Windows, re-sized to 256 x 256 pixels. ### `default_image_color` - The color of the default images (when not providing explicit image files) used on Windows. Possible values are `red`, `green`, `blue`, `yellow`. The default is `blue`. ### `welcome_image_text` - If `welcome_image` is not provided, use this text when generating the image (Windows and PKG only). Defaults to `name` on Windows. ### `header_image_text` - If `header_image` is not provided, use this text when generating the image (Windows only). Defaults to `name`. ### `initialize_conda` - Add an option to the installer so the user can choose whether to run `conda init` after the install. See also `initialize_by_default`. ### `initialize_by_default` - Whether to add the installation to the PATH environment variable. The default is true for GUI installers (msi, pkg) and False for shell installers. The user is able to change the default during interactive installation. NOTE: For Windows, @@ -565,20 +510,17 @@ is able to change the default during interactive installation. NOTE: For Windows ### `register_python` - Whether to offer the user an option to register the installed Python instance as the system's default Python. (Windows only) ### `register_python_default` - Default choice for whether to register the installed Python instance as the system's default Python. The user is still able to change this during interactive installation. (Windows only). ### `check_path_length` - Check the length of the path where the distribution is installed to ensure nodejs can be installed. Raise a message to request shorter path (less than 46 character) or enable long path on windows > 10 (require admin right). Default is True. (Windows only). @@ -588,7 +530,6 @@ Read notes about the particularities of Windows silent mode `/S` in the ### `check_path_spaces` - Check if the path where the distribution is installed contains spaces. Default is True. To allow installations with spaces, change to False. Note that: @@ -600,14 +541,12 @@ Read notes about the particularities of Windows silent mode `/S` in the ### `nsis_template` - If `nsis_template` is not provided, constructor uses its default NSIS template. For more complete customization for the installation experience, provide an NSIS template file. (Windows only). ### `welcome_file` - If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the introduction. File can be plain text (.txt), rich text (.rtf) or HTML (.html). If @@ -620,7 +559,6 @@ begins the installation process. ### `welcome_text` - If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the introduction. If this key is missing, it defaults to a message about Anaconda Cloud. @@ -630,7 +568,6 @@ if you set this key to `""` (empty string). ### `readme_file` - If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the welcome screen. File can be plain text (.txt), rich text (.rtf) or HTML (.html). If @@ -639,7 +576,6 @@ both `readme_file` and `readme_text` are provided, `readme_file` takes precedenc ### `readme_text` - If `installer_type` is `pkg` on MacOS, this message will be shown before the license information, right after the welcome screen. If this key is missing, it defaults to a message about Anaconda Cloud. @@ -648,7 +584,6 @@ You can disable it altogether if you set this key to `""` (empty string). ### `post_install_pages` - Adds extra pages to the installers to be shown after installation. For PKG installers, these can be compiled `installer` plug-ins or @@ -660,7 +595,6 @@ They will be inserted as-is before the conclusion page. ### `conclusion_file` - If `installer_type` is `pkg` on MacOS, this message will be shown at the end of the installer upon success. File can be plain text (.txt), rich text (.rtf) or HTML (.html). If both @@ -671,7 +605,6 @@ If the installer is for Windows, the file type must be nsi. ### `conclusion_text` - A message that will be shown at the end of the installer upon success. The behaviour is slightly different across installer types: - PKG: If this key is missing, it defaults to a message about Anaconda Cloud. @@ -682,7 +615,6 @@ The behaviour is slightly different across installer types: ### `extra_files` - Extra, non-packaged files that should be added to the installer. If provided as relative paths, they will be considered relative to the directory where `construct.yaml` is. This setting can be passed as a list of: @@ -691,7 +623,6 @@ This setting can be passed as a list of: ### `temp_extra_files` - Temporary files that could be referenced in the installation process (i.e. customized `welcome_file` and `conclusion_file` (see above)) . Should be a list of file paths, relative to the directory where `construct.yaml` is. In Windows, these @@ -702,7 +633,6 @@ Supports the same values as `extra_files`. ### `build_outputs` - Additional artifacts to be produced after building the installer. It expects either a list of strings or single-key dictionaries: Allowed keys are: @@ -724,12 +654,10 @@ Allowed keys are: ### `uninstall_with_conda_exe` - Use the standalone binary to perform the uninstallation. Requires conda-standalone 24.11.0 or newer. - ## Available selectors - `aarch64` - `arm64` diff --git a/scripts/make_docs.py b/scripts/make_docs.py index f9770653f..a059d221e 100644 --- a/scripts/make_docs.py +++ b/scripts/make_docs.py @@ -3,7 +3,7 @@ import jinja2 -from constructor import construct +from constructor.construct import ConstructorConfiguration, ns_platform from constructor.conda_interface import SUPPORTED_PLATFORMS REPO_ROOT = dirname(dirname(__file__)) @@ -11,7 +11,7 @@ sys.path.insert(0, REPO_ROOT) -valid_selectors = construct.ns_platform(sys.platform) +valid_selectors = ns_platform(sys.platform) template = """