예제 #1
0
def find_version_in_range(versions, semver_range):
    '''versions is an array of semver versions and semver_range is a semver range expression.

    Assumes the environment has `node` on the $PATH.
    '''
    logging.debug('Trying to match %s against %s.', semver_range, versions)
    if platform_checker.is_windows():
        shell = True
        # Because we have to use `shell=True` on Windows due to https://bugs.python.org/issue17023,
        # we have to do our own escaping. In particular, if semver_range is '>=0.12.0' and is not
        # escaped correctly, then Windows will try to write to a file with that name. The built-in
        # escaping done by subprocess.Popen() does not appear to do the right thing here (it uses
        # single quotes instead of double quotes, which is not sufficient), so we must do the
        # escaping ourselves and convert the args into a string to override the default escaping.
        semver_range = '"%s"' % semver_range
    else:
        shell = False

    args = [
        platform_checker.get_node_executable(), semver, '--range', semver_range
    ] + versions

    if platform_checker.is_windows():
        args = ' '.join(args)

    proc = subprocess.Popen(args, stdout=subprocess.PIPE, shell=shell)
    matching_versions = []
    for line in proc.stdout:
        matching_versions.append(line.rstrip())
    proc.wait()
    if proc.returncode:
        return None
    else:
        return matching_versions
예제 #2
0
def link_dependencys_executable(node_modules_path, dependency_name):
    dependency_root = os.path.join(node_modules_path, dependency_name)
    dependency_config = json_load(os.path.join(dependency_root,
                                               'package.json'))

    # The bin field would ether be a dict or a string. if it's a dict,
    # such as `{ "name": "test", "bin" : { "myapp" : "./cli.js" } }`, we should create a
    # symlink from ./node_modules/test/cli.js to ./node_modules/.bin/myapp.
    # If it's a string, like `{ "name": "test", "bin" : "./cli.js"  }`, then the symlink's name
    # should be name of the package, in this case, it should be ./node_modules/.bin/test .
    bin_config = dependency_config.get('bin')
    if not bin_config:
        return
    elif isinstance(bin_config, dict):
        symlinks_to_create = bin_config
    else:
        symlinks_to_create = {dependency_name: bin_config}

    dot_bin_path = os.path.join(node_modules_path, '.bin')
    if platform_checker.is_windows():
        fs.mkdirs(dot_bin_path)

    for dst_name, relative_src_path in symlinks_to_create.items():
        absolute_dst_path = os.path.join(dot_bin_path, dst_name)
        absolute_src_path = os.path.join(dependency_root, relative_src_path)

        if platform_checker.is_windows():
            shutil.copyfile(absolute_src_path, absolute_dst_path)
        else:
            symlink(absolute_src_path, absolute_dst_path, relative=True)
def link_dependencys_executable(node_modules_path, dependency_name):
    dependency_root = os.path.join(node_modules_path, dependency_name)
    dependency_config = json_load(os.path.join(dependency_root, "package.json"))

    # The bin field would ether be a dict or a string. if it's a dict,
    # such as `{ "name": "test", "bin" : { "myapp" : "./cli.js" } }`, we should create a
    # symlink from ./node_modules/test/cli.js to ./node_modules/.bin/myapp.
    # If it's a string, like `{ "name": "test", "bin" : "./cli.js"  }`, then the symlink's name
    # should be name of the package, in this case, it should be ./node_modules/.bin/test .
    bin_config = dependency_config.get("bin")
    if not bin_config:
        return
    elif isinstance(bin_config, dict):
        symlinks_to_create = bin_config
    else:
        symlinks_to_create = {dependency_name: bin_config}

    dot_bin_path = os.path.join(node_modules_path, ".bin")
    if platform_checker.is_windows():
        fs.mkdirs(dot_bin_path)

    for dst_name, relative_src_path in symlinks_to_create.items():
        absolute_dst_path = os.path.join(dot_bin_path, dst_name)
        absolute_src_path = os.path.join(dependency_root, relative_src_path)

        if platform_checker.is_windows():
            shutil.copyfile(absolute_src_path, absolute_dst_path)
        else:
            symlink(absolute_src_path, absolute_dst_path, relative=True)
