示例#1
0
  def test_sibling_references(self):
    with temporary_dir() as root_dir:
      buildfile = create_buildfile(root_dir, 'a', name='BUILD',
        content=dedent("""
          dependencies(name='util',
            dependencies=[
              jar(org='com.twitter', name='util', rev='0.0.1')
            ]
          )
        """).strip()
      )
      sibling = create_buildfile(root_dir, 'a', name='BUILD.sibling',
        content=dedent("""
          dependencies(name='util-ex',
            dependencies=[
              pants(':util'),
              jar(org='com.twitter', name='util-ex', rev='0.0.1')
            ]
          )
        """).strip()
      )
      ParseContext(buildfile).parse()

      utilex = Target.get(Address.parse(root_dir, 'a:util-ex', is_relative=False))
      utilex_deps = set(utilex.resolve())

      util = Target.get(Address.parse(root_dir, 'a:util', is_relative=False))
      util_deps = set(util.resolve())

      self.assertEquals(util_deps, util_deps.intersection(utilex_deps))
示例#2
0
    def make_target(self, spec="", target_type=Target, dependencies=None, derived_from=None, **kwargs):
        """Creates a target and injects it into the test's build graph.

    :param string spec: The target address spec that locates this target.
    :param type target_type: The concrete target subclass to create this new target from.
    :param list dependencies: A list of target instances this new target depends on.
    :param derived_from: The target this new target was derived from.
    :type derived_from: :class:`pants.base.target.Target`
    """
        address = Address.parse(spec)
        target = target_type(name=address.target_name, address=address, build_graph=self.build_graph, **kwargs)
        dependencies = dependencies or []

        self.build_graph.inject_target(
            target, dependencies=[dep.address for dep in dependencies], derived_from=derived_from
        )

        # TODO(John Sirois): This re-creates a little bit too much work done by the BuildGraph.
        # Fixup the BuildGraph to deal with non BuildFileAddresses better and just leverage it.
        for traversable_dependency_spec in target.traversable_dependency_specs:
            traversable_dependency_address = Address.parse(traversable_dependency_spec, relative_to=address.spec_path)
            traversable_dependency_target = self.build_graph.get_target(traversable_dependency_address)
            if not traversable_dependency_target:
                raise ValueError(
                    "Tests must make targets for traversable dependency specs ahead of them "
                    "being traversed, {} tried to traverse {} which does not exist.".format(
                        target, traversable_dependency_address
                    )
                )
            if traversable_dependency_target not in target.dependencies:
                self.build_graph.inject_dependency(dependent=target.address, dependency=traversable_dependency_address)
                target.mark_transitive_invalidation_hash_dirty()

        return target
示例#3
0
    def test_invalidate_build_file_added(self):
        address_family = self.address_mapper.family('a/b')

        a_b_target = Target(
            name='b',
            dependencies=['//d:e'],
            configurations=['//a', Configuration(embedded='yes')])
        self.assertEqual({Address.parse('a/b'): a_b_target},
                         address_family.addressables)

        with open(os.path.join(self.build_root, 'a/b/sibling.BUILD.json'),
                  'w') as fp:
            fp.write('{"typename": "configuration", "name": "c"}')

        still_valid = self.address_mapper.family('a/b')
        self.assertIs(address_family, still_valid)

        self.address_mapper.invalidate_build_file('a/b/sibling.BUILD.json')
        newly_formed = self.address_mapper.family('a/b')
        self.assertIsNot(address_family, newly_formed)
        self.assertEqual(
            {
                Address.parse('a/b'): a_b_target,
                Address.parse('a/b:c'): Configuration(name='c')
            }, newly_formed.addressables)
示例#4
0
 def parse_address():
   if spec.startswith(':'):
     # the :[target] could be in a sibling BUILD - so parse using the canonical address
     pathish = "%s:%s" % (parse_context.buildfile.canonical_relpath, spec[1:])
     return Address.parse(parse_context.buildfile.root_dir, pathish, False)
   else:
     return Address.parse(parse_context.buildfile.root_dir, spec, False)
示例#5
0
 def test_top_level(self):
   with self.workspace('BUILD') as root_dir:
     self.assertAddress(root_dir, 'BUILD', 'c', Address.parse(root_dir, ':c'))
     self.assertAddress(root_dir, 'BUILD', 'c', Address.parse(root_dir, '.:c'))
     self.assertAddress(root_dir, 'BUILD', 'c', Address.parse(root_dir, './:c'))
     self.assertAddress(root_dir, 'BUILD', 'c', Address.parse(root_dir, './BUILD:c'))
     self.assertAddress(root_dir, 'BUILD', 'c', Address.parse(root_dir, 'BUILD:c'))
