From 1702af86ed56eb14ffed9ee35954261552d78c4c Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Fri, 7 May 2021 13:32:37 +0100 Subject: [PATCH 01/72] Fixes to support PREFIX containing spaces --- constructor/header.sh | 177 ++++++++++++------------------------------ constructor/utils.py | 2 +- 2 files changed, 50 insertions(+), 129 deletions(-) diff --git a/constructor/header.sh b/constructor/header.sh index b32badf7f..9aef87099 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -56,7 +56,7 @@ Installs __NAME__ __VERSION__ #if not keep_pkgs -k do not clear the package cache after installation #endif --p PREFIX install prefix, defaults to $PREFIX, must not contain spaces. +-p PREFIX install prefix, defaults to $PREFIX -s skip running pre/post-link/install scripts -u update an existing installation #if has_conda @@ -64,106 +64,44 @@ Installs __NAME__ __VERSION__ #endif " -if which getopt > /dev/null 2>&1; then - OPTS=$(getopt bifhkp:sut "$*" 2>/dev/null) - if [ ! $? ]; then - printf "%s\\n" "$USAGE" - exit 2 - fi - - eval set -- "$OPTS" - - while true; do - case "$1" in - -h) - printf "%s\\n" "$USAGE" - exit 2 - ;; - -b) - BATCH=1 - shift - ;; - -i) - BATCH=0 - shift - ;; - -f) - FORCE=1 - shift - ;; - -k) - KEEP_PKGS=1 - shift - ;; - -p) - PREFIX="$2" - shift - shift - ;; - -s) - SKIP_SCRIPTS=1 - shift - ;; - -u) - FORCE=1 - shift - ;; -#if has_conda - -t) - TEST=1 - shift - ;; -#endif - --) - shift - break - ;; - *) - printf "ERROR: did not recognize option '%s', please try -h\\n" "$1" - exit 1 - ;; - esac - done -else - while getopts "bifhkp:sut" x; do - case "$x" in - h) - printf "%s\\n" "$USAGE" - exit 2 +while getopts "bifhkp:sut" x; do + case "$x" in + h) + printf "%s\\n" "$USAGE" + exit 2 + ;; + b) + BATCH=1 + ;; + i) + BATCH=0 + ;; + f) + FORCE=1 + ;; + k) + KEEP_PKGS=1 + ;; + p) + PREFIX="$OPTARG" + ;; + s) + SKIP_SCRIPTS=1 + ;; + u) + FORCE=1 ;; - b) - BATCH=1 - ;; - i) - BATCH=0 - ;; - f) - FORCE=1 - ;; - k) - KEEP_PKGS=1 - ;; - p) - PREFIX="$OPTARG" - ;; - s) - SKIP_SCRIPTS=1 - ;; - u) - FORCE=1 - ;; #if has_conda - t) - TEST=1 - ;; + t) + TEST=1 + ;; #endif - ?) - printf "ERROR: did not recognize option '%s', please try -h\\n" "$x" - exit 1 - ;; - esac - done -fi + ?) + printf "ERROR: did not recognize option '%s', please try -h\\n" "$x" + exit 1 + ;; + esac +done # For testing, keep the package cache around longer CLEAR_AFTER_TEST=0 @@ -341,25 +279,10 @@ EOF printf "[%s] >>> " "$PREFIX" read -r user_prefix if [ "$user_prefix" != "" ]; then - case "$user_prefix" in - *\ * ) - printf "ERROR: Cannot install into directories with spaces\\n" >&2 - exit 1 - ;; - *) - eval PREFIX="$user_prefix" - ;; - esac + PREFIX="$user_prefix" fi fi # !BATCH -case "$PREFIX" in - *\ * ) - printf "ERROR: Cannot install into directories with spaces\\n" >&2 - exit 1 - ;; -esac - if [ "$FORCE" = "0" ] && [ -e "$PREFIX" ]; then printf "ERROR: File or directory already exists: '%s'\\n" "$PREFIX" >&2 printf "If you want to update an existing installation, use the -u option.\\n" >&2 @@ -368,7 +291,6 @@ elif [ "$FORCE" = "1" ] && [ -e "$PREFIX" ]; then REINSTALL=1 fi - if ! mkdir -p "$PREFIX"; then printf "ERROR: Could not create directory: '%s'\\n" "$PREFIX" >&2 exit 1 @@ -437,7 +359,7 @@ chmod +x "$CONDA_EXEC" export TMP_BACKUP="$TMP" export TMP=$PREFIX/install_tmp -mkdir -p $TMP +mkdir -p "$TMP" # the second binary payload: the tarball of packages printf "Unpacking payload ...\n" @@ -471,7 +393,6 @@ else fi #endif -PYTHON="$PREFIX/bin/python" MSGS="$PREFIX/.messages.txt" touch "$MSGS" export FORCE @@ -489,8 +410,8 @@ CONDA_PKGS_DIRS="$PREFIX/pkgs" \ "$CONDA_EXEC" install --offline --file "$PREFIX/pkgs/env.txt" -yp "$PREFIX" || exit 1 if [ "$KEEP_PKGS" = "0" ]; then - rm -fr $PREFIX/pkgs/*.tar.bz2 - rm -fr $PREFIX/pkgs/*.conda + rm -f "$PREFIX/pkgs/*.tar.bz2" + rm -f "$PREFIX/pkgs/*.conda" fi __INSTALL_COMMANDS__ @@ -499,14 +420,14 @@ POSTCONDA="$PREFIX/postconda.tar.bz2" "$CONDA_EXEC" constructor --prefix "$PREFIX" --extract-tarball < "$POSTCONDA" || exit 1 rm -f "$POSTCONDA" -rm -f $PREFIX/conda.exe -rm -f $PREFIX/pkgs/env.txt +rm -f "$CONDA_EXEC" +rm -f "$PREFIX/pkgs/env.txt" -rm -rf $PREFIX/install_tmp +rm -rf "$PREFIX/install_tmp" export TMP="$TMP_BACKUP" #if has_conda -mkdir -p $PREFIX/envs +mkdir -p "$PREFIX/envs" #endif #The templating doesn't support nested if statements @@ -537,7 +458,7 @@ if [ "$KEEP_PKGS" = "0" ]; then else # Attempt to delete the empty temporary directories in the package cache # These are artifacts of the constructor --extract-conda-pkgs - find $PREFIX/pkgs -type d -empty -exec rmdir {} \; 2>/dev/null || : + find "$PREFIX/pkgs" -type d -empty -exec rmdir {} \; 2>/dev/null || : fi printf "installation finished.\\n" @@ -583,13 +504,13 @@ if [ "$BATCH" = "0" ]; then printf "\\n" else case $SHELL in - *zsh) $PREFIX/bin/conda init zsh ;; - *) $PREFIX/bin/conda init ;; + *zsh) "$PREFIX/bin/conda" init zsh ;; + *) "$PREFIX/bin/conda" init ;; esac if [ -f "$PREFIX/bin/mamba" ]; then case $SHELL in - *zsh) $PREFIX/bin/mamba init zsh ;; - *) $PREFIX/bin/mamba init ;; + *zsh) "$PREFIX/bin/mamba" init zsh ;; + *) "$PREFIX/bin/mamba" init ;; esac fi fi diff --git a/constructor/utils.py b/constructor/utils.py index 7ede63b57..2a8f47691 100644 --- a/constructor/utils.py +++ b/constructor/utils.py @@ -116,7 +116,7 @@ def add_condarc(info): yield 'FileWrite $CONDARC "%s$\\r$\\n"' % line yield 'FileClose $CONDARC' else: - yield 'cat <$PREFIX/.condarc' + yield 'cat <"$PREFIX/.condarc"' for line in condarc.splitlines(): yield line yield 'EOF' From 1dbe1a530c97f736131fb2d6bda34ac1e0cd906b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Mon, 15 Aug 2022 11:07:38 +0200 Subject: [PATCH 02/72] bring back the getopt compatibility --- constructor/header.sh | 134 ++++++++++++++++++++++++++++++------------ 1 file changed, 98 insertions(+), 36 deletions(-) diff --git a/constructor/header.sh b/constructor/header.sh index 13a50c9c7..69c5f2d34 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -64,44 +64,106 @@ Installs __NAME__ __VERSION__ #endif " -while getopts "bifhkp:sut" x; do - case "$x" in - h) - printf "%s\\n" "$USAGE" - exit 2 - ;; - b) - BATCH=1 - ;; - i) - BATCH=0 - ;; - f) - FORCE=1 - ;; - k) - KEEP_PKGS=1 - ;; - p) - PREFIX="$OPTARG" - ;; - s) - SKIP_SCRIPTS=1 - ;; - u) - FORCE=1 - ;; +if which getopt > /dev/null 2>&1; then + OPTS=$(getopt bifhkp:sut "$*" 2>/dev/null) + if [ ! $? ]; then + printf "%s\\n" "$USAGE" + exit 2 + fi + + eval set -- "$OPTS" + + while true; do + case "$1" in + -h) + printf "%s\\n" "$USAGE" + exit 2 + ;; + -b) + BATCH=1 + shift + ;; + -i) + BATCH=0 + shift + ;; + -f) + FORCE=1 + shift + ;; + -k) + KEEP_PKGS=1 + shift + ;; + -p) + PREFIX="$2" + shift + shift + ;; + -s) + SKIP_SCRIPTS=1 + shift + ;; + -u) + FORCE=1 + shift + ;; #if has_conda - t) - TEST=1 - ;; + -t) + TEST=1 + shift + ;; #endif - ?) - printf "ERROR: did not recognize option '%s', please try -h\\n" "$x" - exit 1 + --) + shift + break + ;; + *) + printf "ERROR: did not recognize option '%s', please try -h\\n" "$1" + exit 1 + ;; + esac + done +else + while getopts "bifhkp:sut" x; do + case "$x" in + h) + printf "%s\\n" "$USAGE" + exit 2 ;; - esac -done + b) + BATCH=1 + ;; + i) + BATCH=0 + ;; + f) + FORCE=1 + ;; + k) + KEEP_PKGS=1 + ;; + p) + PREFIX="$OPTARG" + ;; + s) + SKIP_SCRIPTS=1 + ;; + u) + FORCE=1 + ;; +#if has_conda + t) + TEST=1 + ;; +#endif + ?) + printf "ERROR: did not recognize option '%s', please try -h\\n" "$x" + exit 1 + ;; + esac + done +fi # For testing, keep the package cache around longer CLEAR_AFTER_TEST=0 @@ -445,7 +507,7 @@ POSTCONDA="$PREFIX/postconda.tar.bz2" "$CONDA_EXEC" constructor --prefix "$PREFIX" --extract-tarball < "$POSTCONDA" || exit 1 rm -f "$POSTCONDA" -rm -f $PREFIX/conda.exe +rm -f "$CONDA_EXEC" rm -rf "$PREFIX/install_tmp" export TMP="$TMP_BACKUP" From 56bc9f6b8eec6d732602951c30722b8984ddcfb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Mon, 15 Aug 2022 11:17:40 +0200 Subject: [PATCH 03/72] remove getopt parsing, always use getopts --- constructor/header.sh | 136 ++++++++++++------------------------------ 1 file changed, 39 insertions(+), 97 deletions(-) diff --git a/constructor/header.sh b/constructor/header.sh index 69c5f2d34..c915b0ceb 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -64,106 +64,48 @@ Installs __NAME__ __VERSION__ #endif " -if which getopt > /dev/null 2>&1; then - OPTS=$(getopt bifhkp:sut "$*" 2>/dev/null) - if [ ! $? ]; then - printf "%s\\n" "$USAGE" - exit 2 - fi - - eval set -- "$OPTS" - - while true; do - case "$1" in - -h) - printf "%s\\n" "$USAGE" - exit 2 - ;; - -b) - BATCH=1 - shift - ;; - -i) - BATCH=0 - shift - ;; - -f) - FORCE=1 - shift - ;; - -k) - KEEP_PKGS=1 - shift - ;; - -p) - PREFIX="$2" - shift - shift - ;; - -s) - SKIP_SCRIPTS=1 - shift - ;; - -u) - FORCE=1 - shift - ;; -#if has_conda - -t) - TEST=1 - shift - ;; -#endif - --) - shift - break - ;; - *) - printf "ERROR: did not recognize option '%s', please try -h\\n" "$1" - exit 1 - ;; - esac - done -else - while getopts "bifhkp:sut" x; do - case "$x" in - h) - printf "%s\\n" "$USAGE" - exit 2 +# We used to have a getopt version here, falling back to getopts if needed +# However getopt is not standardized and the version on Mac has different +# behaviour. getopts is good enough for what we need :) +# More info: https://unix.stackexchange.com/questions/62950/ +while getopts "bifhkp:sut" x; do + case "$x" in + h) + printf "%s\\n" "$USAGE" + exit 2 + ;; + b) + BATCH=1 + ;; + i) + BATCH=0 + ;; + f) + FORCE=1 + ;; + k) + KEEP_PKGS=1 + ;; + p) + PREFIX="$OPTARG" + ;; + s) + SKIP_SCRIPTS=1 + ;; + u) + FORCE=1 ;; - b) - BATCH=1 - ;; - i) - BATCH=0 - ;; - f) - FORCE=1 - ;; - k) - KEEP_PKGS=1 - ;; - p) - PREFIX="$OPTARG" - ;; - s) - SKIP_SCRIPTS=1 - ;; - u) - FORCE=1 - ;; #if has_conda - t) - TEST=1 - ;; + t) + TEST=1 + ;; #endif - ?) - printf "ERROR: did not recognize option '%s', please try -h\\n" "$x" - exit 1 - ;; - esac - done -fi + ?) + printf "ERROR: did not recognize option '%s', please try -h\\n" "$x" + exit 1 + ;; + esac +done # For testing, keep the package cache around longer CLEAR_AFTER_TEST=0 From d1ad9115fcc97d5c7d76c42e6ef74b8df1ffa4be Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Wed, 17 Aug 2022 01:05:21 +0100 Subject: [PATCH 04/72] Double-quote variables in new code --- constructor/header.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/constructor/header.sh b/constructor/header.sh index c915b0ceb..58e58bfbe 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -419,9 +419,9 @@ rm -f "$PREFIX/pkgs/env.txt" __INSTALL_COMMANDS__ #if has_conda -mkdir -p $PREFIX/envs -for env_pkgs in ${PREFIX}/pkgs/envs/*/; do - env_name=$(basename ${env_pkgs}) +mkdir -p "$PREFIX/envs" +for env_pkgs in "${PREFIX}"/pkgs/envs/*/; do + env_name=$(basename "${env_pkgs}") if [[ "${env_name}" == "*" ]]; then continue fi From a8514f733945ce47f2657eb84d53d1d9026dcfaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 11:25:28 +0200 Subject: [PATCH 05/72] quote some more stuff --- constructor/header.sh | 4 ++-- constructor/osx/post_extract.sh | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/constructor/header.sh b/constructor/header.sh index 58e58bfbe..eaa46a86f 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -25,7 +25,7 @@ export INSTALLER_PLAT="__PLAT__" THIS_DIR=$(DIRNAME=$(dirname "$0"); cd "$DIRNAME"; pwd) THIS_FILE=$(basename "$0") THIS_PATH="$THIS_DIR/$THIS_FILE" -PREFIX=__DEFAULT_PREFIX__ +PREFIX="__DEFAULT_PREFIX__" #if batch_mode BATCH=1 #else @@ -362,7 +362,7 @@ extract_range $boundary0 $boundary1 > "$CONDA_EXEC" chmod +x "$CONDA_EXEC" export TMP_BACKUP="$TMP" -export TMP=$PREFIX/install_tmp +export "TMP=$PREFIX/install_tmp" mkdir -p "$TMP" # the second binary payload: the tarball of packages diff --git a/constructor/osx/post_extract.sh b/constructor/osx/post_extract.sh index 7c3bc0782..3b1dda3c3 100644 --- a/constructor/osx/post_extract.sh +++ b/constructor/osx/post_extract.sh @@ -19,8 +19,8 @@ CONDA_EXEC="$PREFIX/conda.exe" chmod +x "$CONDA_EXEC" # Create a blank history file so conda thinks this is an existing env -mkdir -p $PREFIX/conda-meta -touch $PREFIX/conda-meta/history +mkdir -p "$PREFIX/conda-meta" +touch "$PREFIX/conda-meta/history" # Extract the conda packages but avoiding the overwriting of the # custom metadata we have already put in place @@ -49,10 +49,10 @@ rm -f "$PREFIX/env.txt" # Same, but for the extra environments -mkdir -p $PREFIX/envs +mkdir -p "$PREFIX/envs" -for env_pkgs in ${PREFIX}/pkgs/envs/*/; do - env_name=$(basename ${env_pkgs}) +for env_pkgs in "${PREFIX}/pkgs/envs/*/"; do + env_name=$(basename "${env_pkgs}") if [[ "${env_name}" == "*" ]]; then continue fi @@ -81,7 +81,7 @@ done # Cleanup! rm -f "$CONDA_EXEC" -find "$PREFIX/pkgs" -type d -empty -exec rmdir {} \; 2>/dev/null || : +find "$PREFIX/pkgs" -type d -empty -exec rmdir "{}" \; 2>/dev/null || : __WRITE_CONDARC__ @@ -93,7 +93,7 @@ fi # This is unneeded for the default install to ~, but if the user changes the # install location, the permissions will default to root unless this is done. -chown -R $USER "$PREFIX" +chown -R "$USER" "$PREFIX" notify "Done! Installation is available in $PREFIX." echo "installation to $PREFIX finished." From 3aadafe01f525c221dcdfbe23cab9f720a67e196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 11:47:01 +0200 Subject: [PATCH 06/72] (re-)enable space checks in all platforms, but default to False --- CONSTRUCT.md | 2 +- constructor/construct.py | 2 +- constructor/header.sh | 21 ++++++++++++++++++++ constructor/osx/preinstall.sh | 2 ++ constructor/osxpkg.py | 37 ++++++++++++++++++++++++----------- constructor/shar.py | 1 + constructor/winexe.py | 2 +- 7 files changed, 53 insertions(+), 14 deletions(-) diff --git a/CONSTRUCT.md b/CONSTRUCT.md index 7b6054591..aa37e6121 100644 --- a/CONSTRUCT.md +++ b/CONSTRUCT.md @@ -487,7 +487,7 @@ or enable long path on windows > 10 (require admin right). Default is True. (Win _required:_ no
_type:_ boolean
Check if the path where the distribution is installed contains spaces and show a warning -if any spaces are found. Default is True. (Windows only). +(EXE, SH installers) or error (PKG installer) if any spaces are found. Default is False. ## `nsis_template` diff --git a/constructor/construct.py b/constructor/construct.py index b7f16ddd2..e519ba40c 100644 --- a/constructor/construct.py +++ b/constructor/construct.py @@ -384,7 +384,7 @@ ('check_path_spaces', False, bool, ''' Check if the path where the distribution is installed contains spaces and show a warning -if any spaces are found. Default is True. (Windows only). +(EXE, SH installers) or error (PKG installer) if any spaces are found. Default is False. '''), ('nsis_template', False, str, ''' diff --git a/constructor/header.sh b/constructor/header.sh index eaa46a86f..750a173ce 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -283,10 +283,31 @@ EOF printf "[%s] >>> " "$PREFIX" read -r user_prefix if [ "$user_prefix" != "" ]; then +#if check_path_spaces is True + case "$user_prefix" in + *\ * ) + printf "ERROR: Cannot install into directories with spaces\\n" >&2 + exit 1 + ;; + *) + eval PREFIX="$user_prefix" + ;; + esac +#else PREFIX="$user_prefix" +#endif fi fi # !BATCH +#if check_path_spaces is True +case "$PREFIX" in + *\ * ) + printf "ERROR: Cannot install into directories with spaces\\n" >&2 + exit 1 + ;; +esac +#endif + if [ "$FORCE" = "0" ] && [ -e "$PREFIX" ]; then printf "ERROR: File or directory already exists: '%s'\\n" "$PREFIX" >&2 printf "If you want to update an existing installation, use the -u option.\\n" >&2 diff --git a/constructor/osx/preinstall.sh b/constructor/osx/preinstall.sh index da7bae9c1..93e49e260 100644 --- a/constructor/osx/preinstall.sh +++ b/constructor/osx/preinstall.sh @@ -26,6 +26,7 @@ end") exit 1 fi +#if check_path_spaces is True # Check if the path has spaces case "$2" in *\ * ) @@ -44,3 +45,4 @@ end") ;; esac +#endif diff --git a/constructor/osxpkg.py b/constructor/osxpkg.py index 42b459845..b0a9de763 100644 --- a/constructor/osxpkg.py +++ b/constructor/osxpkg.py @@ -7,9 +7,17 @@ from plistlib import dump as plist_dump from tempfile import NamedTemporaryFile -import constructor.preconda as preconda -from constructor.imaging import write_images -from constructor.utils import add_condarc, get_final_channels, rm_rf, approx_size_kb +from . import preconda +from .construct import ns_platform +from .imaging import write_images +from .utils import ( + add_condarc, + get_final_channels, + rm_rf, + approx_size_kb, + preprocess, + fill_template, +) OSX_DIR = join(dirname(__file__), "osx") @@ -236,15 +244,13 @@ def move_script(src, dst, info): """ with open(src) as fi: data = fi.read() - + + # ppd hosts the conditions for the #if/#else/#endif preprocessors on scripts + ppd = ns_platform(info['_platform']) + ppd['check_path_spaces'] = info.get("check_path_spaces", False) + # This is necessary for when installing on case-sensitive macOS filesystems. pkg_name_lower = info.get("pkg_name", info['name']).lower() - data = data.replace('__NAME_LOWER__', pkg_name_lower) - data = data.replace('__VERSION__', info['version']) - data = data.replace('__NAME__', info['name']) - data = data.replace('__CHANNELS__', ','.join(get_final_channels(info))) - data = data.replace('__WRITE_CONDARC__', '\n'.join(add_condarc(info))) - default_path_exists_error_text = ( "'{CHOSEN_PATH}' already exists. Please, relaunch the installer and " "choose another location in the Destination Select step." @@ -252,7 +258,16 @@ def move_script(src, dst, info): path_exists_error_text = info.get( "install_path_exists_error_text", default_path_exists_error_text ).format(CHOSEN_PATH=f"$2/{pkg_name_lower}") - data = data.replace('__PATH_EXISTS_ERROR_TEXT__', path_exists_error_text) + replace = { + 'NAME': info['name'], + 'NAME_LOWER': pkg_name_lower, + 'VERSION': info['version'], + 'CHANNELS': ','.join(get_final_channels(info)), + 'WRITE_CONDARC': '\n'.join(add_condarc(info)), + 'PATH_EXISTS_ERROR_TEXT': path_exists_error_text + } + data = preprocess(data, ppd) + data = fill_template(data, replace) with open(dst, 'w') as fo: fo.write(data) diff --git a/constructor/shar.py b/constructor/shar.py index aa8929814..0809cd31b 100644 --- a/constructor/shar.py +++ b/constructor/shar.py @@ -58,6 +58,7 @@ def get_header(conda_exec, tarball, info): ppd['direct_execute_%s' % key] = has_shebang(info[key]) ppd['initialize_by_default'] = info.get('initialize_by_default', None) ppd['has_conda'] = info['_has_conda'] + ppd['check_path_spaces'] = info.get("check_path_spaces", False) install_lines = list(add_condarc(info)) # Needs to happen first -- can be templated replace = { diff --git a/constructor/winexe.py b/constructor/winexe.py index 9dd90b7b2..0a1b9cd0c 100644 --- a/constructor/winexe.py +++ b/constructor/winexe.py @@ -179,7 +179,7 @@ def make_nsi(info, dir_path, extra_files=()): ppd['initialize_by_default'] = info.get('initialize_by_default', None) ppd['register_python_default'] = info.get('register_python_default', None) ppd['check_path_length'] = info.get('check_path_length', None) - ppd['check_path_spaces'] = info.get('check_path_spaces', True) + ppd['check_path_spaces'] = info.get('check_path_spaces', False) ppd['keep_pkgs'] = info.get('keep_pkgs') or False ppd['post_install_exists'] = bool(info.get('post_install')) data = preprocess(data, ppd) From 0871a2a82cb0e68585649f29ecc6af33b5f2dce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 11:50:44 +0200 Subject: [PATCH 07/72] add news --- news/449-allow-spaces-in-prefix | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 news/449-allow-spaces-in-prefix diff --git a/news/449-allow-spaces-in-prefix b/news/449-allow-spaces-in-prefix new file mode 100644 index 000000000..7590bd62c --- /dev/null +++ b/news/449-allow-spaces-in-prefix @@ -0,0 +1,26 @@ +Enhancements: +------------- + +* Installers will allow spaces in `PREFIX` by default now. + Users can re-enable the old behaviour (reject chosen path if it contained spaces) by setting `check_path_spaces` to `True`. + +Bug fixes: +---------- + +* + +Deprecations: +------------- + +* + +Docs: +----- + +* + +Other: +------ + +* + From 7e20a040867683a8003867684d8a6bc9847e1741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 12:09:14 +0200 Subject: [PATCH 08/72] add tests --- tests/test_header.py | 106 ++++++++++++++++++++++++++++--------------- 1 file changed, 70 insertions(+), 36 deletions(-) diff --git a/tests/test_header.py b/tests/test_header.py index 46604d493..044efaa6e 100644 --- a/tests/test_header.py +++ b/tests/test_header.py @@ -1,41 +1,75 @@ -from constructor.shar import read_header_template, preprocess +import os + import pytest +from constructor.shar import read_header_template +from constructor.utils import preprocess +from constructor.osxpkg import OSX_DIR + -@pytest.mark.parametrize('osx', [False, True]) -@pytest.mark.parametrize('direct_execute_post_install', [False, True]) -@pytest.mark.parametrize('direct_execute_pre_install', [False, True]) -@pytest.mark.parametrize('batch_mode', [False, True]) -@pytest.mark.parametrize('keep_pkgs', [False, True]) -@pytest.mark.parametrize('has_conda', [False, True]) -@pytest.mark.parametrize('has_license', [False, True]) -@pytest.mark.parametrize('initialize_by_default', [False, True]) -@pytest.mark.parametrize('has_post_install', [False, True]) -@pytest.mark.parametrize('has_pre_install', [False, True]) -@pytest.mark.parametrize('arch', ['x86', 'x86_64', ' ppc64le', 's390x', 'aarch64']) +@pytest.mark.parametrize("osx", [False, True]) +@pytest.mark.parametrize("direct_execute_post_install", [False, True]) +@pytest.mark.parametrize("direct_execute_pre_install", [False, True]) +@pytest.mark.parametrize("batch_mode", [False, True]) +@pytest.mark.parametrize("keep_pkgs", [False, True]) +@pytest.mark.parametrize("has_conda", [False, True]) +@pytest.mark.parametrize("has_license", [False, True]) +@pytest.mark.parametrize("initialize_by_default", [False, True]) +@pytest.mark.parametrize("has_post_install", [False, True]) +@pytest.mark.parametrize("has_pre_install", [False, True]) +@pytest.mark.parametrize("check_path_spaces", [False, True]) +@pytest.mark.parametrize("arch", ["x86", "x86_64", "ppc64le", "s390x", "aarch64"]) def test_linux_template_processing( - osx, arch, has_pre_install, has_post_install, - initialize_by_default, has_license, has_conda, keep_pkgs, batch_mode, - direct_execute_pre_install, direct_execute_post_install): + osx, + arch, + has_pre_install, + has_post_install, + initialize_by_default, + has_license, + has_conda, + keep_pkgs, + batch_mode, + direct_execute_pre_install, + direct_execute_post_install, + check_path_spaces, +): template = read_header_template() - processed = preprocess(template, { - 'has_license': has_license, - 'osx': osx, - 'batch_mode': batch_mode, - 'keep_pkgs': keep_pkgs, - 'has_conda': has_conda, - 'x86': arch == 'x86', - 'x86_64': arch == 'x86_64', - 'ppc64le': arch == 'ppc64le', - 's390x': arch == 's390x', - 'aarch64': arch == 'aarch64', - 'linux': not osx, - 'has_pre_install': has_pre_install, - 'direct_execute_pre_install': direct_execute_pre_install, - 'has_post_install': has_post_install, - 'direct_execute_post_install': direct_execute_post_install, - 'initialize_by_default': initialize_by_default, - }) - assert '#if' not in processed - assert '#else' not in processed - assert '#endif' not in processed + processed = preprocess( + template, + { + "has_license": has_license, + "osx": osx, + "batch_mode": batch_mode, + "keep_pkgs": keep_pkgs, + "has_conda": has_conda, + "x86": arch == "x86", + "x86_64": arch == "x86_64", + "ppc64le": arch == "ppc64le", + "s390x": arch == "s390x", + "aarch64": arch == "aarch64", + "linux": not osx, + "has_pre_install": has_pre_install, + "direct_execute_pre_install": direct_execute_pre_install, + "has_post_install": has_post_install, + "direct_execute_post_install": direct_execute_post_install, + "initialize_by_default": initialize_by_default, + "check_path_spaces": check_path_spaces, + }, + ) + assert "#if" not in processed + assert "#else" not in processed + assert "#endif" not in processed + + +@pytest.mark.parametrize("arch", ["x86_64", "arm64"]) +@pytest.mark.parametrize("check_path_spaces", [False, True]) +@pytest.mark.parametrize( + "script", ["post_extract.sh", "preinstall.sh", "update_path.sh", "clean_cache.sh"] +) +def test_osxpkg_template_processing(arch, check_path_spaces, script): + with open(os.path.join(OSX_DIR, script)) as f: + data = f.read() + processed = preprocess(data, {"arch": arch, "check_path_spaces": check_path_spaces}) + assert "#if" not in processed + assert "#else" not in processed + assert "#endif" not in processed From f9565f724caa6762116e0070433d28630d8d8fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 12:12:12 +0200 Subject: [PATCH 09/72] use spaces in examples --- examples/osxpkg/construct.yaml | 4 ++-- scripts/run_examples.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/osxpkg/construct.yaml b/examples/osxpkg/construct.yaml index b3b82e3b8..1eeb21023 100644 --- a/examples/osxpkg/construct.yaml +++ b/examples/osxpkg/construct.yaml @@ -2,9 +2,9 @@ name: osxpkgtest version: 1.2.3 # This config will result in a default install path: -# ~/Library/osx-pkg-test +# "~/Library/osx pkg test" (spaces should work) default_location_pkg: Library -pkg_name: osx-pkg-test +pkg_name: "osx pkg test" channels: - http://repo.anaconda.com/pkgs/main/ diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 09eee5143..b159d26ab 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -83,7 +83,7 @@ def run_examples(keep_artifacts=None): if fpath in tested_files or ext not in ('sh', 'exe', 'pkg'): continue tested_files.add(fpath) - env_dir = tempfile.mkdtemp(dir=output_dir) + env_dir = tempfile.mkdtemp(suffix="s p a c e s", dir=output_dir) rm_rf(env_dir) print('---- testing %s' % fpath) fpath = os.path.join(output_dir, fpath) From d800679748fa491a2ba75318534f21f6c338bf99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 12:25:55 +0200 Subject: [PATCH 10/72] fix examples --- examples/extra_envs/test_install.sh | 2 +- examples/extra_files/test_install.sh | 4 ++-- examples/osxpkg/test_install.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/extra_envs/test_install.sh b/examples/extra_envs/test_install.sh index 6ccccfecb..79c669598 100644 --- a/examples/extra_envs/test_install.sh +++ b/examples/extra_envs/test_install.sh @@ -3,7 +3,7 @@ set -ex # if PREFIX is not defined, then this was called from an OSX PKG installer # $2 is the install location, ($HOME by default) -if [ xxx$PREFIX = 'xxx' ]; then +if [ -z "PREFIX" ]; then PREFIX=$(cd "$2/__NAME_LOWER__"; pwd) fi diff --git a/examples/extra_files/test_install.sh b/examples/extra_files/test_install.sh index 9c1262329..fab798502 100644 --- a/examples/extra_files/test_install.sh +++ b/examples/extra_files/test_install.sh @@ -1,9 +1,9 @@ #!/bin/bash set -ex -# if PREFIX is not defined, then this was called from an OSX PKG installer +# if PREFIX is not defined (or empty), then this was called from an OSX PKG installer # $2 is the install location, ($HOME by default) -if [ xxx$PREFIX = 'xxx' ]; then +if [ -z "PREFIX" ]; then PREFIX=$(echo "$2/__NAME_LOWER__" | sed -e 's,//,/,g') PREFIX=$(cd "$PREFIX"; pwd) fi diff --git a/examples/osxpkg/test_install.sh b/examples/osxpkg/test_install.sh index 574b8e782..89150ed09 100644 --- a/examples/osxpkg/test_install.sh +++ b/examples/osxpkg/test_install.sh @@ -2,7 +2,7 @@ set -ex # $2 is the install location, ($HOME by default) -if [ xxx$PREFIX == 'xxx' ]; then +if [ -z "PREFIX" ]; then PREFIX=$(cd "$2/__NAME_LOWER__"; pwd) fi From 5a69eb5be560f98bd06d11cbcf9b45fa670bd4ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 12:37:58 +0200 Subject: [PATCH 11/72] workaround entry points limitations --- examples/extra_envs/test_install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/extra_envs/test_install.sh b/examples/extra_envs/test_install.sh index 79c669598..9bb3e25be 100644 --- a/examples/extra_envs/test_install.sh +++ b/examples/extra_envs/test_install.sh @@ -11,13 +11,13 @@ fi # base environment uses python 3.7 test -f "$PREFIX/conda-meta/history" "$PREFIX/bin/python" -c "from sys import version_info; assert version_info[:2] == (3, 7)" -"$PREFIX/bin/pip" -V +"$PREFIX/bin/python" -m pip -V # extra env named 'py38' uses python 3.8 test -f "$PREFIX/envs/py38/conda-meta/history" "$PREFIX/envs/py38/bin/python" -c "from sys import version_info; assert version_info[:2] == (3, 8)" -"$PREFIX/envs/py38/bin/pip" -V +"$PREFIX/envs/py38/bin/python" -m pip -V # this env only contains dav1d, no python; it should have been created with no errors, # even if we had excluded tk from the package list From c0d6e07e083679716798970bd3a22c0cf906b8b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 13:07:06 +0200 Subject: [PATCH 12/72] fix postinstall test --- examples/osxpkg/test_install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/osxpkg/test_install.sh b/examples/osxpkg/test_install.sh index 89150ed09..1e3c40686 100644 --- a/examples/osxpkg/test_install.sh +++ b/examples/osxpkg/test_install.sh @@ -11,6 +11,6 @@ printenv >> $HOME/postinstall.txt # Some tests # default_location_pkg -[[ $(basename $(dirname $PREFIX)) == "Library" ]] || exit 1 +[[ $(basename $(dirname "$PREFIX")) == "Library" ]] || exit 1 # pkg_name -[[ $(basename $PREFIX) == "osx-pkg-test" ]] || exit 1 +[[ $(basename "$PREFIX") == "osx pkg test" ]] || exit 1 From 603080351131f95c5a558e080c92da4436b28b3d Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Wed, 17 Aug 2022 12:17:13 +0100 Subject: [PATCH 13/72] Fix typo --- constructor/header.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constructor/header.sh b/constructor/header.sh index 750a173ce..2275a5b7f 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -383,7 +383,7 @@ extract_range $boundary0 $boundary1 > "$CONDA_EXEC" chmod +x "$CONDA_EXEC" export TMP_BACKUP="$TMP" -export "TMP=$PREFIX/install_tmp" +export TMP="$PREFIX/install_tmp" mkdir -p "$TMP" # the second binary payload: the tarball of packages From 244afc78f065cc2504c31915962343be70db2692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 13:27:42 +0200 Subject: [PATCH 14/72] fix prefix checks on mac --- examples/extra_envs/test_install.sh | 2 +- examples/extra_files/test_install.sh | 2 +- examples/osxpkg/test_install.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/extra_envs/test_install.sh b/examples/extra_envs/test_install.sh index 9bb3e25be..943f8ae2c 100644 --- a/examples/extra_envs/test_install.sh +++ b/examples/extra_envs/test_install.sh @@ -3,7 +3,7 @@ set -ex # if PREFIX is not defined, then this was called from an OSX PKG installer # $2 is the install location, ($HOME by default) -if [ -z "PREFIX" ]; then +if [ -z "${PREFIX:-}" ]; then PREFIX=$(cd "$2/__NAME_LOWER__"; pwd) fi diff --git a/examples/extra_files/test_install.sh b/examples/extra_files/test_install.sh index fab798502..760b3e6c0 100644 --- a/examples/extra_files/test_install.sh +++ b/examples/extra_files/test_install.sh @@ -3,7 +3,7 @@ set -ex # if PREFIX is not defined (or empty), then this was called from an OSX PKG installer # $2 is the install location, ($HOME by default) -if [ -z "PREFIX" ]; then +if [ -z "${PREFIX:-}" ]; then PREFIX=$(echo "$2/__NAME_LOWER__" | sed -e 's,//,/,g') PREFIX=$(cd "$PREFIX"; pwd) fi diff --git a/examples/osxpkg/test_install.sh b/examples/osxpkg/test_install.sh index 1e3c40686..a1abda715 100644 --- a/examples/osxpkg/test_install.sh +++ b/examples/osxpkg/test_install.sh @@ -2,7 +2,7 @@ set -ex # $2 is the install location, ($HOME by default) -if [ -z "PREFIX" ]; then +if [ -z "${PREFIX:-}" ]; then PREFIX=$(cd "$2/__NAME_LOWER__"; pwd) fi From 9277ce33ad3c8ee4660a045d2958aff33d5fb8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 14:16:02 +0200 Subject: [PATCH 15/72] some more quotes --- constructor/header.sh | 6 +++--- constructor/osx/post_extract.sh | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/constructor/header.sh b/constructor/header.sh index 2275a5b7f..98c9752be 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -283,7 +283,7 @@ EOF printf "[%s] >>> " "$PREFIX" read -r user_prefix if [ "$user_prefix" != "" ]; then -#if check_path_spaces is True +#if check_path_spaces is True case "$user_prefix" in *\ * ) printf "ERROR: Cannot install into directories with spaces\\n" >&2 @@ -442,7 +442,7 @@ __INSTALL_COMMANDS__ #if has_conda mkdir -p "$PREFIX/envs" for env_pkgs in "${PREFIX}"/pkgs/envs/*/; do - env_name=$(basename "${env_pkgs}") + env_name="$(basename "${env_pkgs}")" if [[ "${env_name}" == "*" ]]; then continue fi @@ -450,7 +450,7 @@ for env_pkgs in "${PREFIX}"/pkgs/envs/*/; do mkdir -p "$PREFIX/envs/$env_name" if [[ -f "${env_pkgs}channels.txt" ]]; then - env_channels=$(cat "${env_pkgs}channels.txt") + env_channels="$(cat "${env_pkgs}channels.txt")" rm -f "${env_pkgs}channels.txt" else env_channels="__CHANNELS__" diff --git a/constructor/osx/post_extract.sh b/constructor/osx/post_extract.sh index 3b1dda3c3..b529feb0c 100644 --- a/constructor/osx/post_extract.sh +++ b/constructor/osx/post_extract.sh @@ -51,8 +51,8 @@ rm -f "$PREFIX/env.txt" mkdir -p "$PREFIX/envs" -for env_pkgs in "${PREFIX}/pkgs/envs/*/"; do - env_name=$(basename "${env_pkgs}") +for env_pkgs in "${PREFIX}"/pkgs/envs/*/; do + env_name="$(basename "${env_pkgs}")" if [[ "${env_name}" == "*" ]]; then continue fi @@ -62,10 +62,10 @@ for env_pkgs in "${PREFIX}/pkgs/envs/*/"; do touch "$PREFIX/envs/$env_name/conda-meta/history" if [[ -f "${env_pkgs}channels.txt" ]]; then - env_channels=$(cat "${env_pkgs}channels.txt") + env_channels="$(cat "${env_pkgs}channels.txt")" rm -f "${env_pkgs}channels.txt" else - env_channels=__CHANNELS__ + env_channels="__CHANNELS__" fi # TODO: custom channels per env? # TODO: custom shortcuts per env? From 5e80a55e5143c9464cc032b9e00064b42a651212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 14:16:14 +0200 Subject: [PATCH 16/72] workaround one more entry point issue --- constructor/osx/update_path.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constructor/osx/update_path.sh b/constructor/osx/update_path.sh index 7b24ebf53..8c2cf0d7a 100644 --- a/constructor/osx/update_path.sh +++ b/constructor/osx/update_path.sh @@ -7,4 +7,4 @@ set -x PREFIX="$2/__NAME_LOWER__" PREFIX=$(cd "$PREFIX"; pwd) -"$PREFIX/bin/conda" init --all +"$PREFIX/bin/python" -m conda init --all From c7d3789d2e0874a2c1dbbca392f80c5b4b0ace54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 14:17:36 +0200 Subject: [PATCH 17/72] update example --- examples/extra_envs/construct.yaml | 6 +++--- examples/extra_envs/test_install.sh | 13 ++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/examples/extra_envs/construct.yaml b/examples/extra_envs/construct.yaml index e717775e6..e7e131778 100644 --- a/examples/extra_envs/construct.yaml +++ b/examples/extra_envs/construct.yaml @@ -4,13 +4,13 @@ installer_type: all channels: - http://repo.anaconda.com/pkgs/main/ specs: - - python=3.7 + - python=3.9 - conda # conda is required for extra_envs - console_shortcut # [win] extra_envs: - py38: + py310: specs: - - python=3.8 + - python=3.10 channels: - conda-forge dav1d: diff --git a/examples/extra_envs/test_install.sh b/examples/extra_envs/test_install.sh index 943f8ae2c..849dab850 100644 --- a/examples/extra_envs/test_install.sh +++ b/examples/extra_envs/test_install.sh @@ -8,16 +8,15 @@ if [ -z "${PREFIX:-}" ]; then fi # tests -# base environment uses python 3.7 +# base environment uses python 3.9 test -f "$PREFIX/conda-meta/history" -"$PREFIX/bin/python" -c "from sys import version_info; assert version_info[:2] == (3, 7)" +"$PREFIX/bin/python" -c "from sys import version_info; assert version_info[:2] == (3, 9)" "$PREFIX/bin/python" -m pip -V - -# extra env named 'py38' uses python 3.8 -test -f "$PREFIX/envs/py38/conda-meta/history" -"$PREFIX/envs/py38/bin/python" -c "from sys import version_info; assert version_info[:2] == (3, 8)" -"$PREFIX/envs/py38/bin/python" -m pip -V +# extra env named 'py310' uses python 3.10 +test -f "$PREFIX/envs/py310/conda-meta/history" +"$PREFIX/envs/py310/bin/python" -c "from sys import version_info; assert version_info[:2] == (3, 10)" +"$PREFIX/envs/py310/bin/python" -m pip -V # this env only contains dav1d, no python; it should have been created with no errors, # even if we had excluded tk from the package list From 4351d925292a7d414dd256af587f8d264227a320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 15:20:58 +0200 Subject: [PATCH 18/72] Update constructor/osx/post_extract.sh --- constructor/osx/post_extract.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constructor/osx/post_extract.sh b/constructor/osx/post_extract.sh index b529feb0c..ee2dc356b 100644 --- a/constructor/osx/post_extract.sh +++ b/constructor/osx/post_extract.sh @@ -81,7 +81,7 @@ done # Cleanup! rm -f "$CONDA_EXEC" -find "$PREFIX/pkgs" -type d -empty -exec rmdir "{}" \; 2>/dev/null || : +find "$PREFIX/pkgs" -type d -empty -exec rmdir {} \; 2>/dev/null || : __WRITE_CONDARC__ From 0c30d4d4a51be63b187a87657e8235228b332cc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 16:13:43 +0200 Subject: [PATCH 19/72] notify exit status --- constructor/nsis/_nsis.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/constructor/nsis/_nsis.py b/constructor/nsis/_nsis.py index 5c9708bdc..a8056f8fb 100644 --- a/constructor/nsis/_nsis.py +++ b/constructor/nsis/_nsis.py @@ -199,12 +199,14 @@ def run_post_install(): if not os.path.isfile(cmd_exe): err("Error: running %s failed. cmd.exe could not be found. " "Looked in SystemRoot and windir env vars.\n" % path) + sys.exit(1) args = [cmd_exe, '/d', '/c', path] import subprocess try: subprocess.check_call(args, env=env) except subprocess.CalledProcessError: err("Error: running %s failed\n" % path) + sys.exit(1) def run_pre_uninstall(): @@ -222,12 +224,14 @@ def run_pre_uninstall(): if not os.path.isfile(cmd_exe): err("Error: running %s failed. cmd.exe could not be found. " "Looked in SystemRoot and windir env vars.\n" % path) + sys.exit(1) args = [cmd_exe, '/d', '/c', path] import subprocess try: subprocess.check_call(args, env=env) except subprocess.CalledProcessError: err("Error: running %s failed\n" % path) + sys.exit(1) allusers = (not exists(join(ROOT_PREFIX, '.nonadmin'))) From 5702f46b13c236b9716de8fa68fb83a1e0ed3bce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 16:24:42 +0200 Subject: [PATCH 20/72] exit script failures if env var is set --- constructor/nsis/_nsis.py | 12 ++++++++---- scripts/run_examples.py | 4 +++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/constructor/nsis/_nsis.py b/constructor/nsis/_nsis.py index 14e1f93bf..3940390f2 100644 --- a/constructor/nsis/_nsis.py +++ b/constructor/nsis/_nsis.py @@ -201,14 +201,16 @@ def run_post_install(): if not os.path.isfile(cmd_exe): err("Error: running %s failed. cmd.exe could not be found. " "Looked in SystemRoot and windir env vars.\n" % path) - sys.exit(1) + if os.environ.get("NSIS_SCRIPTS_RAISE_ERRORS"): + sys.exit(1) args = [cmd_exe, '/d', '/c', path] import subprocess try: subprocess.check_call(args, env=env) except subprocess.CalledProcessError: err("Error: running %s failed\n" % path) - sys.exit(1) + if os.environ.get("NSIS_SCRIPTS_RAISE_ERRORS"): + sys.exit(1) def run_pre_uninstall(): @@ -226,14 +228,16 @@ def run_pre_uninstall(): if not os.path.isfile(cmd_exe): err("Error: running %s failed. cmd.exe could not be found. " "Looked in SystemRoot and windir env vars.\n" % path) - sys.exit(1) + if os.environ.get("NSIS_SCRIPTS_RAISE_ERRORS"): + sys.exit(1) args = [cmd_exe, '/d', '/c', path] import subprocess try: subprocess.check_call(args, env=env) except subprocess.CalledProcessError: err("Error: running %s failed\n" % path) - sys.exit(1) + if os.environ.get("NSIS_SCRIPTS_RAISE_ERRORS"): + sys.exit(1) allusers = (not exists(join(ROOT_PREFIX, '.nonadmin'))) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 6f1b6e266..57d1cabd2 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -9,7 +9,6 @@ import tempfile import platform import shutil -from pathlib import Path from constructor.utils import rm_rf @@ -70,6 +69,9 @@ def run_examples(keep_artifacts=None): if os.path.exists(os.path.join(fpath, 'construct.yaml')): example_paths.append(fpath) + # NSIS won't error out when running scripts unless we set this custom environment variable + os.environ["NSIS_SCRIPTS_RAISE_ERRORS"] = 1 + parent_output = tempfile.mkdtemp() tested_files = set() for example_path in sorted(example_paths): From 9b6e4598c0bb0141935721660541f70ad159679e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 17 Aug 2022 16:51:08 +0200 Subject: [PATCH 21/72] pass path properly... --- scripts/run_examples.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 57d1cabd2..ab5a8d0b2 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -70,7 +70,7 @@ def run_examples(keep_artifacts=None): example_paths.append(fpath) # NSIS won't error out when running scripts unless we set this custom environment variable - os.environ["NSIS_SCRIPTS_RAISE_ERRORS"] = 1 + os.environ["NSIS_SCRIPTS_RAISE_ERRORS"] = "1" parent_output = tempfile.mkdtemp() tested_files = set() @@ -102,7 +102,16 @@ def run_examples(keep_artifacts=None): # This command only expands the PKG, but does not install cmd = ['pkgutil', '--expand', fpath, env_dir] elif ext == 'exe': - cmd = ['cmd.exe', '/c', 'start', '/wait', fpath, '/S', '/D=%s' % env_dir] + # NSIS manual: + # > /D sets the default installation directory ($INSTDIR), overriding InstallDir and + # > InstallDirRegKey. It must be the last parameter used in the command line and must + # > not contain any quotes, even if the path contains spaces. Only absolute paths are + # > supported. + # Since subprocess.Popen WILL escape the spaces with quotes, we need to provide them + # as separate arguments. We don't care about multiple spaces collapsing into one, since + # the point is to just have spaces in the installation path -- one would be enough too :) + # This is why we have this weird .split() thingy down here: + cmd = ['cmd.exe', '/c', 'start', '/wait', fpath, '/S', *f'/D={env_dir}'.split()] test_errored = _execute(cmd) if ext == 'exe' and os.environ.get("NSIS_USING_LOG_BUILD"): test_errored = 0 From ab5449a3e58bb480efe8141b8e00807e5b35f615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Mon, 22 Aug 2022 15:11:58 +0200 Subject: [PATCH 22/72] update .bat tests --- examples/extra_envs/test_install.bat | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/extra_envs/test_install.bat b/examples/extra_envs/test_install.bat index 2d70efb1a..3e90cc473 100644 --- a/examples/extra_envs/test_install.bat +++ b/examples/extra_envs/test_install.bat @@ -1,10 +1,10 @@ -:: base env +:: base env has python 3.9 if not exist "%PREFIX%\conda-meta\history" exit 1 -"%PREFIX%\python.exe" -c "from sys import version_info; assert version_info[:2] == (3, 7)" || goto :error +"%PREFIX%\python.exe" -c "from sys import version_info; assert version_info[:2] == (3, 9)" || goto :error -:: extra env named 'py38' -if not exist "%PREFIX%\envs\py38\conda-meta\history" exit 1 -"%PREFIX%\envs\py38\python.exe" -c "from sys import version_info; assert version_info[:2] == (3, 8)" || goto :error +:: extra env named 'py310' has python 3.10 +if not exist "%PREFIX%\envs\py310\conda-meta\history" exit 1 +"%PREFIX%\envs\py310\python.exe" -c "from sys import version_info; assert version_info[:2] == (3, 10)" || goto :error :: extra env named 'dav1d' only contains dav1d, no python if not exist "%PREFIX%\envs\dav1d\conda-meta\history" exit 1 From d95b712eceacfd1b3ffcfb72a01bbf0f99e793ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 10:09:59 +0200 Subject: [PATCH 23/72] flip default value --- CONSTRUCT.md | 4 ++-- constructor/construct.py | 4 ++-- constructor/osxpkg.py | 2 +- constructor/shar.py | 2 +- constructor/winexe.py | 2 +- news/449-allow-spaces-in-prefix | 3 ++- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CONSTRUCT.md b/CONSTRUCT.md index b3a7dbef3..889bc30b9 100644 --- a/CONSTRUCT.md +++ b/CONSTRUCT.md @@ -484,10 +484,10 @@ or enable long path on windows > 10 (require admin right). Default is True. (Win ## `check_path_spaces` -_required:_ no
+_required:_ yes
_type:_ boolean
Check if the path where the distribution is installed contains spaces and show a warning -(EXE, SH installers) or error (PKG installer) if any spaces are found. Default is False. +(EXE, SH installers) or error (PKG installer) if any spaces are found. Default is True. ## `nsis_template` diff --git a/constructor/construct.py b/constructor/construct.py index 296e3419f..6732d521a 100644 --- a/constructor/construct.py +++ b/constructor/construct.py @@ -382,9 +382,9 @@ or enable long path on windows > 10 (require admin right). Default is True. (Windows only). '''), - ('check_path_spaces', False, bool, ''' + ('check_path_spaces', True, bool, ''' Check if the path where the distribution is installed contains spaces and show a warning -(EXE, SH installers) or error (PKG installer) if any spaces are found. Default is False. +(EXE, SH installers) or error (PKG installer) if any spaces are found. Default is True. '''), ('nsis_template', False, str, ''' diff --git a/constructor/osxpkg.py b/constructor/osxpkg.py index b0a9de763..704960b66 100644 --- a/constructor/osxpkg.py +++ b/constructor/osxpkg.py @@ -247,7 +247,7 @@ def move_script(src, dst, info): # ppd hosts the conditions for the #if/#else/#endif preprocessors on scripts ppd = ns_platform(info['_platform']) - ppd['check_path_spaces'] = info.get("check_path_spaces", False) + ppd['check_path_spaces'] = info.get("check_path_spaces", True) # This is necessary for when installing on case-sensitive macOS filesystems. pkg_name_lower = info.get("pkg_name", info['name']).lower() diff --git a/constructor/shar.py b/constructor/shar.py index e1e00a80d..933f0ca32 100644 --- a/constructor/shar.py +++ b/constructor/shar.py @@ -58,7 +58,7 @@ def get_header(conda_exec, tarball, info): ppd['direct_execute_%s' % key] = has_shebang(info[key]) ppd['initialize_by_default'] = info.get('initialize_by_default', None) ppd['has_conda'] = info['_has_conda'] - ppd['check_path_spaces'] = info.get("check_path_spaces", False) + ppd['check_path_spaces'] = info.get("check_path_spaces", True) install_lines = list(add_condarc(info)) # Needs to happen first -- can be templated replace = { diff --git a/constructor/winexe.py b/constructor/winexe.py index 992ed4db4..429febbc9 100644 --- a/constructor/winexe.py +++ b/constructor/winexe.py @@ -193,7 +193,7 @@ def make_nsi(info, dir_path, extra_files=()): ppd['initialize_by_default'] = info.get('initialize_by_default', None) ppd['register_python_default'] = info.get('register_python_default', None) ppd['check_path_length'] = info.get('check_path_length', None) - ppd['check_path_spaces'] = info.get('check_path_spaces', False) + ppd['check_path_spaces'] = info.get('check_path_spaces', True) ppd['keep_pkgs'] = info.get('keep_pkgs') or False ppd['post_install_exists'] = bool(info.get('post_install')) ppd['with_conclusion_text'] = bool(conclusion_text) diff --git a/news/449-allow-spaces-in-prefix b/news/449-allow-spaces-in-prefix index 7590bd62c..8d08a0df6 100644 --- a/news/449-allow-spaces-in-prefix +++ b/news/449-allow-spaces-in-prefix @@ -2,7 +2,8 @@ Enhancements: ------------- * Installers will allow spaces in `PREFIX` by default now. - Users can re-enable the old behaviour (reject chosen path if it contained spaces) by setting `check_path_spaces` to `True`. + Old behaviour (reject chosen path if it contained spaces) is still default. + Opt-in by setting `check_path_spaces` to `False`. Bug fixes: ---------- From 64f72735d7b0e6450455fce95cb1cd22093a7391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 10:13:45 +0200 Subject: [PATCH 24/72] wrong default changed --- CONSTRUCT.md | 2 +- constructor/construct.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CONSTRUCT.md b/CONSTRUCT.md index 889bc30b9..0e9e02f6c 100644 --- a/CONSTRUCT.md +++ b/CONSTRUCT.md @@ -484,7 +484,7 @@ or enable long path on windows > 10 (require admin right). Default is True. (Win ## `check_path_spaces` -_required:_ yes
+_required:_ no
_type:_ boolean
Check if the path where the distribution is installed contains spaces and show a warning (EXE, SH installers) or error (PKG installer) if any spaces are found. Default is True. diff --git a/constructor/construct.py b/constructor/construct.py index 6732d521a..70a4ecb34 100644 --- a/constructor/construct.py +++ b/constructor/construct.py @@ -382,7 +382,7 @@ or enable long path on windows > 10 (require admin right). Default is True. (Windows only). '''), - ('check_path_spaces', True, bool, ''' + ('check_path_spaces', False, bool, ''' Check if the path where the distribution is installed contains spaces and show a warning (EXE, SH installers) or error (PKG installer) if any spaces are found. Default is True. '''), From 2da78473bccb3cdeb05704558ca8dae6f296d0fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 11:10:50 +0200 Subject: [PATCH 25/72] add 'check_path_spaces: False' to examples --- examples/extra_envs/construct.yaml | 1 + examples/extra_files/construct.yaml | 1 + examples/grin/construct.yaml | 2 ++ examples/jetsonconda/construct.yaml | 2 ++ examples/miniconda/construct.yaml | 2 ++ examples/newchan/construct.yaml | 1 + examples/noconda/construct.yaml | 2 ++ examples/osxpkg/construct.yaml | 1 + examples/shortcuts/construct.yaml | 2 ++ 9 files changed, 14 insertions(+) diff --git a/examples/extra_envs/construct.yaml b/examples/extra_envs/construct.yaml index e7e131778..8ba4984f0 100644 --- a/examples/extra_envs/construct.yaml +++ b/examples/extra_envs/construct.yaml @@ -1,6 +1,7 @@ name: ExtraEnvs version: X installer_type: all +check_path_spaces: False channels: - http://repo.anaconda.com/pkgs/main/ specs: diff --git a/examples/extra_files/construct.yaml b/examples/extra_files/construct.yaml index 80cc1fc5b..c65070730 100644 --- a/examples/extra_files/construct.yaml +++ b/examples/extra_files/construct.yaml @@ -1,6 +1,7 @@ name: ExtraFiles version: X installer_type: all +check_path_spaces: False channels: - http://repo.anaconda.com/pkgs/main/ specs: diff --git a/examples/grin/construct.yaml b/examples/grin/construct.yaml index 5b70d958b..737d5ae72 100644 --- a/examples/grin/construct.yaml +++ b/examples/grin/construct.yaml @@ -58,3 +58,5 @@ license_file: eula.txt #header_image_text: |- # multi-line # header-text + +check_path_spaces: False \ No newline at end of file diff --git a/examples/jetsonconda/construct.yaml b/examples/jetsonconda/construct.yaml index d9eb5f9a4..49f514e35 100644 --- a/examples/jetsonconda/construct.yaml +++ b/examples/jetsonconda/construct.yaml @@ -18,3 +18,5 @@ specs: # Welcome image for Windows installer welcome_image: bird.png # [win] + +check_path_spaces: False diff --git a/examples/miniconda/construct.yaml b/examples/miniconda/construct.yaml index 8fe996cd6..5f0b8401a 100644 --- a/examples/miniconda/construct.yaml +++ b/examples/miniconda/construct.yaml @@ -8,3 +8,5 @@ channels: specs: - python - conda + +check_path_spaces: False diff --git a/examples/newchan/construct.yaml b/examples/newchan/construct.yaml index 622d0fe04..c0d54ff71 100644 --- a/examples/newchan/construct.yaml +++ b/examples/newchan/construct.yaml @@ -13,3 +13,4 @@ specs: license_file: eula.txt +check_path_spaces: False diff --git a/examples/noconda/construct.yaml b/examples/noconda/construct.yaml index 5ce38d449..200247b6f 100644 --- a/examples/noconda/construct.yaml +++ b/examples/noconda/construct.yaml @@ -10,3 +10,5 @@ conclusion_text: | You are now ready to run your Python installation. This is a second line and should appear as such on the installer UI. This would be the third one. + +check_path_spaces: False diff --git a/examples/osxpkg/construct.yaml b/examples/osxpkg/construct.yaml index 1eeb21023..73021f972 100644 --- a/examples/osxpkg/construct.yaml +++ b/examples/osxpkg/construct.yaml @@ -5,6 +5,7 @@ version: 1.2.3 # "~/Library/osx pkg test" (spaces should work) default_location_pkg: Library pkg_name: "osx pkg test" +check_path_spaces: False channels: - http://repo.anaconda.com/pkgs/main/ diff --git a/examples/shortcuts/construct.yaml b/examples/shortcuts/construct.yaml index 21ab4eaa7..dba5e6c43 100644 --- a/examples/shortcuts/construct.yaml +++ b/examples/shortcuts/construct.yaml @@ -9,3 +9,5 @@ specs: - python - conda - console_shortcut # [win] + +check_path_spaces: False From bf20f1335696176ce65309871dfb4c32a0ed83df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 11:11:20 +0200 Subject: [PATCH 26/72] improve spaces checking in pkg --- constructor/osx/preinstall.sh | 23 ++++++++++++++--------- constructor/osxpkg.py | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/constructor/osx/preinstall.sh b/constructor/osx/preinstall.sh index 93e49e260..4d76f289d 100644 --- a/constructor/osx/preinstall.sh +++ b/constructor/osx/preinstall.sh @@ -8,12 +8,16 @@ # affected by those restrictions, but it's only executed once the installer has begun # so the only way to prevent an action is to abort and start again from the beginning. -if [[ -e "$2/__NAME_LOWER__" ]]; then +PREFIX="$2/__NAME_LOWER__" +echo "PREFIX=$PREFIX" + +if [[ -e "$PREFIX" ]]; then # The OS X installer provides no way to send a message to the user if this # script fails. So we use AppleScript to do it. # By default, osascript doesn't allow user interaction, so we have to work # around it. http://stackoverflow.com/a/11874852/161801 + logger -p "install.info" "ERROR: __PATH_EXISTS_ERROR_TEXT__" || echo "ERROR: __PATH_EXISTS_ERROR_TEXT__" (osascript -e "try tell application (path to frontmost application as text) set theAlertText to \"Chosen path already exists!\" @@ -28,21 +32,22 @@ fi #if check_path_spaces is True # Check if the path has spaces -case "$2" in - *\ * ) - (osascript -e "try +case "$PREFIX" in + *\ * ) + logger -p "install.info" "ERROR: '$PREFIX' contains spaces!" || echo "ERROR: '$PREFIX' contains spaces!" + (osascript -e "try tell application (path to frontmost application as text) set theAlertText to \"Chosen path contain spaces!\" -set theAlertMessage to \"'$2/__NAME_LOWER__' contains spaces. Please, relaunch the installer and choose another location in the Destination Select step.\" +set theAlertMessage to \"'$PREFIX' contains spaces. Please, relaunch the installer and choose another location in the Destination Select step.\" display alert theAlertText message theAlertMessage as critical buttons {\"OK\"} default button {\"OK\"} end activate app (path to frontmost application as text) answer end") - exit 1 - ;; - *) + exit 1 + ;; + *) - ;; + ;; esac #endif diff --git a/constructor/osxpkg.py b/constructor/osxpkg.py index 704960b66..db031082d 100644 --- a/constructor/osxpkg.py +++ b/constructor/osxpkg.py @@ -1,4 +1,5 @@ import os +import sys import shutil from os.path import isdir, abspath, dirname, exists, join from subprocess import check_call @@ -247,7 +248,7 @@ def move_script(src, dst, info): # ppd hosts the conditions for the #if/#else/#endif preprocessors on scripts ppd = ns_platform(info['_platform']) - ppd['check_path_spaces'] = info.get("check_path_spaces", True) + ppd['check_path_spaces'] = bool(info.get("check_path_spaces", True)) # This is necessary for when installing on case-sensitive macOS filesystems. pkg_name_lower = info.get("pkg_name", info['name']).lower() @@ -346,6 +347,21 @@ def pkgbuild_script(name, info, src, dst='postinstall'): def create(info, verbose=False): + # Do some configuration checks + if info.get("check_path_spaces", True) is True: + if " " in info.get("default_location_pkg", ""): + sys.exit( + "ERROR: 'check_path_spaces' is enabled, but 'default_location_pkg' " + "contains spaces. This will always result in a failed " + "installation! Aborting!" + ) + if " " in info.get("pkg_name", ""): + sys.exit( + "ERROR: 'check_path_spaces' is enabled, but 'pkg_name' " + "contains spaces. This will always result in a failed " + "installation! Aborting!" + ) + global CACHE_DIR, PACKAGE_ROOT, PACKAGES_DIR, SCRIPTS_DIR CACHE_DIR = info['_download_dir'] From bd241c78eaff34768450933dac36bd2e333a891c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 11:22:22 +0200 Subject: [PATCH 27/72] check for spaces in silent mode too? --- constructor/nsis/main.nsi.tmpl | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/constructor/nsis/main.nsi.tmpl b/constructor/nsis/main.nsi.tmpl index 444f515cb..b1cdfad24 100644 --- a/constructor/nsis/main.nsi.tmpl +++ b/constructor/nsis/main.nsi.tmpl @@ -785,7 +785,6 @@ Function OnDirectoryLeave "Warning: 'Destination Folder' contains $R0 space$R1.$\n \ This can cause problems with several Conda packages.$\n \ Please consider removing the space$R1." - NoSpaces: #endif @@ -876,6 +875,19 @@ FunctionEnd Section "Install" ${LogSet} on + ${If} ${Silent} + # Call the CheckForSpaces function. + Push $INSTDIR # Input string (install path). + Call CheckForSpaces + Pop $R0 # The function returns the number of spaces found in the input string. +#if check_path_spaces is True + StrCmp $R0 0 NoSpaces + DetailPrint "::error:: The chosen path contains one or more spaces." + Abort + NoSpaces: +#endif + ${EndIf} + SetOutPath "$INSTDIR\Lib" File "@NSIS_DIR@\_nsis.py" File "@NSIS_DIR@\_system_path.py" From 923c83d5f3b680209cd982dd8f25156ba52347bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 11:23:24 +0200 Subject: [PATCH 28/72] enable errors on MinicondaX for Windows (temp) --- examples/miniconda/construct.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/miniconda/construct.yaml b/examples/miniconda/construct.yaml index 5f0b8401a..e381ab276 100644 --- a/examples/miniconda/construct.yaml +++ b/examples/miniconda/construct.yaml @@ -9,4 +9,4 @@ specs: - python - conda -check_path_spaces: False +check_path_spaces: False # [unix] From fd4cd936e187f13c4df383f577f5e6d17ea7b755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 11:31:32 +0200 Subject: [PATCH 29/72] make sure all dialog boxes for error have DetailPrint statements so we can catch them on the logs too --- constructor/nsis/main.nsi.tmpl | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/constructor/nsis/main.nsi.tmpl b/constructor/nsis/main.nsi.tmpl index b1cdfad24..5b3ab8606 100644 --- a/constructor/nsis/main.nsi.tmpl +++ b/constructor/nsis/main.nsi.tmpl @@ -785,6 +785,10 @@ Function OnDirectoryLeave "Warning: 'Destination Folder' contains $R0 space$R1.$\n \ This can cause problems with several Conda packages.$\n \ Please consider removing the space$R1." + ${If} ${Silent} + DetailPrint "::error:: 'Destination folder' contains $R0 space$R1." + abort + ${EndIf} NoSpaces: #endif @@ -795,6 +799,7 @@ Function OnDirectoryLeave Pop $R0 StrCmp $R0 "" NoInvalidCharaceters + DetailPrint "::error:: 'Destination Folder' contains the following invalid character: $R0" MessageBox MB_OK|MB_ICONEXCLAMATION \ "Error: 'Destination Folder' contains the following invalid character: $R0" abort @@ -803,6 +808,7 @@ Function OnDirectoryLeave UnicodePathTest::SpecialCharPathTest $INSTDIR Pop $R1 StrCmp $R1 "nothingspecial" nothing_special_path + DetailPrint "::error:: 'Destination Folder' contains the following invalid character$R1" messagebox mb_ok|MB_ICONEXCLAMATION \ "Error: 'Destination Folder' contains the following invalid character$R1" abort @@ -819,7 +825,9 @@ Function OnDirectoryLeave StrCmp ${PY_VER} "2.7" not_cp_acp_capable StrCmp $R1 "ascii_cp_acp" valid_path not_cp_acp_capable: - + DetailPrint "::error:: Due to incompatibility with several \ + Python libraries, 'Destination Folder' cannot contain non-ascii characters \ + (special characters or diacritics). Please choose another location." messagebox mb_ok|MB_ICONEXCLAMATION "Error: Due to incompatibility with several \ Python libraries, 'Destination Folder' cannot contain non-ascii characters \ (special characters or diacritics). Please choose another location." @@ -831,6 +839,8 @@ Function OnDirectoryLeave ${IsWritable} $INSTDIR $R1 IntCmp $R1 0 pathgood Pop $R1 + DetailPrint "::error: Path $INSTDIR is not writable. Please check permissions or \ + try respawning the installer with elevated privileges." MessageBox mb_ok|MB_ICONEXCLAMATION \ "Error: Path $INSTDIR is not writable. Please check permissions or \ try respawning the installer with elevated privileges." @@ -875,19 +885,6 @@ FunctionEnd Section "Install" ${LogSet} on - ${If} ${Silent} - # Call the CheckForSpaces function. - Push $INSTDIR # Input string (install path). - Call CheckForSpaces - Pop $R0 # The function returns the number of spaces found in the input string. -#if check_path_spaces is True - StrCmp $R0 0 NoSpaces - DetailPrint "::error:: The chosen path contains one or more spaces." - Abort - NoSpaces: -#endif - ${EndIf} - SetOutPath "$INSTDIR\Lib" File "@NSIS_DIR@\_nsis.py" File "@NSIS_DIR@\_system_path.py" From d121979d857794cc56be737cae7f4349b5c47a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 12:07:43 +0200 Subject: [PATCH 30/72] OnDirectoryLeave not called on silent mode? --- constructor/nsis/main.nsi.tmpl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/constructor/nsis/main.nsi.tmpl b/constructor/nsis/main.nsi.tmpl index 5b3ab8606..87af4c457 100644 --- a/constructor/nsis/main.nsi.tmpl +++ b/constructor/nsis/main.nsi.tmpl @@ -731,6 +731,7 @@ Pop $0 Function OnDirectoryLeave ${If} ${IsNonEmptyDirectory} "$InstDir" + DetailPrint "::error:: Directory '$INSTDIR' is not empty, please choose a different location." MessageBox MB_OK|MB_ICONEXCLAMATION \ "Directory '$INSTDIR' is not empty,$\n\ please choose a different location." @@ -752,6 +753,9 @@ Function OnDirectoryLeave WriteRegDWORD HKLM "SYSTEM\CurrentControlSet\Control\FileSystem" "LongPathsEnabled" 1 ; If we don't have admin right, we suggest a shorter path or suggest to run with admin right ${Else} + DetailPrint "::error:: The installation path should be shorter than 46 characters or \ + the installation requires administrator rights to enable long \ + path on Windows." MessageBox MB_OK|MB_ICONSTOP "The installation path should be shorter than 46 characters or \ the installation requires administrator rights to enable long \ path on Windows." @@ -759,6 +763,8 @@ Function OnDirectoryLeave ${EndIf} ; If we don't have admin right, we suggest a shorter path or suggest to run with admin right ${Else} + DetailPrint "::error:: The installation path should be shorter than 46 characters. \ + Please choose another location." MessageBox MB_OK|MB_ICONSTOP "The installation path should be shorter than 46 characters. \ Please choose another location." Abort @@ -840,7 +846,7 @@ Function OnDirectoryLeave IntCmp $R1 0 pathgood Pop $R1 DetailPrint "::error: Path $INSTDIR is not writable. Please check permissions or \ - try respawning the installer with elevated privileges." + try respawning the installer with elevated privileges." MessageBox mb_ok|MB_ICONEXCLAMATION \ "Error: Path $INSTDIR is not writable. Please check permissions or \ try respawning the installer with elevated privileges." @@ -885,6 +891,10 @@ FunctionEnd Section "Install" ${LogSet} on + ${If} ${Silent} + call OnDirectoryLeave + ${EndIf} + SetOutPath "$INSTDIR\Lib" File "@NSIS_DIR@\_nsis.py" File "@NSIS_DIR@\_system_path.py" From 00016c93ca5d7a92a0ca276945a3923c01d08006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 12:22:20 +0200 Subject: [PATCH 31/72] better docs about Windows silent installs --- CONSTRUCT.md | 19 +++++++++++++++++-- constructor/construct.py | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/CONSTRUCT.md b/CONSTRUCT.md index 0e9e02f6c..bd48247fe 100644 --- a/CONSTRUCT.md +++ b/CONSTRUCT.md @@ -199,13 +199,22 @@ _required:_ no
_types:_ string, list
The type of the installer being created. Possible values are: - `sh`: shell-based installer for Linux or macOS; -- `pkg`: macOS GUI installer -- `exe`: Windows GUI installer +- `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 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 quotes. For example: + `CMD.EXE /C START /WAIT myproject.exe /S /D=C:\path with spaces\my project`. + ## `license_file` _required:_ no
@@ -482,6 +491,9 @@ Check the length of the path where the distribution is installed to ensure nodej 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` _required:_ no
@@ -489,6 +501,9 @@ _type:_ boolean
Check if the path where the distribution is installed contains spaces and show a warning (EXE, SH installers) or error (PKG installer) if any spaces are found. Default is True. +Read notes about the particularities of Windows silent mode `/S` in the +`installer_type` documentation. + ## `nsis_template` _required:_ no
diff --git a/constructor/construct.py b/constructor/construct.py index 70a4ecb34..b2cf2353c 100644 --- a/constructor/construct.py +++ b/constructor/construct.py @@ -158,12 +158,21 @@ ('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 -- `exe`: Windows GUI installer +- `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 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 quotes. For example: + `CMD.EXE /C START /WAIT myproject.exe /S /D=C:\\path with spaces\\my project`. '''), ('license_file', False, str, ''' @@ -380,11 +389,17 @@ 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 and show a warning (EXE, SH installers) or error (PKG installer) if any spaces are found. Default is True. + +Read notes about the particularities of Windows silent mode `/S` in the +`installer_type` documentation. '''), ('nsis_template', False, str, ''' From 252852a798a8b16dd4a4a44588b17aaf130b276e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 12:41:40 +0200 Subject: [PATCH 32/72] add /SD options to all messageboxes with buttons --- constructor/nsis/main.nsi.tmpl | 41 +++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/constructor/nsis/main.nsi.tmpl b/constructor/nsis/main.nsi.tmpl index 87af4c457..4f5dadcf1 100644 --- a/constructor/nsis/main.nsi.tmpl +++ b/constructor/nsis/main.nsi.tmpl @@ -224,8 +224,9 @@ FunctionEnd Install for just me, add to PATH and register as system Python:$\n\ $EXEFILE /RegisterPython=1 /AddToPath=1$\n$\n\ Install for just me, with no registry modification (for CI):$\n\ - $EXEFILE /NoRegistry=1$\n" - Abort + $EXEFILE /NoRegistry=1$\n" \ + /SD IDOK + Abort ${EndIf} ClearErrors @@ -455,7 +456,8 @@ Function .onInit MessageBox MB_OK|MB_ICONEXCLAMATION \ "This installer is for a 64-bit version for @NAME@$\n\ but your system is 32-bit. Please use the 32-bit Windows$\n\ - @NAME@ installer." + @NAME@ installer." \ + /SD IDOK Abort ${EndIf} #endif @@ -541,7 +543,8 @@ Function .onInit StrCpy $INSTDIR_JUSTME $0 ${Else} # Should never happen; indicates a logic error above. - MessageBox MB_OK "Internal error: IsUserDomain not set properly!" + MessageBox MB_OK "Internal error: IsUserDomain not set properly!" \ + /SD IDOK Abort ${EndIf} @@ -734,7 +737,8 @@ Function OnDirectoryLeave DetailPrint "::error:: Directory '$INSTDIR' is not empty, please choose a different location." MessageBox MB_OK|MB_ICONEXCLAMATION \ "Directory '$INSTDIR' is not empty,$\n\ - please choose a different location." + please choose a different location." \ + /SD IDOK Abort ${EndIf} @@ -758,7 +762,8 @@ Function OnDirectoryLeave path on Windows." MessageBox MB_OK|MB_ICONSTOP "The installation path should be shorter than 46 characters or \ the installation requires administrator rights to enable long \ - path on Windows." + path on Windows." \ + /SD IDOK Abort ${EndIf} ; If we don't have admin right, we suggest a shorter path or suggest to run with admin right @@ -766,7 +771,8 @@ Function OnDirectoryLeave DetailPrint "::error:: The installation path should be shorter than 46 characters. \ Please choose another location." MessageBox MB_OK|MB_ICONSTOP "The installation path should be shorter than 46 characters. \ - Please choose another location." + Please choose another location." \ + /SD IDOK Abort ${EndIf} ${EndIf} @@ -790,7 +796,8 @@ Function OnDirectoryLeave MessageBox MB_OK|MB_ICONINFORMATION \ "Warning: 'Destination Folder' contains $R0 space$R1.$\n \ This can cause problems with several Conda packages.$\n \ - Please consider removing the space$R1." + Please consider removing the space$R1." \ + /SD IDOK ${If} ${Silent} DetailPrint "::error:: 'Destination folder' contains $R0 space$R1." abort @@ -807,7 +814,8 @@ Function OnDirectoryLeave StrCmp $R0 "" NoInvalidCharaceters DetailPrint "::error:: 'Destination Folder' contains the following invalid character: $R0" MessageBox MB_OK|MB_ICONEXCLAMATION \ - "Error: 'Destination Folder' contains the following invalid character: $R0" + "Error: 'Destination Folder' contains the following invalid character: $R0" \ + /SD IDOK abort NoInvalidCharaceters: @@ -815,8 +823,9 @@ Function OnDirectoryLeave Pop $R1 StrCmp $R1 "nothingspecial" nothing_special_path DetailPrint "::error:: 'Destination Folder' contains the following invalid character$R1" - messagebox mb_ok|MB_ICONEXCLAMATION \ - "Error: 'Destination Folder' contains the following invalid character$R1" + MessageBox MB_OK|MB_ICONEXCLAMATION \ + "Error: 'Destination Folder' contains the following invalid character$R1" \ + /SD IDOK abort nothing_special_path: @@ -834,9 +843,10 @@ Function OnDirectoryLeave DetailPrint "::error:: Due to incompatibility with several \ Python libraries, 'Destination Folder' cannot contain non-ascii characters \ (special characters or diacritics). Please choose another location." - messagebox mb_ok|MB_ICONEXCLAMATION "Error: Due to incompatibility with several \ + MessageBox MB_OK|MB_ICONEXCLAMATION "Error: Due to incompatibility with several \ Python libraries, 'Destination Folder' cannot contain non-ascii characters \ - (special characters or diacritics). Please choose another location." + (special characters or diacritics). Please choose another location." \ + /SD IDOK abort valid_path: @@ -847,9 +857,10 @@ Function OnDirectoryLeave Pop $R1 DetailPrint "::error: Path $INSTDIR is not writable. Please check permissions or \ try respawning the installer with elevated privileges." - MessageBox mb_ok|MB_ICONEXCLAMATION \ + MessageBox MB_OK|MB_ICONEXCLAMATION \ "Error: Path $INSTDIR is not writable. Please check permissions or \ - try respawning the installer with elevated privileges." + try respawning the installer with elevated privileges." \ + /SD IDOK Abort pathgood: From 4a2afc641073cd2c241bc3020902978a8a993e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 13:31:51 +0200 Subject: [PATCH 33/72] add debugging to each function --- constructor/nsis/main.nsi.tmpl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/constructor/nsis/main.nsi.tmpl b/constructor/nsis/main.nsi.tmpl index 4f5dadcf1..10dcf765d 100644 --- a/constructor/nsis/main.nsi.tmpl +++ b/constructor/nsis/main.nsi.tmpl @@ -158,6 +158,7 @@ Page Custom mui_AnaCustomOptions_Show !insertmacro MUI_LANGUAGE "English" Function SkipPageIfUACInnerInstance + ${LogSet} on ${If} ${UAC_IsInnerInstance} Abort ${EndIf} @@ -304,11 +305,13 @@ FunctionEnd !macroend Function OnInit_Release + ${LogSet} on !insertmacro ParseCommandLineArgs FunctionEnd Function InstModePage_RadioButton_OnClick + ${LogSet} on Exch $0 Push $1 Push $2 @@ -324,6 +327,7 @@ Function InstModePage_RadioButton_OnClick FunctionEnd Function InstModePage_Create + ${LogSet} on Push $0 Push $1 Push $2 @@ -370,6 +374,7 @@ Function InstModePage_Create FunctionEnd Function DisableBackButtonIfUACInnerInstance + ${LogSet} on Push $0 ${If} ${UAC_IsInnerInstance} GetDlgItem $0 $HWNDParent 3 @@ -379,6 +384,7 @@ Function DisableBackButtonIfUACInnerInstance FunctionEnd Function RemoveNextBtnShield + ${LogSet} on Push $0 GetDlgItem $0 $HWNDParent 1 SendMessage $0 ${BCM_SETSHIELD} 0 0 @@ -386,6 +392,7 @@ Function RemoveNextBtnShield FunctionEnd Function InstModeChanged + ${LogSet} on # When using the installer with /S (silent mode), the /D option sets $INSTDIR, # and it is therefore important not to overwrite $INSTDIR here, but it is also # important that we do call SetShellVarContext with the appropriate value. @@ -416,6 +423,7 @@ FunctionEnd !macroend Function InstModePage_Leave + ${LogSet} on Push $0 Push $1 Push $2 @@ -651,6 +659,7 @@ FunctionEnd # http://nsis.sourceforge.net/Check_for_spaces_in_a_directory_path Function CheckForSpaces + ${LogSet} on Exch $R0 Push $R1 Push $R2 @@ -674,6 +683,7 @@ FunctionEnd # http://nsis.sourceforge.net/StrCSpn,_StrCSpnReverse:_Scan_strings_for_characters Function StrCSpn + ${LogSet} on Exch $R0 ; string to check Exch Exch $R1 ; string of chars @@ -733,6 +743,7 @@ Pop $0 Function OnDirectoryLeave + ${LogSet} on ${If} ${IsNonEmptyDirectory} "$InstDir" DetailPrint "::error:: Directory '$INSTDIR' is not empty, please choose a different location." MessageBox MB_OK|MB_ICONEXCLAMATION \ @@ -869,6 +880,7 @@ Function OnDirectoryLeave FunctionEnd Function .onVerifyInstDir + ${LogSet} on StrLen $0 $Desktop StrCpy $0 $INSTDIR $0 StrCmp $0 $Desktop 0 PathGood @@ -877,6 +889,7 @@ Function .onVerifyInstDir FunctionEnd Function AbortRetryNSExecWait + ${LogSet} on Pop $1 Pop $2 ${Do} From 06aae1001cdaddd2dc77dff2bc61525a67fba9aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 13:31:59 +0200 Subject: [PATCH 34/72] allow long paths in all examples --- examples/extra_envs/construct.yaml | 1 + examples/extra_files/construct.yaml | 1 + examples/grin/construct.yaml | 3 ++- examples/jetsonconda/construct.yaml | 1 + examples/miniconda/construct.yaml | 1 + examples/newchan/construct.yaml | 1 + examples/noconda/construct.yaml | 1 + examples/osxpkg/construct.yaml | 1 + examples/shortcuts/construct.yaml | 1 + 9 files changed, 10 insertions(+), 1 deletion(-) diff --git a/examples/extra_envs/construct.yaml b/examples/extra_envs/construct.yaml index 8ba4984f0..1e0a46f12 100644 --- a/examples/extra_envs/construct.yaml +++ b/examples/extra_envs/construct.yaml @@ -2,6 +2,7 @@ name: ExtraEnvs version: X installer_type: all check_path_spaces: False +check_path_length: False channels: - http://repo.anaconda.com/pkgs/main/ specs: diff --git a/examples/extra_files/construct.yaml b/examples/extra_files/construct.yaml index c65070730..1d248235e 100644 --- a/examples/extra_files/construct.yaml +++ b/examples/extra_files/construct.yaml @@ -2,6 +2,7 @@ name: ExtraFiles version: X installer_type: all check_path_spaces: False +check_path_length: False channels: - http://repo.anaconda.com/pkgs/main/ specs: diff --git a/examples/grin/construct.yaml b/examples/grin/construct.yaml index 737d5ae72..2bb45f6aa 100644 --- a/examples/grin/construct.yaml +++ b/examples/grin/construct.yaml @@ -59,4 +59,5 @@ license_file: eula.txt # multi-line # header-text -check_path_spaces: False \ No newline at end of file +check_path_spaces: False +check_path_length: False diff --git a/examples/jetsonconda/construct.yaml b/examples/jetsonconda/construct.yaml index 49f514e35..426cf2636 100644 --- a/examples/jetsonconda/construct.yaml +++ b/examples/jetsonconda/construct.yaml @@ -20,3 +20,4 @@ specs: welcome_image: bird.png # [win] check_path_spaces: False +check_path_length: False diff --git a/examples/miniconda/construct.yaml b/examples/miniconda/construct.yaml index e381ab276..01edb638a 100644 --- a/examples/miniconda/construct.yaml +++ b/examples/miniconda/construct.yaml @@ -10,3 +10,4 @@ specs: - conda check_path_spaces: False # [unix] +check_path_length: False diff --git a/examples/newchan/construct.yaml b/examples/newchan/construct.yaml index c0d54ff71..05a1b668b 100644 --- a/examples/newchan/construct.yaml +++ b/examples/newchan/construct.yaml @@ -14,3 +14,4 @@ specs: license_file: eula.txt check_path_spaces: False +check_path_length: False diff --git a/examples/noconda/construct.yaml b/examples/noconda/construct.yaml index 200247b6f..24caf68af 100644 --- a/examples/noconda/construct.yaml +++ b/examples/noconda/construct.yaml @@ -12,3 +12,4 @@ conclusion_text: | This would be the third one. check_path_spaces: False +check_path_length: False diff --git a/examples/osxpkg/construct.yaml b/examples/osxpkg/construct.yaml index 73021f972..868ae8ddf 100644 --- a/examples/osxpkg/construct.yaml +++ b/examples/osxpkg/construct.yaml @@ -6,6 +6,7 @@ version: 1.2.3 default_location_pkg: Library pkg_name: "osx pkg test" check_path_spaces: False +check_path_length: False channels: - http://repo.anaconda.com/pkgs/main/ diff --git a/examples/shortcuts/construct.yaml b/examples/shortcuts/construct.yaml index dba5e6c43..5b2012486 100644 --- a/examples/shortcuts/construct.yaml +++ b/examples/shortcuts/construct.yaml @@ -11,3 +11,4 @@ specs: - console_shortcut # [win] check_path_spaces: False +check_path_length: False From 8dbfabe7205ede776dc3f72fef7e8d9ea832b331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 14:14:32 +0200 Subject: [PATCH 35/72] tempdir issues getting in the way? --- .github/workflows/main.yml | 8 ++++++++ scripts/run_examples.py | 3 +++ 2 files changed, 11 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index eb4355b9e..fb47440ae 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -78,6 +78,14 @@ jobs: curl -sL "https://sourceforge.net/projects/nsis/files/NSIS%203/${nsis_version}/nsis-${nsis_version}-log.zip/download" -o "nsis-${nsis_version}-log.zip" 7z x "nsis-${nsis_version}-log.zip" -aoa -o"$CONDA_PREFIX/NSIS/" echo "NSIS_USING_LOG_BUILD=1" >> $GITHUB_ENV + - name: Set temp dirs correctly + if: startsWith(matrix.os, 'windows') + # https://github.com/actions/virtual-environments/issues/712 + shell: powershell + run: | + echo "TMPDIR=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV + echo "TEMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV + echo "TMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV - name: Run examples and prepare artifacts run: | source ../conda/etc/profile.d/conda.sh diff --git a/scripts/run_examples.py b/scripts/run_examples.py index ab5a8d0b2..3907d8593 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -9,6 +9,7 @@ import tempfile import platform import shutil +from pathlib import Path from constructor.utils import rm_rf @@ -78,6 +79,8 @@ def run_examples(keep_artifacts=None): print(example_path) print('-' * len(example_path)) output_dir = tempfile.mkdtemp(dir=parent_output) + # resolve path to avoid some issues with TEMPDIR on Windows + output_dir = Path(output_dir).resolve() cmd = COV_CMD + ['constructor', example_path, '--output-dir', output_dir] errored += _execute(cmd) for fpath in os.listdir(output_dir): From 433d3db388e908701e60492b47804d0ffce26310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 14:28:56 +0200 Subject: [PATCH 36/72] add timings and handle io errors in run_examples --- scripts/run_examples.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 3907d8593..c909b800b 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -9,6 +9,9 @@ import tempfile import platform import shutil +import time +from datetime import timedelta + from pathlib import Path from constructor.utils import rm_rf @@ -30,14 +33,17 @@ def _execute(cmd): print(' '.join(cmd)) + t0 = time.time() p = subprocess.Popen(cmd, stderr=subprocess.PIPE) print('--- STDOUT ---') _, stderr = p.communicate() + t1 = time.time() if stderr: print('--- STDERR ---') if PY3: stderr = stderr.decode() print(stderr.strip()) + print('--- Execution done in', timedelta(seconds=t1 - t0)) return p.returncode != 0 @@ -118,12 +124,17 @@ def run_examples(keep_artifacts=None): test_errored = _execute(cmd) if ext == 'exe' and os.environ.get("NSIS_USING_LOG_BUILD"): test_errored = 0 - with open(os.path.join(env_dir, "install.log"), encoding="utf-16-le") as f: - print('--- LOGS ---') - for line in f: - if ":error:" in line: - print(line.rstrip()) - test_errored = 1 + print('--- LOGS ---') + try: + with open(os.path.join(env_dir, "install.log"), encoding="utf-16-le") as f: + for line in f: + if ":error:" in line: + print(line.rstrip()) + test_errored = 1 + except Exception as exc: + test_errored = 1 + print(f"{type(exc)}: {exc}") + errored += test_errored if keep_artifacts: shutil.move(fpath, keep_artifacts) From 20727ea06d3fb33579db8dd4a991d45d31e88a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 14:44:34 +0200 Subject: [PATCH 37/72] prettier debugging --- scripts/run_examples.py | 45 ++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index c909b800b..0e934cd01 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -34,17 +34,19 @@ def _execute(cmd): print(' '.join(cmd)) t0 = time.time() - p = subprocess.Popen(cmd, stderr=subprocess.PIPE) - print('--- STDOUT ---') - _, stderr = p.communicate() + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + stdout, stderr = p.communicate() t1 = time.time() - if stderr: - print('--- STDERR ---') - if PY3: - stderr = stderr.decode() - print(stderr.strip()) + errored = p.returncode != 0 + if errored: + if stdout: + print('--- STDOUT ---') + print(stdout) + if stderr: + print('--- STDERR ---') + print(stderr) print('--- Execution done in', timedelta(seconds=t1 - t0)) - return p.returncode != 0 + return errored def run_examples(keep_artifacts=None): @@ -81,14 +83,16 @@ def run_examples(keep_artifacts=None): parent_output = tempfile.mkdtemp() tested_files = set() + which_errored = {} for example_path in sorted(example_paths): print(example_path) print('-' * len(example_path)) output_dir = tempfile.mkdtemp(dir=parent_output) # resolve path to avoid some issues with TEMPDIR on Windows - output_dir = Path(output_dir).resolve() + output_dir = str(Path(output_dir).resolve()) cmd = COV_CMD + ['constructor', example_path, '--output-dir', output_dir] - errored += _execute(cmd) + creation_errored = _execute(cmd) + errored += creation_errored for fpath in os.listdir(output_dir): ext = fpath.rsplit('.', 1)[-1] if fpath in tested_files or ext not in ('sh', 'exe', 'pkg'): @@ -139,14 +143,23 @@ def run_examples(keep_artifacts=None): if keep_artifacts: shutil.move(fpath, keep_artifacts) # more complete logs are available under /var/log/install.log - if test_errored and ext == "pkg" and os.environ.get("CI"): - print('--- LOGS ---') - print("Tip: Debug locally and check the full logs in the Installer UI") - print(" or check /var/log/install.log if run from the CLI.") + if test_errored: + which_errored.setdefault(example_path, []).append(fpath) + if ext == "pkg" and os.environ.get("CI"): + print('--- LOGS ---') + print("Tip: Debug locally and check the full logs in the Installer UI") + print(" or check /var/log/install.log if run from the CLI.") + if creation_errored: + which_errored.setdefault(example_path, []).append("could not create installer") print('') + break if errored: - print('Some examples failed!') + print('Some examples failed:') + for installer, reasons in which_errored.items(): + print(f"+ {os.path.basename(installer)}") + for reason in reasons: + print(f"---> {os.path.basename(reason)}") print('Assets saved in: %s' % parent_output) else: print('All examples ran successfully!') From f2e06bfcba1d3d61db6571372437e0ffaffcc62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 14:57:54 +0200 Subject: [PATCH 38/72] document the nuances in run_examples --- scripts/run_examples.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 0e934cd01..80d37f5fe 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -126,33 +126,37 @@ def run_examples(keep_artifacts=None): # This is why we have this weird .split() thingy down here: cmd = ['cmd.exe', '/c', 'start', '/wait', fpath, '/S', *f'/D={env_dir}'.split()] test_errored = _execute(cmd) + # Windows EXEs never throw a non-0 exit code, so we need to check the logs, + # which are only written if a special NSIS build is used + win_error_lines = [] if ext == 'exe' and os.environ.get("NSIS_USING_LOG_BUILD"): test_errored = 0 - print('--- LOGS ---') try: with open(os.path.join(env_dir, "install.log"), encoding="utf-16-le") as f: for line in f: if ":error:" in line: - print(line.rstrip()) + win_error_lines.append(line) test_errored = 1 except Exception as exc: test_errored = 1 print(f"{type(exc)}: {exc}") - errored += test_errored - if keep_artifacts: - shutil.move(fpath, keep_artifacts) - # more complete logs are available under /var/log/install.log if test_errored: which_errored.setdefault(example_path, []).append(fpath) + if win_error_lines: + print('--- LOGS ---') + for line in win_error_lines: + print(line.rstrip()) if ext == "pkg" and os.environ.get("CI"): + # more complete logs are available under /var/log/install.log print('--- LOGS ---') print("Tip: Debug locally and check the full logs in the Installer UI") print(" or check /var/log/install.log if run from the CLI.") + if keep_artifacts: + shutil.move(fpath, keep_artifacts) if creation_errored: which_errored.setdefault(example_path, []).append("could not create installer") print('') - break if errored: print('Some examples failed:') From ede8e86c9ba8be3994ca20fdd76194bbffa09c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 15:00:24 +0200 Subject: [PATCH 39/72] handle IO error lines --- scripts/run_examples.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 80d37f5fe..b2824dbf8 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -139,7 +139,7 @@ def run_examples(keep_artifacts=None): test_errored = 1 except Exception as exc: test_errored = 1 - print(f"{type(exc)}: {exc}") + win_error_lines.append(f"Could not read logs! {type(exc)}: {exc}") errored += test_errored if test_errored: which_errored.setdefault(example_path, []).append(fpath) From 6464409d59cc9281134e3d3e975746a15857110d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 15:16:54 +0200 Subject: [PATCH 40/72] run examples on noconda --- examples/miniconda/construct.yaml | 2 +- examples/noconda/construct.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/miniconda/construct.yaml b/examples/miniconda/construct.yaml index 01edb638a..8661da87d 100644 --- a/examples/miniconda/construct.yaml +++ b/examples/miniconda/construct.yaml @@ -9,5 +9,5 @@ specs: - python - conda -check_path_spaces: False # [unix] +check_path_spaces: False check_path_length: False diff --git a/examples/noconda/construct.yaml b/examples/noconda/construct.yaml index 24caf68af..059a31ad3 100644 --- a/examples/noconda/construct.yaml +++ b/examples/noconda/construct.yaml @@ -11,5 +11,5 @@ conclusion_text: | This is a second line and should appear as such on the installer UI. This would be the third one. -check_path_spaces: False +check_path_spaces: False # [unix] check_path_length: False From b5554bff484ccab2d00237fd0e53bfc1836dce6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 15:33:32 +0200 Subject: [PATCH 41/72] add a little tip --- scripts/run_examples.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index b2824dbf8..a5a054b5f 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -139,7 +139,12 @@ def run_examples(keep_artifacts=None): test_errored = 1 except Exception as exc: test_errored = 1 - win_error_lines.append(f"Could not read logs! {type(exc)}: {exc}") + win_error_lines.append( + f"Could not read logs! {exc.__class__.__name__}: {exc}\n" + "This usually means that the destination folder could not be created.\n" + "Possible causes: permissions, non-supported characters, long paths...\n" + "Consider setting 'check_path_spaces' and 'check_path_length' to 'False'." + ) errored += test_errored if test_errored: which_errored.setdefault(example_path, []).append(fpath) From a6136c984a0fec4c6ada06176c8957af3b7ef0a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 15:33:51 +0200 Subject: [PATCH 42/72] this should pass --- examples/noconda/construct.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/noconda/construct.yaml b/examples/noconda/construct.yaml index 059a31ad3..24caf68af 100644 --- a/examples/noconda/construct.yaml +++ b/examples/noconda/construct.yaml @@ -11,5 +11,5 @@ conclusion_text: | This is a second line and should appear as such on the installer UI. This would be the third one. -check_path_spaces: False # [unix] +check_path_spaces: False check_path_length: False From 611d2c4b0dbefc66e95abce4d49575a9069308d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Wed, 24 Aug 2022 15:54:54 +0200 Subject: [PATCH 43/72] handle edge cases for empty log files too --- scripts/run_examples.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index a5a054b5f..b460b1e84 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -63,9 +63,16 @@ def run_examples(keep_artifacts=None): int Number of failed examples """ + if sys.platform.startswith("win") and "NSIS_USING_LOG_BUILD" not in os.environ: + print( + "! Warning !" + " Windows installers are tested with NSIS in silent mode, which does" + " not report errors on exit. You should use logging-enabled NSIS builds" + " to generate a 'install.log' file the script will search for errors" + " after completion." + ) example_paths = [] errored = 0 - if platform.system() != 'Darwin': BLACKLIST.append(os.path.join(EXAMPLES_DIR, "osxpkg")) if keep_artifacts: @@ -132,11 +139,16 @@ def run_examples(keep_artifacts=None): if ext == 'exe' and os.environ.get("NSIS_USING_LOG_BUILD"): test_errored = 0 try: + log_is_empty = True with open(os.path.join(env_dir, "install.log"), encoding="utf-16-le") as f: for line in f: + log_is_empty = False if ":error:" in line: win_error_lines.append(line) test_errored = 1 + if log_is_empty: + test_errored = 1 + win_error_lines.append("Logfile was unexpectedly empty!") except Exception as exc: test_errored = 1 win_error_lines.append( From 86e136051adf248aabd97b7aea470a181690cfaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Tue, 30 Aug 2022 12:04:00 +0200 Subject: [PATCH 44/72] update news --- news/449-allow-spaces-in-prefix | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/news/449-allow-spaces-in-prefix b/news/449-allow-spaces-in-prefix index 8d08a0df6..5f0c40066 100644 --- a/news/449-allow-spaces-in-prefix +++ b/news/449-allow-spaces-in-prefix @@ -1,27 +1,22 @@ -Enhancements: -------------- +### Enhancements: -* Installers will allow spaces in `PREFIX` by default now. +* Installers support spaces in `PREFIX` now. Old behaviour (reject chosen path if it contained spaces) is still default. - Opt-in by setting `check_path_spaces` to `False`. + Opt-in by setting `check_path_spaces` to `False`. (#449) -Bug fixes: ----------- +### Bug fixes: * -Deprecations: -------------- +### Deprecations: * -Docs: ------ +### Docs: * -Other: ------- +### Other: * From 332e101df52cb8b5a16748a5cf68d10737c694a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Tue, 6 Sep 2022 10:58:32 +0200 Subject: [PATCH 45/72] do not check path on this example either --- examples/customize_controls/construct.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/customize_controls/construct.yaml b/examples/customize_controls/construct.yaml index d7c0eea8d..f6a315bbe 100644 --- a/examples/customize_controls/construct.yaml +++ b/examples/customize_controls/construct.yaml @@ -11,3 +11,5 @@ specs: register_python: False initialize_conda: False +check_path_spaces: False +check_path_length: False From 168dc1b7fb2ed935f69431005d64443f2815e643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Tue, 6 Sep 2022 17:10:45 +0200 Subject: [PATCH 46/72] avoid issues with spaces in shebangs during initialization --- constructor/header.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/constructor/header.sh b/constructor/header.sh index 330c7d75e..573deff55 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -553,13 +553,15 @@ if [ "$BATCH" = "0" ]; then printf "\\n" else case $SHELL in - *zsh) "$PREFIX/bin/conda" init zsh ;; - *) "$PREFIX/bin/conda" init ;; + # We call the module directly to avoid issues with spaces in shebang + *zsh) "$PREFIX/bin/python" -m conda init zsh ;; + *) "$PREFIX/bin/python" -m conda init ;; esac if [ -f "$PREFIX/bin/mamba" ]; then case $SHELL in - *zsh) "$PREFIX/bin/mamba" init zsh ;; - *) "$PREFIX/bin/mamba" init ;; + # We call the entry point directly to avoid issues with spaces in shebang + *zsh) "$PREFIX/bin/python" "$PREFIX/bin/mamba" init zsh ;; + *) "$PREFIX/bin/python" "$PREFIX/bin/mamba" init ;; esac fi fi From 727f3097dadef6f6d36a96081f2479f5d5dcccff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Mon, 12 Sep 2022 12:39:43 +0200 Subject: [PATCH 47/72] update docs --- CONSTRUCT.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/CONSTRUCT.md b/CONSTRUCT.md index 92d41aaa5..d74c785eb 100644 --- a/CONSTRUCT.md +++ b/CONSTRUCT.md @@ -534,9 +534,6 @@ Check if the path where the distribution is installed contains spaces and show a Read notes about the particularities of Windows silent mode `/S` in the `installer_type` documentation. -Read notes about the particularities of Windows silent mode `/S` in the -`installer_type` documentation. - ## `nsis_template` _required:_ no
From 2041d86b7e17ae917e42ed1a92285ca003842ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Mon, 12 Sep 2022 12:43:47 +0200 Subject: [PATCH 48/72] do not rely on direct entry points --- examples/extra_envs/test_install.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/extra_envs/test_install.sh b/examples/extra_envs/test_install.sh index 4bc89bdd9..cff46f471 100644 --- a/examples/extra_envs/test_install.sh +++ b/examples/extra_envs/test_install.sh @@ -11,16 +11,20 @@ fi # base environment uses python 3.9 and excludes tk test -f "$PREFIX/conda-meta/history" "$PREFIX/bin/python" -c "from sys import version_info; assert version_info[:2] == (3, 9)" -"$PREFIX/bin/pip" -V +# we use python -m pip instead of the pip entry point +# because the spaces break the shebang - this will be fixed +# with a new conda release, but for now this is the workaround +# we need. same with conda in the block below! +"$PREFIX/bin/python" -m pip -V # tk(inter) shouldn't be listed by conda! -"$PREFIX/bin/conda" list -p "$PREFIX" | grep tk && exit 1 +"$PREFIX/bin/python" -m conda list -p "$PREFIX" | grep tk && exit 1 echo "Previous test failed as expected" # extra env named 'py310' uses python 3.10, has tk, but we removed setuptools test -f "$PREFIX/envs/py310/conda-meta/history" "$PREFIX/envs/py310/bin/python" -c "from sys import version_info; assert version_info[:2] == (3, 10)" # setuptools shouldn't be listed by conda! -"$PREFIX/bin/conda" list -p "$PREFIX/envs/py310" | grep setuptools && exit 1 +"$PREFIX/bin/python" -m conda list -p "$PREFIX/envs/py310" | grep setuptools && exit 1 "$PREFIX/envs/py310/bin/python" -c "import setuptools" && exit 1 echo "Previous test failed as expected" From 63dcaf4c67497e95923c8fe070c2b68ae9eb1e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Mon, 12 Sep 2022 21:51:38 +0200 Subject: [PATCH 49/72] fix pytest --- tests/test_header.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/test_header.py b/tests/test_header.py index 4836d16a9..343363a99 100644 --- a/tests/test_header.py +++ b/tests/test_header.py @@ -54,7 +54,15 @@ def test_linux_template_processing( @pytest.mark.parametrize("arch", ["x86_64", "arm64"]) @pytest.mark.parametrize("check_path_spaces", [False, True]) @pytest.mark.parametrize( - "script", ["post_extract.sh", "preinstall.sh", "update_path.sh", "clean_cache.sh"] + "script", + [ + "checks_before_install.sh", + "prepare_installation.sh", + "run_installation.sh", + "update_path.sh", + "clean_cache.sh", + "run_user_script.sh", + ] ) def test_osxpkg_template_processing(arch, check_path_spaces, script): with open(os.path.join(OSX_DIR, script)) as f: From 3b9706741a0df52df3688153a79db8e22a6b9c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Mon, 12 Sep 2022 21:51:45 +0200 Subject: [PATCH 50/72] quote these too --- constructor/osx/prepare_installation.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/constructor/osx/prepare_installation.sh b/constructor/osx/prepare_installation.sh index c80217fdb..f2b32ca6e 100644 --- a/constructor/osx/prepare_installation.sh +++ b/constructor/osx/prepare_installation.sh @@ -25,8 +25,8 @@ CONDA_EXEC="$PREFIX/conda.exe" chmod +x "$CONDA_EXEC" # Create a blank history file so conda thinks this is an existing env -mkdir -p $PREFIX/conda-meta -touch $PREFIX/conda-meta/history +mkdir -p "$PREFIX/conda-meta" +touch "$PREFIX/conda-meta/history" # Extract the conda packages but avoiding the overwriting of the # custom metadata we have already put in place From 794dc9f8cf63a73ccdcec3f425018ffb748c6244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Mon, 12 Sep 2022 22:00:17 +0200 Subject: [PATCH 51/72] do not check path on examples --- examples/scripts/construct.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/scripts/construct.yaml b/examples/scripts/construct.yaml index 187fba4b1..97d64e197 100644 --- a/examples/scripts/construct.yaml +++ b/examples/scripts/construct.yaml @@ -11,3 +11,5 @@ pre_install_desc: "Adding this description makes the script selectable in the UI post_install: post_install.sh # [unix] post_install: post_install.bat # [win] post_install_desc: "Adding this description makes the script selectable in the UI" +check_path_spaces: False +check_path_length: False From 75d6b32f31dd87eae2be40bbda6c43c3c13aeb36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Tue, 13 Sep 2022 10:52:52 +0200 Subject: [PATCH 52/72] None is a valid value --- constructor/osxpkg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/constructor/osxpkg.py b/constructor/osxpkg.py index 0f2436608..bd9a4f2b4 100644 --- a/constructor/osxpkg.py +++ b/constructor/osxpkg.py @@ -255,7 +255,7 @@ def move_script(src, dst, info, ensure_shebang=False, user_script_type=None): Fill template scripts checks_before_install.sh, prepare_installation.sh and others, and move them to the installer workspace. """ - assert user_script_type in ("pre_install", "post_install") + assert user_script_type in (None, "pre_install", "post_install") with open(src) as fi: data = fi.read() From dcc0a4566b040ad586b9ee60bd0614f8e58601ed Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Fri, 16 Sep 2022 17:58:02 +0100 Subject: [PATCH 53/72] More quotes and use POSIX sh syntax --- examples/osxpkg/test_install.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/osxpkg/test_install.sh b/examples/osxpkg/test_install.sh index 60960ae24..460d73ad1 100644 --- a/examples/osxpkg/test_install.sh +++ b/examples/osxpkg/test_install.sh @@ -1,11 +1,11 @@ -#!/bin/bash +#!/bin/sh set -ex -echo '## Hello from Post_install script ' > $HOME/postinstall.txt -printenv >> $HOME/postinstall.txt +echo '## Hello from Post_install script ' > "$HOME/postinstall.txt" +printenv >> "$HOME/postinstall.txt" # Some tests # default_location_pkg -[[ $(basename $(dirname "$PREFIX")) == "Library" ]] || exit 1 +[ "$(basename "$(dirname "$PREFIX")")" = "Library" ] || exit 1 # pkg_name -[[ $(basename "$PREFIX") == "osx pkg test" ]] || exit 1 +[ "$(basename "$PREFIX")" = "osx pkg test" ] || exit 1 From 604b88b5f1d9c8996654e401d4ed3d0c3c1353ae Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Mon, 2 Jan 2023 16:11:41 +0100 Subject: [PATCH 54/72] Fix --- constructor/header.sh | 2 +- examples/extra_envs/construct.yaml | 1 + examples/signing/construct.yaml | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/constructor/header.sh b/constructor/header.sh index 1c552c98e..7e924f56f 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -441,7 +441,7 @@ rm -f "$PREFIX/pkgs/env.txt" #if has_conda mkdir -p "$PREFIX/envs" -for env_pkgs in "${PREFIX}/pkgs/envs/*/"; do +for env_pkgs in "${PREFIX}"/pkgs/envs/*/; do env_name=$(basename "${env_pkgs}") if [ "$env_name" = "*" ]; then continue diff --git a/examples/extra_envs/construct.yaml b/examples/extra_envs/construct.yaml index b8a06ab7b..3c2721263 100644 --- a/examples/extra_envs/construct.yaml +++ b/examples/extra_envs/construct.yaml @@ -25,3 +25,4 @@ extra_envs: post_install: test_install.sh # [unix] post_install: test_install.bat # [win] +check_path_spaces: False diff --git a/examples/signing/construct.yaml b/examples/signing/construct.yaml index f4453b415..e8bd13380 100644 --- a/examples/signing/construct.yaml +++ b/examples/signing/construct.yaml @@ -8,3 +8,4 @@ specs: # This certificate is generated an copied over on the spot during CI # See scripts/create_self_signed_certificate.ps1 for more info signing_certificate: certificate.pfx # [win] +check_path_spaces: False From 42c76b85f12c75f497d0e61b059bee30078f00c8 Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Mon, 2 Jan 2023 17:58:54 +0100 Subject: [PATCH 55/72] Update constructor/header.sh Co-authored-by: Ken Odegard --- constructor/header.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/constructor/header.sh b/constructor/header.sh index 7e924f56f..9493e93fc 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -561,9 +561,9 @@ if [ "$BATCH" = "0" ]; then esac if [ -f "$PREFIX/bin/mamba" ]; then case $SHELL in - # We call the entry point directly to avoid issues with spaces in shebang - *zsh) "$PREFIX/bin/python" "$PREFIX/bin/mamba" init zsh ;; - *) "$PREFIX/bin/python" "$PREFIX/bin/mamba" init ;; + # We call the module directly to avoid issues with spaces in shebang + *zsh) "$PREFIX/bin/python" -m mamba.mamba init zsh ;; + *) "$PREFIX/bin/python" -m mamba.mamba init ;; esac fi fi From 3923546398120998a8cca7816be43bfd99291cd0 Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Mon, 2 Jan 2023 18:56:57 +0100 Subject: [PATCH 56/72] Run examples in un-buffered mode to see output --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b37dea4b0..506f6fb75 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -124,7 +124,7 @@ jobs: source $CONDA/etc/profile.d/conda.sh conda activate constructor mkdir -p examples_artifacts/ - python scripts/run_examples.py --keep-artifacts=examples_artifacts/ + python -u scripts/run_examples.py --keep-artifacts=examples_artifacts/ - name: Upload the example installers as artifacts if: github.event_name == 'pull_request' && matrix.pyver == '3.9' uses: actions/upload-artifact@v3 From 7a88a84c94fdb26f95aeb13fc17c4404548f749a Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Tue, 3 Jan 2023 13:05:06 +0100 Subject: [PATCH 57/72] Set 5 minute timeout for example execution --- scripts/run_examples.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 618622c73..4d74df599 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -35,9 +35,15 @@ def _execute(cmd): print(' '.join(cmd)) t0 = time.time() p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - stdout, stderr = p.communicate() + try: + stdout, stderr = p.communicate(timeout=300) + errored = p.returncode != 0 + except subprocess.TimeoutExpired: + p.kill() + stdout, stderr = p.communicate() + print('--- TEST TIMEOUT ---') + errored = True t1 = time.time() - errored = p.returncode != 0 if errored: if stdout: print('--- STDOUT ---') From aa5719f80c4a1eff46ef99b9aacb42bca3596b3c Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Thu, 5 Jan 2023 13:29:56 +0100 Subject: [PATCH 58/72] Convert uninstall return code into error --- scripts/run_examples.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 4d74df599..472843785 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -188,7 +188,12 @@ def run_examples(keep_artifacts=None): # the tempdir cleanup later f"/S _?={env_dir}" ] - _execute(cmd) + test_errored = _execute(cmd) + errored += test_errored + if test_errored: + which_errored.setdefault(example_path, []).append( + "Wrong uninstall exit code or timeout." + ) paths_after_uninstall = os.listdir(env_dir) if len(paths_after_uninstall) > 2: # The debug installer writes to install.log too, which will only From 524f052f4aec80f6016cd246074b760da9b75efc Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Thu, 5 Jan 2023 14:25:53 +0100 Subject: [PATCH 59/72] Test without spaces on windows --- scripts/run_examples.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 472843785..18d02749b 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -111,7 +111,8 @@ def run_examples(keep_artifacts=None): if fpath in tested_files or ext not in ('sh', 'exe', 'pkg'): continue tested_files.add(fpath) - env_dir = tempfile.mkdtemp(suffix="s p a c e s", dir=output_dir) + test_suffix = "s p a c e s" if not sys.platform.startswith("win") else None + env_dir = tempfile.mkdtemp(suffix=test_suffix, dir=output_dir) rm_rf(env_dir) print('--- Testing %s' % fpath) fpath = os.path.join(output_dir, fpath) From ac2e7c6f975df86d04316b9efbdb8c9135b043fd Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Thu, 5 Jan 2023 18:03:52 +0100 Subject: [PATCH 60/72] Update scripts/run_examples.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jaime Rodríguez-Guerra --- scripts/run_examples.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 18d02749b..a328f3b7c 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -187,7 +187,7 @@ def run_examples(keep_artifacts=None): # waited; otherwise, since the uninstaller copies itself to a different location # so it can be auto-deleted, it returns immediately and it gives us problems with # the tempdir cleanup later - f"/S _?={env_dir}" + "/S", *f"_?={env_dir}".split() ] test_errored = _execute(cmd) errored += test_errored From 4bc1b0c48a6552bcc5a9cf6d30db764a9ce0cfd3 Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Thu, 5 Jan 2023 18:20:21 +0100 Subject: [PATCH 61/72] Revert "Test without spaces on windows" This reverts commit 524f052f4aec80f6016cd246074b760da9b75efc. --- scripts/run_examples.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index a328f3b7c..277940558 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -111,8 +111,7 @@ def run_examples(keep_artifacts=None): if fpath in tested_files or ext not in ('sh', 'exe', 'pkg'): continue tested_files.add(fpath) - test_suffix = "s p a c e s" if not sys.platform.startswith("win") else None - env_dir = tempfile.mkdtemp(suffix=test_suffix, dir=output_dir) + env_dir = tempfile.mkdtemp(suffix="s p a c e s", dir=output_dir) rm_rf(env_dir) print('--- Testing %s' % fpath) fpath = os.path.join(output_dir, fpath) From 59342a0a6416e251c909e0a33733ae84194e3abc Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Fri, 6 Jan 2023 13:31:32 +0100 Subject: [PATCH 62/72] Revert "Update scripts/run_examples.py" This reverts commit ac2e7c6f975df86d04316b9efbdb8c9135b043fd. --- scripts/run_examples.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 277940558..472843785 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -186,7 +186,7 @@ def run_examples(keep_artifacts=None): # waited; otherwise, since the uninstaller copies itself to a different location # so it can be auto-deleted, it returns immediately and it gives us problems with # the tempdir cleanup later - "/S", *f"_?={env_dir}".split() + f"/S _?={env_dir}" ] test_errored = _execute(cmd) errored += test_errored From 04e89c688611f3f840e16e130d5bb40fef1e3a25 Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Fri, 6 Jan 2023 13:31:40 +0100 Subject: [PATCH 63/72] Revert "Revert "Test without spaces on windows"" This reverts commit 4bc1b0c48a6552bcc5a9cf6d30db764a9ce0cfd3. --- scripts/run_examples.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 472843785..18d02749b 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -111,7 +111,8 @@ def run_examples(keep_artifacts=None): if fpath in tested_files or ext not in ('sh', 'exe', 'pkg'): continue tested_files.add(fpath) - env_dir = tempfile.mkdtemp(suffix="s p a c e s", dir=output_dir) + test_suffix = "s p a c e s" if not sys.platform.startswith("win") else None + env_dir = tempfile.mkdtemp(suffix=test_suffix, dir=output_dir) rm_rf(env_dir) print('--- Testing %s' % fpath) fpath = os.path.join(output_dir, fpath) From f907a4e180a3469ab5ace633f7f664e96964cb55 Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Fri, 6 Jan 2023 16:12:56 +0100 Subject: [PATCH 64/72] Test some windows installers with spaces, but then without uninstaller test --- scripts/run_examples.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 18d02749b..88835fc1b 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -111,7 +111,8 @@ def run_examples(keep_artifacts=None): if fpath in tested_files or ext not in ('sh', 'exe', 'pkg'): continue tested_files.add(fpath) - test_suffix = "s p a c e s" if not sys.platform.startswith("win") else None + test_with_spaces = not sys.platform.startswith("win") or "conda" in fpath.lower() + test_suffix = "s p a c e s" if test_with_spaces else None env_dir = tempfile.mkdtemp(suffix=test_suffix, dir=output_dir) rm_rf(env_dir) print('--- Testing %s' % fpath) @@ -176,8 +177,10 @@ def run_examples(keep_artifacts=None): print('--- LOGS ---') print("Tip: Debug locally and check the full logs in the Installer UI") print(" or check /var/log/install.log if run from the CLI.") - elif ext == "exe": + elif ext == "exe" and not test_with_spaces: # The installer succeeded, test the uninstaller on Windows + # The un-installers are only tested when testing without spaces, as they hang during + # testing but work in UI mode. uninstaller = next((p for p in os.listdir(env_dir) if p.startswith("Uninstall-")), None) if uninstaller: cmd = [ From b37072d679ace7505cbc8733b4101347ecc0d53f Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Fri, 6 Jan 2023 19:38:36 +0100 Subject: [PATCH 65/72] Try quotes around env_dir for nsis uninstall calls --- scripts/run_examples.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 88835fc1b..c51e20f50 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -177,10 +177,10 @@ def run_examples(keep_artifacts=None): print('--- LOGS ---') print("Tip: Debug locally and check the full logs in the Installer UI") print(" or check /var/log/install.log if run from the CLI.") - elif ext == "exe" and not test_with_spaces: + elif ext == "exe": # The installer succeeded, test the uninstaller on Windows - # The un-installers are only tested when testing without spaces, as they hang during - # testing but work in UI mode. + # The un-installers are only tested when testing without spaces, as they hang + # during testing but work in UI mode. uninstaller = next((p for p in os.listdir(env_dir) if p.startswith("Uninstall-")), None) if uninstaller: cmd = [ @@ -190,7 +190,7 @@ def run_examples(keep_artifacts=None): # waited; otherwise, since the uninstaller copies itself to a different location # so it can be auto-deleted, it returns immediately and it gives us problems with # the tempdir cleanup later - f"/S _?={env_dir}" + f"/S _?='{env_dir}'" ] test_errored = _execute(cmd) errored += test_errored From 4a82db8be4d7669413def9782349b0495f57370a Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Sat, 7 Jan 2023 09:09:09 +0100 Subject: [PATCH 66/72] Revert "Try quotes around env_dir for nsis uninstall calls" This reverts commit b37072d679ace7505cbc8733b4101347ecc0d53f. --- scripts/run_examples.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index c51e20f50..88835fc1b 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -177,10 +177,10 @@ def run_examples(keep_artifacts=None): print('--- LOGS ---') print("Tip: Debug locally and check the full logs in the Installer UI") print(" or check /var/log/install.log if run from the CLI.") - elif ext == "exe": + elif ext == "exe" and not test_with_spaces: # The installer succeeded, test the uninstaller on Windows - # The un-installers are only tested when testing without spaces, as they hang - # during testing but work in UI mode. + # The un-installers are only tested when testing without spaces, as they hang during + # testing but work in UI mode. uninstaller = next((p for p in os.listdir(env_dir) if p.startswith("Uninstall-")), None) if uninstaller: cmd = [ @@ -190,7 +190,7 @@ def run_examples(keep_artifacts=None): # waited; otherwise, since the uninstaller copies itself to a different location # so it can be auto-deleted, it returns immediately and it gives us problems with # the tempdir cleanup later - f"/S _?='{env_dir}'" + f"/S _?={env_dir}" ] test_errored = _execute(cmd) errored += test_errored From 0814e5cdba2cf32c7cd1bc54aebdec9cab658508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Mon, 9 Jan 2023 20:14:29 +0100 Subject: [PATCH 67/72] forbid spaces if conda is present in base on linux and macos --- constructor/construct.py | 7 +++++-- constructor/fcp.py | 22 ++++++++++++++++------ constructor/header.sh | 4 ++++ constructor/osxpkg.py | 19 +++++++------------ 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/constructor/construct.py b/constructor/construct.py index c590b1c9f..e37b77eb0 100644 --- a/constructor/construct.py +++ b/constructor/construct.py @@ -444,8 +444,11 @@ '''), ('check_path_spaces', False, bool, ''' -Check if the path where the distribution is installed contains spaces and show a warning -(EXE, SH installers) or error (PKG installer) if any spaces are found. Default is 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: + +- 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. diff --git a/constructor/fcp.py b/constructor/fcp.py index b1f834e13..737e9fc51 100644 --- a/constructor/fcp.py +++ b/constructor/fcp.py @@ -367,19 +367,28 @@ def _fetch_precs(precs, download_dir, transmute_file_type=''): def _main(name, version, download_dir, platform, channel_urls=(), channels_remap=(), specs=(), exclude=(), menu_packages=(), ignore_duplicate_files=True, environment=None, environment_file=None, verbose=True, dry_run=False, conda_exe="conda.exe", - transmute_file_type='', extra_envs=None): + transmute_file_type='', extra_envs=None, check_path_spaces=True): precs = _solve_precs( name, version, download_dir, platform, channel_urls=channel_urls, channels_remap=channels_remap, specs=specs, exclude=exclude, menu_packages=menu_packages, environment=environment, environment_file=environment_file, verbose=verbose, conda_exe=conda_exe ) + extra_envs = extra_envs or {} + conda_in_base: PackageCacheRecord = next((prec for prec in precs if prec.name == "conda"), None) + if conda_in_base: + if not check_path_spaces and platform.startswith(("linux-", "osx-")): + raise RuntimeError( + "'check_path_spaces=False' cannot be used on Linux and macOS installers " + "if 'conda' is present in the 'base' environment." + ) + elif extra_envs: + raise RuntimeError( + "conda needs to be present in 'base' environment for 'extra_envs' to work" + ) extra_envs_precs = {} - for env_name, env_config in (extra_envs or {}).items(): - if not any(prec.name == "conda" for prec in precs): - raise RuntimeError("conda needs to be present in `base` environment for extra_envs to work") - + for env_name, env_config in extra_envs.items(): if verbose: print("Solving extra environment:", env_name) extra_envs_precs[env_name] = _solve_precs( @@ -445,6 +454,7 @@ def main(info, verbose=True, dry_run=False, conda_exe="conda.exe"): environment_file = info.get("environment_file", None) transmute_file_type = info.get("transmute_file_type", "") extra_envs = info.get("extra_envs", {}) + check_path_spaces = info.get("check_path_spaces", True) if not channel_urls and not channels_remap: sys.exit("Error: at least one entry in 'channels' or 'channels_remap' is required") @@ -467,7 +477,7 @@ def main(info, verbose=True, dry_run=False, conda_exe="conda.exe"): has_conda, extra_envs_info) = _main( name, version, download_dir, platform, channel_urls, channels_remap, specs, exclude, menu_packages, ignore_duplicate_files, environment, environment_file, - verbose, dry_run, conda_exe, transmute_file_type, extra_envs + verbose, dry_run, conda_exe, transmute_file_type, extra_envs, check_path_spaces ) info["_all_pkg_records"] = pkg_records # full PackageRecord objects diff --git a/constructor/header.sh b/constructor/header.sh index 9493e93fc..b5d8859d9 100644 --- a/constructor/header.sh +++ b/constructor/header.sh @@ -58,7 +58,11 @@ Installs __NAME__ __VERSION__ #if not keep_pkgs -k do not clear the package cache after installation #endif +#if check_path_spaces +-p PREFIX install prefix, defaults to $PREFIX, must not contain spaces. +#else -p PREFIX install prefix, defaults to $PREFIX +#endif -s skip running pre/post-link/install scripts -u update an existing installation #if has_conda diff --git a/constructor/osxpkg.py b/constructor/osxpkg.py index bd9a4f2b4..eaee55d23 100644 --- a/constructor/osxpkg.py +++ b/constructor/osxpkg.py @@ -374,18 +374,13 @@ def pkgbuild_script(name, info, src, dst='postinstall', **kwargs): def create(info, verbose=False): # Do some configuration checks if info.get("check_path_spaces", True) is True: - if " " in info.get("default_location_pkg", ""): - sys.exit( - "ERROR: 'check_path_spaces' is enabled, but 'default_location_pkg' " - "contains spaces. This will always result in a failed " - "installation! Aborting!" - ) - if " " in info.get("pkg_name", ""): - sys.exit( - "ERROR: 'check_path_spaces' is enabled, but 'pkg_name' " - "contains spaces. This will always result in a failed " - "installation! Aborting!" - ) + for key in "default_location_pkg", "pkg_name": + if " " in info.get(key, ""): + sys.exit( + f"ERROR: 'check_path_spaces' is enabled, but '{key}' " + "contains spaces. This will always result in a failed " + "installation! Aborting!" + ) global CACHE_DIR, PACKAGE_ROOT, PACKAGES_DIR, SCRIPTS_DIR From f0b462704fdc639f5c4ba9886cf9cce9e2800280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Mon, 9 Jan 2023 20:38:50 +0100 Subject: [PATCH 68/72] refine which examples support spaces --- examples/customize_controls/construct.yaml | 2 -- examples/extra_envs/construct.yaml | 3 --- examples/jetsonconda/construct.yaml | 3 --- examples/miniconda/construct.yaml | 3 --- examples/osxpkg/construct.yaml | 6 ++---- examples/shortcuts/construct.yaml | 2 -- scripts/run_examples.py | 4 +++- 7 files changed, 5 insertions(+), 18 deletions(-) diff --git a/examples/customize_controls/construct.yaml b/examples/customize_controls/construct.yaml index f6a315bbe..d7c0eea8d 100644 --- a/examples/customize_controls/construct.yaml +++ b/examples/customize_controls/construct.yaml @@ -11,5 +11,3 @@ specs: register_python: False initialize_conda: False -check_path_spaces: False -check_path_length: False diff --git a/examples/extra_envs/construct.yaml b/examples/extra_envs/construct.yaml index 20e8681c4..ecec305e4 100644 --- a/examples/extra_envs/construct.yaml +++ b/examples/extra_envs/construct.yaml @@ -1,8 +1,6 @@ name: ExtraEnvs version: X installer_type: all -check_path_spaces: False -check_path_length: False channels: - http://repo.anaconda.com/pkgs/main/ specs: @@ -25,7 +23,6 @@ extra_envs: post_install: test_install.sh # [unix] post_install: test_install.bat # [win] -check_path_spaces: False build_outputs: - info.json - pkgs_list diff --git a/examples/jetsonconda/construct.yaml b/examples/jetsonconda/construct.yaml index 426cf2636..d9eb5f9a4 100644 --- a/examples/jetsonconda/construct.yaml +++ b/examples/jetsonconda/construct.yaml @@ -18,6 +18,3 @@ specs: # Welcome image for Windows installer welcome_image: bird.png # [win] - -check_path_spaces: False -check_path_length: False diff --git a/examples/miniconda/construct.yaml b/examples/miniconda/construct.yaml index 8661da87d..8fe996cd6 100644 --- a/examples/miniconda/construct.yaml +++ b/examples/miniconda/construct.yaml @@ -8,6 +8,3 @@ channels: specs: - python - conda - -check_path_spaces: False -check_path_length: False diff --git a/examples/osxpkg/construct.yaml b/examples/osxpkg/construct.yaml index 868ae8ddf..e39618677 100644 --- a/examples/osxpkg/construct.yaml +++ b/examples/osxpkg/construct.yaml @@ -2,11 +2,9 @@ name: osxpkgtest version: 1.2.3 # This config will result in a default install path: -# "~/Library/osx pkg test" (spaces should work) +# "~/Library/osx-pkg-test" (spaces not allowed because 'conda' is in 'specs') default_location_pkg: Library -pkg_name: "osx pkg test" -check_path_spaces: False -check_path_length: False +pkg_name: "osx-pkg-test" channels: - http://repo.anaconda.com/pkgs/main/ diff --git a/examples/shortcuts/construct.yaml b/examples/shortcuts/construct.yaml index 5b2012486..238b5503f 100644 --- a/examples/shortcuts/construct.yaml +++ b/examples/shortcuts/construct.yaml @@ -10,5 +10,3 @@ specs: - conda - console_shortcut # [win] -check_path_spaces: False -check_path_length: False diff --git a/scripts/run_examples.py b/scripts/run_examples.py index 88835fc1b..ebf959326 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -29,6 +29,7 @@ PY3 = sys.version_info[0] == 3 WHITELIST = ['grin', 'jetsonconda', 'miniconda', 'newchan'] BLACKLIST = [] +WITH_SPACES = {"extra_files", "noconda", "signing", "scripts"} def _execute(cmd): @@ -103,6 +104,8 @@ def run_examples(keep_artifacts=None): output_dir = tempfile.mkdtemp(dir=parent_output) # resolve path to avoid some issues with TEMPDIR on Windows output_dir = str(Path(output_dir).resolve()) + example_name = Path(example_path).parent.name + test_with_spaces = example_name in WITH_SPACES cmd = COV_CMD + ['constructor', '-v', example_path, '--output-dir', output_dir] creation_errored = _execute(cmd) errored += creation_errored @@ -111,7 +114,6 @@ def run_examples(keep_artifacts=None): if fpath in tested_files or ext not in ('sh', 'exe', 'pkg'): continue tested_files.add(fpath) - test_with_spaces = not sys.platform.startswith("win") or "conda" in fpath.lower() test_suffix = "s p a c e s" if test_with_spaces else None env_dir = tempfile.mkdtemp(suffix=test_suffix, dir=output_dir) rm_rf(env_dir) From 4d392eb2c424d6c709d30a5ca63736250ac4446c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Mon, 9 Jan 2023 20:41:58 +0100 Subject: [PATCH 69/72] sync docs --- CONSTRUCT.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CONSTRUCT.md b/CONSTRUCT.md index 1233951e1..0ec1ed1bd 100644 --- a/CONSTRUCT.md +++ b/CONSTRUCT.md @@ -557,8 +557,11 @@ Read notes about the particularities of Windows silent mode `/S` in the _required:_ no
_type:_ boolean
-Check if the path where the distribution is installed contains spaces and show a warning -(EXE, SH installers) or error (PKG installer) if any spaces are found. Default is 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: + +- 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. From 9945cae5dbdde7f892d7711948515da47eb5bfc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Rodr=C3=ADguez-Guerra?= Date: Tue, 10 Jan 2023 09:28:19 +0100 Subject: [PATCH 70/72] fix osx test --- examples/osxpkg/test_install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/osxpkg/test_install.sh b/examples/osxpkg/test_install.sh index 460d73ad1..ce7abf0fd 100644 --- a/examples/osxpkg/test_install.sh +++ b/examples/osxpkg/test_install.sh @@ -8,4 +8,4 @@ printenv >> "$HOME/postinstall.txt" # default_location_pkg [ "$(basename "$(dirname "$PREFIX")")" = "Library" ] || exit 1 # pkg_name -[ "$(basename "$PREFIX")" = "osx pkg test" ] || exit 1 +[ "$(basename "$PREFIX")" = "osx-pkg-test" ] || exit 1 From 2da402614e732ffbb5d45364f6f36620c3ccdac9 Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Tue, 10 Jan 2023 12:04:28 +0100 Subject: [PATCH 71/72] Increase timeout --- scripts/run_examples.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run_examples.py b/scripts/run_examples.py index ebf959326..88fa39ba4 100644 --- a/scripts/run_examples.py +++ b/scripts/run_examples.py @@ -37,7 +37,7 @@ def _execute(cmd): t0 = time.time() p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) try: - stdout, stderr = p.communicate(timeout=300) + stdout, stderr = p.communicate(timeout=420) errored = p.returncode != 0 except subprocess.TimeoutExpired: p.kill() From c57b9ff82ba22ced09a04bd7ee951f67c303b743 Mon Sep 17 00:00:00 2001 From: Daniel Bast <2790401+dbast@users.noreply.github.com> Date: Tue, 10 Jan 2023 17:08:54 +0100 Subject: [PATCH 72/72] Update .github/workflows/main.yml --- .github/workflows/main.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 506f6fb75..b2cb1783b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -99,14 +99,6 @@ jobs: curl -sL "https://sourceforge.net/projects/nsis/files/NSIS%203/${nsis_version}/nsis-${nsis_version}-log.zip/download" -o "nsis-${nsis_version}-log.zip" 7z x "nsis-${nsis_version}-log.zip" -aoa -o"$CONDA_PREFIX/NSIS/" echo "NSIS_USING_LOG_BUILD=1" >> $GITHUB_ENV - - name: Set temp dirs correctly - if: startsWith(matrix.os, 'windows') - # https://github.com/actions/virtual-environments/issues/712 - shell: powershell - run: | - echo "TMPDIR=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV - echo "TEMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV - echo "TMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV - name: Generate self-signed certificate (Windows) if: startsWith(matrix.os, 'windows') shell: cmd