def test_scan_addresses(self):
   root_build_file = self.add_to_build_file('BUILD', 'target(name="foo")')
   subdir_build_file = self.add_to_build_file('subdir/BUILD', 'target(name="bar")')
   subdir_suffix_build_file = self.add_to_build_file('subdir/BUILD.suffix', 'target(name="baz")')
   with open(os.path.join(self.build_root, 'BUILD.invalid.suffix'), 'w') as invalid_build_file:
     invalid_build_file.write('target(name="foobar")')
   self.assertEquals({BuildFileAddress(root_build_file, 'foo'),
                      BuildFileAddress(subdir_build_file, 'bar'),
                      BuildFileAddress(subdir_suffix_build_file, 'baz')},
                     self.address_mapper.scan_addresses(root=self.build_root))
Beispiel #2
0
    def test_get_non_synthetic_scala_targets(self):
        # Create a custom context so we can manually inject multiple
        # targets of different source types and synthetic vs non-synthetic
        # to test the target filtering logic.
        context = self._create_context()

        # scala_library - should remain.
        scala_target_address = BuildFileAddress(
            self.add_to_build_file(
                'a/scala/BUILD',
                'scala_library(name="s", sources=["Source.scala"])'), 's')
        context.build_graph.inject_address_closure(scala_target_address)
        scala_target = context.build_graph.get_target(scala_target_address)

        # scala_library but with java sources - should be filtered
        scala_target_java_source_address = BuildFileAddress(
            self.add_to_build_file(
                'a/scala_java/BUILD',
                'scala_library(name="sj", sources=["Source.java"])'), 'sj')
        context.build_graph.inject_address_closure(
            scala_target_java_source_address)
        scala_target_with_java_source = context.build_graph.get_target(
            scala_target_java_source_address)

        # java_library - should be filtered
        java_target_address = BuildFileAddress(
            self.add_to_build_file(
                'a/java/BUILD',
                'java_library(name="j", sources=["Source.java"])'), 'j')
        context.build_graph.inject_address_closure(java_target_address)
        java_target = context.build_graph.get_target(java_target_address)

        # synthetic scala_library - should be filtered
        synthetic_scala_target = self.make_target('a/synthetic_scala:ss',
                                                  ScalaLibrary)

        # add all these targets to context.
        context.replace_targets([
            java_target, scala_target, scala_target_with_java_source,
            synthetic_scala_target
        ])

        # scala_library would bring in 'scala-library-2.9.3 defined in BUILD.tools
        # so we have an extra target here.
        self.assertEqual(5, len(context.targets()))

        # Now create the task and run the non_synthetic scala-only filtering.
        task = self._create_scalastyle_task_from_context(context)
        result_targets = task._get_non_synthetic_scala_targets(
            context.targets())

        # Only the scala target should remain
        self.assertEquals(1, len(result_targets))
        self.assertEqual(scala_target, result_targets[0])
Beispiel #3
0
  def test_build_file_forms(self):
    with self.workspace('a/b/c/BUILD') as root_dir:
      build_file = BuildFile(root_dir, relpath='a/b/c')
      self.assert_address('a/b/c', 'c', BuildFileAddress(build_file))
      self.assert_address('a/b/c', 'foo', BuildFileAddress(build_file, target_name='foo'))
      self.assertEqual('a/b/c:foo', BuildFileAddress(build_file, target_name='foo').spec)

    with self.workspace('BUILD') as root_dir:
      build_file = BuildFile(root_dir, relpath='')
      self.assert_address('', 'foo', BuildFileAddress(build_file, target_name='foo'))
      self.assertEqual(':foo', BuildFileAddress(build_file, target_name='foo').spec)