示例#6
0
  def test_parse_from_sub_dir(self):
    with self.workspace('a/b/c/BUILD') as root_dir:
      with pushd(os.path.join(root_dir, 'a')):
        self.assertAddress(root_dir, 'a/b/c/BUILD', 'c',
                           Address.parse(root_dir, 'b/c', is_relative=True))

        with pytest.raises(IOError):
          Address.parse(root_dir, 'b/c', is_relative=False)
示例#7
0
    def test_target_invalid(self):
        self.add_to_build_file('a/BUILD', 'target(name="a")')
        with self.assertRaises(AddressLookupError):
            self.build_graph.inject_address_closure(Address.parse('a:nope'))

        self.add_to_build_file('b/BUILD', 'target(name="a")')
        with self.assertRaises(AddressLookupError):
            self.build_graph.inject_address_closure(Address.parse('b'))
        with self.assertRaises(AddressLookupError):
            self.build_graph.inject_address_closure(Address.parse('b:b'))
示例#8
0
  def test_target_invalid(self):
    self.add_to_build_file('a/BUILD', 'target(name="a")')
    with self.assertRaises(AddressLookupError):
      self.build_graph.inject_address_closure(Address.parse('a:nope'))

    self.add_to_build_file('b/BUILD', 'target(name="a")')
    with self.assertRaises(AddressLookupError):
      self.build_graph.inject_address_closure(Address.parse('b'))
    with self.assertRaises(AddressLookupError):
      self.build_graph.inject_address_closure(Address.parse('b:b'))
示例#9
0
 def test_create_single(self):
   address_family = AddressFamily.create('/dev/null',
                                         [AddressMap('/dev/null/0', {
                                           'one': Thing(name='one', age=42),
                                           'two': Thing(name='two', age=37)
                                         })])
   self.assertEqual('', address_family.namespace)
   self.assertEqual({Address.parse('//:one'): Thing(name='one', age=42),
                     Address.parse('//:two'): Thing(name='two', age=37)},
                    address_family.addressables)
示例#10
0
  def _synthesize_resources_target(self):
    # Create an address for the synthetic target.
    spec = self.address.spec + '_synthetic_resources'
    synthetic_address = Address.parse(spec=spec)
    # For safety, ensure an address that's not used already, even though that's highly unlikely.
    while self._build_graph.contains_address(synthetic_address):
      spec += '_'
      synthetic_address = Address.parse(spec=spec)

    self._build_graph.inject_synthetic_target(synthetic_address, Resources,
                                              sources=self.payload.resources.source_paths,
                                              derived_from=self)
    return self._build_graph.get_target(synthetic_address)
示例#11
0
 def test_create_single(self):
     address_family = AddressFamily.create('/dev/null', [
         AddressMap('/dev/null/0', {
             'one': Thing(name='one', age=42),
             'two': Thing(name='two', age=37)
         })
     ])
     self.assertEqual('', address_family.namespace)
     self.assertEqual(
         {
             Address.parse('//:one'): Thing(name='one', age=42),
             Address.parse('//:two'): Thing(name='two', age=37)
         }, address_family.addressables)
示例#12
0
  def test_resolve_cache(self):
    graph = self.create_json_graph()

    nonstrict_address = Address.parse('examples/graph_test:nonstrict')
    nonstrict = graph.resolve(nonstrict_address)
    self.assertIs(nonstrict, graph.resolve(nonstrict_address))

    # The already resolved `nonstrict` interior node should be re-used by `java1`.
    java1_address = Address.parse('examples/graph_test:java1')
    java1 = graph.resolve(java1_address)
    self.assertIs(nonstrict, java1.configurations[1])

    self.assertIs(java1, graph.resolve(java1_address))
示例#13
0
  def test_invalidation_relative(self):
    resolved = self.address_mapper.resolve(Address.parse('a/b'))
    a_b_target = Target(name='b',
                        dependencies=['//d:e'],
                        configurations=['//a', Configuration(embedded='yes')])
    self.assertEqual(a_b_target, resolved)

    build_file = os.path.join(self.build_root, 'a/b/b.BUILD.json')
    os.unlink(build_file)
    self.assertIs(resolved, self.address_mapper.resolve(Address.parse('a/b')))

    self.address_mapper.invalidate_build_file('a/b/b.BUILD.json')
    with self.assertRaises(ResolveError):
      self.address_mapper.resolve(Address.parse('a/b'))
