author Gregory Szorc <>
Tue, 07 Nov 2017 16:38:39 -0800
changeset 441455 b5f79b0f2a3586faf692c715b443264478e921c3
parent 429927 237a3f842dc137837a91ce1234dd4697b00db307
child 455465 a3ddf5e47032d544ba30255735c580ad3774218d
permissions -rw-r--r--
Bug 1412932 - Switch to PGO build in; r=ted Previously, made the decision of whether to perform a PGO build. This required passing around MOZ_PGO and invoking a separate make target if this variable was set. In this commit, we move this logic to We employ a special mechanism in to override the default make target so `make` evaluates "profiledbuild" if MOZ_PGO is set. This also required using an explicit target for $(MAKE) invocations inside the "profiledbuild" rule to avoid infinite recursion. MozReview-Commit-ID: 8sHiVspMisM

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at

from __future__ import absolute_import, print_function

import json
import os
import tempfile
from distutils.spawn import find_executable

import mozpack.path as mozpath
from mozpack.files import FileFinder
from mozprocess import ProcessHandlerMixin

from mozlint import result

here = os.path.abspath(os.path.dirname(__file__))

results = []

class PyCompatProcess(ProcessHandlerMixin):
    def __init__(self, config, *args, **kwargs):
        self.config = config
        kwargs['processOutputLine'] = [self.process_line]
        ProcessHandlerMixin.__init__(self, *args, **kwargs)

    def process_line(self, line):
            res = json.loads(line)
        except ValueError:
            print('Non JSON output from linter, will not be processed: {}'.format(line))

        res['level'] = 'error'
        results.append(result.from_config(self.config, **res))

def run_linter(python, paths, config, **lintargs):
    binary = find_executable(python)
    if not binary:
        # TODO bootstrap python3 if not available
        print('error: {} not detected, aborting py-compat check'.format(python))
        if 'MOZ_AUTOMATION' in os.environ:
            return 1
        return []

    root = lintargs['root']
    pattern = "**/*.py"
    exclude = [mozpath.join(root, e) for e in lintargs.get('exclude', [])]
    files = []
    for path in paths:
        path = mozpath.normsep(path)
        if os.path.isfile(path):

        ignore = [e[len(path):].lstrip('/') for e in exclude
                  if mozpath.commonprefix((path, e)) == path]
        finder = FileFinder(path, ignore=ignore)
        files.extend([os.path.join(path, p) for p, f in finder.find(pattern)])

    with tempfile.NamedTemporaryFile(mode='w') as fh:

        cmd = [binary, os.path.join(here, ''),]

        proc = PyCompatProcess(config, cmd)
        except KeyboardInterrupt:

    return results

def lintpy2(*args, **kwargs):
    return run_linter('python2', *args, **kwargs)

def lintpy3(*args, **kwargs):
    return run_linter('python3', *args, **kwargs)