Beispiel #4
0
    def test_get_non_excluded_scala_sources(self):
        # Create a custom context so we can manually inject scala targets
        # with mixed sources in them to test the source filtering logic.
        context = self._create_context(config=dedent('''
      [scalastyle]
      config: {config}
      excludes: {excludes}
    '''.format(config=self._create_scalastyle_config_file(),
               excludes=self._create_scalastyle_excludes_file(
                   ['a/scala_2/Source2.scala']))))

        # this scala target has mixed *.scala and *.java sources.
        # the *.java source should filtered out.
        scala_target_address_1 = BuildFileAddress(
            self.add_to_build_file(
                'a/scala_1/BUILD',
                'scala_library(name="s1", sources=["Source1.java", "Source1.scala"])'
            ), 's1')
        self.build_graph.inject_address_closure(scala_target_address_1)
        scala_target_1 = self.build_graph.get_target(scala_target_address_1)

        # this scala target has single *.scala source but will be excluded out
        # by the [scalastyle].[excludes] setting.
        scala_target_address_2 = BuildFileAddress(
            self.add_to_build_file(
                'a/scala_2/BUILD',
                'scala_library(name="s2", sources=["Source2.scala"])'), 's2')
        self.build_graph.inject_address_closure(scala_target_address_2)
        scala_target_2 = self.build_graph.get_target(scala_target_address_2)

        context = self._create_context(
            config=dedent('''
        [scalastyle]
        config: {config}
        excludes: {excludes}
      '''.format(config=self._create_scalastyle_config_file(),
                 excludes=self._create_scalastyle_excludes_file(
                     ['a/scala_2/Source2.scala']))),
            target_roots=[scala_target_1, scala_target_2])

        # Remember, we have the extra 'scala-library-2.9.3' dep target.
        self.assertEqual(3, len(context.targets()))

        # Now create the task and run the scala source and exclusion filtering.
        task = self._create_scalastyle_task_from_context(context)
        result_sources = task._get_non_excluded_scala_sources(
            task._get_non_synthetic_scala_targets(context.targets()))

        # Only the scala source from target 1 should remain
        self.assertEquals(1, len(result_sources))
        self.assertEqual('a/scala_1/Source1.scala', result_sources[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 = SyntheticAddress.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
Beispiel #6
0
    def test_derived_from_chain(self):
        context = self.context()

        # add concrete target
        build_file = self.add_to_build_file(
            'y/BUILD',
            dedent('''
    java_library(
      name='concrete',
      sources=['SourceA.scala'],
    )
    '''))
        concrete_address = BuildFileAddress(build_file, 'concrete')
        context.build_graph.inject_address_closure(concrete_address)
        concrete = context.build_graph.get_target(concrete_address)

        # add synthetic targets
        syn_one = context.add_new_target(SyntheticAddress('y', 'syn_one'),
                                         JavaLibrary,
                                         derived_from=concrete,
                                         sources=["SourceB.scala"])
        syn_two = context.add_new_target(SyntheticAddress('y', 'syn_two'),
                                         JavaLibrary,
                                         derived_from=syn_one,
                                         sources=["SourceC.scala"])

        # validate
        self.assertEquals(list(syn_two.derived_from_chain),
                          [syn_one, concrete])
        self.assertEquals(list(syn_one.derived_from_chain), [concrete])
        self.assertEquals(list(concrete.derived_from_chain), [])
 def test_scan_addresses_with_excludes(self):
   root_build_file = self.add_to_build_file('BUILD', 'target(name="foo")')
   self.add_to_build_file('subdir/BUILD', 'target(name="bar")')
   spec_excludes = [os.path.join(self.build_root, 'subdir')]
   self.assertEquals({BuildFileAddress(root_build_file, 'foo')},
                     self.address_mapper.scan_addresses(root=self.build_root,
                                                        spec_excludes=spec_excludes))
Beispiel #8
0
    def test_fail(self):
        # Default scalastyle config (import grouping rule) and no excludes.

        # Create a scala source that would FAIL ImportGroupingChecker rule.
        self.create_file(relpath='a/scala/fail.scala',
                         contents=dedent('''
        import java.io._
        object HelloWorld {
           def main(args: Array[String]) {
              println("Hello, world!")
           }
        }
        import java.util._
      '''))
        scala_target_address = BuildFileAddress(
            self.add_to_build_file(
                'a/scala/BUILD',
                'scala_library(name="fail", sources=["fail.scala"])'), 'fail')
        self.build_graph.inject_address_closure(scala_target_address)
        scala_target = self.build_graph.get_target(scala_target_address)

        context = self._create_context(target_roots=[scala_target])

        with self.assertRaises(TaskError):
            self.execute(context)
Beispiel #9
0
    def test_end_to_end_pass(self):
        # Default scalastyle config (import grouping rule) and no excludes.

        # Create a scala source that would PASS ImportGroupingChecker rule.
        self.create_file(relpath='a/scala/pass.scala',
                         contents=dedent("""
        import java.util
        object HelloWorld {
           def main(args: Array[String]) {
              println("Hello, world!")
           }
        }
      """))
        scala_target_address = BuildFileAddress(
            self.add_to_build_file(
                'a/scala/BUILD',
                'scala_library(name="pass", sources=["pass.scala"])'), 'pass')
        self.build_graph.inject_address_closure(scala_target_address)
        scala_target = self.build_graph.get_target(scala_target_address)

        context = self._create_context(
            scalastyle_config=self._create_scalastyle_config_file(),
            target_roots=[scala_target])

        self.execute(context)
Beispiel #10
0
    def _resolve_and_inject(self, dependent_remote_lib, dependency_import_id):
        """Resolves dependency_import_id's BUILD file and injects it into the build graph.

    :param GoRemoteLibrary dependent_remote_lib:
        Injects the resolved target of dependency_import_id as a dependency of this
        remote library.
    :param str dependency_import_id:
        Global import id of the remote library whose BUILD file to look up.
    :return GoRemoteLibrary:
        Returns the resulting resolved remote library after injecting it in the build graph.
        If the resulting library has already been resolved/injected, returns None.
    :raises UndeclaredRemoteLibError:
        If no BUILD file exists for dependency_import_id under the same source root of
        dependent_remote_lib, raises exception.
    """
        remote_source_root = dependent_remote_lib.target_base
        spec_path = os.path.join(remote_source_root, dependency_import_id)
        try:
            build_file = FilesystemBuildFile(get_buildroot(),
                                             relpath=spec_path)
        except FilesystemBuildFile.MissingBuildFileError:
            raise self.UndeclaredRemoteLibError(spec_path)
        address = BuildFileAddress(build_file)
        self.context.build_graph.inject_address_closure(address)
        self.context.build_graph.inject_dependency(
            dependent_remote_lib.address, address)
        return self.context.build_graph.get_target(address)
Beispiel #11
0
    def test_sibling_build_files_duplicates(self):
        # This workspace is malformed, you can't shadow a name in a sibling BUILD file
        self.add_to_build_file(
            'BUILD',
            dedent('''
      fake(name="base",
           dependencies=[
             ':foo',
           ])
      '''))

        self.add_to_build_file(
            'BUILD.foo',
            dedent('''
      fake(name="foo",
           dependencies=[
             ':bat',
           ])
      '''))

        self.add_to_build_file('./BUILD.bar',
                               dedent('''
      fake(name="base")
      '''))

        with pytest.raises(BuildFileParser.SiblingConflictException):
            base_build_file = BuildFile(self.build_root, 'BUILD')
            bf_address = BuildFileAddress(base_build_file, 'base')
            self.build_file_parser.address_map_from_spec_path(
                bf_address.spec_path)
Beispiel #12
0
 def __call__(self, *args, **kwargs):
     addressable = self._addressable_type(*args, **kwargs)
     addressable_name = addressable.addressable_name
     if addressable_name:
         address = BuildFileAddress(self._build_file, addressable_name)
         self._registration_callback(address, addressable)
     return addressable
Beispiel #13
0
 def dep_address_iter():
     for dep_spec in self.dependencies:
         dep_spec_path, dep_target_name = parse_spec(
             dep_spec, relative_to=self.build_file.spec_path)
         dep_build_file = BuildFileCache.spec_path_to_build_file(
             self.build_file.root_dir, dep_spec_path)
         dep_address = BuildFileAddress(dep_build_file, dep_target_name)
         yield dep_address
Beispiel #14
0
 def test_empty_libraries(self):
     build_file = self.add_to_build_file(
         'BUILD', dedent('''
 unpacked_jars(name='foo',
 )'''))
     with self.assertRaises(UnpackedJars.ExpectedLibrariesError):
         self.build_graph.inject_address_closure(
             BuildFileAddress(build_file, 'foo'))
Beispiel #15
0
 def test_bad_main_declaration(self):
   build_file = self.add_to_build_file('BUILD', dedent('''
       jvm_binary(name='bar',
         main=['com.example.Bar'],
       )
       '''))
   with self.assertRaisesRegexp(TargetDefinitionException,
                                r'Invalid target JvmBinary.*bar.*main must be a fully'):
     self.build_graph.inject_address_closure(BuildFileAddress(build_file, 'bar'))
Beispiel #16
0
 def test_trivial_target(self):
     self.add_to_build_file('BUILD', '''fake(name='foozle')''')
     build_file = BuildFile(self.build_root, 'BUILD')
     address_map = self.build_file_parser.parse_build_file(build_file)
     self.assertEqual(len(address_map), 1)
     address, addressable = address_map.popitem()
     self.assertEqual(address, BuildFileAddress(build_file, 'foozle'))
     self.assertEqual(addressable.name, 'foozle')
     self.assertEqual(addressable.target_type, ErrorTarget)
Beispiel #17
0
 def test_bad_source_declaration(self):
   build_file = self.add_to_build_file('BUILD', dedent('''
       jvm_binary(name='foo',
         main='com.example.Foo',
         source=['foo.py'],
       )
       '''))
   with self.assertRaisesRegexp(TargetDefinitionException,
                                r'Invalid target JvmBinary.*foo.*source must be a single'):
     self.build_graph.inject_address_closure(BuildFileAddress(build_file, 'foo'))
    def test_trivial_target(self):
        self.add_to_build_file('BUILD', 'fake(name="foozle")')
        build_file = FilesystemBuildFile(self.build_root, 'BUILD')
        address_map = self.build_file_parser.parse_build_file(build_file)

        self.assertEqual(len(address_map), 1)
        address, proxy = address_map.popitem()
        self.assertEqual(address, BuildFileAddress(build_file, 'foozle'))
        self.assertEqual(proxy.addressed_name, 'foozle')
        self.assertEqual(proxy.addressed_type, ErrorTarget)
Beispiel #19
0
    def _parse_spec(self, spec):
        def normalize_spec_path(path):
            is_abs = not path.startswith('//') and os.path.isabs(path)
            if is_abs:
                path = os.path.realpath(path)
                if os.path.commonprefix([self._root_dir, path
                                         ]) != self._root_dir:
                    raise self.BadSpecError(
                        'Absolute address path {0} does not share build root {1}'
                        .format(path, self._root_dir))
            else:
                if path.startswith('//'):
                    path = path[2:]
                path = os.path.join(self._root_dir, path)

            normalized = os.path.relpath(path, self._root_dir)
            if normalized == '.':
                normalized = ''
            return normalized

        if spec.endswith('::'):
            addresses = set()
            spec_path = spec[:-len('::')]
            spec_dir = normalize_spec_path(spec_path)
            if not os.path.isdir(os.path.join(self._root_dir, spec_dir)):
                raise self.BadSpecError(
                    'Can only recursive glob directories and {0} is not a valid dir'
                    .format(spec_dir))
            try:
                for build_file in BuildFile.scan_buildfiles(
                        self._root_dir, spec_dir):
                    addresses.update(
                        self._address_mapper.addresses_in_spec_path(
                            build_file.spec_path))
                return addresses
            except (BuildFile.BuildFileError, AddressLookupError) as e:
                raise self.BadSpecError(e)
        elif spec.endswith(':'):
            spec_path = spec[:-len(':')]
            spec_dir = normalize_spec_path(spec_path)
            try:
                return set(
                    self._address_mapper.addresses_in_spec_path(spec_dir))
            except AddressLookupError as e:
                raise self.BadSpecError(e)
        else:
            spec_parts = spec.rsplit(':', 1)
            spec_parts[0] = normalize_spec_path(spec_parts[0])
            spec_path, target_name = parse_spec(':'.join(spec_parts))
            try:
                build_file = BuildFile.from_cache(self._root_dir, spec_path)
                return set([BuildFileAddress(build_file, target_name)])
            except BuildFile.BuildFileError as e:
                raise self.BadSpecError(e)
Beispiel #20
0
    def test_resolve(self):
        build_file = self.add_to_build_file(
            'BUILD', dedent(''' target(
        name = 'foo'
      )
      '''))

        address = BuildFileAddress(build_file, 'foo')
        addressable = self.address_mapper.resolve(address)
        self.assertEquals(address.target_name, addressable.addressable_name)
        self.assertEqual(addressable.target_type, Dependencies)
Beispiel #21
0
 def test_bad_jar_rules(self):
   build_file = self.add_to_build_file('BUILD', dedent('''
       jvm_binary(name='foo',
         main='com.example.Foo',
         deploy_jar_rules='invalid',
       )
       '''))
   with self.assertRaisesRegexp(TargetDefinitionException,
                                 r'Invalid target JvmBinary.*foo.*'
                                 r'deploy_jar_rules must be a JarRules specification. got str'):
     self.build_graph.inject_address_closure(BuildFileAddress(build_file, 'foo'))
Beispiel #22
0
 def _inject_spec_closure_into_build_graph(self,
                                           spec_path,
                                           target_name,
                                           build_graph,
                                           addresses_already_closed=None):
     addresses_already_closed = addresses_already_closed or set()
     build_file = BuildFileCache.spec_path_to_build_file(
         self._root_dir, spec_path)
     address = BuildFileAddress(build_file, target_name)
     self.inject_address_closure_into_build_graph(address, build_graph,
                                                  addresses_already_closed)
Beispiel #23
0
 def spec_to_address(self, spec, relative_to=''):
   """A helper method for mapping a spec to the correct BuildFileAddress.
   :param spec: a spec to lookup in the map.
   :raises AddressLookupError: if the BUILD file cannot be found in the path specified by the spec
   :returns a new BuildFileAddress instanace
   """
   spec_path, name = parse_spec(spec, relative_to=relative_to)
   try:
     build_file = BuildFile.from_cache(self.root_dir, spec_path)
   except BuildFile.BuildFileError as e:
     raise self.InvalidBuildFileReference('{message}\n  when translating spec {spec}'
                                          .format(message=e, spec=spec))
   return BuildFileAddress(build_file, name)
Beispiel #24
0
  def test_raises_address_not_in_build_file(self):
    build_file = self.add_to_build_file('BUILD', dedent(
      '''
      target(
        name = 'foo'
      )
      '''
    ))

    # Create an address that doesn't exist in an existing BUILD file
    address = BuildFileAddress(build_file, 'bar')
    with self.assertRaises(BuildFileAddressMapper.AddressNotInBuildFile):
      self.address_mapper.resolve(address)
Beispiel #25
0
 def test_bad_basename(self):
     build_file = self.add_to_build_file(
         'BUILD',
         dedent('''
 jvm_app(name='foo',
   basename='foo',
 )
 '''))
     with self.assertRaisesRegexp(
             TargetDefinitionException,
             r'Invalid target JvmApp.* foo.*basename must not equal name.'):
         self.build_graph.inject_address_closure(
             BuildFileAddress(build_file, 'foo'))
Beispiel #26
0
 def test_empty_traversable_properties(self):
     build_file = self.add_to_build_file(
         'BUILD',
         dedent('''
 java_library(
   name='foo',
   sources=["foo.java"],
 )
 '''))
     self.build_graph.inject_address_closure(
         BuildFileAddress(build_file, 'foo'))
     target = self.build_graph.get_target(SyntheticAddress.parse('//:foo'))
     self.assertSequenceEqual([], list(target.traversable_specs))
     self.assertSequenceEqual([], list(target.traversable_dependency_specs))
Beispiel #27
0
  def test_traversable_dependency_specs(self):
    build_file = self.add_to_build_file('BUILD', dedent('''
    jvm_target(name='foo',
      resources=[':resource_target'],
    )
    resources(name='resource_target',
      sources=['foo.txt'],
    )
    '''))

    self.build_graph.inject_address_closure(BuildFileAddress(build_file, 'foo'))
    target = self.build_graph.get_target(SyntheticAddress.parse('//:foo'))
    self.assertSequenceEqual([], list(target.traversable_specs))
    self.assertSequenceEqual([':resource_target'], list(target.traversable_dependency_specs))
Beispiel #28
0
    def __init__(self, target_type, build_file, args, kwargs):
        if 'name' not in kwargs:
            raise ValueError(
                'name is a required parameter to all Target objects'
                ' specified within a BUILD file.'
                '  Target type was: {target_type}.'
                '  Current BUILD file is: {build_file}.'.format(
                    target_type=target_type, build_file=build_file))

        if args:
            raise ValueError(
                'All arguments passed to Targets within BUILD files should'
                ' use explicit keyword syntax.'
                '  Target type was: {target_type}.'
                '  Current BUILD file is: {build_file}.'
                '  Arguments passed were: {args}'.format(
                    target_type=target_type, build_file=build_file, args=args))

        if 'build_file' in kwargs:
            raise ValueError(
                'build_file cannot be passed as an explicit argument to a'
                ' target within a BUILD file.'
                '  Target type was: {target_type}.'
                '  Current BUILD file is: {build_file}.'
                '  build_file argument passed was: {build_file_arg}'.format(
                    target_type=target_type,
                    build_file=build_file,
                    build_file_arg=kwargs.get('build_file')))

        self.target_type = target_type
        self.build_file = build_file
        self.kwargs = kwargs
        self.name = kwargs['name']
        self.address = BuildFileAddress(build_file, self.name)
        self.description = None

        self.dependencies = self.kwargs.pop('dependencies', [])
        self._dependency_addresses = None
        for dep_spec in self.dependencies:
            if not isinstance(dep_spec, Compatibility.string):
                msg = (
                    'dependencies passed to Target constructors must be strings.  {dep_spec} is not'
                    ' a string.  Target type was: {target_type}.  Current BUILD file is: {build_file}.'
                    .format(target_type=target_type,
                            build_file=build_file,
                            dep_spec=dep_spec))
                raise TargetDefinitionException(target=self, msg=msg)
Beispiel #29
0
  def _add_java_target_for_test(self, context, name, test_java_source):
    rel_dir = os.path.join('src/java', name)
    self.create_file(
      relpath=os.path.join(rel_dir, '{name}.java'.format(name=name)),
      contents=test_java_source)

    java_target_address = BuildFileAddress(
      self.add_to_build_file(
        os.path.join(rel_dir, 'BUILD'),
        'java_library(name="{name}", sources=["{name}.java"])'.format(name=name)),
      '{name}'.format(name=name))

    context.build_graph.inject_address_closure(java_target_address)
    java_target = context.build_graph.get_target(java_target_address)
    new_target_roots = [java_target]
    new_target_roots.extend(context.target_roots if context.target_roots else [])
    context.replace_targets(new_target_roots)
Beispiel #30
0
 def test_illegal_kwargs(self):
     with self.assertRaises(Target.UnknownArguments) as cm:
         context = self.context()
         build_file = self.add_to_build_file(
             'foo/BUILD',
             dedent('''
   java_library(
     name='bar',
     sources=[],
     foobar='barfoo',
   )
   '''))
         address = BuildFileAddress(build_file, 'bar')
         context.build_graph.inject_address_closure(address)
         context.build_graph.get_target(address)
     self.assertTrue('foobar = barfoo' in str(cm.exception))
     self.assertTrue('foo:bar' in str(cm.exception))