示例#14
0
    def _synthesize_resources_target(self):
        # Create an address for the synthetic target.
        spec = self.address.spec + '_synthetic_resources'
        synthetic_address = Address.parse(spec=spec)
        # For safety, ensure an address that's not used already, even though that's highly unlikely.
        while self._build_graph.contains_address(synthetic_address):
            spec += '_'
            synthetic_address = Address.parse(spec=spec)

        self._build_graph.inject_synthetic_target(
            synthetic_address,
            Resources,
            sources=self.payload.resources.source_paths,
            derived_from=self)
        return self._build_graph.get_target(synthetic_address)
示例#15
0
    def test_invalidation_relative(self):
        resolved = self.address_mapper.resolve(Address.parse('a/b'))
        a_b_target = Target(
            name='b',
            dependencies=['//d:e'],
            configurations=['//a', Configuration(embedded='yes')])
        self.assertEqual(a_b_target, resolved)

        build_file = os.path.join(self.build_root, 'a/b/b.BUILD.json')
        os.unlink(build_file)
        self.assertIs(resolved,
                      self.address_mapper.resolve(Address.parse('a/b')))

        self.address_mapper.invalidate_build_file('a/b/b.BUILD.json')
        with self.assertRaises(ResolveError):
            self.address_mapper.resolve(Address.parse('a/b'))
示例#16
0
 def test_resolve(self):
     resolved = self.address_mapper.resolve(Address.parse('a/b'))
     self.assertEqual(
         Target(name='b',
                dependencies=['//d:e'],
                configurations=['//a', Configuration(embedded='yes')]),
         resolved)
示例#17
0
    def to_jar_dependencies(relative_to, jar_library_specs, build_graph):
        """Convenience method to resolve a list of specs to JarLibraries and return its jars attributes.

    Expects that the jar_libraries are declared relative to this target.

    :param Address relative_to: address target that references jar_library_specs, for
      error messages
    :param list jar_library_specs: string specs to JavaLibrary targets. Note, this list should be returned
      by the caller's traversable_specs() implementation to make sure that the jar_dependency jars
      have been added to the build graph.
    :param BuildGraph build_graph: build graph instance used to search for specs
    :return: list of JarDependency instances represented by the library_specs
    """
        jar_deps = OrderedSet()
        for spec in jar_library_specs:
            if not isinstance(spec, six.string_types):
                raise JarLibrary.ExpectedAddressError(
                    "{address}: expected imports to contain string addresses, got {found_class}."
                    .format(address=relative_to.spec,
                            found_class=type(spec).__name__))

            lookup = Address.parse(spec, relative_to=relative_to.spec_path)
            target = build_graph.get_target(lookup)
            if not isinstance(target, JarLibrary):
                raise JarLibrary.WrongTargetTypeError(
                    "{address}: expected {spec} to be jar_library target type, got {found_class}"
                    .format(address=relative_to.spec,
                            spec=spec,
                            found_class=type(target).__name__))
            jar_deps.update(target.jar_dependencies)

        return list(jar_deps)
  def test_raises_address_not_in_build_file(self):
    self.add_to_build_file('BUILD', 'target(name="foo")')

    # Create an address that doesn't exist in an existing BUILD file
    address = Address.parse(':bar')
    with self.assertRaises(BuildFileAddressMapper.AddressNotInBuildFile):
      self.address_mapper.resolve(address)
示例#19
0
 def java_sources(self):
     for spec in self._java_sources_specs:
         address = Address.parse(spec, relative_to=self.address.spec_path)
         target = self._build_graph.get_target(address)
         if target is None:
             raise TargetDefinitionException(self, "No such java target: {}".format(spec))
         yield target
示例#20
0
 def traversable_specs(self):
   for spec in super(PythonTarget, self).traversable_specs:
     yield spec
   if self._provides:
     for spec in self._provides._binaries.values():
       address = Address.parse(spec, relative_to=self.address.spec_path)
       yield address.spec
示例#21
0
文件: target.py 项目: priyakoth/pants
  def create_sources_field(self, sources, sources_rel_path, address=None, key_arg=None):
    """Factory method to create a SourcesField appropriate for the type of the sources object.

    Note that this method is called before the call to Target.__init__ so don't expect fields to
    be populated!
    :return: a payload field object representing the sources parameter
    :rtype: SourcesField
    """

    if isinstance(sources, Addresses):
      # Currently, this is only created by the result of from_target() which takes a single argument
      if len(sources.addresses) != 1:
        raise self.WrongNumberOfAddresses(
          "Expected a single address to from_target() as argument to {spec}"
          .format(spec=address.spec))
      referenced_address = Address.parse(sources.addresses[0], relative_to=sources.rel_path)
      return DeferredSourcesField(ref_address=referenced_address)
    elif isinstance(sources, FilesetWithSpec):
      filespec = sources.filespec
    else:
      sources = sources or []
      assert_list(sources, key_arg=key_arg)
      filespec = {'globs': [os.path.join(sources_rel_path, src) for src in (sources or [])]}

    return SourcesField(sources=sources, sources_rel_path=sources_rel_path, filespec=filespec)