예제 #4
0
def find_version_in_range(versions, semver_range):
    '''versions is an array of semver versions and semver_range is a semver range expression.

    Assumes the environment has `node` on the $PATH.
    '''
    logging.debug('Trying to match %s against %s.', semver_range, versions)
    if platform_checker.is_windows():
        shell = True
        # Because we have to use `shell=True` on Windows due to https://bugs.python.org/issue17023,
        # we have to do our own escaping. In particular, if semver_range is '>=0.12.0' and is not
        # escaped correctly, then Windows will try to write to a file with that name. The built-in
        # escaping done by subprocess.Popen() does not appear to do the right thing here (it uses
        # single quotes instead of double quotes, which is not sufficient), so we must do the
        # escaping ourselves and convert the args into a string to override the default escaping.
        semver_range = '"%s"' % semver_range
    else:
        shell = False

    args = [platform_checker.get_node_executable(), semver, '--range', semver_range] + versions

    if platform_checker.is_windows():
        args = ' '.join(args)

    proc = subprocess.Popen(args, stdout=subprocess.PIPE, shell=shell)
    matching_versions = []
    for line in proc.stdout:
        matching_versions.append(line.rstrip())
    proc.wait()
    if proc.returncode:
        return None
    else:
        return matching_versions
예제 #5
0
def run_js_test(test_runner, pkg_path, name):
    """Run `apm test` or `npm test` in the given pkg_path."""

    logging.info('Running `%s test` in %s...', test_runner, pkg_path)

    # In Atom 1.2+, "apm test" exits with an error when there is no "spec" directory
    if test_runner == 'apm' and not os.path.isdir(
            os.path.join(pkg_path, 'spec')):
        logging.info('NO TESTS TO RUN FOR: %s', name)
        return

    if test_runner == 'apm':
        test_args = ['node', '--harmony', APM_TEST_WRAPPER, pkg_path]
    else:
        test_args = ['npm', 'test']

    proc = subprocess.Popen(test_args,
                            cwd=pkg_path,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT,
                            shell=platform_checker.is_windows())
    stdout = []
    for line in proc.stdout:
        # line is a bytes string literal in Python 3.
        logging.info('[%s test %s]: %s', test_runner, name,
                     line.rstrip().decode('utf-8'))
        stdout.append(line)
    proc.wait()

    if proc.returncode:
        logging.info('TEST FAILED: %s\nstdout:\n%s', name, '\n'.join(stdout))
        raise Exception('TEST FAILED: %s test %s' % (test_runner, name))
    else:
        logging.info('TEST PASSED: %s', name)
예제 #6
0
def run_js_test(test_runner, pkg_path, name):
    """Run `apm test` or `npm test` in the given pkg_path."""

    logging.info('Running `%s test` in %s...', test_runner, pkg_path)

    # Add --one option to `apm test` to ensure no deprecated APIs are used:
    # http://blog.atom.io/2015/05/01/removing-deprecated-apis.html.
    test_args = [test_runner, 'test']
    if test_runner == 'apm':
        test_args += ['--one']

    proc = subprocess.Popen(test_args,
                            cwd=pkg_path,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT,
                            shell=platform_checker.is_windows())
    stdout = []
    for line in proc.stdout:
        # line is a bytes string literal in Python 3.
        logging.info('[%s test %s]: %s', test_runner, name,
                     line.rstrip().decode('utf-8'))
        stdout.append(line)
    proc.wait()

    if proc.returncode:
        logging.info('TEST FAILED: %s\nstdout:\n%s', name, '\n'.join(stdout))
        raise Exception('TEST FAILED: %s test %s' % (test_runner, name))
    else:
        logging.info('TEST PASSED: %s', name)
