Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed detecting errors/warnings in output of the 'build' command. #423

Merged
merged 1 commit into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 7 additions & 27 deletions zest/releaser/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

from build import ProjectBuilder
from colorama import Fore
from subprocess import CalledProcessError
from subprocess import check_output
from subprocess import STDOUT
from urllib import request
from urllib.error import HTTPError

Expand Down Expand Up @@ -65,31 +62,14 @@ def package_in_pypi(package):
def _project_builder_runner(cmd, cwd=None, extra_environ=None):
"""Run the build command and format warnings and errors.

It runs the build command in a subprocess. Warnings and errors are formatted
in red so that they will work correctly with utils.show_interesting_lines(). We
mimic the setuptools/wheels output that way.
"""
env = os.environ.copy()
if extra_environ:
env.update(extra_environ)
It runs the build command in a subprocess.
extra_environ will contain for example:

try:
result = check_output(cmd, cwd=cwd, env=env, stderr=STDOUT)
except CalledProcessError as e:
raise SystemExit(
f"Build failed with the following error:\n{e.output.decode()}\nExiting"
) from e
result_split = result.split(b"\n")
formatted_result = []
for line in result_split:
line = line.decode()
if line.lower().startswith(("warning", "error")):
line = (
Fore.RED + line + Fore.RESET
) # reset so that not all the lines after a warning are red
formatted_result.append(line)
formatted_result_joined = "\n".join(formatted_result)
utils.show_interesting_lines(formatted_result_joined)
{'PEP517_BUILD_BACKEND': 'setuptools.build_meta:__legacy__'}
"""
utils.show_interesting_lines(
execute_command(cmd, cwd=cwd, extra_environ=extra_environ)
)


class Releaser(baserelease.Basereleaser):
Expand Down
36 changes: 22 additions & 14 deletions zest/releaser/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ def show_interesting_lines(result):
# warnings/errors, print complete result.
print(result)
if not ask(
"There were errors or warnings. Are you sure " "you want to continue?",
"There were errors or warnings. Are you sure you want to continue?",
default=False,
):
sys.exit(1)
Expand Down Expand Up @@ -662,26 +662,32 @@ def format_command(command):
return " ".join(args)


def _execute_command(command):
def _execute_command(command, cwd=None, extra_environ=None):
"""Execute a command, returning stdout, plus maybe parts of stderr."""
# Enforce the command to be a list or arguments.
assert isinstance(command, (list, tuple))
logger.debug("Running command: '%s'", format_command(command))
env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path))
if extra_environ is not None:
env.update(extra_environ)
# By default we show errors, of course.
show_stderr = True
if command[0].startswith(sys.executable):
env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path))
if "upload" in command or "register" in command:
# We really do want to see the stderr here, otherwise a
# failed upload does not even show up in the output.
show_stderr = True
else:
show_stderr = False
else:
env = None
show_stderr = True
# For several Python commands, we do not want to see the stderr:
# if we include it for `python setup.py --version`, then the version
# may contain all kinds of warnings.
show_stderr = False
# But we really DO want to see the stderr for some other Python commands,
# otherwise for example a failed upload would not even show up in the output.
for flag in ("upload", "register", "build_sdist", "build_wheel", "-mbuild"):
if flag in command:
show_stderr = True
break
process_kwargs = {
"stdin": subprocess.PIPE,
"stdout": subprocess.PIPE,
"stderr": subprocess.PIPE,
"cwd": cwd,
"env": env,
"text": True,
}
Expand Down Expand Up @@ -731,7 +737,9 @@ def get_errors(stderr_output):
return "\n".join(errors)


def execute_command(command, allow_retry=False, fail_message=""):
def execute_command(
command, allow_retry=False, fail_message="", cwd=None, extra_environ=None
):
"""Run the command and possibly retry it.

When allow_retry is False, we simply call the base
Expand All @@ -752,7 +760,7 @@ def execute_command(command, allow_retry=False, fail_message=""):

It might be a warning, but we cannot detect the distinction.
"""
result = _execute_command(command)
result = _execute_command(command, cwd=cwd, extra_environ=extra_environ)
if not allow_retry:
return result
if Fore.RED not in result:
Expand Down