示例#22
0
 def test_validation(self):
     target = Target(name='mybird',
                     address=Address.parse('//:mybird'),
                     build_graph=self.build_graph)
     # jars attribute must contain only JarLibrary instances
     with self.assertRaises(TargetDefinitionException):
         JarLibrary(name="test", jars=[target])
示例#23
0
  def test_invalidation_un_normalized(self):
    resolved = self.address_mapper.resolve(Address.parse('a/b'))
    a_b_target = Target(name='b',
                        dependencies=['//d:e'],
                        configurations=['//a', Configuration(embedded='yes')])
    self.assertEqual(a_b_target, resolved)

    os.unlink(os.path.join(self.build_root, 'a/b/b.BUILD.json'))
    self.assertIs(resolved, self.address_mapper.resolve(Address.parse('a/b')))

    un_normalized_build_root = os.path.join(self.work_dir, 'build_root_linked')
    os.symlink(self.build_root, un_normalized_build_root)
    un_normalized_build_file = os.path.join(un_normalized_build_root, 'a/b/b.BUILD.json')
    self.address_mapper.invalidate_build_file(un_normalized_build_file)
    with self.assertRaises(ResolveError):
      self.address_mapper.resolve(Address.parse('a/b'))
    def assert_parsed_list(self, cmdline_spec_list, expected):
        def sort(addresses):
            return sorted(addresses, key=lambda address: address.spec)

        self.assertEqual(
            sort(Address.parse(addr) for addr in expected),
            sort(self.spec_parser.parse_addresses(cmdline_spec_list)))
示例#25
0
 def test_excludes(self):
     # TODO(Eric Ayers) There doesn't seem to be any way to set this field at the moment.
     lib = JarLibrary(name='foo',
                      address=Address.parse('//:foo'),
                      build_graph=self.build_graph,
                      jars=[jar1])
     self.assertEquals([], lib.excludes)
示例#26
0
 def parse_jarcoordinate(coordinate):
     components = coordinate.split('#', 1)
     if len(components) == 2:
         org, name = components
         return org, name
     else:
         try:
             # TODO(Eric Ayers) This code is suspect.  Target.get() is a very old method and almost certainly broken.
             # Refactor to use methods from BuildGraph or BuildFileAddressMapper
             address = Address.parse(get_buildroot(), coordinate)
             target = Target.get(address)
             if not target:
                 siblings = Target.get_all_addresses(address.build_file)
                 prompt = 'did you mean' if len(
                     siblings) == 1 else 'maybe you meant one of these'
                 raise TaskError('%s => %s?:\n    %s' %
                                 (address, prompt, '\n    '.join(
                                     str(a) for a in siblings)))
             if not target.is_exported:
                 raise TaskError('%s is not an exported target' %
                                 coordinate)
             return target.provides.org, target.provides.name
         except (BuildFile.BuildFileError,
                 BuildFileParser.BuildFileParserError,
                 AddressLookupError) as e:
             raise TaskError(
                 '{message}\n  Problem with BUILD file  at {coordinate}'
                 .format(message=e, coordinate=coordinate))
示例#27
0
  def test_register_bad_target_alias(self):
    with self.assertRaises(TypeError):
      self.build_configuration._register_target_alias('fred', object())

    target = Target('fred', Address.parse('a:b'), BuildGraph(address_mapper=None))
    with self.assertRaises(TypeError):
      self.build_configuration._register_target_alias('fred', target)
示例#28
0
 def parse_jarcoordinate(coordinate):
     components = coordinate.split('#', 1)
     if len(components) == 2:
         org, name = components
         return org, name
     else:
         try:
             address = Address.parse(get_buildroot(), coordinate)
             try:
                 target = Target.get(address)
                 if not target:
                     siblings = Target.get_all_addresses(
                         address.buildfile)
                     prompt = 'did you mean' if len(
                         siblings
                     ) == 1 else 'maybe you meant one of these'
                     raise TaskError('%s => %s?:\n    %s' %
                                     (address, prompt, '\n    '.join(
                                         str(a) for a in siblings)))
                 if not target.is_exported:
                     raise TaskError('%s is not an exported target' %
                                     coordinate)
                 return target.provides.org, target.provides.name
             except (ImportError, SyntaxError, TypeError):
                 raise TaskError('Failed to parse %s' %
                                 address.buildfile.relpath)
         except IOError:
             raise TaskError('No BUILD file could be found at %s' %
                             coordinate)