예제 #7
0
def run_js_test(test_runner, pkg_path, name):
    """Run `apm test` or `npm test` in the given pkg_path."""

    logging.info('Running `%s test` in %s...', test_runner, pkg_path)

    # Add --one option to `apm test` to ensure no deprecated APIs are used:
    # http://blog.atom.io/2015/05/01/removing-deprecated-apis.html.
    test_args = [test_runner, 'test']
    if test_runner == 'apm':
        test_args += ['--one']

    proc = subprocess.Popen(
            test_args,
            cwd=pkg_path,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            shell=platform_checker.is_windows())
    stdout = []
    for line in proc.stdout:
        # line is a bytes string literal in Python 3.
        logging.info('[%s test %s]: %s', test_runner, name, line.rstrip().decode('utf-8'))
        stdout.append(line)
    proc.wait()

    if proc.returncode:
        logging.info('TEST FAILED: %s\nstdout:\n%s', name, '\n'.join(stdout))
        raise Exception('TEST FAILED: %s test %s' % (test_runner, name))
    else:
        logging.info('TEST PASSED: %s', name)
예제 #8
0
def run_js_test(test_runner, pkg_path, name):
    """Run `apm test` or `npm test` in the given pkg_path."""

    logging.info('Running `%s test` in %s...', test_runner, pkg_path)

    # In Atom 1.2+, "apm test" exits with an error when there is no "spec" directory
    if test_runner == 'apm' and not os.path.isdir(os.path.join(pkg_path, 'spec')):
        logging.info('NO TESTS TO RUN FOR: %s', name)
        return

    if test_runner == 'apm':
        test_args = ['node', '--harmony', APM_TEST_WRAPPER, pkg_path]
    else:
        test_args = ['npm', 'test']

    proc = subprocess.Popen(
            test_args,
            cwd=pkg_path,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            shell=platform_checker.is_windows())
    stdout = []
    for line in proc.stdout:
        # line is a bytes string literal in Python 3.
        logging.info('[%s test %s]: %s', test_runner, name, line.rstrip().decode('utf-8'))
        stdout.append(line)
    proc.wait()

    if proc.returncode:
        logging.info('TEST FAILED: %s\nstdout:\n%s', name, '\n'.join(stdout))
        raise Exception('TEST FAILED: %s test %s' % (test_runner, name))
    else:
        logging.info('TEST PASSED: %s', name)
예제 #9
0
 def install(self):
     if platform_checker.is_windows():
         # Python's multiprocessing library has issues on Windows, so it seems easiest to avoid it:
         # https://docs.python.org/2/library/multiprocessing.html#windows
         self._do_serial_install()
     else:
         self._do_multiprocess_install()
 def install(self):
     if platform_checker.is_windows():
         # Python's multiprocessing library has issues on Windows, so it seems easiest to avoid it:
         # https://docs.python.org/2/library/multiprocessing.html#windows
         self._do_serial_install()
     else:
         self._do_multiprocess_install()
예제 #11
0
def run_flow_check(pkg_path, name, show_all):
    """Run a flow typecheck in the given pkg_path."""
    logging.info('Running `flow check` in %s...', pkg_path)
    test_args = ['flow', 'check']
    if show_all:
        test_args.append('--show-all-errors')

    proc = subprocess.Popen(
            test_args,
            cwd=pkg_path,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            shell=platform_checker.is_windows())
    stdout = []
    for line in proc.stdout:
        # line is a bytes string literal in Python 3.
        logging.info('[flow check %s]: %s', name, line.rstrip().decode('utf-8'))
        stdout.append(line)
    proc.wait()

    if proc.returncode:
        logging.info('FLOW CHECK FAILED: %s\nstdout:\n%s', name, '\n'.join(stdout))
        raise Exception('FLOW CHECK FAILED: flow test %s' % name)
    else:
        logging.info('FLOW CHECK PASSED: %s', name)
