mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1269513 - Add a helper for check_output in Python configure. r=glandium
MozReview-Commit-ID: H3IX5HLyJeu
This commit is contained in:
parent
0a11236205
commit
2a763b7273
@ -10,15 +10,12 @@ yasm = check_prog('YASM', ['yasm'], allow_missing=True)
|
||||
|
||||
@depends_if(yasm)
|
||||
@checking('yasm version')
|
||||
@imports('subprocess')
|
||||
def yasm_version(yasm):
|
||||
try:
|
||||
version = Version(subprocess.check_output(
|
||||
[yasm, '--version']
|
||||
).splitlines()[0].split()[1])
|
||||
return version
|
||||
except subprocess.CalledProcessError as e:
|
||||
die('Failed to get yasm version: %s', e.message)
|
||||
version = check_cmd_output(
|
||||
yasm, '--version',
|
||||
onerror=lambda: die('Failed to get yasm version.')
|
||||
).splitlines()[0].split()[1]
|
||||
return version
|
||||
|
||||
# Until we move all the yasm consumers out of old-configure.
|
||||
# bug 1257904
|
||||
@ -174,7 +171,6 @@ add_old_configure_assignment('TOOLCHAIN_PREFIX', toolchain_prefix)
|
||||
@imports('os')
|
||||
@imports('subprocess')
|
||||
@imports(_from='mozbuild.configure.util', _import='LineIO')
|
||||
@imports(_from='mozbuild.shellutil', _import='quote')
|
||||
@imports(_from='tempfile', _import='mkstemp')
|
||||
def try_preprocess(compiler, language, source):
|
||||
suffix = {
|
||||
@ -192,22 +188,8 @@ def try_preprocess(compiler, language, source):
|
||||
|
||||
os.write(fd, source)
|
||||
os.close(fd)
|
||||
|
||||
cmd = compiler + ['-E', path]
|
||||
log.debug('Executing: `%s`', quote(*cmd))
|
||||
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
stdout, stderr = proc.communicate()
|
||||
retcode = proc.wait()
|
||||
if retcode == 0:
|
||||
return stdout
|
||||
|
||||
log.debug('The command returned non-zero exit status %d.', retcode)
|
||||
for out, desc in ((stdout, 'output'), (stderr, 'error output')):
|
||||
if out:
|
||||
log.debug('Its %s was:', desc)
|
||||
with LineIO(lambda l: log.debug('| %s', l)) as o:
|
||||
o.write(out)
|
||||
return check_cmd_output(*cmd)
|
||||
finally:
|
||||
os.remove(path)
|
||||
|
||||
|
@ -18,6 +18,37 @@ def configure_error(message):
|
||||
their inputs from moz.configure usage.'''
|
||||
raise ConfigureError(message)
|
||||
|
||||
# A wrapper to obtain a process' output that returns the output generated
|
||||
# by running the given command if it exits normally, and streams that
|
||||
# output to log.debug and calls die or the given error callback if it
|
||||
# does not.
|
||||
@imports('subprocess')
|
||||
@imports('sys')
|
||||
@imports(_from='mozbuild.configure.util', _import='LineIO')
|
||||
@imports(_from='mozbuild.shellutil', _import='quote')
|
||||
def check_cmd_output(*args, **kwargs):
|
||||
onerror = kwargs.pop('onerror', None)
|
||||
|
||||
with log.queue_debug():
|
||||
log.debug('Executing: `%s`', quote(*args))
|
||||
proc = subprocess.Popen(args, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
stdout, stderr = proc.communicate()
|
||||
retcode = proc.wait()
|
||||
if retcode == 0:
|
||||
return stdout
|
||||
|
||||
log.debug('The command returned non-zero exit status %d.',
|
||||
retcode)
|
||||
for out, desc in ((stdout, 'output'), (stderr, 'error output')):
|
||||
if out:
|
||||
log.debug('Its %s was:', desc)
|
||||
with LineIO(lambda l: log.debug('| %s', l)) as o:
|
||||
o.write(out)
|
||||
if onerror:
|
||||
return onerror()
|
||||
die('Command `%s` failed with exit status %d.' %
|
||||
(quote(*args), retcode))
|
||||
|
||||
@imports('os')
|
||||
def is_absolute_or_relative(path):
|
||||
|
@ -116,12 +116,11 @@ add_old_configure_assignment('PERL', perl_for_old_configure)
|
||||
def perl_version_check(min_version):
|
||||
@depends(perl)
|
||||
@checking('for minimum required perl version >= %s' % min_version)
|
||||
@imports('subprocess')
|
||||
def get_perl_version(perl):
|
||||
try:
|
||||
return Version(subprocess.check_output([perl, '-e', 'print $]']))
|
||||
except subprocess.CalledProcessError as e:
|
||||
die('Failed to get perl version: %s', e.message)
|
||||
return Version(check_cmd_output(
|
||||
perl, '-e', 'print $]',
|
||||
onerror=lambda: die('Failed to get perl version.')
|
||||
))
|
||||
|
||||
@depends(get_perl_version)
|
||||
def check_perl_version(version):
|
||||
|
@ -7,18 +7,24 @@ from __future__ import absolute_import, print_function, unicode_literals
|
||||
import logging
|
||||
import os
|
||||
import tempfile
|
||||
import textwrap
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
from StringIO import StringIO
|
||||
|
||||
from mozunit import main
|
||||
from mozpack import path as mozpath
|
||||
|
||||
from mozbuild.configure.util import (
|
||||
ConfigureOutputHandler,
|
||||
LineIO,
|
||||
Version,
|
||||
)
|
||||
from mozbuild.util import exec_
|
||||
|
||||
from buildconfig import topsrcdir
|
||||
from common import ConfigureTestSandbox
|
||||
|
||||
|
||||
class TestConfigureOutputHandler(unittest.TestCase):
|
||||
@ -438,6 +444,85 @@ class TestVersion(unittest.TestCase):
|
||||
self.assertEqual(v.minor, 0)
|
||||
self.assertEqual(v.patch, 0)
|
||||
|
||||
class TestCheckCmdOutput(unittest.TestCase):
|
||||
|
||||
def get_result(self, command='', paths=None):
|
||||
paths = paths or {}
|
||||
config = {}
|
||||
out = StringIO()
|
||||
sandbox = ConfigureTestSandbox(paths, config, {}, ['/bin/configure'],
|
||||
out, out)
|
||||
sandbox.include_file(mozpath.join(topsrcdir, 'build',
|
||||
'moz.configure', 'util.configure'))
|
||||
status = 0
|
||||
try:
|
||||
exec_(command, sandbox)
|
||||
sandbox.run()
|
||||
except SystemExit as e:
|
||||
status = e.code
|
||||
return config, out.getvalue(), status
|
||||
|
||||
def test_simple_program(self):
|
||||
def mock_simple_prog(_, args):
|
||||
if len(args) == 1 and args[0] == '--help':
|
||||
return 0, 'simple program help...', ''
|
||||
self.fail("Unexpected arguments to mock_simple_program: %s" %
|
||||
args)
|
||||
prog_path = mozpath.abspath('/simple/prog')
|
||||
cmd = "log.info(check_cmd_output('%s', '--help'))" % prog_path
|
||||
config, out, status = self.get_result(cmd,
|
||||
paths={prog_path: mock_simple_prog})
|
||||
self.assertEqual(config, {})
|
||||
self.assertEqual(status, 0)
|
||||
self.assertEqual(out, 'simple program help...\n')
|
||||
|
||||
def test_failing_program(self):
|
||||
def mock_error_prog(_, args):
|
||||
if len(args) == 1 and args[0] == '--error':
|
||||
return (127, 'simple program output',
|
||||
'simple program error output')
|
||||
self.fail("Unexpected arguments to mock_error_program: %s" %
|
||||
args)
|
||||
prog_path = mozpath.abspath('/simple/prog')
|
||||
cmd = "log.info(check_cmd_output('%s', '--error'))" % prog_path
|
||||
config, out, status = self.get_result(cmd,
|
||||
paths={prog_path: mock_error_prog})
|
||||
self.assertEqual(config, {})
|
||||
self.assertEqual(status, 1)
|
||||
self.assertEqual(out, textwrap.dedent('''\
|
||||
DEBUG: Executing: `%s --error`
|
||||
DEBUG: The command returned non-zero exit status 127.
|
||||
DEBUG: Its output was:
|
||||
DEBUG: | simple program output
|
||||
DEBUG: Its error output was:
|
||||
DEBUG: | simple program error output
|
||||
ERROR: Command `%s --error` failed with exit status 127.
|
||||
''' % (prog_path, prog_path)))
|
||||
|
||||
def test_error_callback(self):
|
||||
def mock_error_prog(_, args):
|
||||
if len(args) == 1 and args[0] == '--error':
|
||||
return 127, 'simple program error...', ''
|
||||
self.fail("Unexpected arguments to mock_error_program: %s" %
|
||||
args)
|
||||
|
||||
prog_path = mozpath.abspath('/simple/prog')
|
||||
cmd = textwrap.dedent('''\
|
||||
check_cmd_output('%s', '--error',
|
||||
onerror=lambda: die('`prog` produced an error'))
|
||||
''' % prog_path)
|
||||
config, out, status = self.get_result(cmd,
|
||||
paths={prog_path: mock_error_prog})
|
||||
self.assertEqual(config, {})
|
||||
self.assertEqual(status, 1)
|
||||
self.assertEqual(out, textwrap.dedent('''\
|
||||
DEBUG: Executing: `%s --error`
|
||||
DEBUG: The command returned non-zero exit status 127.
|
||||
DEBUG: Its output was:
|
||||
DEBUG: | simple program error...
|
||||
ERROR: `prog` produced an error
|
||||
''' % prog_path))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
Loading…
Reference in New Issue
Block a user