示例#29
0
  def __init__(self,
               name,
               build_file,
               build_file_source_lines,
               target_source_lines,
               target_interval,
               dependencies,
               dependencies_interval):
    """See BuildFileManipulator.load() for how to construct one as a user."""
    self.name = name
    self.build_file = build_file
    self.target_address = BuildFileAddress(build_file, name)
    self._build_file_source_lines = build_file_source_lines
    self._target_source_lines = target_source_lines
    self._target_interval = target_interval
    self._dependencies_interval = dependencies_interval
    self._dependencies_by_address = {}

    for dep in dependencies:
      dep_address = Address.parse(dep.spec, relative_to=build_file.spec_path)
      if dep_address in self._dependencies_by_address:
        raise BuildTargetParseError('The address {dep_address} occurred multiple times in the '
                                    'dependency specs for target {name} in {build_file}. '
                                    .format(dep_address=dep_address.spec,
                                            name=name,
                                            build_file=build_file))
      self._dependencies_by_address[dep_address] = dep
示例#30
0
    def to_jar_dependencies(relative_to, jar_library_specs, build_graph):
        """Convenience method to resolve a list of specs to JarLibraries and return its jars attributes.

    Expects that the jar_libraries are declared relative to this target.

    :param Address relative_to: address target that references jar_library_specs, for
      error messages
    :param list jar_library_specs: string specs to JavaLibrary targets. Note, this list should be returned
      by the caller's traversable_specs() implementation to make sure that the jar_dependency jars
      have been added to the build graph.
    :param BuildGraph build_graph: build graph instance used to search for specs
    :return: list of JarDependency instances represented by the library_specs
    """
        jar_deps = OrderedSet()
        for spec in jar_library_specs:
            if not isinstance(spec, six.string_types):
                raise JarLibrary.ExpectedAddressError(
                    "{address}: expected imports to contain string addresses, got {found_class}.".format(
                        address=relative_to.spec, found_class=type(spec).__name__
                    )
                )

            lookup = Address.parse(spec, relative_to=relative_to.spec_path)
            target = build_graph.get_target(lookup)
            if not isinstance(target, JarLibrary):
                raise JarLibrary.WrongTargetTypeError(
                    "{address}: expected {spec} to be jar_library target type, got {found_class}".format(
                        address=relative_to.spec, spec=spec, found_class=type(target).__name__
                    )
                )
            jar_deps.update(target.jar_dependencies)

        return list(jar_deps)
示例#31
0
  def test_target_insertion_middle(self):
    expected_build_string = dedent(
      """\
      # This comment should stay
      target_type(
        name = 'target_top',
        dependencies = [
          ':dep_a',
        ]
      )



      target_type(
        name = 'target_middle',
        dependencies = [
          ':dep_b',
          ':new_dep',
        ],
      )
      # This comment should be okay
      target_type(
        name = 'target_bottom',
      )
      # Also this one though it's weird"""
    )

    build_file = self.add_to_build_file('BUILD', self.multi_target_build_string)

    multi_targ_bfm = BuildFileManipulator.load(build_file, 'target_middle', {'target_type'})
    multi_targ_bfm.add_dependency(Address.parse(':new_dep'))
    build_file_str = '\n'.join(multi_targ_bfm.build_file_lines())
    self.assertEqual(build_file_str, expected_build_string)
  def test_raises_address_not_in_build_file(self):
    self.add_to_build_file('BUILD', 'target(name="foo")')

    # Create an address that doesn't exist in an existing BUILD file
    address = Address.parse(':bar')
    with self.assertRaises(BuildFileAddressMapper.AddressNotInBuildFile):
      self.address_mapper.resolve(address)
示例#33
0
 def parse_jarcoordinate(coordinate):
     components = coordinate.split('#', 1)
     if len(components) == 2:
         org, name = components
         return org, name
     else:
         spec = components[0]
         address = Address.parse(spec)
         try:
             self.context.build_graph.inject_address_closure(address)
             target = self.context.build_graph.get_target(address)
             if not target:
                 siblings = self.context.address_mapper.addresses_in_spec_path(
                     address.spec_path)
                 prompt = 'did you mean' if len(
                     siblings) == 1 else 'maybe you meant one of these'
                 raise TaskError('{} => {}?:\n    {}'.format(
                     address, prompt,
                     '\n    '.join(str(a) for a in siblings)))
             if not target.is_exported:
                 raise TaskError(
                     '{} is not an exported target'.format(coordinate))
             return target.provides.org, target.provides.name
         except (BuildFile.BuildFileError,
                 BuildFileParser.BuildFileParserError,
                 AddressLookupError) as e:
             raise TaskError(
                 '{message}\n  Problem identifying target at {spec}'.
                 format(message=e, spec=spec))