예제 #12
0
def run_flow_check(pkg_path, name, show_all):
    """Run a flow typecheck in the given pkg_path."""
    logging.info('Running `flow check` in %s...', pkg_path)
    test_args = ['flow', 'check']
    if show_all:
        test_args.append('--show-all-errors')

    proc = subprocess.Popen(test_args,
                            cwd=pkg_path,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT,
                            shell=platform_checker.is_windows())
    stdout = []
    for line in proc.stdout:
        # line is a bytes string literal in Python 3.
        logging.info('[flow check %s]: %s', name,
                     line.rstrip().decode('utf-8'))
        stdout.append(line)
    proc.wait()

    if proc.returncode:
        logging.info('FLOW CHECK FAILED: %s\nstdout:\n%s', name,
                     '\n'.join(stdout))
        raise Exception('FLOW CHECK FAILED: flow test %s' % name)
    else:
        logging.info('FLOW CHECK PASSED: %s', name)
예제 #13
0
    def run_tests(self):
        apm_tests = []
        npm_tests = []
        serial_only_tests = []

        for package_config in self._package_manager.get_configs():
            pkg_path = package_config['packageRootAbsolutePath']
            name = package_config['name']

            # We run the tests in Nuclide/spec in a separate integration test step.
            if name == 'nuclide':
                continue

            if package_config['excludeTestsFromContinuousIntegration']:
                continue

            test_runner = package_config['testRunner']
            if test_runner == 'apm' and not self._include_apm:
                continue

            if self._packages_to_test and name not in self._packages_to_test:
                continue

            test_args = (test_runner, pkg_path, name)
            if package_config['testsCannotBeRunInParallel']:
              test_bucket = serial_only_tests
            elif test_runner == 'npm':
              test_bucket = npm_tests
            else:
              test_bucket = apm_tests
            test_bucket.append(test_args)

        if self._run_in_band or platform_checker.is_windows():
            # We run all tests in serial on Windows because Python's multiprocessing library has issues:
            # https://docs.python.org/2/library/multiprocessing.html#windows
            parallel_tests = []
            serial_tests = npm_tests + apm_tests
        else:
            # Currently, all tests appear to be able to be run in parallel. We keep this code
            # here in case we have to special-case any tests (on a short-term basis) to be run
            # serially after all of the parallel tests have finished.
            parallel_tests = npm_tests + apm_tests
            serial_tests = []

        serial_tests += serial_only_tests

        serial_tests += [('flow', self._package_manager.get_nuclide_path(), 'nuclide')]

        if parallel_tests:
            pool = Pool(processes=max(1, cpu_count() - 2))
            results = [pool.apply_async(run_test, args=test_args) for test_args in parallel_tests]
            for async_result in results:
                async_result.wait()
                if not async_result.successful():
                    raise async_result.get()

        for test_args in serial_tests:
            (test_runner, pkg_path, name) = test_args
            run_test(test_runner, pkg_path, name)
