Пример #1
0
    def __init__(self, mach_cmd):
        super(NodeRunner, self).__init__(mach_cmd)
        self.topsrcdir = mach_cmd.topsrcdir
        self._mach_context = mach_cmd._mach_context
        self.python_path = mach_cmd.virtualenv_manager.python_path

        from mozbuild.nodeutil import find_node_executable

        self.node_path = os.path.abspath(find_node_executable()[0])
Пример #2
0
def node(command_context, args):
    from mozbuild.nodeutil import find_node_executable

    # Avoid logging the command
    command_context.log_manager.terminal_handler.setLevel(logging.CRITICAL)

    node_path, _ = find_node_executable()

    return command_context.run_process(
        [node_path] + args,
        pass_thru=True,  # Allow user to run Node interactively.
        ensure_exit_code=False,  # Don't throw on non-zero exit code.
    )
Пример #3
0
def lint(paths, config, binary=None, fix=None, setup=None, **lintargs):
    """Run eslint."""
    log = lintargs["log"]
    setup_helper.set_project_root(lintargs["root"])
    module_path = setup_helper.get_project_root()

    # Valid binaries are:
    #  - Any provided by the binary argument.
    #  - Any pointed at by the ESLINT environmental variable.
    #  - Those provided by |mach lint --setup|.

    if not binary:
        binary, _ = find_node_executable()

    if not binary:
        print(ESLINT_NOT_FOUND_MESSAGE)
        return 1

    extra_args = lintargs.get("extra_args") or []
    exclude_args = []
    for path in config.get("exclude", []):
        exclude_args.extend(
            ["--ignore-pattern",
             os.path.relpath(path, lintargs["root"])])

    cmd_args = ([
        binary,
        os.path.join(module_path, "node_modules", "eslint", "bin",
                     "eslint.js"),
        # This keeps ext as a single argument.
        "--ext",
        "[{}]".format(",".join(config["extensions"])),
        "--format",
        "json",
        "--no-error-on-unmatched-pattern",
    ] + extra_args + exclude_args + paths)
    log.debug("Command: {}".format(" ".join(cmd_args)))
    results = run(cmd_args, config)
    fixed = 0
    # eslint requires that --fix be set before the --ext argument.
    if fix:
        fixed += len(results)
        cmd_args.insert(2, "--fix")
        results = run(cmd_args, config)
        fixed = fixed - len(results)

    return {"results": results, "fixed": fixed}
Пример #4
0
def check_node_executables_valid():
    node_path, version = find_node_executable()
    if not node_path:
        print(NODE_NOT_FOUND_MESSAGE)
        return False
    if not version:
        print(NODE_MACHING_VERSION_NOT_FOUND_MESSAGE % NODE_MIN_VERSION)
        return False

    npm_path, version = find_npm_executable()
    if not npm_path:
        print(NPM_NOT_FOUND_MESSAGE)
        return False
    if not version:
        print(NPM_MACHING_VERSION_NOT_FOUND_MESSAGE % NPM_MIN_VERSION)
        return False

    return True
Пример #5
0
 def setUp(self):
     if not buildconfig.substs.get("NODEJS"):
         buildconfig.substs['NODEJS'] = find_node_executable()[0]
     SCRIPT_ALLOWLIST.append(TEST_SCRIPT)
Пример #6
0
    def _node_path(self):
        from mozbuild.nodeutil import find_node_executable

        node, _ = find_node_executable()

        return os.path.dirname(node)
Пример #7
0
def lint(paths, config, binary=None, fix=None, setup=None, **lintargs):
    """Run eslint."""
    setup_helper.set_project_root(lintargs['root'])
    module_path = setup_helper.get_project_root()

    # Valid binaries are:
    #  - Any provided by the binary argument.
    #  - Any pointed at by the ESLINT environmental variable.
    #  - Those provided by |mach lint --setup|.

    if not binary:
        binary, _ = find_node_executable()

    if not binary:
        print(ESLINT_NOT_FOUND_MESSAGE)
        return 1

    extra_args = lintargs.get('extra_args') or []
    exclude_args = []
    for path in config.get('exclude', []):
        exclude_args.extend(
            ['--ignore-pattern',
             os.path.relpath(path, lintargs['root'])])

    cmd_args = [
        binary,
        os.path.join(module_path, "node_modules", "eslint", "bin",
                     "eslint.js"),
        # Enable the HTML plugin.
        # We can't currently enable this in the global config file
        # because it has bad interactions with the SublimeText
        # ESLint plugin (bug 1229874).
        '--plugin',
        'html',
        # This keeps ext as a single argument.
        '--ext',
        '[{}]'.format(','.join(config['extensions'])),
        '--format',
        'json',
    ] + extra_args + exclude_args + paths

    # eslint requires that --fix be set before the --ext argument.
    if fix:
        cmd_args.insert(2, '--fix')

    shell = False
    if os.environ.get('MSYSTEM') in ('MINGW32', 'MINGW64'):
        # The eslint binary needs to be run from a shell with msys
        shell = True

    orig = signal.signal(signal.SIGINT, signal.SIG_IGN)
    proc = ProcessHandler(cmd_args, env=os.environ, stream=None, shell=shell)
    proc.run()
    signal.signal(signal.SIGINT, orig)

    try:
        proc.wait()
    except KeyboardInterrupt:
        proc.kill()
        return []

    if not proc.output:
        return []  # no output means success

    try:
        jsonresult = json.loads(proc.output[0])
    except ValueError:
        print(ESLINT_ERROR_MESSAGE.format("\n".join(proc.output)))
        return 1

    results = []
    for obj in jsonresult:
        errors = obj['messages']

        for err in errors:
            err.update({
                'hint': err.get('fix'),
                'level': 'error' if err['severity'] == 2 else 'warning',
                'lineno': err.get('line') or 0,
                'path': obj['filePath'],
                'rule': err.get('ruleId'),
            })
            results.append(result.from_config(config, **err))

    return results