示例#34
0
  def test_create_bad_targets(self):
    with self.assertRaises(TypeError):
      BuildFileAliases(targets={'fred': object()})

    target = Target('fred', Address.parse('a:b'), BuildGraph(address_mapper=None))
    with self.assertRaises(TypeError):
      BuildFileAliases(targets={'fred': target})
示例#35
0
 def test_cycle_self(self):
   graph = self.create_json_graph()
   with self.assertRaises(CycleError) as exc:
     graph.resolve(Address.parse('examples/graph_test:self_cycle'))
   self.assertEqual(['* examples/graph_test:self_cycle',
                     '* examples/graph_test:self_cycle'],
                    self.extract_path_tail(exc.exception, 2))
示例#36
0
  def test_simple_targets(self):
    simple_targets = dedent(
      """
      target_type(
        name = 'no_deps',
      )

      target_type(
        name = 'empty_deps',
        dependencies = [
        ]
      )

      target_type(
        name = 'empty_deps_inline',
        dependencies = []
      )
      """
    )

    build_file = self.add_to_build_file('BUILD', simple_targets)

    for no_deps_name in ['no_deps', 'empty_deps', 'empty_deps_inline']:
      no_deps = BuildFileManipulator.load(build_file, no_deps_name, {'target_type'})
      self.assertEqual(tuple(no_deps.dependency_lines()), tuple())
      no_deps.add_dependency(Address.parse(':fake_dep'))
      self.assertEqual(tuple(no_deps.dependency_lines()),
                       tuple(['  dependencies = [',
                              "    ':fake_dep',",
                              '  ],']))
      no_deps.add_dependency(Address.parse(':b_fake_dep'))
      no_deps.add_dependency(Address.parse(':a_fake_dep'))
      self.assertEqual(tuple(no_deps.dependency_lines()),
                       tuple(['  dependencies = [',
                              "    ':a_fake_dep',",
                              "    ':b_fake_dep',",
                              "    ':fake_dep',",
                              '  ],']))
      self.assertEqual(tuple(no_deps.target_lines()),
                       tuple(['target_type(',
                              "  name = '{0}',".format(no_deps_name),
                              '  dependencies = [',
                              "    ':a_fake_dep',",
                              "    ':b_fake_dep',",
                              "    ':fake_dep',",
                              '  ],',
                              ')']))
示例#37
0
 def test_parse(self):
   self.assert_address('a/b', 'target', Address.parse('a/b:target'))
   self.assert_address('a/b', 'target', Address.parse('//a/b:target'))
   self.assert_address('a/b', 'b', Address.parse('a/b'))
   self.assert_address('a/b', 'b', Address.parse('//a/b'))
   self.assert_address('a/b', 'target', Address.parse(':target', relative_to='a/b'))
   self.assert_address('', 'target', Address.parse('//:target', relative_to='a/b'))
   self.assert_address('', 'target', Address.parse(':target'))
   self.assert_address('a/b', 'target', Address.parse(':target', relative_to='a/b'))
示例#38
0
  def target(cls, address):
    """Resolves the given target address to a Target object.

    address: The BUILD target address to resolve.

    Returns the corresponding Target or else None if the address does not point to a defined Target.
    """
    return Target.get(Address.parse(cls.build_root, address, is_relative=False))
 def test_resolve(self):
   build_file = self.add_to_build_file('BUILD', 'target(name="foo")')
   address, addressable = self.address_mapper.resolve(Address.parse('//:foo'))
   self.assertIsInstance(address, BuildFileAddress)
   self.assertEqual(build_file, address.build_file)
   self.assertEqual('foo', address.target_name)
   self.assertEqual(address.target_name, addressable.addressed_name)
   self.assertEqual(addressable.addressed_type, Target)
示例#40
0
 def get_target(spec):
     address = Address.parse(spec,
                             relative_to=self.address.spec_path)
     tgt = self._build_graph.get_target(address)
     if tgt is None:
         raise TargetDefinitionException(
             self, 'No such resource target: {}'.format(address))
     return tgt
示例#41
0
  def test_targets_ignore_synthetics_with_no_derived_from_not_injected_into_graph(self):
    a = self.make_target('a')
    b = self.make_target('b')
    context = self.context(target_roots=[b])
    self.assertEquals([b], context.targets())

    context.add_new_target(Address.parse('syn_with_deps'), Target, dependencies=[a])
    self.assertEquals([b], context.targets())
