mirror of
https://github.com/certbot/certbot.git
synced 2026-06-15 19:49:05 -04:00
It is about the exit codes that are returned from the various scripts in tools during tox execution. Indeed, tox relies on the non-zero exit code from a given script to know that something failed during the execution. Previously, theses scripts were in bash, and a bash script returns an exit code that is the higher code returned from any of the command executed by the script. So if any command return a non-zero (in particular pylint or pytest), then the script return also non-zero. Now that these scripts are converted into python, pylint and pytest are executed via subprocess, that returns the exit code as variables. But if theses codes are not handled explicitly, the python script itself will return zero if no python exception occured. As a consequence currently, Certbot CI system is unable to detect any test error or lint error, because there is no exception in this case, only exit codes from the binaries executed. This PR fixes that, by handling correctly the exit code from the most critical scripts, install_and_test.py and tox.cover.py, but also all the scripts that I converted into Python and that could be executed in the context of a shell (via tox or directly for instance).
95 lines
3.5 KiB
Python
Executable file
95 lines
3.5 KiB
Python
Executable file
#!/usr/bin/env python
|
|
# pip installs packages using pinned package versions. If CERTBOT_OLDEST is set
|
|
# to 1, a combination of tools/oldest_constraints.txt,
|
|
# tools/dev_constraints.txt, and local-oldest-requirements.txt contained in the
|
|
# top level of the package's directory is used, otherwise, a combination of
|
|
# certbot-auto's requirements file and tools/dev_constraints.txt is used. The
|
|
# other file always takes precedence over tools/dev_constraints.txt. If
|
|
# CERTBOT_OLDEST is set, this script must be run with `-e <package-name>` and
|
|
# no other arguments.
|
|
|
|
from __future__ import print_function, absolute_import
|
|
|
|
import subprocess
|
|
import os
|
|
import sys
|
|
import re
|
|
import shutil
|
|
import tempfile
|
|
|
|
import merge_requirements as merge_module
|
|
import readlink
|
|
|
|
def find_tools_path():
|
|
return os.path.dirname(readlink.main(__file__))
|
|
|
|
def certbot_oldest_processing(tools_path, args, test_constraints):
|
|
if args[0] != '-e' or len(args) != 2:
|
|
raise ValueError('When CERTBOT_OLDEST is set, this script must be run '
|
|
'with a single -e <path> argument.')
|
|
# remove any extras such as [dev]
|
|
pkg_dir = re.sub(r'\[\w+\]', '', args[1])
|
|
requirements = os.path.join(pkg_dir, 'local-oldest-requirements.txt')
|
|
# packages like acme don't have any local oldest requirements
|
|
if not os.path.isfile(requirements):
|
|
requirements = None
|
|
shutil.copy(os.path.join(tools_path, 'oldest_constraints.txt'), test_constraints)
|
|
|
|
return requirements
|
|
|
|
def certbot_normal_processing(tools_path, test_constraints):
|
|
repo_path = os.path.dirname(tools_path)
|
|
certbot_requirements = os.path.normpath(os.path.join(
|
|
repo_path, 'letsencrypt-auto-source/pieces/dependency-requirements.txt'))
|
|
with open(certbot_requirements, 'r') as fd:
|
|
data = fd.readlines()
|
|
with open(test_constraints, 'w') as fd:
|
|
for line in data:
|
|
search = re.search(r'^(\S*==\S*).*$', line)
|
|
if search:
|
|
fd.write('{0}{1}'.format(search.group(1), os.linesep))
|
|
|
|
def merge_requirements(tools_path, test_constraints, all_constraints):
|
|
merged_requirements = merge_module.main(
|
|
os.path.join(tools_path, 'dev_constraints.txt'),
|
|
test_constraints
|
|
)
|
|
with open(all_constraints, 'w') as fd:
|
|
fd.write(merged_requirements)
|
|
|
|
def call_with_print(command, cwd=None):
|
|
print(command)
|
|
return subprocess.call(command, shell=True, cwd=cwd or os.getcwd())
|
|
|
|
def main(args):
|
|
tools_path = find_tools_path()
|
|
working_dir = tempfile.mkdtemp()
|
|
|
|
exit_code = 0
|
|
|
|
try:
|
|
test_constraints = os.path.join(working_dir, 'test_constraints.txt')
|
|
all_constraints = os.path.join(working_dir, 'all_constraints.txt')
|
|
|
|
requirements = None
|
|
if os.environ.get('CERTBOT_OLDEST') == '1':
|
|
requirements = certbot_oldest_processing(tools_path, args, test_constraints)
|
|
else:
|
|
certbot_normal_processing(tools_path, test_constraints)
|
|
|
|
merge_requirements(tools_path, test_constraints, all_constraints)
|
|
if requirements:
|
|
exit_code = call_with_print(' '.join([
|
|
sys.executable, '-m', 'pip', 'install', '-q', '--constraint', all_constraints,
|
|
'--requirement', requirements])) or exit_code
|
|
|
|
command = [sys.executable, '-m', 'pip', 'install', '-q', '--constraint', all_constraints]
|
|
command.extend(args)
|
|
exit_code = call_with_print(' '.join(command)) or exit_code
|
|
finally:
|
|
shutil.rmtree(working_dir)
|
|
|
|
return exit_code
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main(sys.argv[1:]))
|