Пример #8
0
def node_path():
    from mozbuild.nodeutil import find_node_executable

    node, _ = find_node_executable()

    return os.path.abspath(node)
Пример #9
0
def package_setup(
    package_root,
    package_name,
    should_update=False,
    should_clobber=False,
    no_optional=False,
):
    """Ensure `package_name` at `package_root` is installed.

    When `should_update` is true, clobber, install, and produce a new
    "package-lock.json" file.

    This populates `package_root/node_modules`.

    """
    orig_project_root = get_project_root()
    orig_cwd = os.getcwd()

    if should_update:
        should_clobber = True

    try:
        set_project_root(package_root)
        sys.path.append(os.path.dirname(__file__))

        # npm sometimes fails to respect cwd when it is run using check_call so
        # we manually switch folders here instead.
        project_root = get_project_root()
        os.chdir(project_root)

        if should_clobber:
            node_modules_path = os.path.join(project_root, "node_modules")
            print("Clobbering %s..." % node_modules_path)
            if sys.platform.startswith("win") and have_winrm():
                process = subprocess.Popen(["winrm", "-rf", node_modules_path])
                process.wait()
            else:
                mozfileremove(node_modules_path)

        npm_path, _ = find_npm_executable()
        if not npm_path:
            return 1

        node_path, _ = find_node_executable()
        if not node_path:
            return 1

        extra_parameters = ["--loglevel=error"]

        if no_optional:
            extra_parameters.append("--no-optional")

        package_lock_json_path = os.path.join(get_project_root(),
                                              "package-lock.json")

        if should_update:
            cmd = [npm_path, "install"]
            mozfileremove(package_lock_json_path)
        else:
            cmd = [npm_path, "ci"]

        # On non-Windows, ensure npm is called via node, as node may not be in the
        # path.
        if platform.system() != "Windows":
            cmd.insert(0, node_path)

        # Ensure that bare `node` and `npm` in scripts, including post-install scripts, finds the
        # binary we're invoking with.  Without this, it's easy for compiled extensions to get
        # mismatched versions of the Node.js extension API.
        extra_parameters.append("--scripts-prepend-node-path")

        cmd.extend(extra_parameters)

        print('Installing %s for mach using "%s"...' %
              (package_name, " ".join(cmd)))
        result = call_process(package_name, cmd)

        if not result:
            return 1

        bin_path = os.path.join(get_project_root(), "node_modules", ".bin",
                                package_name)

        print("\n%s installed successfully!" % package_name)
        print("\nNOTE: Your local %s binary is at %s\n" %
              (package_name, bin_path))

    finally:
        set_project_root(orig_project_root)
        os.chdir(orig_cwd)