示例#42
0
  def test_targets_synthetic(self):
    a = self.make_target('a')
    b = self.make_target('b', dependencies=[a])
    c = self.make_target('c', dependencies=[b])
    d = self.make_target('d', dependencies=[c, a])
    context = self.context(target_roots=[c])
    self.assertEquals([c, b, a], context.targets())

    syn_b = context.add_new_target(Address.parse('syn_b'), Target, derived_from=b)
    context.add_new_target(Address.parse('syn_d'), Target, derived_from=d)
    # We expect syn_b to be included now since it has been synthesized during this run from an
    # in-play target.
    self.assertEquals([c, b, a, syn_b], context.targets())

    # And verify the predicate operates over both normal and synthetic targets.
    self.assertEquals([syn_b], context.targets(lambda t: t.derived_from != t))
    self.assertEquals([c, b, a], context.targets(lambda t: t.derived_from == t))
示例#43
0
  def test_targets_ignore_synthetics_with_no_derived_from_not_injected_into_graph(self):
    a = self.make_target('a')
    b = self.make_target('b')
    context = self.context(target_roots=[b])
    self.assertEquals([b], context.targets())

    context.add_new_target(Address.parse('syn_with_deps'), Target, dependencies=[a])
    self.assertEquals([b], context.targets())
示例#44
0
  def test_targets_synthetic(self):
    a = self.make_target('a')
    b = self.make_target('b', dependencies=[a])
    c = self.make_target('c', dependencies=[b])
    d = self.make_target('d', dependencies=[c, a])
    context = self.context(target_roots=[c])
    self.assertEquals([c, b, a], context.targets())

    syn_b = context.add_new_target(Address.parse('syn_b'), Target, derived_from=b)
    context.add_new_target(Address.parse('syn_d'), Target, derived_from=d)
    # We expect syn_b to be included now since it has been synthesized during this run from an
    # in-play target.
    self.assertEquals([c, b, a, syn_b], context.targets())

    # And verify the predicate operates over both normal and synthetic targets.
    self.assertEquals([syn_b], context.targets(lambda t: t.derived_from != t))
    self.assertEquals([c, b, a], context.targets(lambda t: t.derived_from == t))
示例#45
0
 def test_contains_address(self):
   a = Address.parse('a')
   self.assertFalse(self.build_graph.contains_address(a))
   target = Target(name='a',
                   address=a,
                   build_graph=self.build_graph)
   self.build_graph.inject_target(target)
   self.assertTrue(self.build_graph.contains_address(a))
 def resolve_spec(self, spec):
     """Converts a spec to an address and maps it using `resolve`"""
     try:
         address = Address.parse(spec)
     except ValueError as e:
         raise self.InvalidAddressError(e)
     _, addressable = self.resolve(address)
     return addressable
 def resolve_spec(self, spec):
   """Converts a spec to an address and maps it using `resolve`"""
   try:
     address = Address.parse(spec)
   except ValueError as e:
     raise self.InvalidAddressError(e)
   _, addressable = self.resolve(address)
   return addressable
示例#48
0
    def test_create_bad_targets(self):
        with self.assertRaises(TypeError):
            BuildFileAliases(targets={'fred': object()})

        target = Target('fred', Address.parse('a:b'),
                        BuildGraph(address_mapper=None))
        with self.assertRaises(TypeError):
            BuildFileAliases(targets={'fred': target})
示例#49
0
 def traversable_specs(self):
     for spec in super(PythonTarget, self).traversable_specs:
         yield spec
     if self._provides:
         for spec in self._provides._binaries.values():
             address = Address.parse(spec,
                                     relative_to=self.address.spec_path)
             yield address.spec
示例#50
0
 def java_sources(self):
     for spec in self._java_sources_specs:
         address = Address.parse(spec, relative_to=self.address.spec_path)
         target = self._build_graph.get_target(address)
         if target is None:
             raise TargetDefinitionException(
                 self, 'No such java target: {}'.format(spec))
         yield target
示例#51
0
 def test_contains_address(self):
   a = Address.parse('a')
   self.assertFalse(self.build_graph.contains_address(a))
   target = Target(name='a',
                   address=a,
                   build_graph=self.build_graph)
   self.build_graph.inject_target(target)
   self.assertTrue(self.build_graph.contains_address(a))
示例#52
0
def _synthesize_command(root_dir, args):
  register_commands()
  command = args[0]

  if command in Command.all_commands():
    subcommand_args = args[1:] if len(args) > 1 else []
    return command, _add_default_options(command, subcommand_args)

  if command.startswith('-'):
    _exit_and_fail('Invalid command: %s' % command)

  # assume 'build' if a command was omitted.
  try:
    Address.parse(root_dir, command)
    return _BUILD_COMMAND, _add_default_options(_BUILD_COMMAND, args)
  except:
    _exit_and_fail('Failed to execute pants build: %s' % traceback.format_exc())
 def test_resolve(self):
   build_file = self.add_to_build_file('BUILD', 'target(name="foo")')
   address, addressable = self.address_mapper.resolve(Address.parse('//:foo'))
   self.assertIsInstance(address, BuildFileAddress)
   self.assertEqual(build_file, address.build_file)
   self.assertEqual('foo', address.target_name)
   self.assertEqual(address.target_name, addressable.addressable_name)
   self.assertEqual(addressable.target_type, Target)
