def _run_and_check(self, address_specs, incremental_import=None):
        """
    Invoke idea-plugin goal and check for target specs and project in the
    generated project and workspace file.

    :param address_specs: list of address specs
    :return: n/a
    """
        self.assertTrue(address_specs, "targets are empty")
        spec_parser = CmdLineSpecParser(get_buildroot())
        # project_path is always the directory of the first target,
        # which is where intellij is going to zoom in under project view.
        project_path = spec_parser.parse_address_spec(
            address_specs[0]).directory

        with self.temporary_workdir() as workdir:
            with temporary_file(root_dir=workdir, cleanup=True) as output_file:
                args = [
                    'idea-plugin',
                    f'--output-file={output_file.name}',
                    '--no-open',
                ]
                if incremental_import is not None:
                    args.append(f'--incremental-import={incremental_import}')
                pants_run = self.run_pants_with_workdir(
                    args + address_specs, workdir)
                self.assert_success(pants_run)

                project_dir = self._get_project_dir(output_file.name)
                self.assertTrue(os.path.exists(project_dir),
                                f"{project_dir} does not exist")
                self._do_check(project_dir,
                               project_path,
                               address_specs,
                               incremental_import=incremental_import)
Ejemplo n.º 2
0
 def _get_targets(spec_str):
   spec_parser = CmdLineSpecParser(get_buildroot())
   try:
     address_spec = spec_parser.parse_address_spec(spec_str)
     addresses = self.context.address_mapper.scan_address_specs([address_spec])
   except AddressLookupError as e:
     raise TaskError('Failed to parse address selector: {spec_str}\n {message}'.format(spec_str=spec_str, message=e))
   # filter specs may not have been parsed as part of the context: force parsing
   matches = set()
   for address in addresses:
     self.context.build_graph.inject_address_closure(address)
     matches.add(self.context.build_graph.get_target(address))
   if not matches:
     raise TaskError('No matches for address selector: {spec_str}'.format(spec_str=spec_str))
   return matches
Ejemplo n.º 3
0
    def parse_address_specs(
        cls,
        target_specs: Iterable[str],
        build_root: Optional[str] = None,
        exclude_patterns: Optional[Iterable[str]] = None,
        tags: Optional[Iterable[str]] = None,
    ) -> AddressSpecs:
        """Parse string specs into unique `AddressSpec` objects."""
        build_root = build_root or get_buildroot()
        spec_parser = CmdLineSpecParser(build_root)

        dependencies = tuple(
            OrderedSet(
                spec_parser.parse_address_spec(spec_str)
                for spec_str in target_specs))
        return AddressSpecs(
            dependencies=dependencies,
            exclude_patterns=exclude_patterns if exclude_patterns else tuple(),
            tags=tags)
Ejemplo n.º 4
0
  def set_start_time(self, start_time):
    # Launch RunTracker as early as possible (before .run() is called).
    self._run_tracker = RunTracker.global_instance()

    # Propagates parent_build_id to pants runs that may be called from this pants run.
    os.environ['PANTS_PARENT_BUILD_ID'] = self._run_tracker.run_id

    self._reporting = Reporting.global_instance()

    self._run_start_time = start_time
    self._reporting.initialize(self._run_tracker, self._options, start_time=self._run_start_time)

    spec_parser = CmdLineSpecParser(get_buildroot())
    address_specs = [
      spec_parser.parse_address_spec(spec).to_spec_string()
      for spec in self._options.specs
    ]
    # Note: This will not include values from `--owner-of` or `--changed-*` flags.
    self._run_tracker.run_info.add_info("specs_from_command_line", address_specs, stringify=False)

    # Capture a repro of the 'before' state for this build, if needed.
    self._repro = Reproducer.global_instance().create_repro()
    if self._repro:
      self._repro.capture(self._run_tracker.run_info.get_as_dict())
class CmdLineSpecParserTest(TestBase):
    def setUp(self):
        super().setUp()
        self._spec_parser = CmdLineSpecParser(self.build_root)

    def test_normal(self):
        self.assert_parsed(':root', single('', 'root'))
        self.assert_parsed('//:root', single('', 'root'))

        self.assert_parsed('a', single('a'))
        self.assert_parsed('a:a', single('a', 'a'))

        self.assert_parsed('a/b', single('a/b'))
        self.assert_parsed('a/b:b', single('a/b', 'b'))
        self.assert_parsed('a/b:c', single('a/b', 'c'))

    def test_sibling(self):
        self.assert_parsed(':', sib(''))
        self.assert_parsed('//:', sib(''))

        self.assert_parsed('a:', sib('a'))
        self.assert_parsed('//a:', sib('a'))

        self.assert_parsed('a/b:', sib('a/b'))
        self.assert_parsed('//a/b:', sib('a/b'))

    def test_sibling_or_descendents(self):
        self.assert_parsed('::', desc(''))
        self.assert_parsed('//::', desc(''))

        self.assert_parsed('a::', desc('a'))
        self.assert_parsed('//a::', desc('a'))

        self.assert_parsed('a/b::', desc('a/b'))
        self.assert_parsed('//a/b::', desc('a/b'))

    def test_absolute(self):
        self.assert_parsed(os.path.join(self.build_root, 'a'), single('a'))
        self.assert_parsed(os.path.join(self.build_root, 'a:a'),
                           single('a', 'a'))
        self.assert_parsed(os.path.join(self.build_root, 'a:'), sib('a'))
        self.assert_parsed(os.path.join(self.build_root, 'a::'), desc('a'))

        with self.assertRaises(CmdLineSpecParser.BadSpecError):
            self.assert_parsed('/not/the/buildroot/a', sib('a'))

    def test_absolute_double_slashed(self):
        # By adding a double slash, we are insisting that this absolute path is actually
        # relative to the buildroot. Thus, it should parse correctly.
        double_absolute = '/' + os.path.join(self.build_root, 'a')
        self.assertEqual('//', double_absolute[:2],
                         'A sanity check we have a leading-// absolute spec')
        self.assert_parsed(double_absolute, single(double_absolute[2:]))

    def test_cmd_line_affordances(self):
        self.assert_parsed('./:root', single('', 'root'))
        self.assert_parsed('//./:root', single('', 'root'))
        self.assert_parsed('//./a/../:root', single('', 'root'))
        self.assert_parsed(os.path.join(self.build_root, './a/../:root'),
                           single('', 'root'))

        self.assert_parsed('a/', single('a'))
        self.assert_parsed('./a/', single('a'))
        self.assert_parsed(os.path.join(self.build_root, './a/'), single('a'))

        self.assert_parsed('a/b/:b', single('a/b', 'b'))
        self.assert_parsed('./a/b/:b', single('a/b', 'b'))
        self.assert_parsed(os.path.join(self.build_root, './a/b/:b'),
                           single('a/b', 'b'))

    def assert_parsed(self, spec_str: str,
                      expected_address_spec: AddressSpec) -> None:
        self.assertEqual(self._spec_parser.parse_address_spec(spec_str),
                         expected_address_spec)