Пример #10
0
def eslint_setup(should_clobber=False):
    """Ensure eslint is optimally configured.

    This command will inspect your eslint configuration and
    guide you through an interactive wizard helping you configure
    eslint for optimal use on Mozilla projects.
    """
    orig_cwd = os.getcwd()
    sys.path.append(os.path.dirname(__file__))

    # npm sometimes fails to respect cwd when it is run using check_call so
    # we manually switch folders here instead.
    project_root = get_project_root()
    os.chdir(project_root)

    if should_clobber:
        node_modules_path = os.path.join(project_root, "node_modules")
        print("Clobbering node_modules...")
        if sys.platform.startswith('win') and have_winrm():
            process = subprocess.Popen(['winrm', '-rf', node_modules_path])
            process.wait()
        else:
            mozfileremove(node_modules_path)

    npm_path, version = find_npm_executable()
    if not npm_path:
        return 1

    node_path, _ = find_node_executable()
    if not node_path:
        return 1

    extra_parameters = ["--loglevel=error"]

    package_lock_json_path = os.path.join(get_project_root(),
                                          "package-lock.json")
    package_lock_json_tmp_path = os.path.join(tempfile.gettempdir(),
                                              "package-lock.json.tmp")

    # If we have an npm version newer than 5.8.0, just use 'ci', as that's much
    # simpler and does exactly what we want.
    npm_is_older_version = version < StrictVersion("5.8.0").version

    if npm_is_older_version:
        cmd = [node_path, npm_path, "install"]
        shutil.copy2(package_lock_json_path, package_lock_json_tmp_path)
    else:
        cmd = [node_path, npm_path, "ci"]

    cmd.extend(extra_parameters)
    print("Installing eslint for mach using \"%s\"..." % (" ".join(cmd)))
    result = call_process("eslint", cmd)

    if npm_is_older_version:
        shutil.move(package_lock_json_tmp_path, package_lock_json_path)

    if not result:
        return 1

    eslint_path = os.path.join(get_project_root(), "node_modules", ".bin",
                               "eslint")

    print("\nESLint and approved plugins installed successfully!")
    print("\nNOTE: Your local eslint binary is at %s\n" % eslint_path)

    os.chdir(orig_cwd)
Пример #11
0
def package_setup(package_root,
                  package_name,
                  should_clobber=False,
                  no_optional=False):
    """Ensure `package_name` at `package_root` is installed.

    This populates `package_root/node_modules`.
    """
    orig_project_root = get_project_root()
    orig_cwd = os.getcwd()
    try:
        set_project_root(package_root)
        sys.path.append(os.path.dirname(__file__))

        # npm sometimes fails to respect cwd when it is run using check_call so
        # we manually switch folders here instead.
        project_root = get_project_root()
        os.chdir(project_root)

        if should_clobber:
            node_modules_path = os.path.join(project_root, "node_modules")
            print("Clobbering %s..." % node_modules_path)
            if sys.platform.startswith('win') and have_winrm():
                process = subprocess.Popen(['winrm', '-rf', node_modules_path])
                process.wait()
            else:
                mozfileremove(node_modules_path)

        npm_path, version = find_npm_executable()
        if not npm_path:
            return 1

        node_path, _ = find_node_executable()
        if not node_path:
            return 1

        extra_parameters = ["--loglevel=error"]

        if no_optional:
            extra_parameters.append('--no-optional')

        package_lock_json_path = os.path.join(get_project_root(),
                                              "package-lock.json")
        package_lock_json_tmp_path = os.path.join(tempfile.gettempdir(),
                                                  "package-lock.json.tmp")

        # If we have an npm version newer than 5.8.0, just use 'ci', as that's much
        # simpler and does exactly what we want.
        npm_is_older_version = version < StrictVersion("5.8.0").version

        if npm_is_older_version:
            cmd = [npm_path, "install"]
            shutil.copy2(package_lock_json_path, package_lock_json_tmp_path)
        else:
            cmd = [npm_path, "ci"]

        # On non-Windows, ensure npm is called via node, as node may not be in the
        # path.
        if platform.system() != "Windows":
            cmd.insert(0, node_path)

        cmd.extend(extra_parameters)

        # Ensure that bare `node` and `npm` in scripts, including post-install scripts, finds the
        # binary we're invoking with.  Without this, it's easy for compiled extensions to get
        # mismatched versions of the Node.js extension API.
        path = os.environ.get('PATH', '').split(os.pathsep)
        node_dir = os.path.dirname(node_path)
        if node_dir not in path:
            path = [node_dir] + path

        print("Installing %s for mach using \"%s\"..." %
              (package_name, " ".join(cmd)))
        result = call_process(package_name,
                              cmd,
                              append_env={'PATH': os.pathsep.join(path)})

        if npm_is_older_version:
            shutil.move(package_lock_json_tmp_path, package_lock_json_path)

        if not result:
            return 1

        bin_path = os.path.join(get_project_root(), "node_modules", ".bin",
                                package_name)

        print("\n%s installed successfully!" % package_name)
        print("\nNOTE: Your local %s binary is at %s\n" %
              (package_name, bin_path))

    finally:
        set_project_root(orig_project_root)
        os.chdir(orig_cwd)