예제 #14
0
    def run_tests(self):
        apm_tests = []
        npm_tests = []
        serial_only_tests = []

        for package_config in self._package_manager.get_configs():
            pkg_path = package_config['packageRootAbsolutePath']
            name = package_config['name']

            # We run the tests in Nuclide/spec in a separate integration test step.
            if name == 'nuclide':
                continue

            if package_config['excludeTestsFromContinuousIntegration']:
                continue

            test_runner = package_config['testRunner']
            if test_runner == 'apm' and not self._include_apm:
                continue

            if self._packages_to_test and name not in self._packages_to_test:
                continue

            test_args = (test_runner, pkg_path, name)
            if package_config['testsCannotBeRunInParallel']:
              test_bucket = serial_only_tests
            elif test_runner == 'npm':
              test_bucket = npm_tests
            else:
              test_bucket = apm_tests
            test_bucket.append(test_args)

        if self._run_in_band or platform_checker.is_windows():
            # We run all tests in serial on Windows because Python's multiprocessing library has issues:
            # https://docs.python.org/2/library/multiprocessing.html#windows
            parallel_tests = []
            serial_tests = npm_tests + apm_tests
        else:
            # Currently, all tests appear to be able to be run in parallel. We keep this code
            # here in case we have to special-case any tests (on a short-term basis) to be run
            # serially after all of the parallel tests have finished.
            parallel_tests = npm_tests + apm_tests
            serial_tests = []

        serial_tests += serial_only_tests

        serial_tests += [('flow', self._package_manager.get_nuclide_path(), 'nuclide')]

        if parallel_tests:
            pool = Pool(processes=max(1, cpu_count() - 2))
            results = [pool.apply_async(run_test, args=test_args) for test_args in parallel_tests]
            for async_result in results:
                async_result.wait()
                if not async_result.successful():
                    raise async_result.get()

        for test_args in serial_tests:
            (test_runner, pkg_path, name) = test_args
            run_test(test_runner, pkg_path, name)
예제 #15
0
def run_js_test(test_runner, pkg_path, name):
    """Run `apm test` or `npm test` in the given pkg_path."""

    logging.info('Running `%s test` in %s...', test_runner, pkg_path)

    # In Atom 1.2+, "apm test" exits with an error when there is no "spec" directory
    if test_runner == 'apm' and not os.path.isdir(
            os.path.join(pkg_path, 'spec')):
        logging.info('NO TESTS TO RUN FOR: %s', name)
        return

    if test_runner == 'apm':
        test_args = ['node', '--harmony', APM_TEST_WRAPPER, pkg_path]
    else:
        test_args = ['npm', 'test']

    for tries in xrange(0, RETRY_LIMIT):
        proc = subprocess.Popen(test_args,
                                cwd=pkg_path,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT,
                                shell=platform_checker.is_windows())
        retry = False
        stdout = []
        for line in proc.stdout:
            # line is a bytes string literal in Python 3.
            logging.info('[%s test %s]: %s', test_runner, name,
                         line.rstrip().decode('utf-8'))
            stdout.append(line)
            # There are some loglines that correlate highly to test failures due to a bug in atom,
            # so we retry the test if we see this bad test output.  See: D2809659 for an explanation.
            if test_runner == 'apm' and tries < RETRY_LIMIT - 1 and BAD_TEST_OUTPUT in line:
                logging.info('[%s test %s]: %s: %s', test_runner, name,
                             'Aborting test due to bad output',
                             BAD_TEST_OUTPUT)
                retry = True
                break
        proc.wait()

        if retry:
            continue

        if proc.returncode:
            logging.info('TEST FAILED: %s\nstdout:\n%s', name,
                         '\n'.join(stdout))
            raise Exception('TEST FAILED: %s test %s' % (test_runner, name))
        else:
            logging.info('TEST PASSED: %s', name)
        break
예제 #16
0
    def run_tests(self):
        apm_tests = []
        npm_tests = []
        flow_tests = []

        for package_config in self._package_manager.get_configs():
            if package_config['excludeTestsFromContinuousIntegration']:
                continue

            test_runner = package_config['testRunner']
            if test_runner == 'apm' and not self._include_apm:
                continue

            pkg_path = package_config['packageRootAbsolutePath']
            name = package_config['name']
            test_args = (test_runner, pkg_path, name)
            test_bucket = npm_tests if test_runner == 'npm' else apm_tests
            test_bucket.append(test_args)

            if package_config['flowCheck']:
                flow_tests.append(('flow', pkg_path, name))

        if platform_checker.is_windows():
            # We run all tests in serial on Windows because Python's multiprocessing library has issues:
            # https://docs.python.org/2/library/multiprocessing.html#windows
            parallel_tests = []
            serial_tests = npm_tests + apm_tests + flow_tests
        else:
            # Currently, all tests appear to be able to be run in parallel. We keep this code
            # here in case we have to special-case any tests (on a short-term basis) to be run
            # serially after all of the parallel tests have finished.
            parallel_tests = npm_tests + apm_tests + flow_tests
            serial_tests = []

        if parallel_tests:
            pool = Pool(processes=cpu_count())
            results = [
                pool.apply_async(run_test, args=test_args)
                for test_args in parallel_tests
            ]
            for async_result in results:
                async_result.wait()
                if not async_result.successful():
                    raise async_result.get()

        for test_args in serial_tests:
            (test_runner, pkg_path, name) = test_args
            run_test(test_runner, pkg_path, name)
