Skip to content

Commit

Permalink
Fix .sh license pager and test .sh installers in interactive mode (#638)
Browse files Browse the repository at this point in the history
* Test miniforge .sh installer in interactive mode on even Python versions

* Add License will Dollar to miniforge example

* Prevent variable substitution in LICENSE/CONCLUSION by the header.sh

* News

* Update examples/miniforge/EULA.txt

Co-authored-by: jaimergp <[email protected]>

* Update examples/miniforge/EULA.txt

Co-authored-by: jaimergp <[email protected]>

* Update examples/miniforge/EULA.txt

Co-authored-by: jaimergp <[email protected]>

* Protect use setable variables in header.sh against string subsitution

---------

Co-authored-by: jaimergp <[email protected]>
  • Loading branch information
dbast and jaimergp authored Feb 7, 2023
1 parent 59f9710 commit 224bab9
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 32 deletions.
54 changes: 27 additions & 27 deletions constructor/header.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ fi

# Export variables to make installer metadata available to pre/post install scripts
# NOTE: If more vars are added, make sure to update the examples/scripts tests too
export INSTALLER_NAME="__NAME__"
export INSTALLER_VER="__VERSION__"
export INSTALLER_PLAT="__PLAT__"
export INSTALLER_NAME='__NAME__'
export INSTALLER_VER='__VERSION__'
export INSTALLER_PLAT='__PLAT__'
export INSTALLER_TYPE="SH"

THIS_DIR=$(DIRNAME=$(dirname "$0"); cd "$DIRNAME"; pwd)
Expand All @@ -49,7 +49,7 @@ REINSTALL=0
USAGE="
usage: $0 [options]
Installs __NAME__ __VERSION__
Installs ${INSTALLER_NAME} ${INSTALLER_VER}
#if batch_mode
-i run install in interactive mode
Expand Down Expand Up @@ -130,9 +130,9 @@ then
if [ "$(uname -m)" = "x86_64" ]; then
printf "WARNING:\\n"
printf " Your system is x86_64, but you are trying to install an x86 (32-bit)\\n"
printf " version of __NAME__. Unless you have the necessary 32-bit libraries\\n"
printf " installed, __NAME__ will not work.\\n"
printf " We STRONGLY recommend installing the x86_64 version of __NAME__ on\\n"
printf " version of %s. Unless you have the necessary 32-bit libraries\\n" "${INSTALLER_NAME}"
printf " installed, %s will not work.\\n" "${INSTALLER_NAME}"
printf " We STRONGLY recommend installing the x86_64 version of %s on\\n" "${INSTALLER_NAME}"
printf " an x86_64 system.\\n"
printf " Are sure you want to continue the installation? [yes|no]\\n"
printf "[no] >>> "
Expand All @@ -150,7 +150,7 @@ then
if [ "$(uname -m)" != "x86_64" ]; then
printf "WARNING:\\n"
printf " Your operating system appears not to be 64-bit, but you are trying to\\n"
printf " install a 64-bit version of __NAME__.\\n"
printf " install a 64-bit version of %s.\\n" "${INSTALLER_NAME}"
printf " Are sure you want to continue the installation? [yes|no]\\n"
printf "[no] >>> "
read -r ans
Expand All @@ -167,7 +167,7 @@ then
if [ "$(uname -m)" != "ppc64le" ]; then
printf "WARNING:\\n"
printf " Your machine hardware does not appear to be Power8 (little endian), \\n"
printf " but you are trying to install a ppc64le version of __NAME__.\\n"
printf " but you are trying to install a ppc64le version of %s.\\n" "${INSTALLER_NAME}"
printf " Are sure you want to continue the installation? [yes|no]\\n"
printf "[no] >>> "
read -r ans
Expand All @@ -184,7 +184,7 @@ then
if [ "$(uname -m)" != "s390x" ]; then
printf "WARNING:\\n"
printf " Your machine hardware does not appear to be s390x (big endian), \\n"
printf " but you are trying to install a s390x version of __NAME__.\\n"
printf " but you are trying to install a s390x version of %s.\\n" "${INSTALLER_NAME}"
printf " Are sure you want to continue the installation? [yes|no]\\n"
printf "[no] >>> "
read -r ans
Expand All @@ -201,7 +201,7 @@ then
if [ "$(uname -m)" != "aarch64" ]; then
printf "WARNING:\\n"
printf " Your machine hardware does not appear to be aarch64, \\n"
printf " but you are trying to install a aarch64 version of __NAME__.\\n"
printf " but you are trying to install a aarch64 version of %s.\\n" "${INSTALLER_NAME}"
printf " Are sure you want to continue the installation? [yes|no]\\n"
printf "[no] >>> "
read -r ans
Expand All @@ -218,7 +218,7 @@ then
if [ "$(uname)" != "Darwin" ]; then
printf "WARNING:\\n"
printf " Your operating system does not appear to be macOS, \\n"
printf " but you are trying to install a macOS version of __NAME__.\\n"
printf " but you are trying to install a macOS version of %s.\\n" "${INSTALLER_NAME}"
printf " Are sure you want to continue the installation? [yes|no]\\n"
printf "[no] >>> "
read -r ans
Expand All @@ -235,7 +235,7 @@ then
if [ "$(uname)" != "Linux" ]; then
printf "WARNING:\\n"
printf " Your operating system does not appear to be Linux, \\n"
printf " but you are trying to install a Linux version of __NAME__.\\n"
printf " but you are trying to install a Linux version of %s.\\n" "${INSTALLER_NAME}"
printf " Are sure you want to continue the installation? [yes|no]\\n"
printf "[no] >>> "
read -r ans
Expand All @@ -249,7 +249,7 @@ then
#endif

printf "\\n"
printf "Welcome to __NAME__ __VERSION__\\n"
printf "Welcome to %s %s\\n" "${INSTALLER_NAME}" "${INSTALLER_VER}"
#if has_license
printf "\\n"
printf "In order to continue the installation process, please review the license\\n"
Expand All @@ -261,7 +261,7 @@ then
if command -v "more" > /dev/null 2>&1; then
pager="more"
fi
"$pager" <<EOF
"$pager" <<'EOF'
__LICENSE__
EOF
printf "\\n"
Expand All @@ -283,7 +283,7 @@ EOF
#endif

printf "\\n"
printf "__NAME__ will now be installed into this location:\\n"
printf "%s will now be installed into this location:\\n" "${INSTALLER_NAME}"
printf "%s\\n" "$PREFIX"
printf "\\n"
printf " - Press ENTER to confirm the location\\n"
Expand Down Expand Up @@ -517,17 +517,17 @@ else
find "$PREFIX/pkgs" -type d -empty -exec rmdir {} \; 2>/dev/null || :
fi

cat <<EOF
cat <<'EOF'
__CONCLUSION_TEXT__
EOF

if [ "${PYTHONPATH:-}" != "" ]; then
printf "WARNING:\\n"
printf " You currently have a PYTHONPATH environment variable set. This may cause\\n"
printf " unexpected behavior when running the Python interpreter in __NAME__.\\n"
printf " unexpected behavior when running the Python interpreter in %s.\\n" "${INSTALLER_NAME}"
printf " For best results, please verify that your PYTHONPATH only points to\\n"
printf " directories of packages that are compatible with the Python interpreter\\n"
printf " in __NAME__: %s\\n" "$PREFIX"
printf " in %s: %s\\n" "${INSTALLER_NAME}" "$PREFIX"
fi

if [ "$BATCH" = "0" ]; then
Expand All @@ -541,7 +541,7 @@ if [ "$BATCH" = "0" ]; then
#if has_conda and initialize_conda is True
# Interactive mode.

printf "Do you wish the installer to initialize __NAME__\\n"
printf "Do you wish the installer to initialize %s\\n" "${INSTALLER_NAME}"
printf "by running conda init? [yes|no]\\n"
printf "[%s] >>> " "$DEFAULT"
read -r ans
Expand Down Expand Up @@ -582,7 +582,7 @@ if [ "$BATCH" = "0" ]; then
printf "\\n"
#endif

printf "Thank you for installing __NAME__!\\n"
printf "Thank you for installing %s!\\n" "${INSTALLER_NAME}"
fi # !BATCH


Expand All @@ -593,16 +593,16 @@ if [ "$TEST" = "1" ]; then
(# shellcheck disable=SC1091
. "$PREFIX"/bin/activate
which conda-build > /dev/null 2>&1 || conda install -y conda-build
if [ ! -d "$PREFIX"/conda-bld/__PLAT__ ]; then
mkdir -p "$PREFIX"/conda-bld/__PLAT__
if [ ! -d "$PREFIX/conda-bld/${INSTALLER_PLAT}" ]; then
mkdir -p "$PREFIX/conda-bld/${INSTALLER_PLAT}"
fi
cp -f "$PREFIX"/pkgs/*.tar.bz2 "$PREFIX"/conda-bld/__PLAT__/
cp -f "$PREFIX"/pkgs/*.conda "$PREFIX"/conda-bld/__PLAT__/
cp -f "$PREFIX"/pkgs/*.tar.bz2 "$PREFIX/conda-bld/${INSTALLER_PLAT}/"
cp -f "$PREFIX"/pkgs/*.conda "$PREFIX/conda-bld/${INSTALLER_PLAT}/"
if [ "$CLEAR_AFTER_TEST" = "1" ]; then
rm -rf "$PREFIX/pkgs"
fi
conda index "$PREFIX"/conda-bld/__PLAT__/
conda-build --override-channels --channel local --test --keep-going "$PREFIX"/conda-bld/__PLAT__/*.tar.bz2
conda index "$PREFIX/conda-bld/${INSTALLER_PLAT}/"
conda-build --override-channels --channel local --test --keep-going "$PREFIX/conda-bld/${INSTALLER_PLAT}/"*.tar.bz2
) || NFAILS=$?
if [ "$NFAILS" != "0" ]; then
if [ "$NFAILS" = "1" ]; then
Expand Down
28 changes: 28 additions & 0 deletions examples/miniforge/EULA.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Copyright (c) 2016, Example, Inc.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Example, Inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL EXAMPLE, INC. BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The License has to be read correctly so that dollar signs don't lead to an unset
parameter error:
You have to pay US $8, if you can read this.
1 change: 1 addition & 0 deletions examples/miniforge/construct.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: Miniforge3
version: 4.10.1-0
company: conda-forge
license_file: EULA.txt

channels:
- conda-forge
Expand Down
19 changes: 19 additions & 0 deletions news/638-fix-header.sh-pager
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
### Enhancements

* <news item>

### Bug fixes

* Protect all user setable variables in .sh installers against variable substitution. This allows `$` signs as part of the license/conclusion/name/version text without causing unexpected `$1: unbound variable` errors. (#635 via #638)

### Deprecations

* <news item>

### Docs

* <news item>

### Other

* Test some .sh installers in interactive mode to test the interactive code path of the header.sh. (#637 via #638)
29 changes: 24 additions & 5 deletions scripts/run_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,31 @@
BLACKLIST = []
WITH_SPACES = {"extra_files", "noconda", "signing", "scripts"}

# .sh installers to also test in interactiv mode
# (require all to a have License = have same interactive input steps)
INTERACTIVE_TESTS = ['miniforge']
# Test runs with even Python version are done in interactive mode, odd in batch mode
INTERACTIVE_TESTING = (sys.version_info.minor % 2) == 0

def _execute(cmd, **env_vars):

def _execute(cmd, installer_input=None, **env_vars):
print(' '.join(cmd))
t0 = time.time()
if env_vars:
env = os.environ.copy()
env.update(env_vars)
else:
env = None
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, env=env)
p = subprocess.Popen(
cmd,
stdin=subprocess.PIPE if installer_input else None,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
env=env,
)
try:
stdout, stderr = p.communicate(timeout=420)
stdout, stderr = p.communicate(input=installer_input, timeout=420)
errored = p.returncode != 0
except subprocess.TimeoutExpired:
p.kill()
Expand Down Expand Up @@ -137,8 +150,14 @@ def run_examples(keep_artifacts=None, conda_exe=None, debug=False):
rm_rf(env_dir)
fpath = os.path.join(output_dir, fpath)
print('--- Testing', os.path.basename(fpath))
installer_input = None
if ext == 'sh':
cmd = ['/bin/sh', fpath, '-b', '-p', env_dir]
if INTERACTIVE_TESTING and example_name in INTERACTIVE_TESTS:
cmd = ['/bin/sh', fpath]
# Input: Enter, yes to the license, installation folder, no to initialize shells
installer_input = f"\nyes\n{env_dir}\nno\n"
else:
cmd = ['/bin/sh', fpath, '-b', '-p', env_dir]
elif ext == 'pkg':
if os.environ.get("CI"):
# We want to run it in an arbitrary directory, but the options
Expand All @@ -162,7 +181,7 @@ def run_examples(keep_artifacts=None, conda_exe=None, debug=False):
# This is why we have this weird .split() thingy down here:
cmd = ['cmd.exe', '/c', 'start', '/wait', fpath, '/S', *f'/D={env_dir}'.split()]
env = {"CONDA_VERBOSITY": "3"} if debug else {}
test_errored = _execute(cmd, **env)
test_errored = _execute(cmd, installer_input=installer_input, **env)
# 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 = []
Expand Down

0 comments on commit 224bab9

Please sign in to comment.