Пример #12
0
def lint(paths, config, binary=None, fix=None, setup=None, **lintargs):
    """Run eslint."""
    log = lintargs["log"]
    setup_helper.set_project_root(lintargs["root"])
    module_path = setup_helper.get_project_root()

    # Valid binaries are:
    #  - Any provided by the binary argument.
    #  - Any pointed at by the ESLINT environmental variable.
    #  - Those provided by |mach lint --setup|.

    if not binary:
        binary, _ = find_node_executable()

    if not binary:
        print(ESLINT_NOT_FOUND_MESSAGE)
        return 1

    extra_args = lintargs.get("extra_args") or []
    exclude_args = []
    for path in config.get("exclude", []):
        exclude_args.extend(
            ["--ignore-pattern",
             os.path.relpath(path, lintargs["root"])])

    cmd_args = ([
        binary,
        os.path.join(module_path, "node_modules", "eslint", "bin",
                     "eslint.js"),
        # This keeps ext as a single argument.
        "--ext",
        "[{}]".format(",".join(config["extensions"])),
        "--format",
        "json",
        "--no-error-on-unmatched-pattern",
    ] + extra_args + exclude_args + paths)
    log.debug("Command: {}".format(" ".join(cmd_args)))

    # eslint requires that --fix be set before the --ext argument.
    if fix:
        cmd_args.insert(2, "--fix")

    shell = False
    if os.environ.get("MSYSTEM") in ("MINGW32", "MINGW64"):
        # The eslint binary needs to be run from a shell with msys
        shell = True
    encoding = "utf-8"

    orig = signal.signal(signal.SIGINT, signal.SIG_IGN)
    proc = subprocess.Popen(cmd_args,
                            shell=shell,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    signal.signal(signal.SIGINT, orig)

    try:
        output, errors = proc.communicate()
    except KeyboardInterrupt:
        proc.kill()
        return []

    if errors:
        errors = errors.decode(encoding, "replace")
        print(ESLINT_ERROR_MESSAGE.format(errors))

    if proc.returncode >= 2:
        return 1

    if not output:
        return []  # no output means success
    output = output.decode(encoding, "replace")
    try:
        jsonresult = json.loads(output)
    except ValueError:
        print(ESLINT_ERROR_MESSAGE.format(output))
        return 1

    results = []
    for obj in jsonresult:
        errors = obj["messages"]

        for err in errors:
            err.update({
                "hint": err.get("fix"),
                "level": "error" if err["severity"] == 2 else "warning",
                "lineno": err.get("line") or 0,
                "path": obj["filePath"],
                "rule": err.get("ruleId"),
            })
            results.append(result.from_config(config, **err))

    return results
Пример #13
0
def lint(paths, config, binary=None, fix=None, setup=None, **lintargs):
    """Run eslint."""
    log = lintargs['log']
    setup_helper.set_project_root(lintargs['root'])
    module_path = setup_helper.get_project_root()

    # Valid binaries are:
    #  - Any provided by the binary argument.
    #  - Any pointed at by the ESLINT environmental variable.
    #  - Those provided by |mach lint --setup|.

    if not binary:
        binary, _ = find_node_executable()

    if not binary:
        print(ESLINT_NOT_FOUND_MESSAGE)
        return 1

    extra_args = lintargs.get('extra_args') or []
    exclude_args = []
    for path in config.get('exclude', []):
        exclude_args.extend(
            ['--ignore-pattern',
             os.path.relpath(path, lintargs['root'])])

    cmd_args = [
        binary,
        os.path.join(module_path, "node_modules", "eslint", "bin",
                     "eslint.js"),
        # This keeps ext as a single argument.
        '--ext',
        '[{}]'.format(','.join(config['extensions'])),
        '--format',
        'json',
        '--no-error-on-unmatched-pattern',
    ] + extra_args + exclude_args + paths
    log.debug("Command: {}".format(' '.join(cmd_args)))

    # eslint requires that --fix be set before the --ext argument.
    if fix:
        cmd_args.insert(2, '--fix')

    shell = False
    if os.environ.get('MSYSTEM') in ('MINGW32', 'MINGW64'):
        # The eslint binary needs to be run from a shell with msys
        shell = True
    encoding = 'utf-8'

    orig = signal.signal(signal.SIGINT, signal.SIG_IGN)
    proc = subprocess.Popen(cmd_args,
                            shell=shell,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    signal.signal(signal.SIGINT, orig)

    try:
        output, errors = proc.communicate()
    except KeyboardInterrupt:
        proc.kill()
        return []

    if errors:
        errors = errors.decode(encoding, "replace")
        print(ESLINT_ERROR_MESSAGE.format(errors))

    if proc.returncode >= 2:
        return 1

    if not output:
        return []  # no output means success
    output = output.decode(encoding, "replace")
    try:
        jsonresult = json.loads(output)
    except ValueError:
        print(ESLINT_ERROR_MESSAGE.format(output))
        return 1

    results = []
    for obj in jsonresult:
        errors = obj['messages']

        for err in errors:
            err.update({
                'hint': err.get('fix'),
                'level': 'error' if err['severity'] == 2 else 'warning',
                'lineno': err.get('line') or 0,
                'path': obj['filePath'],
                'rule': err.get('ruleId'),
            })
            results.append(result.from_config(config, **err))

    return results