Skip to content

Commit

Permalink
Added support for script_env_variables (#718)
Browse files Browse the repository at this point in the history
Support declaring environment variables for pre- and post-install scripts
  • Loading branch information
jlstevens authored Sep 29, 2023
1 parent 99e966e commit 18e97b2
Show file tree
Hide file tree
Showing 15 changed files with 144 additions and 0 deletions.
24 changes: 24 additions & 0 deletions CONSTRUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,30 @@ _type:_ string<br/>
Application name in the Windows "Programs and Features" control panel.
Defaults to `${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})`.

### `script_env_variables`

_required:_ no<br/>
_type:_ dictionary<br/>

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`

_required:_ no<br/>
Expand Down
20 changes: 20 additions & 0 deletions constructor/construct.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,26 @@
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
Expand Down
2 changes: 2 additions & 0 deletions constructor/header.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ fi

# Export variables to make installer metadata available to pre/post install scripts
# NOTE: If more vars are added, make sure to update the examples/scripts tests too

_SCRIPT_ENV_VARIABLES_='' # Templated extra environment variable(s)
export INSTALLER_NAME='__NAME__'
export INSTALLER_VER='__VERSION__'
export INSTALLER_PLAT='__PLAT__'
Expand Down
1 change: 1 addition & 0 deletions constructor/nsis/main.nsi.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,7 @@ Section "Install"
File /nonfatal /r __INDEX_CACHE__
File /r __REPODATA_RECORD__

@SCRIPT_ENV_VARIABLES@
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("CONDA_SAFETY_CHECKS", "disabled").r0'
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("CONDA_EXTRA_SAFETY_CHECKS", "no").r0'
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("CONDA_PKGS_DIRS", "$INSTDIR\pkgs")".r0'
Expand Down
1 change: 1 addition & 0 deletions constructor/osx/run_user_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export INSTALLER_VER="__VERSION__"
export INSTALLER_PLAT="__PLAT__"
export INSTALLER_TYPE="PKG"
export PRE_OR_POST="__PRE_OR_POST__"
_SCRIPT_ENV_VARIABLES_='' # Templated extra environment variable(s)

# Run user-provided script
if [ -f "$PREFIX/pkgs/user_${PRE_OR_POST}" ]; then
Expand Down
4 changes: 4 additions & 0 deletions constructor/osxpkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,12 @@ def move_script(src, dst, info, ensure_shebang=False, user_script_type=None):
'CONSTRUCTOR_VERSION': info['CONSTRUCTOR_VERSION'],
}
data = preprocess(data, ppd)
custom_variables = info.get('script_env_variables', {})
data = fill_template(data, replace)

data = data.replace("_SCRIPT_ENV_VARIABLES_=''", '\n'.join(
[f"export {key}='{value}'" for key, value in custom_variables.items()]))

with open(dst, 'w') as fo:
if (
ensure_shebang
Expand Down
3 changes: 3 additions & 0 deletions constructor/shar.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,11 @@ def get_header(conda_exec, tarball, info):

data = read_header_template()
data = preprocess(data, ppd)
custom_variables = info.get('script_env_variables', {})
data = fill_template(data, replace)

data = data.replace("_SCRIPT_ENV_VARIABLES_=''", '\n'.join(
[f"export {key}='{value}'" for key, value in custom_variables.items()]))
return data


Expand Down
18 changes: 18 additions & 0 deletions constructor/winexe.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,23 @@ def insert_tempfiles_commands(paths: os.PathLike) -> List[str]:
return lines


def setup_script_env_variables(info) -> List[str]:
"""Helper function to insert extra environment variables into nsis template.
Args:
info: Dictionary of information parsed from construct.yaml
Returns:
List[str]: Commands to be inserted into nsi template
"""
lines = []
for name, value in info.get('script_env_variables', {}).items():
lines.append(
"System::Call 'kernel32::SetEnvironmentVariable(t,t)i"
+ f"""("{name}", {str_esc(value)}).r0'""")
return lines


def custom_nsi_insert_from_file(filepath: os.PathLike) -> str:
"""Insert NSI script commands from file.
Expand Down Expand Up @@ -332,6 +349,7 @@ def make_nsi(info, dir_path, extra_files=None, temp_extra_files=None):
'${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})'
)),
('@EXTRA_FILES@', '\n '.join(extra_files_commands(extra_files, dir_path))),
('@SCRIPT_ENV_VARIABLES@', '\n '.join(setup_script_env_variables(info))),
(
'@CUSTOM_WELCOME_FILE@',
custom_nsi_insert_from_file(info.get('welcome_file', ''))
Expand Down
24 changes: 24 additions & 0 deletions docs/source/construct-yaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,30 @@ _type:_ string<br/>
Application name in the Windows "Programs and Features" control panel.
Defaults to `${NAME} ${VERSION} (Python ${PYVERSION} ${ARCH})`.

### `script_env_variables`

_required:_ no<br/>
_type:_ dictionary<br/>

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`

_required:_ no<br/>
Expand Down
8 changes: 8 additions & 0 deletions examples/scripts/construct.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ channels:
- http://repo.anaconda.com/pkgs/main/
specs:
- python

script_env_variables:
CUSTOM_VARIABLE_1: FIR$T-CUSTOM_'\''STRING'\'' WITH SPACES AND @*! "CHARACTERS" # [not win]
CUSTOM_VARIABLE_2: $ECOND-CUSTOM_'\''STRING'\'' WITH SPACES AND @*! "CHARACTERS" # [not win]
CUSTOM_VARIABLE_1: FIR$T-CUSTOM_STRING WITH SPACES AND @*! CHARACTERS # [win]
CUSTOM_VARIABLE_2: $ECOND-CUSTOM_STRING WITH SPACES AND @*! CHARACTERS # [win]


pre_install: pre_install.sh # [unix]
pre_install: pre_install.bat # [win]
pre_install_desc: "Adding this description makes the script selectable in the UI"
Expand Down
2 changes: 2 additions & 0 deletions examples/scripts/post_install.bat
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ if not "%INSTALLER_VER%" == "X" exit 1
if not "%INSTALLER_PLAT%" == "win-64" exit 1
if not "%INSTALLER_TYPE%" == "EXE" exit 1
if "%PREFIX%" == "" exit 1
if not "%CUSTOM_VARIABLE_1%" == "FIR$T-CUSTOM_STRING WITH SPACES AND @*! CHARACTERS" exit 1
if not "%CUSTOM_VARIABLE_2%" == "$ECOND-CUSTOM_STRING WITH SPACES AND @*! CHARACTERS" exit 1
if not exist "%PREFIX%\pre_install_sentinel.txt" exit 1
7 changes: 7 additions & 0 deletions examples/scripts/post_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@ echo "INSTALLER_NAME=${INSTALLER_NAME}"
echo "INSTALLER_VER=${INSTALLER_VER}"
echo "INSTALLER_PLAT=${INSTALLER_PLAT}"
echo "INSTALLER_TYPE=${INSTALLER_TYPE}"
echo "CUSTOM_VARIABLE_1=${CUSTOM_VARIABLE_1}"
echo "CUSTOM_VARIABLE_2=${CUSTOM_VARIABLE_2}"
echo "PREFIX=${PREFIX}"

test "${INSTALLER_NAME}" = "Scripts"
test "${INSTALLER_VER}" = "X"
# shellcheck disable=SC2016 # String interpolation disabling is deliberate
test "${CUSTOM_VARIABLE_1}" = 'FIR$T-CUSTOM_'\''STRING'\'' WITH SPACES AND @*! "CHARACTERS"'
# shellcheck disable=SC2016 # String interpolation disabling is deliberate
test "${CUSTOM_VARIABLE_2}" = '$ECOND-CUSTOM_'\''STRING'\'' WITH SPACES AND @*! "CHARACTERS"'

if [[ $(uname -s) == Linux ]]; then
if [[ ${INSTALLER_PLAT} != linux-* ]]; then
exit 1
Expand Down
2 changes: 2 additions & 0 deletions examples/scripts/pre_install.bat
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ if not "%INSTALLER_VER%" == "X" exit 1
if not "%INSTALLER_PLAT%" == "win-64" exit 1
if not "%INSTALLER_TYPE%" == "EXE" exit 1
if "%PREFIX%" == "" exit 1
if not "%CUSTOM_VARIABLE_1%" == "FIR$T-CUSTOM_STRING WITH SPACES AND @*! CHARACTERS" exit 1
if not "%CUSTOM_VARIABLE_2%" == "$ECOND-CUSTOM_STRING WITH SPACES AND @*! CHARACTERS" exit 1
echo Added by pre-install script > "%PREFIX%\pre_install_sentinel.txt"
7 changes: 7 additions & 0 deletions examples/scripts/pre_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@ echo "INSTALLER_NAME=${INSTALLER_NAME}"
echo "INSTALLER_VER=${INSTALLER_VER}"
echo "INSTALLER_PLAT=${INSTALLER_PLAT}"
echo "INSTALLER_TYPE=${INSTALLER_TYPE}"
echo "CUSTOM_VARIABLE_1=${CUSTOM_VARIABLE_1}"
echo "CUSTOM_VARIABLE_2=${CUSTOM_VARIABLE_2}"
echo "PREFIX=${PREFIX}"

test "${INSTALLER_NAME}" = "Scripts"
test "${INSTALLER_VER}" = "X"
# shellcheck disable=SC2016 # String interpolation disabling is deliberate
test "${CUSTOM_VARIABLE_1}" = 'FIR$T-CUSTOM_'\''STRING'\'' WITH SPACES AND @*! "CHARACTERS"'
# shellcheck disable=SC2016 # String interpolation disabling is deliberate
test "${CUSTOM_VARIABLE_2}" = '$ECOND-CUSTOM_'\''STRING'\'' WITH SPACES AND @*! "CHARACTERS"'

if [[ $(uname -s) == Linux ]]; then
if [[ ${INSTALLER_PLAT} != linux-* ]]; then
exit 1
Expand Down
21 changes: 21 additions & 0 deletions news/718-script_env_variables-option
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
### Enhancements

* Added support for `script_env_variables` allowing specification of
environment variables in the `construct.yaml` for use by pre- and
post-install scripts.

### Bug fixes

* <news item>

### Deprecations

* <news item>

### Docs

* <news item>

### Other

* <news item>

0 comments on commit 18e97b2

Please sign in to comment.