PATH_TO_NODE = setting_overrides.get(
    'PATH_TO_NODE',
    'node'
) PATH_TO_NPM = setting_overrides.get(
    'PATH_TO_NPM',
    'npm'
) NODE_VERSION_COMMAND = setting_overrides.get(
    'NODE_VERSION_COMMAND',
    '--version',
) NODE_VERSION_FILTER = setting_overrides.get(
    'NODE_VERSION_FILTER',
    lambda version: tuple(map(int, (version[1:] if version[0] == 'v' else version).split('.'))),
) NPM_VERSION_COMMAND = setting_overrides.get(
    'NPM_VERSION_COMMAND',
    '--version',
) NPM_VERSION_FILTER = setting_overrides.get(
    'NPM_VERSION_FILTER',
    lambda version: tuple(map(int, version.split('.'))),
) class DynamicImportError(Exception):
    pass class ErrorInterrogatingEnvironment(Exception):
    pass class MalformedVersionInput(Exception):
    pass class MissingDependency(Exception):
    pass class OutdatedDependency(Exception):
    pass class ModuleDoesNotContainAnyServices(Exception):
    pass
import sys
import subprocess
import tempfile
import importlib
import re
import inspect
from django.utils import six
from .settings import (
    PATH_TO_NODE, PATH_TO_NPM, NODE_VERSION_COMMAND, NODE_VERSION_FILTER, NPM_VERSION_COMMAND, NPM_VERSION_FILTER,
)
from .exceptions import (
    DynamicImportError, ErrorInterrogatingEnvironment, MalformedVersionInput, MissingDependency, OutdatedDependency,
    ModuleDoesNotContainAnyServices
)
    from . import node, npm  # Avoid a circular import
    from .base_service import BaseService  # Avoid a circular import


def run_command(cmd_to_run):
    """
    Wrapper around subprocess that pipes the stderr and stdout from `cmd_to_run`
    to temporary files. Using the temporary files gets around subprocess.PIPE's
    issues with handling large buffers.

    Note: this command will block the python process until `cmd_to_run` has completed.

    Returns a tuple, containing the stderr and stdout as strings.
    """
    with tempfile.TemporaryFile() as stdout_file, tempfile.TemporaryFile() as stderr_file:

        # Run the command
        popen = subprocess.Popen(cmd_to_run, stdout=stdout_file, stderr=stderr_file)
        popen.wait()

        stderr_file.seek(0)
        stdout_file.seek(0)

        stderr = stderr_file.read()
        stdout = stdout_file.read()

        if six.PY3:
            stderr = stderr.decode()
            stdout = stdout.decode()

        return stderr, stdout


def _interrogate(cmd_to_run, version_filter):
    try:
        stderr, stdout = run_command(cmd_to_run)
        if stderr:
            raise ErrorInterrogatingEnvironment(stderr)
        installed = True
        version_raw = stdout.strip()
    except OSError:
        installed = False
        version_raw = None
    version = None
    if version_raw:
        version = version_filter(version_raw)
    return installed, version, version_raw,

# Interrogate the system
node_installed, node_version, node_version_raw = _interrogate(

    (PATH_TO_NODE, NODE_VERSION_COMMAND,),