예제 #17
0
    def clean(self):
        import datetime

        start = datetime.datetime.now()
        logging.info("START CLEAN: %s", start)

        if platform_checker.is_windows():
            # Python's multiprocessing library has issues on Windows, so it seems easiest to avoid it:
            # https://docs.python.org/2/library/multiprocessing.html#windows
            self._do_serial_clean()
        else:
            self._do_multiprocess_clean()

        end = datetime.datetime.now()
        logging.info("FINISH CLEAN: %s", end)
        logging.info("PackageManager.clean_dependencies() took %s seconds.", (end - start).seconds)
예제 #18
0
파일: semver.py 프로젝트: dalinaum/nuclide
def find_version_in_range(versions, semver_range):
    '''versions is an array of semver versions and semver_range is a semver range expression.

    Assumes the environment has `node` on the $PATH.
    '''
    logging.debug('Trying to match %s against %s.', semver_range, versions)
    args = [platform_checker.get_node_executable(), semver] + versions + ['-r', semver_range]
    shell = True if platform_checker.is_windows() else False
    proc = subprocess.Popen(args, stdout=subprocess.PIPE, shell=shell)
    matching_versions = []
    for line in proc.stdout:
        matching_versions.append(line.rstrip())
    proc.wait()
    if proc.returncode:
        return None
    else:
        return matching_versions
예제 #19
0
    def run_tests(self):
        apm_tests = []
        npm_tests = []
        flow_tests = []

        for package_config in self._package_manager.get_configs():
            if package_config['excludeTestsFromContinuousIntegration']:
                continue

            test_runner = package_config['testRunner']
            if test_runner == 'apm' and not self._include_apm:
                continue

            pkg_path = package_config['packageRootAbsolutePath']
            name = package_config['name']
            test_args = (test_runner, pkg_path, name)
            test_bucket = npm_tests if test_runner == 'npm' else apm_tests
            test_bucket.append(test_args)

            if package_config['flowCheck']:
                flow_tests.append(('flow', pkg_path, name))

        if platform_checker.is_windows():
            # We run all tests in serial on Windows because Python's multiprocessing library has issues:
            # https://docs.python.org/2/library/multiprocessing.html#windows
            parallel_tests = []
            serial_tests = npm_tests + apm_tests + flow_tests
        else:
            # Currently, all tests appear to be able to be run in parallel. We keep this code
            # here in case we have to special-case any tests (on a short-term basis) to be run
            # serially after all of the parallel tests have finished.
            parallel_tests = npm_tests + apm_tests + flow_tests
            serial_tests = []

        if parallel_tests:
            pool = Pool(processes=cpu_count())
            results = [pool.apply_async(run_test, args=test_args) for test_args in parallel_tests]
            for async_result in results:
                async_result.wait()
                if not async_result.successful():
                    raise async_result.get()

        for test_args in serial_tests:
            (test_runner, pkg_path, name) = test_args
            run_test(test_runner, pkg_path, name)
