def test_pants_binary_dep_isolation_with_multiple_targets(self):
   pex1 = os.path.join(get_buildroot(), 'dist', 'main_with_no_conflict.pex')
   pex2 = os.path.join(get_buildroot(), 'dist', 'main_with_no_pycountry.pex')
   try:
     command=['binary', '{}:main_with_no_conflict'.format(self.fasthello_install_requires),
              '{}:main_with_no_pycountry'.format(self.fasthello_install_requires)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     # Check that the pex was built.
     self.assertTrue(os.path.isfile(pex1))
     self.assertTrue(os.path.isfile(pex2))
     # Check that the pex 1 runs.
     output = subprocess.check_output(pex1)
     self._assert_native_greeting(output)
     # Check that the pex 2 fails due to no python_dists leaked into it.
     try:
       output = subprocess.check_output(pex2)
     except subprocess.CalledProcessError as e:
       self.assertNotEquals(0, e.returncode)
   finally:
     # Cleanup
     if os.path.exists(pex1):
       os.remove(pex1)
     if os.path.exists(pex2):
       os.remove(pex2)
Beispiel #2
0
  def setUp(self):
    self.origin = safe_mkdtemp()
    with pushd(self.origin):
      subprocess.check_call(['git', 'init', '--bare'])

    self.gitdir = safe_mkdtemp()
    self.worktree = safe_mkdtemp()

    self.readme_file = os.path.join(self.worktree, 'README')

    with environment_as(GIT_DIR=self.gitdir, GIT_WORK_TREE=self.worktree):
      self.init_repo('depot', self.origin)

      touch(self.readme_file)
      subprocess.check_call(['git', 'add', 'README'])
      safe_mkdir(os.path.join(self.worktree, 'dir'))
      with open(os.path.join(self.worktree, 'dir', 'f'), 'w') as f:
        f.write("file in subdir")

      # Make some symlinks
      os.symlink('f', os.path.join(self.worktree, 'dir', 'relative-symlink'))
      os.symlink('no-such-file', os.path.join(self.worktree, 'dir', 'relative-nonexistent'))
      os.symlink('dir/f', os.path.join(self.worktree, 'dir', 'not-absolute\u2764'))
      os.symlink('../README', os.path.join(self.worktree, 'dir', 'relative-dotdot'))
      os.symlink('dir', os.path.join(self.worktree, 'link-to-dir'))
      os.symlink('README/f', os.path.join(self.worktree, 'not-a-dir'))
      os.symlink('loop1', os.path.join(self.worktree, 'loop2'))
      os.symlink('loop2', os.path.join(self.worktree, 'loop1'))

      subprocess.check_call(['git', 'add', 'README', 'dir', 'loop1', 'loop2',
                             'link-to-dir', 'not-a-dir'])
      subprocess.check_call(['git', 'commit', '-am', 'initial commit with decode -> \x81b'])
      self.initial_rev = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip()
      subprocess.check_call(['git', 'tag', 'first'])
      subprocess.check_call(['git', 'push', '--tags', 'depot', 'master'])
      subprocess.check_call(['git', 'branch', '--set-upstream-to', 'depot/master'])

      with safe_open(self.readme_file, 'w') as readme:
        readme.write('Hello World.\u2764'.encode('utf-8'))
      subprocess.check_call(['git', 'commit', '-am', 'Update README.'])

      self.current_rev = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip()

    self.clone2 = safe_mkdtemp()
    with pushd(self.clone2):
      self.init_repo('origin', self.origin)
      subprocess.check_call(['git', 'pull', '--tags', 'origin', 'master:master'])

      with safe_open(os.path.realpath('README'), 'a') as readme:
        readme.write('--')
      subprocess.check_call(['git', 'commit', '-am', 'Update README 2.'])
      subprocess.check_call(['git', 'push', '--tags', 'origin', 'master'])

    self.git = Git(gitdir=self.gitdir, worktree=self.worktree)
Beispiel #3
0
  def test_awslambda_bundle(self):
    with temporary_dir() as distdir:
      config = {
        'GLOBAL': {
          'pants_distdir': distdir,
          'pythonpath': ['%(buildroot)s/contrib/awslambda/python/src/python'],
          'backend_packages': ['pants.backend.python', 'pants.contrib.awslambda.python'],
        }
      }

      command = [
        'bundle',
        'contrib/awslambda/python/src/python/pants/contrib/awslambda/python/examples:hello-lambda',
      ]
      pants_run = self.run_pants(command=command, config=config)
      self.assert_success(pants_run)

      # Now run the lambda via the wrapper handler injected by lambdex (note that this
      # is distinct from the pex's entry point - a handler must be a function with two arguments,
      # whereas the pex entry point is a module).
      awslambda = os.path.join(distdir, 'hello-lambda.pex')
      output = subprocess.check_output(env={'PEX_INTERPRETER': '1'}, args=[
        '{} -c "from lambdex_handler import handler; handler(None, None)"'.format(awslambda)
      ], shell=True)
      self.assertEquals(b'Hello from the United States!', output.strip())
Beispiel #4
0
    def test_pants_resolves_local_dists_for_current_platform_only(self):
        # Test that pants will override pants.ini platforms config when building
        # or running a target that depends on native (c or cpp) sources.
        with temporary_dir() as tmp_dir:
            pex = os.path.join(tmp_dir, 'main.pex')
            pants_ini_config = {
                'python-setup': {
                    'platforms': ['current', 'linux-x86_64']
                }
            }
            # Clean all to rebuild requirements pex.
            command = [
                '--pants-distdir={}'.format(tmp_dir), 'run',
                '{}:main'.format(self.fasthello_project)
            ]
            pants_run = self.run_pants(command=command,
                                       config=pants_ini_config)
            self.assert_success(pants_run)

            command = ['binary', '{}:main'.format(self.fasthello_project)]
            pants_run = self.run_pants(command=command,
                                       config=pants_ini_config)
            self.assert_success(pants_run)
            # Check that the pex was built.
            self.assertTrue(os.path.isfile(pex))
            # Check that the pex runs.
            output = subprocess.check_output(pex)
            self._assert_native_greeting(output)
Beispiel #5
0
def get_pyenv_root():
    try:
        return subprocess.check_output(['pyenv',
                                        'root']).decode('utf-8').strip()
    except (OSError, subprocess.CalledProcessError):
        logger.info('No pyenv binary found. Will not use pyenv interpreters.')
    return None
Beispiel #6
0
 def jvm_locations(self):
     # OSX will have a java_home tool that can be used to locate a unix-compatible java home dir.
     #
     # See:
     #   https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/java_home.1.html
     #
     # The `--xml` output looks like so:
     # <?xml version="1.0" encoding="UTF-8"?>
     # <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
     #                        "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
     # <plist version="1.0">
     #   <array>
     #     <dict>
     #       ...
     #       <key>JVMHomePath</key>
     #       <string>/Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home</string>
     #       ...
     #     </dict>
     #     ...
     #   </array>
     # </plist>
     if os.path.exists(self._osx_java_home_exe):
         try:
             plist = subprocess.check_output(
                 [self._osx_java_home_exe, '--failfast', '--xml'])
             plist_results = plistlib.loads(
                 plist) if PY3 else plistlib.readPlistFromString(plist)
             for distribution in plist_results:
                 home = distribution['JVMHomePath']
                 yield self.Location.from_home(home)
         except subprocess.CalledProcessError:
             pass
  def test_pants_resolves_local_dists_for_current_platform_only(self):
    # Test that pants will override pants.ini platforms config when building
    # or running a target that depends on native (c or cpp) sources.
    with temporary_dir() as tmp_dir:
      pex = os.path.join(tmp_dir, 'main.pex')
      pants_ini_config = {
        'python-setup': {
          'platforms': ['current', 'this-platform-does_not-exist'],
        },
      }
      command=[
        '--pants-distdir={}'.format(tmp_dir),
        'run',
        '{}:main'.format(self.fasthello_project)]
      pants_run = self.run_pants(command=command, config=pants_ini_config)
      self.assert_success(pants_run)

      command=['binary', '{}:main'.format(self.fasthello_project)]
      pants_run = self.run_pants(command=command, config=pants_ini_config)
      self.assert_success(pants_run)
      # Check that the pex was built.
      self.assertTrue(os.path.isfile(pex))
      # Check that the pex runs.
      output = subprocess.check_output(pex)
      self._assert_native_greeting(output)
Beispiel #8
0
            def commit_contents_to_files(message, encoding, content, *files):
                for path in files:
                    with safe_open(os.path.join(self.worktree, path),
                                   'w') as fp:
                        fp.write(content)
                subprocess.check_call(['git', 'add', '.'])

                subprocess.check_call([
                    'git', 'config', '--local', '--add', 'i18n.commitencoding',
                    encoding
                ])
                subprocess.check_call(
                    ['git', 'config', '--local', 'commit.gpgSign', 'false'])
                try:
                    subprocess.check_call(
                        ['git', 'commit', '-m',
                         message.encode(encoding)])
                finally:
                    subprocess.check_call([
                        'git', 'config', '--local', '--unset-all',
                        'i18n.commitencoding'
                    ])

                return subprocess.check_output(['git', 'rev-parse',
                                                'HEAD']).strip()
Beispiel #9
0
    def assert_no_gopath(self):
        go_distribution = self.distribution()

        go_env = go_distribution.go_env()

        # As of go 1.8, when GOPATH is unset (set to ''), it defaults to ~/go (assuming HOME is set -
        # and we can't unset that since it might legitmately be used by the subcommand) - so we manually
        # fetch the "unset" default value here as our expected value for tests below.
        # The key thing to note here is this default value is used only when `gopath` passed to
        # `GoDistribution` is None, implying the command to be run does not need or use a GOPATH.
        cmd = [
            os.path.join(go_distribution.goroot, 'bin', 'go'), 'env', 'GOPATH'
        ]
        env = os.environ.copy()
        env.update(go_env)
        default_gopath = subprocess.check_output(cmd, env=env).strip()

        go_cmd = go_distribution.create_go_cmd(cmd='env', args=['GOPATH'])

        self.assertEqual(go_env, go_cmd.env)
        self.assertEqual('go', os.path.basename(go_cmd.cmdline[0]))
        self.assertEqual(['env', 'GOPATH'], go_cmd.cmdline[1:])
        self.assertRegexpMatches(
            str(go_cmd),
            r'^GOROOT=[^ ]+ GOPATH={} .*/go env GOPATH'.format(default_gopath))
        self.assertEqual(default_gopath, go_cmd.check_output().strip())
Beispiel #10
0
 def commit_contents_to_files(content, *files):
   for path in files:
     with safe_open(os.path.join(self.worktree, path), 'w') as fp:
       fp.write(content)
   subprocess.check_call(['git', 'add', '.'])
   subprocess.check_call(['git', 'commit', '-m', 'change {}'.format(files)])
   return subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip()
Beispiel #11
0
 def test_hermetic_environment_subprocesses(self):
     self.assertIn('USER', os.environ)
     with hermetic_environment_as(**dict(AAA='333')):
         output = subprocess.check_output('env', shell=True).decode('utf-8')
         self.assertNotIn('USER='******'AAA', os.environ)
         self.assertEquals(os.environ['AAA'], '333')
     self.assertIn('USER', os.environ)
     self.assertNotIn('AAA', os.environ)
 def test_go_crosscompile(self):
     # We assume that targeting windows is cross-compiling.
     output_file = "dist/go/bin/hello.exe"
     safe_delete(output_file)
     args = ['binary', 'contrib/go/examples/src/go/hello']
     pants_run = self.run_pants(args, extra_env={"GOOS": "windows"})
     self.assert_success(pants_run)
     self.assertIn("for MS Windows",
                   subprocess.check_output(["file", output_file]))
 def test_go_crosscompile(self):
   # We assume that targeting windows is cross-compiling.
   output_file = "dist/go/bin/hello.exe"
   safe_delete(output_file)
   args = ['binary',
           'contrib/go/examples/src/go/hello']
   pants_run = self.run_pants(args, extra_env={"GOOS": "windows"})
   self.assert_success(pants_run)
   self.assertIn(b"for MS Windows", subprocess.check_output(["file", output_file]))
Beispiel #14
0
 def test_hermetic_environment_subprocesses(self):
   self.assertIn('USER', os.environ)
   with hermetic_environment_as(**dict(AAA='333')):
     output = subprocess.check_output('env', shell=True)
     self.assertNotIn('USER='******'AAA', os.environ)
     self.assertEquals(os.environ['AAA'], '333')
   self.assertIn('USER', os.environ)
   self.assertNotIn('AAA', os.environ)
Beispiel #15
0
 def test_hermetic_environment_subprocesses(self):
     with self.ensure_user_defined_in_environment():
         with hermetic_environment_as(AAA='333'):
             output = subprocess.check_output('env',
                                              shell=True).decode('utf-8')
             self.assertNotIn('USER='******'AAA', os.environ)
             self.assertEqual(os.environ['AAA'], '333')
         self.assertIn('USER', os.environ)
         self.assertNotIn('AAA', os.environ)
        def check_output(self, **kwargs):
            """Runs this command returning its captured stdout.

      :param **kwargs: Any extra keyword arguments to pass along to `subprocess.Popen`.
      :returns: The captured standard output stream of the command.
      :rtype: string
      :raises: :class:`subprocess.CalledProcessError` if the command fails.
      """
            env, kwargs = self._prepare_env(kwargs)
            return subprocess.check_output(self.cmd, env=env, **kwargs)
Beispiel #17
0
 def commit_contents_to_files(content, *files):
     for path in files:
         with safe_open(os.path.join(self.worktree, path),
                        'w') as fp:
             fp.write(content)
     subprocess.check_call(['git', 'add', '.'])
     subprocess.check_call(
         ['git', 'commit', '-m', 'change {}'.format(files)])
     return subprocess.check_output(['git', 'rev-parse',
                                     'HEAD']).strip()
Beispiel #18
0
  def check_output(self, **kwargs):
    """Runs this command returning its captured stdout.

    :param kwargs: Any extra keyword arguments to pass along to `subprocess.Popen`.
    :returns: The captured standard output stream of the command.
    :rtype: string
    :raises: :class:`subprocess.CalledProcessError` if the command fails.
    """
    env, kwargs = self._prepare_env(kwargs)
    return subprocess.check_output(self.cmd, env=env, **kwargs)
Beispiel #19
0
    def ensure_conan_remote_configuration(self, conan_binary):
        """
    Ensure that the conan registry.txt file is sanitized and loaded with
    a pants-specific remote for package fetching.

    :param conan_binary: The conan client pex to use for manipulating registry.txt.
    """

        # Conan will prepend the conan-center remote to the remote registry when
        # bootstrapped for the first time, so we want to delete it from the registry
        # and replace it with Pants-controlled remotes.
        remove_conan_center_remote_cmdline = self._remove_conan_center_remote_cmdline(
            conan_binary)
        try:
            # Slice the command line because subprocess errors when the first element in the
            # list of command strings is the setting of an environment variable.
            stdout = subprocess.check_output(
                remove_conan_center_remote_cmdline.split()[1:])
            self.context.log.debug(stdout)
        except subprocess.CalledProcessError as e:
            if not "'conan-center' not found in remotes" in e.output:
                raise TaskError(
                    'Error deleting conan-center from conan registry: {}'.
                    format(e.output))

        # Add the pants-specific conan remote.
        index_num = 0
        for remote_url in reversed(self.get_options().conan_remotes):
            index_num += 1
            # NB: --insert prepends a remote to conan's remote list. We reverse the options remote
            # list to maintain a sensible default for conan emote search order.
            add_pants_conan_remote_cmdline = self._add_pants_conan_remote_cmdline(
                conan_binary, index_num, remote_url)
            try:
                stdout = subprocess.check_output(
                    add_pants_conan_remote_cmdline.split()[1:])
                self.context.log.debug(stdout)
            except subprocess.CalledProcessError as e:
                if not "already exists in remotes" in e.output:
                    raise TaskError(
                        'Error adding pants-specific conan remote: {}'.format(
                            e.output))
Beispiel #20
0
 def test_pants_binary(self):
     command = ['binary', '{}:main'.format(self.fasthello_project)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     # Check that the pex was built.
     pex = os.path.join(get_buildroot(), 'dist', 'main.pex')
     self.assertTrue(os.path.isfile(pex))
     # Check that the pex runs.
     output = subprocess.check_output(pex)
     self.assertIn('Super hello', output)
     # Cleanup
     os.remove(pex)
  def python_interpreter_path(cls, version):
    """Returns the interpreter path if the current system has the specified version of python.

    :param version: A python version string, such as 2.7, 3.
    """
    try:
      py_path = subprocess.check_output(['python%s' % version,
                                         '-c',
                                         'import sys; print(sys.executable)']).strip()
      return os.path.realpath(py_path)
    except OSError:
      return None
 def test_pants_binary(self):
   command=['binary', '{}:main'.format(self.fasthello_project)]
   pants_run = self.run_pants(command=command)
   self.assert_success(pants_run)
   # Check that the pex was built.
   pex = os.path.join(get_buildroot(), 'dist', 'main.pex')
   self.assertTrue(os.path.isfile(pex))
   # Check that the pex runs.
   output = subprocess.check_output(pex)
   self.assertIn('Super hello', output)
   # Cleanup
   os.remove(pex)
Beispiel #23
0
    def check_output(self, env=None, **kwargs):
      """Returns the output of the executed Go command.

      :param dict env: A custom environment to launch the Go command in.  If `None` the current
                       environment is used.
      :param kwargs: Keyword arguments to pass through to `subprocess.check_output`.
      :return str: Output of Go command.
      :raises subprocess.CalledProcessError: Raises if Go command fails.
      """
      env = (env or os.environ).copy()
      env.update(self.env)
      return subprocess.check_output(self.cmdline, env=env, **kwargs)
 def test_with_install_requires(self):
   command=['run', '{}:main_with_no_conflict'.format(self.fasthello_install_requires)]
   pants_run = self.run_pants(command=command)
   self.assert_success(pants_run)
   self.assertIn('United States', pants_run.stdout_data)
   command=['binary', '{}:main_with_no_conflict'.format(self.fasthello_install_requires)]
   pants_run = self.run_pants(command=command)
   self.assert_success(pants_run)
   pex = os.path.join(get_buildroot(), 'dist', 'main_with_no_conflict.pex')
   output = subprocess.check_output(pex)
   self.assertIn('United States', output)
   os.remove(pex)
Beispiel #25
0
    def check_output(self, env=None, **kwargs):
      """Returns the output of the executed Go command.

      :param dict env: A custom environment to launch the Go command in.  If `None` the current
                       environment is used.
      :param kwargs: Keyword arguments to pass through to `subprocess.check_output`.
      :return str: Output of Go command.
      :raises subprocess.CalledProcessError: Raises if Go command fails.
      """
      env = (env or os.environ).copy()
      env.update(self.env)
      return subprocess.check_output(self.cmdline, env=env, **kwargs)
Beispiel #26
0
  def test_changed_diffspec_and_files(self):
    with create_isolated_git_repo():
      git_sha = subprocess.check_output(['git', 'rev-parse', 'HEAD^^']).strip()
      stdout = self.assert_changed_new_equals_old(['--changed-diffspec={}'.format(git_sha), '--files'])

      # The output should be the files added in the last 2 commits.
      self.assertEqual(
        lines_to_set(stdout),
        {'src/python/python_targets/BUILD',
         'src/python/python_targets/test_binary.py',
         'src/python/python_targets/test_library.py',
         'src/python/python_targets/test_unclaimed_src.py'}
      )
 def test_pants_binary_dep_isolation_with_multiple_targets(self):
   with temporary_dir() as tmp_dir:
     pex1 = os.path.join(tmp_dir, 'main_with_no_conflict.pex')
     pex2 = os.path.join(tmp_dir, 'main_with_no_pycountry.pex')
     command=[
       '--pants-distdir={}'.format(tmp_dir),
       'binary',
       '{}:main_with_no_conflict'.format(self.fasthello_install_requires_dir),
       '{}:main_with_no_pycountry'.format(self.fasthello_install_requires_dir)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     # Check that the pex was built.
     self.assertTrue(os.path.isfile(pex1))
     self.assertTrue(os.path.isfile(pex2))
     # Check that the pex 1 runs.
     output = subprocess.check_output(pex1)
     self._assert_native_greeting(output)
     # Check that the pex 2 fails due to no python_dists leaked into it.
     try:
       output = subprocess.check_output(pex2)
     except subprocess.CalledProcessError as e:
       self.assertNotEquals(0, e.returncode)
Beispiel #28
0
def python_interpreter_path(version):
  """Returns the interpreter path if the current system has the specified version of python.

  :param string version: A python version string, such as 2.7, 3.
  :returns: the normalized path to the interpreter binary if found; otherwise `None`
  :rtype: string
  """
  try:
    command = ['python{}'.format(version), '-c', 'import sys; print(sys.executable)']
    py_path = subprocess.check_output(command).decode('utf-8').strip()
    return os.path.realpath(py_path)
  except subprocess.CalledProcessError:
    return None
 def test_binary_dep_isolation_with_multiple_targets(self):
   with temporary_dir() as tmp_dir:
     pex1 = os.path.join(tmp_dir, 'main_with_no_conflict.pex')
     pex2 = os.path.join(tmp_dir, 'main_with_no_pycountry.pex')
     command=[
       '--pants-distdir={}'.format(tmp_dir),
       'binary',
       '{}:main_with_no_conflict'.format(self.fasthello_install_requires_dir),
       '{}:main_with_no_pycountry'.format(self.fasthello_install_requires_dir)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     # Check that the pex was built.
     self.assertTrue(os.path.isfile(pex1))
     self.assertTrue(os.path.isfile(pex2))
     # Check that the pex 1 runs.
     output = subprocess.check_output(pex1).decode('utf-8')
     self._assert_native_greeting(output)
     # Check that the pex 2 fails due to no python_dists leaked into it.
     try:
       subprocess.check_output(pex2)
     except subprocess.CalledProcessError as e:
       self.assertNotEqual(0, e.returncode)
Beispiel #30
0
    def _run_rakudobrew_command(self, argv):
        subproc_env = os.environ.copy()
        subproc_env['PATH'] = create_path_env_var(self.path_entries,
                                                  subproc_env,
                                                  prepend=True)

        all_argv = ['rakudobrew'] + argv
        pretty_printed_argv = safe_shlex_join(all_argv)
        try:
            return subprocess.check_output(all_argv, env=subproc_env)
        except (OSError, subprocess.CalledProcessError) as e:
            raise self.RakudoBrewBootstrapError(
                "Error with rakudobrew command '{}': {}".format(
                    pretty_printed_argv, e), e)
Beispiel #31
0
 def test_pants_binary(self):
   pex = os.path.join(get_buildroot(), 'dist', 'main.pex')
   try:
     command=['binary', '{}:main'.format(self.fasthello_project)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     # Check that the pex was built.
     self.assertTrue(os.path.isfile(pex))
     # Check that the pex runs.
     output = subprocess.check_output(pex)
     self._assert_native_greeting(output)
   finally:
     if os.path.exists(pex):
       os.remove(pex)
Beispiel #32
0
      def commit_contents_to_files(message, encoding, content, *files):
        for path in files:
          with safe_open(os.path.join(self.worktree, path), 'w') as fp:
            fp.write(content)
        subprocess.check_call(['git', 'add', '.'])

        subprocess.check_call(['git', 'config', '--local', '--add', 'i18n.commitencoding',
                               encoding])
        try:
          subprocess.check_call(['git', 'commit', '-m', message.encode(encoding)])
        finally:
          subprocess.check_call(['git', 'config', '--local', '--unset-all', 'i18n.commitencoding'])

        return subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip()
    def test_python_distribution_with_setup_requires(self):
        # Validate that setup_requires dependencies are present and functional.
        # PANTS_TEST_SETUP_REQUIRES triggers test functionality in this particular setup.py.
        with environment_as(PANTS_TEST_SETUP_REQUIRES='1'):
            command = ['run', '{}:main'.format(self.hello_setup_requires)]
            pants_run = self.run_pants(command=command)
            self.assertRaises(Exception)
            # Indicates the pycountry package is available to setup.py script.
            self.assertIn('current/setup_requires_site/pycountry/__init__.py',
                          pants_run.stderr_data)
            # Indicates that the pycountry wheel has been installed on PYTHONPATH correctly.
            self.assertIn('pycountry-18.5.20.dist-info', pants_run.stderr_data)

        # Valdiate the run task. Use clean-all to invalidate cached python_dist wheels from
        # previous test run. Use -ldebug to get debug info on setup_requires functionality.
        command = [
            '-ldebug', 'clean-all', 'run',
            '{}:main'.format(self.hello_setup_requires)
        ]
        pants_run = self.run_pants(command=command)
        self.assertIn("Installing setup requirements: ['pycountry']",
                      pants_run.stdout_data)
        self.assertIn("Setting PYTHONPATH with setup_requires site directory",
                      pants_run.stdout_data)

        # Validate that the binary can build and run properly. Use clean-all to invalidate cached
        # python_dist wheels from previous test run. Use -ldebug to get debug info on setup_requires
        # functionality.
        pex = os.path.join(get_buildroot(), 'dist', 'main.pex')
        try:
            command = [
                '-ldebug', 'clean-all', 'binary',
                '{}:main'.format(self.hello_setup_requires)
            ]
            pants_run = self.run_pants(command=command)
            self.assert_success(pants_run)
            self.assertIn("Installing setup requirements: ['pycountry']",
                          pants_run.stdout_data)
            self.assertIn(
                "Setting PYTHONPATH with setup_requires site directory",
                pants_run.stdout_data)
            # Check that the pex was built.
            self.assertTrue(os.path.isfile(pex))
            # Check that the pex runs.
            output = subprocess.check_output(pex).decode('utf-8')
            self.assertIn('Hello, world!', output)
        finally:
            if os.path.exists(pex):
                # Cleanup.
                os.remove(pex)
def python_interpreter_path(version):
  """Returns the interpreter path if the current system has the specified version of python.

  :param string version: A python version string, such as 2.7, 3.
  :returns: the normalized path to the interpreter binary if found; otherwise `None`
  :rtype: string
  """
  if PY2:
    FileNotFoundError = IOError
  try:
    command = ['python{}'.format(version), '-c', 'import sys; print(sys.executable)']
    py_path = subprocess.check_output(command).decode('utf-8').strip()
    return os.path.realpath(py_path)
  except (subprocess.CalledProcessError, FileNotFoundError):
    return None
 def test_with_install_requires(self):
   with temporary_dir() as tmp_dir:
     pex = os.path.join(tmp_dir, 'main_with_no_conflict.pex')
     command=[
       '--pants-distdir={}'.format(tmp_dir),
       'run',
       '{}:main_with_no_conflict'.format(self.fasthello_install_requires_dir)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     self.assertIn('United States', pants_run.stdout_data)
     command=['binary', '{}:main_with_no_conflict'.format(self.fasthello_install_requires_dir)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     output = subprocess.check_output(pex)
     self.assertIn('United States', output)
 def test_with_install_requires(self):
   with temporary_dir() as tmp_dir:
     pex = os.path.join(tmp_dir, 'main_with_no_conflict.pex')
     command=[
       '--pants-distdir={}'.format(tmp_dir),
       'run',
       '{}:main_with_no_conflict'.format(self.fasthello_install_requires)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     self.assertIn('United States', pants_run.stdout_data)
     command=['binary', '{}:main_with_no_conflict'.format(self.fasthello_install_requires)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     output = subprocess.check_output(pex)
     self.assertIn('United States', output)
Beispiel #37
0
 def go_fmt_invalid_targets(self, flags):
   targets = self.get_targets(self.is_checked)
   with self.invalidated(targets) as invalidation_check:
     invalid_targets = [vt.target for vt in invalidation_check.invalid_vts]
     sources = self.calculate_sources(invalid_targets)
     if sources:
       args = [os.path.join(self.go_dist.goroot, 'bin', 'gofmt')] + flags + list(sources)
       try:
         output = subprocess.check_output(args)
       except subprocess.CalledProcessError as e:
         raise TaskError('{} failed with exit code {}'.format(' '.join(args), e.returncode),
                         exit_code=e.returncode)
       yield output
     else:
       yield None
 def test_pants_binary(self):
   with temporary_dir() as tmp_dir:
     pex = os.path.join(tmp_dir, 'main.pex')
     wheel_glob = os.path.join(tmp_dir, 'fasthello-1.0.0-*.whl')
     command=[
       '--pants-distdir={}'.format(tmp_dir), 'binary', '{}:main'.format(self.fasthello_project)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     # Check that the pex was built.
     self.assertTrue(os.path.isfile(pex))
     # Check that the pex runs.
     output = subprocess.check_output(pex)
     self._assert_native_greeting(output)
     # Check that we have exact one wheel output
     self.assertEqual(len(glob.glob(wheel_glob)), 1)
Beispiel #39
0
 def test_with_install_requires(self):
   pex = os.path.join(get_buildroot(), 'dist', 'main_with_no_conflict.pex')
   try:
     command=['run', '{}:main_with_no_conflict'.format(self.fasthello_install_requires)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     self.assertIn('United States', pants_run.stdout_data)
     command=['binary', '{}:main_with_no_conflict'.format(self.fasthello_install_requires)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     output = subprocess.check_output(pex)
     self.assertIn('United States', output)
   finally:
     if os.path.exists(pex):
       os.remove(pex)
Beispiel #40
0
  def _invoke_capturing_output(self, cmd, cwd=None):
    if cwd is None:
      cwd = self.build_root

    toolchain_dirs = self.toolchain.path_entries()
    isolated_toolchain_path = get_joined_path(toolchain_dirs)
    try:
      with environment_as(PATH=isolated_toolchain_path):
        return subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError as e:
      raise Exception(
        "Command failed while invoking the native toolchain "
        "with code '{code}', cwd='{cwd}', cmd='{cmd}'. Combined stdout and stderr:\n{out}"
        .format(code=e.returncode, cwd=cwd, cmd=' '.join(cmd), out=e.output),
        e)
Beispiel #41
0
  def get_subprocess_output(cls, command, ignore_stderr=True, **kwargs):
    """Get the output of an executed command.

    :param command: An iterable representing the command to execute (e.g. ['ls', '-al']).
    :param ignore_stderr: Whether or not to ignore stderr output vs interleave it with stdout.
    :raises: `ProcessManager.ExecutionError` on `OSError` or `CalledProcessError`.
    :returns: The output of the command.
    """
    if ignore_stderr is False:
      kwargs.setdefault('stderr', subprocess.STDOUT)

    try:
      return subprocess.check_output(command, **kwargs).decode('utf-8').strip()
    except (OSError, subprocess.CalledProcessError) as e:
      subprocess_output = getattr(e, 'output', '').strip()
      raise cls.ExecutionError(str(e), subprocess_output)
Beispiel #42
0
  def get_subprocess_output(cls, command, ignore_stderr=True, **kwargs):
    """Get the output of an executed command.

    :param command: An iterable representing the command to execute (e.g. ['ls', '-al']).
    :param ignore_stderr: Whether or not to ignore stderr output vs interleave it with stdout.
    :raises: `ProcessManager.ExecutionError` on `OSError` or `CalledProcessError`.
    :returns: The output of the command.
    """
    if ignore_stderr is False:
      kwargs.setdefault('stderr', subprocess.STDOUT)

    try:
      return subprocess.check_output(command, **kwargs).decode('utf-8').strip()
    except (OSError, subprocess.CalledProcessError) as e:
      subprocess_output = getattr(e, 'output', '').strip()
      raise cls.ExecutionError(str(e), subprocess_output)
 def test_pants_binary(self):
   with temporary_dir() as tmp_dir:
     pex = os.path.join(tmp_dir, 'main.pex')
     command=[
       '--pants-distdir={}'.format(tmp_dir), 'binary', '{}:main'.format(self.fasthello_project)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     # Check that the pex was built.
     self.assertTrue(os.path.isfile(pex))
     # Check that the pex runs.
     output = subprocess.check_output(pex).decode('utf-8')
     self._assert_native_greeting(output)
     # Check that we have exactly one wheel output.
     single_wheel_output = assert_single_element(glob.glob(os.path.join(tmp_dir, '*.whl')))
     self.assertRegexpMatches(os.path.basename(single_wheel_output),
                              r'\A{}'.format(re.escape('fasthello-1.0.0+')))
 def test_pants_binary(self):
     with temporary_dir() as tmp_dir:
         pex = os.path.join(tmp_dir, 'main.pex')
         wheel_glob = os.path.join(tmp_dir, 'fasthello-1.0.0-*.whl')
         command = [
             '--pants-distdir={}'.format(tmp_dir), 'binary',
             '{}:main'.format(self.fasthello_project)
         ]
         pants_run = self.run_pants(command=command)
         self.assert_success(pants_run)
         # Check that the pex was built.
         self.assertTrue(os.path.isfile(pex))
         # Check that the pex runs.
         output = subprocess.check_output(pex)
         self._assert_native_greeting(output)
         # Check that we have exact one wheel output
         self.assertEqual(len(glob.glob(wheel_glob)), 1)
Beispiel #45
0
    def _invoke_compiler_exe(self, cmd, env):
        try:
            # Get stderr interspersed in the error message too -- this should not affect output parsing.
            compiler_output = subprocess.check_output(
                cmd, env=env, stderr=subprocess.STDOUT).decode('utf-8')
        except OSError as e:
            # We use `safe_shlex_join` here to pretty-print the command.
            raise self.ParseSearchDirsError(
                "Process invocation with argv '{}' and environment {!r} failed."
                .format(safe_shlex_join(cmd), env), e)
        except subprocess.CalledProcessError as e:
            raise self.ParseSearchDirsError(
                "Process invocation with argv '{}' and environment {!r} exited with non-zero code {}. "
                "output:\n{}".format(safe_shlex_join(cmd), env, e.returncode,
                                     e.output), e)

        return compiler_output
 def _invoke_capturing_output(self, cmd, env=None):
   env = env or {}
   try:
     with environment_as(**env):
       return subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode('utf-8')
   except subprocess.CalledProcessError as e:
     raise Exception(
       "Command failed while invoking the native toolchain "
       "with code '{code}', cwd='{cwd}', cmd='{cmd}', env='{env}'. "
       "Combined stdout and stderr:\n{out}"
       .format(code=e.returncode,
               cwd=os.getcwd(),
               # safe_shlex_join() is just for pretty-printing.
               cmd=safe_shlex_join(cmd),
               env=env,
               out=e.output),
       e)
 def test_pants_binary(self):
   with temporary_dir() as tmp_dir:
     pex = os.path.join(tmp_dir, 'main.pex')
     # The + is because we append the target's fingerprint to the version. We test this version
     # string in test_build_local_python_distributions.py.
     wheel_glob = os.path.join(tmp_dir, 'fasthello-1.0.0+*.whl')
     command=[
       '--pants-distdir={}'.format(tmp_dir), 'binary', '{}:main'.format(self.fasthello_project)]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     # Check that the pex was built.
     self.assertTrue(os.path.isfile(pex))
     # Check that the pex runs.
     output = subprocess.check_output(pex)
     self._assert_native_greeting(output)
     # Check that we have exact one wheel output
     self.assertEqual(len(glob.glob(wheel_glob)), 1)
Beispiel #48
0
 def _invoke_capturing_output(self, cmd, env=None):
     if env is None:
         env = os.environ.copy()
     try:
         with environment_as(**env):
             return subprocess.check_output(cmd, stderr=subprocess.STDOUT)
     except subprocess.CalledProcessError as e:
         raise Exception(
             "Command failed while invoking the native toolchain "
             "with code '{code}', cwd='{cwd}', cmd='{cmd}', env='{env}'. "
             "Combined stdout and stderr:\n{out}".format(
                 code=e.returncode,
                 cwd=os.getcwd(),
                 # safe_shlex_join() is just for pretty-printing.
                 cmd=safe_shlex_join(cmd),
                 env=env,
                 out=e.output),
             e)
  def _invoke_compiler_exe(self, cmd, env):
    try:
      # Get stderr interspersed in the error message too -- this should not affect output parsing.
      compiler_output = subprocess.check_output(cmd, env=env, stderr=subprocess.STDOUT).decode('utf-8')
    except OSError as e:
      # We use `safe_shlex_join` here to pretty-print the command.
      raise self.ParseSearchDirsError(
        "Process invocation with argv '{}' and environment {!r} failed."
        .format(safe_shlex_join(cmd), env),
        e)
    except subprocess.CalledProcessError as e:
      raise self.ParseSearchDirsError(
        "Process invocation with argv '{}' and environment {!r} exited with non-zero code {}. "
        "output:\n{}"
        .format(safe_shlex_join(cmd), env, e.returncode, e.output),
        e)

    return compiler_output
 def test_pydist_binary(self):
   with temporary_dir() as tmp_dir:
     pex = os.path.join(tmp_dir, 'main_with_no_conflict.pex')
     command = [
       '--pants-distdir={}'.format(tmp_dir),
       'binary',
       '{}:main_with_no_conflict'.format(self.hello_install_requires_dir),
     ]
     pants_run = self.run_pants(command=command)
     self.assert_success(pants_run)
     # Check that the pex was built.
     self.assertTrue(os.path.isfile(pex))
     # Check that the pex runs.
     output = subprocess.check_output(pex).decode('utf-8')
     self._assert_nation_and_greeting(output)
     # Check that we have exactly one wheel output.
     single_wheel_output = assert_single_element(glob.glob(os.path.join(tmp_dir, '*.whl')))
     assertRegex(self, os.path.basename(single_wheel_output),
                 r'\A{}'.format(re.escape('hello_with_install_requires-1.0.0+')))
  def _check_products(self, context, binary, expected_output=None, expected_shebang=None):
    pex_name = '{}.pex'.format(binary.address.target_name)
    products = context.products.get('deployable_archives')
    self.assertIsNotNone(products)
    product_data = products.get(binary)
    product_basedir = list(product_data.keys())[0]
    self.assertEqual(product_data[product_basedir], [pex_name])

    # Check pex copy.
    pex_copy = os.path.join(self.build_root, 'dist', pex_name)
    self.assertTrue(os.path.isfile(pex_copy))

    # Check that the pex runs.
    output = subprocess.check_output(pex_copy).decode('utf-8')
    if expected_output:
      self.assertEqual(expected_output, output)

    # Check that the pex has the expected shebang.
    if expected_shebang:
      with open(pex_copy, 'rb') as pex:
        line = pex.readline()
        self.assertEqual(expected_shebang, line)
  def test_python_distribution_with_setup_requires(self):
    # Validate that setup_requires dependencies are present and functional.
    # PANTS_TEST_SETUP_REQUIRES triggers test functionality in this particular setup.py.
    with environment_as(PANTS_TEST_SETUP_REQUIRES='1'):
      command=['run', '{}:main'.format(self.hello_setup_requires)]
      pants_run = self.run_pants(command=command)
      self.assertRaises(Exception)
      # Indicates the pycountry package is available to setup.py script.
      self.assertIn('current/setup_requires_site/pycountry/__init__.py', pants_run.stderr_data)
      # Indicates that the pycountry wheel has been installed on PYTHONPATH correctly.
      self.assertIn('pycountry-18.5.20.dist-info', pants_run.stderr_data)

    # Valdiate the run task. Use clean-all to invalidate cached python_dist wheels from
    # previous test run. Use -ldebug to get debug info on setup_requires functionality.
    command=['-ldebug', 'clean-all', 'run', '{}:main'.format(self.hello_setup_requires)]
    pants_run = self.run_pants(command=command)
    self.assertIn("Installing setup requirements: ['pycountry']", pants_run.stdout_data)
    self.assertIn("Setting PYTHONPATH with setup_requires site directory", pants_run.stdout_data)

    # Validate that the binary can build and run properly. Use clean-all to invalidate cached
    # python_dist wheels from previous test run. Use -ldebug to get debug info on setup_requires
    # functionality.
    pex = os.path.join(get_buildroot(), 'dist', 'main.pex')
    try:
      command=['-ldebug', 'clean-all', 'binary', '{}:main'.format(self.hello_setup_requires)]
      pants_run = self.run_pants(command=command)
      self.assert_success(pants_run)
      self.assertIn("Installing setup requirements: ['pycountry']", pants_run.stdout_data)
      self.assertIn("Setting PYTHONPATH with setup_requires site directory", pants_run.stdout_data)
      # Check that the pex was built.
      self.assertTrue(os.path.isfile(pex))
      # Check that the pex runs.
      output = subprocess.check_output(pex)
      self.assertIn('Hello, world!', output)
    finally:
      if os.path.exists(pex):
        # Cleanup.
        os.remove(pex)
  def test_pants_resolves_local_dists_for_current_platform_only(self):
    # Test that pants will override pants.ini platforms config when building
    # or running a target that depends on native (c or cpp) sources.
    pex = os.path.join(get_buildroot(), 'dist', 'main.pex')
    pants_ini_config = {'python-setup': {'platforms': ['current', 'linux-x86_64']}}
    try:
      # Clean all to rebuild requirements pex.
      command=['clean-all', 'run', '{}:main'.format(self.fasthello_project)]
      pants_run = self.run_pants(command=command, config=pants_ini_config)
      self.assert_success(pants_run)

      command=['binary', '{}:main'.format(self.fasthello_project)]
      pants_run = self.run_pants(command=command, config=pants_ini_config)
      self.assert_success(pants_run)
      # Check that the pex was built.
      self.assertTrue(os.path.isfile(pex))
      # Check that the pex runs.
      output = subprocess.check_output(pex)
      self._assert_native_greeting(output)
    finally:
      if os.path.exists(pex):
        # Cleanup
        os.remove(pex)
  def assert_no_gopath(self):
    go_distribution = self.distribution()

    go_env = go_distribution.go_env()

    # As of go 1.8, when GOPATH is unset (set to ''), it defaults to ~/go (assuming HOME is set -
    # and we can't unset that since it might legitmately be used by the subcommand) - so we manually
    # fetch the "unset" default value here as our expected value for tests below.
    # The key thing to note here is this default value is used only when `gopath` passed to
    # `GoDistribution` is None, implying the command to be run does not need or use a GOPATH.
    cmd = [os.path.join(go_distribution.goroot, 'bin', 'go'), 'env', 'GOPATH']
    env = os.environ.copy()
    env.update(go_env)
    default_gopath = subprocess.check_output(cmd, env=env).strip()

    go_cmd = go_distribution.create_go_cmd(cmd='env', args=['GOPATH'])

    self.assertEqual(go_env, go_cmd.env)
    self.assertEqual('go', os.path.basename(go_cmd.cmdline[0]))
    self.assertEqual(['env', 'GOPATH'], go_cmd.cmdline[1:])
    self.assertRegexpMatches(str(go_cmd),
                             r'^GOROOT=[^ ]+ GOPATH={} .*/go env GOPATH'.format(default_gopath))
    self.assertEqual(default_gopath, go_cmd.check_output().strip())
Beispiel #55
0
  def test_changelog_utf8(self):
    with environment_as(GIT_DIR=self.gitdir, GIT_WORK_TREE=self.worktree):
      def commit_contents_to_files(message, encoding, content, *files):
        for path in files:
          with safe_open(os.path.join(self.worktree, path), 'w') as fp:
            fp.write(content)
        subprocess.check_call(['git', 'add', '.'])

        subprocess.check_call(['git', 'config', '--local', '--add', 'i18n.commitencoding',
                               encoding])
        try:
          subprocess.check_call(['git', 'commit', '-m', message.encode(encoding)])
        finally:
          subprocess.check_call(['git', 'config', '--local', '--unset-all', 'i18n.commitencoding'])

        return subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip()

      # Mix in a non-UTF-8 author to all commits to exercise the corner described here does not
      # adversely impact the ability to render the changelog (even if rendering for certain
      # characters is incorrect): http://comments.gmane.org/gmane.comp.version-control.git/262685
      # NB: This method of override requires we include `user.name` and `user.email` even though we
      # only use `user.name` to exercise non-UTF-8.  Without `user.email`, it will be unset and
      # commits can then fail on machines without a proper hostname setup for git to fall back to
      # when concocting a last-ditch `user.email`.
      non_utf8_config = dedent("""
      [user]
        name = Noralf Trønnes
        email = [email protected]
      """).encode('iso-8859-1')

      with open(os.path.join(self.gitdir, 'config'), 'wb') as fp:
        fp.write(non_utf8_config)

      # Note the copyright symbol is used as the non-ascii character in the next 3 commits
      commit_contents_to_files('START1 © END', 'iso-8859-1', '1', 'foo')
      commit_contents_to_files('START2 © END', 'latin1', '1', 'bar')
      commit_contents_to_files('START3 © END', 'utf-8', '1', 'baz')

      commit_contents_to_files('START4 ~ END', 'us-ascii', '1', 'bip')

      # Prove our non-utf-8 encodings were stored in the commit metadata.
      log = subprocess.check_output(['git', 'log', '--format=%e'])
      self.assertEqual(['us-ascii', 'latin1', 'iso-8859-1'], filter(None, log.strip().splitlines()))

      # And show that the git log successfully transcodes all the commits none-the-less to utf-8
      changelog = self.git.changelog()

      # The ascii commit should combine with the iso-8859-1 author an fail to transcode the
      # o-with-stroke character, and so it should be replaced with the utf-8 replacement character
      # \uFFF or �.
      self.assertIn('Noralf Tr�nnes', changelog)
      self.assertIn('Noralf Tr\uFFFDnnes', changelog)

      # For the other 3 commits, each of iso-8859-1, latin1 and utf-8 have an encoding for the
      # o-with-stroke character - \u00F8 or ø - so we should find it;
      self.assertIn('Noralf Trønnes', changelog)
      self.assertIn('Noralf Tr\u00F8nnes', changelog)

      self.assertIn('START1 © END', changelog)
      self.assertIn('START2 © END', changelog)
      self.assertIn('START3 © END', changelog)
      self.assertIn('START4 ~ END', changelog)