示例#54
0
  def _alternate_target_roots(cls, options, address_mapper, build_graph):
    processed = set()
    for jvm_tool in JvmToolMixin.get_registered_tools():
      dep_spec = jvm_tool.dep_spec(options)
      dep_address = Address.parse(dep_spec)
      # Some JVM tools are requested multiple times, we only need to handle them once.
      if dep_address not in processed:
        processed.add(dep_address)
        try:
          if build_graph.contains_address(dep_address) or address_mapper.resolve(dep_address):
            # The user has defined a tool classpath override - we let that stand.
            continue
        except AddressLookupError as e:
          if jvm_tool.classpath is None:
            raise cls._tool_resolve_error(e, dep_spec, jvm_tool)
          else:
            if not jvm_tool.is_default(options):
              # The user specified a target spec for this jvm tool that doesn't actually exist.
              # We want to error out here instead of just silently using the default option while
              # appearing to respect their config.
              raise cls.ToolResolveError(dedent("""
                  Failed to resolve target for tool: {tool}. This target was obtained from
                  option {option} in scope {scope}.

                  Make sure you didn't make a typo in the tool's address. You specified that the
                  tool should use the target found at "{tool}".

                  This target has a default classpath configured, so you can simply remove:
                    [{scope}]
                    {option}: {tool}
                  from pants.ini (or any other config file) to use the default tool.

                  The default classpath is: {default_classpath}

                  Note that tool target addresses in pants.ini should be specified *without* quotes.
                """).strip().format(tool=dep_spec,
                                    option=jvm_tool.key,
                                    scope=jvm_tool.scope,
                                    default_classpath=':'.join(map(str, jvm_tool.classpath or ()))))
            if jvm_tool.classpath:
              tool_classpath_target = JarLibrary(name=dep_address.target_name,
                                                 address=dep_address,
                                                 build_graph=build_graph,
                                                 jars=jvm_tool.classpath)
            else:
              # The tool classpath is empty by default, so we just inject a dummy target that
              # ivy resolves as the empty list classpath.  JarLibrary won't do since it requires
              # one or more jars, so we just pick a target type ivy has no resolve work to do for.
              tool_classpath_target = Target(name=dep_address.target_name,
                                             address=dep_address,
                                             build_graph=build_graph)
            build_graph.inject_target(tool_classpath_target)

    # We use the trick of not returning alternate roots, but instead just filling the dep_spec
    # holes with a JarLibrary built from a tool's default classpath JarDependency list if there is
    # no over-riding targets present. This means we do modify the build_graph, but we at least do
    # it at a time in the engine lifecycle cut out for handling that.
    return None
示例#55
0
    def make_target(self,
                    spec='',
                    target_type=Target,
                    dependencies=None,
                    derived_from=None,
                    **kwargs):
        """Creates a target and injects it into the test's build graph.

    :param string spec: The target address spec that locates this target.
    :param type target_type: The concrete target subclass to create this new target from.
    :param list dependencies: A list of target instances this new target depends on.
    :param derived_from: The target this new target was derived from.
    :type derived_from: :class:`pants.base.target.Target`
    """
        address = Address.parse(spec)
        target = target_type(name=address.target_name,
                             address=address,
                             build_graph=self.build_graph,
                             **kwargs)
        dependencies = dependencies or []

        self.build_graph.inject_target(
            target,
            dependencies=[dep.address for dep in dependencies],
            derived_from=derived_from)

        # TODO(John Sirois): This re-creates a little bit too much work done by the BuildGraph.
        # Fixup the BuildGraph to deal with non BuildFileAddresses better and just leverage it.
        for traversable_dependency_spec in target.traversable_dependency_specs:
            traversable_dependency_address = Address.parse(
                traversable_dependency_spec, relative_to=address.spec_path)
            traversable_dependency_target = self.build_graph.get_target(
                traversable_dependency_address)
            if not traversable_dependency_target:
                raise ValueError(
                    'Tests must make targets for traversable dependency specs ahead of them '
                    'being traversed, {} tried to traverse {} which does not exist.'
                    .format(target, traversable_dependency_address))
            if traversable_dependency_target not in target.dependencies:
                self.build_graph.inject_dependency(
                    dependent=target.address,
                    dependency=traversable_dependency_address)
                target.mark_transitive_invalidation_hash_dirty()

        return target