예제 #20
0
def run_js_test(test_runner, pkg_path, name):
    """Run `apm test` or `npm test` in the given pkg_path."""

    logging.info('Running `%s test` in %s...', test_runner, pkg_path)

    # In Atom 1.2+, "apm test" exits with an error when there is no "spec" directory
    if test_runner == 'apm' and not os.path.isdir(os.path.join(pkg_path, 'spec')):
        logging.info('NO TESTS TO RUN FOR: %s', name)
        return

    if test_runner == 'apm':
        test_args = ['node', '--harmony', APM_TEST_WRAPPER, pkg_path]
    else:
        test_args = ['npm', 'test']

    for tries in xrange(0, RETRY_LIMIT):
        proc = subprocess.Popen(
                test_args,
                cwd=pkg_path,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                shell=platform_checker.is_windows())
        retry = False
        stdout = []
        for line in proc.stdout:
            # line is a bytes string literal in Python 3.
            logging.info('[%s test %s]: %s', test_runner, name, line.rstrip().decode('utf-8'))
            stdout.append(line)
            # There are some loglines that correlate highly to test failures due to a bug in atom,
            # so we retry the test if we see this bad test output.  See: D2809659 for an explanation.
            if test_runner == 'apm' and tries < RETRY_LIMIT - 1 and BAD_TEST_OUTPUT in line:
                logging.info('[%s test %s]: %s: %s', test_runner, name, 'Aborting test due to bad output', BAD_TEST_OUTPUT)
                retry = True
                break
        proc.wait()

        if retry:
            continue

        if proc.returncode:
            logging.info('TEST FAILED: %s\nstdout:\n%s', name, '\n'.join(stdout))
            raise Exception('TEST FAILED: %s test %s' % (test_runner, name))
        else:
            logging.info('TEST PASSED: %s', name)
        break
예제 #21
0
def cross_platform_check_output(cmd_args, **kwargs):
    ''' This is a subprocess.check_output() implementation providing cross-platform support
    '''

    # Unfortunately, it appears that shell=True must be used on Windows to behave like it does on
    # OS X and Linux: https://bugs.python.org/issue17023. Alternatively, we could try to get the
    # full path to the executable, but that seems like a pain.
    if platform_checker.is_windows():
        kwargs['shell'] = True

    kwargs['stdout'] = subprocess.PIPE
    process = subprocess.Popen(cmd_args, **kwargs)
    stdout, stderr = process.communicate()
    returncode = process.returncode

    if returncode:
        logging.error('Error running %s in %s', cmd_args, kwargs.get('cwd', os.getcwd()))
        raise subprocess.CalledProcessError(returncode, cmd_args)

    return stdout
예제 #22
0
파일: fs.py 프로젝트: dalinaum/nuclide
def cross_platform_check_call(args, cwd=None, stdout=None, stderr=None):
    '''Use this instead of subprocess.check_call() when the executable in args is not an absolute path.

    args: Array of strings, such as ['npm', 'install'].
    '''
    if platform_checker.is_windows():
        # Unfortunately, it appears that shell=True must be used on Windows to get check_call to
        # behave like it does on OS X and Linux: https://bugs.python.org/issue17023. Alternatively,
        # we could try to get the full path to the executable, but that seems like a pain.
        subprocess.check_call(args,
                              cwd=cwd,
                              stdout=stdout,
                              stderr=stderr,
                              shell=True,
                              )
    else:
        subprocess.check_call(args,
                              cwd=cwd,
                              stdout=stdout,
                              stderr=stderr,
                              )
예제 #23
0
def cross_platform_check_output(cmd_args, **kwargs):
    ''' This is a subprocess.check_output() implementation providing cross-platform support
    '''

    # Unfortunately, it appears that shell=True must be used on Windows to behave like it does on
    # OS X and Linux: https://bugs.python.org/issue17023. Alternatively, we could try to get the
    # full path to the executable, but that seems like a pain.
    if platform_checker.is_windows():
        kwargs['shell'] = True

    kwargs['stdout'] = subprocess.PIPE
    process = subprocess.Popen(cmd_args, **kwargs)
    stdout, stderr = process.communicate()
    returncode = process.returncode

    if returncode:
        logging.error('Error running %s in %s', cmd_args,
                      kwargs.get('cwd', os.getcwd()))
        raise subprocess.CalledProcessError(returncode, cmd_args)

    return stdout
예제 #24
0
파일: fs.py 프로젝트: zgao/as-nuclide
def symlink(src, dest, relative=False):
    """Create symlink from src to dest, create directory if dest's dirname doesn't exist, won't
       throw exception if dest already exists and its symlink points to src.

       Args:
        relative: Create relative symlink instead of absolute symlink (only works on *nix).
    """
    dest_dir = os.path.dirname(dest)
    if not os.path.isdir(dest_dir):
        os.makedirs(dest_dir)
    if not os.path.islink(dest) or os.path.realpath(os.path.join(dest_dir, src)) != os.path.realpath(dest):
        try:
            if platform_checker.is_windows() and os.path.isdir(src):
                cross_platform_check_output(["mklink", "/J", "/D", dest, src])
            else:
                if relative and os.path.isabs(src):
                    src = os.path.relpath(src, os.path.dirname(dest))
                os.symlink(src, dest)
        except OSError as e:
            if e.errno == errno.EEXIST:
                os.remove(dest)
                os.symlink(src, dest)
예제 #25
0
def symlink(src, dest, relative=False):
    """Create symlink from src to dest, create directory if dest's dirname doesn't exist, won't
       throw exception if dest already exists and its symlink points to src.

       Args:
        relative: Create relative symlink instead of absolute symlink (only works on *nix).
    """
    dest_dir = os.path.dirname(dest)
    if not os.path.isdir(dest_dir):
        os.makedirs(dest_dir)
    if (not os.path.islink(dest) or os.path.realpath(
            os.path.join(dest_dir, src)) != os.path.realpath(dest)):
        try:
            if platform_checker.is_windows() and os.path.isdir(src):
                cross_platform_check_output(['mklink', '/J', '/D', dest, src])
            else:
                if relative and os.path.isabs(src):
                    src = os.path.relpath(src, os.path.dirname(dest))
                os.symlink(src, dest)
        except OSError as e:
            if e.errno == errno.EEXIST:
                os.remove(dest)
                os.symlink(src, dest)
예제 #26
0
def install_dependencies(package_config, npm):
    name = package_config['name']
    is_node_package = package_config['isNodePackage']
    package_type = 'Node' if is_node_package else 'Atom'
    logging.info('Installing dependencies for %s package %s...', package_type, name)

    # Link private node dependencies.
    src_path = package_config['packageRootAbsolutePath']
    fs.mkdirs(os.path.join(src_path, 'node_modules'))
    for local_dependency, local_dependency_config in package_config['localDependencies'].items():
        src_dir = local_dependency_config['packageRootAbsolutePath']
        dest_dir = os.path.join(src_path, 'node_modules', local_dependency)
        if platform_checker.is_windows():
            shutil.rmtree(dest_dir, ignore_errors=True)
            shutil.copytree(src_dir, dest_dir)
        else:
            symlink(src_dir, dest_dir)
        link_dependencys_executable(src_path, local_dependency)

    # Install other public node dependencies.
    npm.install(src_path, local_packages=package_config['localDependencies'], include_dev_dependencies=package_config['includeDevDependencies'])
    logging.info('Done installing dependencies for %s', name)

    # Install libclang dependencies, if appropriate.
    if package_config.get('installLibClang', False):
        from fb.libclang import install_libclang
        logging.info('Installing libclang extra dependencies...')
        install_libclang(src_path)
        logging.info('Done installing libclang extra dependencies.')

    is_node_package = package_config.get('isNodePackage')
    if not is_node_package:
        logging.info('Running `apm link %s`...', src_path)
        args = ['apm', 'link', src_path]
        fs.cross_platform_check_call(args)
        logging.info('Done linking %s', name)