Example #1
0
  def register_options(cls, register):
    super(ZincCompile, cls).register_options(register)
    register('--plugins', advanced=True, action='append', fingerprint=True,
             help='Use these scalac plugins.')
    register('--plugin-args', advanced=True, type=dict_option, default={}, fingerprint=True,
             help='Map from plugin name to list of arguments for that plugin.')
    register('--name-hashing', advanced=True, action='store_true', default=False, fingerprint=True,
             help='Use zinc name hashing.')

    cls.register_jvm_tool(register,
                          'zinc',
                          main=cls._ZINC_MAIN,
                          custom_rules=[
                            # The compiler-interface and sbt-interface tool jars carry xsbt and
                            # xsbti interfaces that are used across the shaded tool jar boundary so
                            # we preserve these root packages wholesale along with the core scala
                            # APIs.
                            Shader.exclude_package('scala', recursive=True),
                            Shader.exclude_package('xsbt', recursive=True),
                            Shader.exclude_package('xsbti', recursive=True),
                          ])
    cls.register_jvm_tool(register, 'compiler-interface')
    cls.register_jvm_tool(register, 'sbt-interface')

    cls.register_jvm_tool(register, 'plugin-jars', default=[])
Example #2
0
    def register_options(cls, register):
        super(ZincCompile, cls).register_options(register)
        register("--plugins", action="append", fingerprint=True, help="Use these scalac plugins.")
        register(
            "--plugin-args",
            advanced=True,
            type=Options.dict,
            default={},
            fingerprint=True,
            help="Map from plugin name to list of arguments for that plugin.",
        )
        register("--name-hashing", action="store_true", default=False, fingerprint=True, help="Use zinc name hashing.")

        cls.register_jvm_tool(
            register,
            "zinc",
            main=cls._ZINC_MAIN,
            custom_rules=[
                # The compiler-interface and sbt-interface tool jars carry xsbt and
                # xsbti interfaces that are used across the shaded tool jar boundary so
                # we preserve these root packages wholesale along with the core scala
                # APIs.
                Shader.exclude_package("scala", recursive=True),
                Shader.exclude_package("xsbt", recursive=True),
                Shader.exclude_package("xsbti", recursive=True),
            ],
            fingerprint=True,
        )
        cls.register_jvm_tool(register, "compiler-interface", fingerprint=True)
        cls.register_jvm_tool(register, "sbt-interface", fingerprint=True)

        cls.register_jvm_tool(register, "plugin-jars", default=[], fingerprint=True)
Example #3
0
 def register_options(cls, register, register_jvm_tool):
   register('--skip', action='store_true', help='Skip running junit.')
   register('--fail-fast', action='store_true',
            help='Fail fast on the first test failure in a suite.')
   register('--batch-size', advanced=True, type=int, default=sys.maxint,
            help='Run at most this many tests in a single test process.')
   register('--test', action='append',
            help='Force running of just these tests.  Tests can be specified using any of: '
                 '[classname], [classname]#[methodname], [filename] or [filename]#[methodname]')
   register('--per-test-timer', action='store_true', help='Show progress and timer for each test.')
   register('--default-parallel', advanced=True, action='store_true',
            help='Run classes without @TestParallel or @TestSerial annotations in parallel.')
   register('--parallel-threads', advanced=True, type=int, default=0,
            help='Number of threads to run tests in parallel. 0 for autoset.')
   register('--test-shard', advanced=True,
            help='Subset of tests to run, in the form M/N, 0 <= M < N. '
                 'For example, 1/3 means run tests number 2, 5, 8, 11, ...')
   register('--suppress-output', action='store_true', default=True,
            help='Redirect test output to files in .pants.d/test/junit.')
   register('--cwd', advanced=True,
            help='Set the working directory. If no argument is passed, use the build root. '
                 'If cwd is set on a target, it will supersede this argument.')
   register_jvm_tool(register,
                     'junit',
                     main=JUnitRun._MAIN,
                     # TODO(John Sirois): Investigate how much less we can get away with.
                     # Clearly both tests and the runner need access to the same @Test, @Before,
                     # as well as other annotations, but there is also the Assert class and some
                     # subset of the @Rules, @Theories and @RunWith APIs.
                     custom_rules=[
                       Shader.exclude_package('org.junit', recursive=True),
                       Shader.exclude_package('org.hamcrest', recursive=True)
                     ])
Example #4
0
 def register_options(cls, register, register_jvm_tool):
   register('--skip', action='store_true', help='Skip running junit.')
   register('--fail-fast', action='store_true',
            help='Fail fast on the first test failure in a suite.')
   register('--batch-size', type=int, default=sys.maxint,
            help='Run at most this many tests in a single test process.')
   register('--test', action='append',
            help='Force running of just these tests.  Tests can be specified using any of: '
                 '[classname], [classname]#[methodname], [filename] or [filename]#[methodname]')
   register('--xml-report', action='store_true', help='Output an XML report for the test run.')
   register('--per-test-timer', action='store_true', help='Show progress and timer for each test.')
   register('--default-parallel', action='store_true',
            help='Run classes without @TestParallel or @TestSerial annotations in parallel.')
   register('--parallel-threads', type=int, default=0,
            help='Number of threads to run tests in parallel. 0 for autoset.')
   register('--test-shard',
            help='Subset of tests to run, in the form M/N, 0 <= M < N. '
                 'For example, 1/3 means run tests number 2, 5, 8, 11, ...')
   register('--suppress-output', action='store_true', default=True,
            help='Redirect test output to files in .pants.d/test/junit. Implied by --xml-report.')
   register('--cwd', default=_CWD_NOT_PRESENT, nargs='?',
            help='Set the working directory. If no argument is passed, use the first target path.')
   register_jvm_tool(register,
                     'junit',
                     main=JUnitRun._MAIN,
                     # TODO(John Sirois): Investigate how much less we can get away with.
                     # Clearly both tests and the runner need access to the same @Test, @Before,
                     # as well as other annotations, but there is also the Assert class and some
                     # subset of the @Rules, @Theories and @RunWith APIs.
                     custom_rules=[
                       Shader.exclude_package('org.junit', recursive=True),
                       Shader.exclude_package('org.hamcrest', recursive=True)
                     ])
Example #5
0
  def test_assemble_default_rules_default_package(self):
    input_jar = self.populate_input_jar('main.class', 'com/google/common/base/Function.class')

    rules = self.shader.assemble_binary_rules('main', input_jar)

    self.assertEqual(Shader.exclude_package(), rules[0])
    self.assertIn(Shader.exclude_package('javax.annotation'), rules[1:-1])
    self.assertEqual(Shader.shade_package('com.google.common.base'), rules[-1])
Example #6
0
  def test_assemble_default_rules(self):
    input_jar = self.populate_input_jar('org/pantsbuild/tools/fake/Main.class',
                                        'com/google/common/base/Function.class')

    rules = self.shader.assemble_binary_rules('org.pantsbuild.tools.fake.Main', input_jar)

    self.assertEqual(Shader.exclude_package('org.pantsbuild.tools.fake'), rules[0])
    self.assertIn(Shader.exclude_package('javax.annotation'), rules[1:-1])
    self.assertEqual(Shader.shade_package('com.google.common.base'), rules[-1])
Example #7
0
    def test_assemble_default_rules_default_package(self):
        input_jar = self.populate_input_jar(
            'main.class', 'com/google/common/base/Function.class')

        rules = self.shader.assemble_binary_rules('main', input_jar)

        self.assertEqual(Shader.exclude_package(), rules[0])
        self.assertIn(Shader.exclude_package('javax.annotation'), rules[1:-1])
        self.assertEqual(Shader.shade_package('com.google.common.base'),
                         rules[-1])
Example #8
0
    def test_assemble_default_rules(self):
        input_jar = self.populate_input_jar(
            'org/pantsbuild/tools/fake/Main.class',
            'com/google/common/base/Function.class')

        rules = self.shader.assemble_binary_rules(
            'org.pantsbuild.tools.fake.Main', input_jar)

        self.assertEqual(Shader.exclude_package('org.pantsbuild.tools.fake'),
                         rules[0])
        self.assertIn(Shader.exclude_package('javax.annotation'), rules[1:-1])
        self.assertEqual(Shader.shade_package('com.google.common.base'),
                         rules[-1])
Example #9
0
 def register_options(cls, register):
   super(Checkstyle, cls).register_options(register)
   register('--skip', action='store_true', fingerprint=True,
            help='Skip checkstyle.')
   register('--configuration', advanced=True, type=file_option, fingerprint=True,
            help='Path to the checkstyle configuration file.')
   register('--properties', advanced=True, type=dict_option, default={}, fingerprint=True,
            help='Dictionary of property mappings to use for checkstyle.properties.')
   register('--confs', advanced=True, default=['default'],
            help='One or more ivy configurations to resolve for this target.')
   register('--jvm-options', advanced=True, action='append', metavar='<option>...',
            help='Run checkstyle with these extra jvm options.')
   cls.register_jvm_tool(register,
                         'checkstyle',
                         main=cls._CHECKSTYLE_MAIN,
                         custom_rules=[
                             # Checkstyle uses reflection to load checks and has an affordance that
                             # allows leaving off a check classes' package name.  This affordance
                             # breaks for built-in checkstyle checks under shading so we ensure all
                             # checkstyle packages are excluded from shading such that just its
                             # third party transitive deps (guava and the like), are shaded.
                             # See the module configuration rules here which describe this:
                             #   http://checkstyle.sourceforge.net/config.html#Modules
                             Shader.exclude_package('com.puppycrawl.tools.checkstyle',
                                                    recursive=True),
                         ])
Example #10
0
  def test_runner_command(self):
    input_jar = self.populate_input_jar('main.class', 'com/google/common/base/Function.class')
    custom_rules = [Shader.exclude_package('log4j', recursive=True)]

    with self.shader.binary_shader(self.output_jar, 'main', input_jar,
                                   custom_rules=custom_rules) as shader:
      command = shader.command

      self.assertTrue(command.pop(0).endswith('java'))

      jar_or_cp = command.pop(0)
      self.assertIn(jar_or_cp, {'-cp', 'classpath', '-jar'})
      self.assertEqual(self.jarjar, os.path.abspath(command.pop(0)))

      if jar_or_cp != '-jar':
        # We don't really care what the name of the jarjar main class is - shader.command[2]
        command.pop(0)

      self.assertEqual('process', command.pop(0))

      rules_file = command.pop(0)
      self.assertTrue(os.path.exists(rules_file))
      with open(rules_file) as fp:
        lines = fp.read().splitlines()
        self.assertEqual('rule log4j.** log4j.@1', lines[0])  # The custom rule.
        self.assertEqual('rule * @1', lines[1])  # Exclude main's package.
        self.assertIn('rule javax.annotation.* javax.annotation.@1', lines)  # Exclude system.
        self.assertEqual('rule com.google.common.base.* {}com.google.common.base.@1'
                         .format(Shader.SHADE_PREFIX), lines[-1])  # Shade the rest.

      self.assertEqual(input_jar, command.pop(0))
      self.assertEqual(self.output_jar, command.pop(0))
Example #11
0
    def register_options(cls, register):
        super(ZincCompile, cls).register_options(register)
        register('--plugins',
                 action='append',
                 fingerprint=True,
                 help='Use these scalac plugins.')
        register(
            '--plugin-args',
            advanced=True,
            type=Options.dict,
            default={},
            fingerprint=True,
            help='Map from plugin name to list of arguments for that plugin.')
        register('--name-hashing',
                 action='store_true',
                 default=False,
                 fingerprint=True,
                 help='Use zinc name hashing.')

        cls.register_jvm_tool(
            register,
            'zinc',
            main=cls._ZINC_MAIN,
            custom_rules=[
                # The compiler-interface and sbt-interface tool jars carry xsbt and
                # xsbti interfaces that are used across the shaded tool jar boundary so
                # we preserve these root packages wholesale along with the core scala
                # APIs.
                Shader.exclude_package('scala', recursive=True),
                Shader.exclude_package('xsbt', recursive=True),
                Shader.exclude_package('xsbti', recursive=True),
            ],
            fingerprint=True)
        cls.register_jvm_tool(register, 'compiler-interface', fingerprint=True)
        cls.register_jvm_tool(register, 'sbt-interface', fingerprint=True)

        cls.register_jvm_tool(register,
                              'plugin-jars',
                              default=[],
                              fingerprint=True)
Example #12
0
 def register_options(cls, register, register_jvm_tool):
   register('--skip', action='store_true', help='Skip running junit.')
   register('--fail-fast', action='store_true',
            help='Fail fast on the first test failure in a suite.')
   register('--batch-size', advanced=True, type=int, default=sys.maxint,
            help='Run at most this many tests in a single test process.')
   register('--test', action='append',
            help='Force running of just these tests.  Tests can be specified using any of: '
                 '[classname], [classname]#[methodname], [filename] or [filename]#[methodname]')
   register('--per-test-timer', action='store_true', help='Show progress and timer for each test.')
   register('--default-parallel', advanced=True, action='store_true',
            help='Run classes without @TestParallel or @TestSerial annotations in parallel.')
   register('--parallel-threads', advanced=True, type=int, default=0,
            help='Number of threads to run tests in parallel. 0 for autoset.')
   register('--test-shard', advanced=True,
            help='Subset of tests to run, in the form M/N, 0 <= M < N. '
                 'For example, 1/3 means run tests number 2, 5, 8, 11, ...')
   register('--suppress-output', action='store_true', default=True,
            help='Redirect test output to files in .pants.d/test/junit.')
   register('--cwd', advanced=True,
            help='Set the working directory. If no argument is passed, use the build root. '
                 'If cwd is set on a target, it will supersede this argument.')
   register('--strict-jvm-version', action='store_true', default=False, advanced=True,
            help='If true, will strictly require running junits with the same version of java as '
                 'the platform -target level. Otherwise, the platform -target level will be '
                 'treated as the minimum jvm to run.')
   register_jvm_tool(register,
                     'junit',
                     main=JUnitRun._MAIN,
                     # TODO(John Sirois): Investigate how much less we can get away with.
                     # Clearly both tests and the runner need access to the same @Test, @Before,
                     # as well as other annotations, but there is also the Assert class and some
                     # subset of the @Rules, @Theories and @RunWith APIs.
                     custom_rules=[
                       Shader.exclude_package('org.junit', recursive=True),
                       Shader.exclude_package('org.hamcrest', recursive=True)
                     ])
Example #13
0
  def test_assemble_custom_rules(self):
    input_jar = self.populate_input_jar('main.class')

    rules = self.shader.assemble_binary_rules('main', input_jar,
                                              custom_rules=[Shader.shade_class('bob'),
                                                            Shader.exclude_class('fred')])

    self.assertEqual(Shader.shade_class('bob'), rules[0])
    self.assertEqual(Shader.exclude_class('fred'), rules[1])
    self.assertEqual(Shader.exclude_package(), rules[2])
    self.assertIn(Shader.exclude_package('javax.annotation'), rules[3:])
Example #14
0
 def register_options(cls, register):
     super(Checkstyle, cls).register_options(register)
     register('--skip',
              action='store_true',
              fingerprint=True,
              help='Skip checkstyle.')
     register('--configuration',
              advanced=True,
              type=file_option,
              fingerprint=True,
              help='Path to the checkstyle configuration file.')
     register(
         '--properties',
         advanced=True,
         type=dict_option,
         default={},
         fingerprint=True,
         help=
         'Dictionary of property mappings to use for checkstyle.properties.'
     )
     register(
         '--confs',
         advanced=True,
         default=['default'],
         help='One or more ivy configurations to resolve for this target.')
     register('--jvm-options',
              advanced=True,
              action='append',
              metavar='<option>...',
              help='Run checkstyle with these extra jvm options.')
     cls.register_jvm_tool(
         register,
         'checkstyle',
         main=cls._CHECKSTYLE_MAIN,
         custom_rules=[
             # Checkstyle uses reflection to load checks and has an affordance that
             # allows leaving off a check classes' package name.  This affordance
             # breaks for built-in checkstyle checks under shading so we ensure all
             # checkstyle packages are excluded from shading such that just its
             # third party transitive deps (guava and the like), are shaded.
             # See the module configuration rules here which describe this:
             #   http://checkstyle.sourceforge.net/config.html#Modules
             Shader.exclude_package('com.puppycrawl.tools.checkstyle',
                                    recursive=True),
         ])
Example #15
0
    def test_assemble_custom_rules(self):
        input_jar = self.populate_input_jar('main.class')

        rules = self.shader.assemble_binary_rules(
            'main',
            input_jar,
            custom_rules=[
                Shader.shade_class('bob'),
                Shader.exclude_class('fred')
            ])

        self.assertEqual(Shader.shade_class('bob'), rules[0])
        self.assertEqual(Shader.exclude_class('fred'), rules[1])
        self.assertEqual(Shader.exclude_package(), rules[2])
        self.assertIn(Shader.exclude_package('javax.annotation'), rules[3:])
Example #16
0
    def test_runner_command(self):
        input_jar = self.populate_input_jar(
            'main.class', 'com/google/common/base/Function.class')
        custom_rules = [Shader.exclude_package('log4j', recursive=True)]

        with self.shader.binary_shader(self.output_jar,
                                       'main',
                                       input_jar,
                                       custom_rules=custom_rules) as shader:
            command = shader.command

            self.assertTrue(command.pop(0).endswith('java'))

            jar_or_cp = command.pop(0)
            self.assertIn(jar_or_cp, {'-cp', 'classpath', '-jar'})
            self.assertEqual(self.jarjar, os.path.abspath(command.pop(0)))

            if jar_or_cp != '-jar':
                # We don't really care what the name of the jarjar main class is - shader.command[2]
                command.pop(0)

            self.assertEqual('process', command.pop(0))

            rules_file = command.pop(0)
            self.assertTrue(os.path.exists(rules_file))
            with open(rules_file) as fp:
                lines = fp.read().splitlines()
                self.assertEqual('rule log4j.** log4j.@1',
                                 lines[0])  # The custom rule.
                self.assertEqual('rule * @1',
                                 lines[1])  # Exclude main's package.
                self.assertIn('rule javax.annotation.* javax.annotation.@1',
                              lines)  # Exclude system.
                self.assertEqual(
                    'rule com.google.common.base.* {}com.google.common.base.@1'
                    .format(Shader.SHADE_PREFIX), lines[-1])  # Shade the rest.

            self.assertEqual(input_jar, command.pop(0))
            self.assertEqual(self.output_jar, command.pop(0))
Example #17
0
 def setUp(self):
   self.jarjar = '/not/really/jarjar.jar'
   self.shader = Shader(jarjar=self.jarjar)
   self.output_jar = '/not/really/shaded.jar'
Example #18
0
class ShaderTest(unittest.TestCase):
    def setUp(self):
        self.jarjar = '/not/really/jarjar.jar'
        self.shader = Shader(jarjar=self.jarjar)
        self.output_jar = '/not/really/shaded.jar'

    def populate_input_jar(self, *entries):
        fd, input_jar_path = tempfile.mkstemp()
        os.close(fd)
        self.addCleanup(safe_delete, input_jar_path)
        with open_zip(input_jar_path, 'w') as jar:
            for entry in entries:
                jar.writestr(entry, '0xCAFEBABE')
        return input_jar_path

    def test_assemble_default_rules(self):
        input_jar = self.populate_input_jar(
            'org/pantsbuild/tools/fake/Main.class',
            'com/google/common/base/Function.class')

        rules = self.shader.assemble_binary_rules(
            'org.pantsbuild.tools.fake.Main', input_jar)

        self.assertEqual(Shader.exclude_package('org.pantsbuild.tools.fake'),
                         rules[0])
        self.assertIn(Shader.exclude_package('javax.annotation'), rules[1:-1])
        self.assertEqual(Shader.shade_package('com.google.common.base'),
                         rules[-1])

    def test_assemble_default_rules_default_package(self):
        input_jar = self.populate_input_jar(
            'main.class', 'com/google/common/base/Function.class')

        rules = self.shader.assemble_binary_rules('main', input_jar)

        self.assertEqual(Shader.exclude_package(), rules[0])
        self.assertIn(Shader.exclude_package('javax.annotation'), rules[1:-1])
        self.assertEqual(Shader.shade_package('com.google.common.base'),
                         rules[-1])

    def test_assemble_custom_rules(self):
        input_jar = self.populate_input_jar('main.class')

        rules = self.shader.assemble_binary_rules(
            'main',
            input_jar,
            custom_rules=[
                Shader.shade_class('bob'),
                Shader.exclude_class('fred')
            ])

        self.assertEqual(Shader.shade_class('bob'), rules[0])
        self.assertEqual(Shader.exclude_class('fred'), rules[1])
        self.assertEqual(Shader.exclude_package(), rules[2])
        self.assertIn(Shader.exclude_package('javax.annotation'), rules[3:])

    def test_runner_command(self):
        input_jar = self.populate_input_jar(
            'main.class', 'com/google/common/base/Function.class')
        custom_rules = [Shader.exclude_package('log4j', recursive=True)]

        with self.shader.binary_shader(self.output_jar,
                                       'main',
                                       input_jar,
                                       custom_rules=custom_rules) as shader:
            command = shader.command

            self.assertTrue(command.pop(0).endswith('java'))

            jar_or_cp = command.pop(0)
            self.assertIn(jar_or_cp, {'-cp', 'classpath', '-jar'})
            self.assertEqual(self.jarjar, os.path.abspath(command.pop(0)))

            if jar_or_cp != '-jar':
                # We don't really care what the name of the jarjar main class is - shader.command[2]
                command.pop(0)

            self.assertEqual('process', command.pop(0))

            rules_file = command.pop(0)
            self.assertTrue(os.path.exists(rules_file))
            with open(rules_file) as fp:
                lines = fp.read().splitlines()
                self.assertEqual('rule log4j.** log4j.@1',
                                 lines[0])  # The custom rule.
                self.assertEqual('rule * @1',
                                 lines[1])  # Exclude main's package.
                self.assertIn('rule javax.annotation.* javax.annotation.@1',
                              lines)  # Exclude system.
                self.assertEqual(
                    'rule com.google.common.base.* {}com.google.common.base.@1'
                    .format(Shader.SHADE_PREFIX), lines[-1])  # Shade the rest.

            self.assertEqual(input_jar, command.pop(0))
            self.assertEqual(self.output_jar, command.pop(0))
Example #19
0
 def setUp(self):
     self.jarjar = '/not/really/jarjar.jar'
     self.shader = Shader(jarjar=self.jarjar)
     self.output_jar = '/not/really/shaded.jar'
Example #20
0
 def setUp(self):
   self.jarjar = '/not/really/jarjar.jar'
   with subsystem_instance(DistributionLocator):
     executor = SubprocessExecutor(DistributionLocator.cached())
     self.shader = Shader(jarjar=self.jarjar, executor=executor)
   self.output_jar = '/not/really/shaded.jar'
Example #21
0
class ShaderTest(unittest.TestCase):
  def setUp(self):
    self.jarjar = '/not/really/jarjar.jar'
    with subsystem_instance(DistributionLocator):
      executor = SubprocessExecutor(DistributionLocator.cached())
      self.shader = Shader(jarjar=self.jarjar, executor=executor)
    self.output_jar = '/not/really/shaded.jar'

  def populate_input_jar(self, *entries):
    fd, input_jar_path = tempfile.mkstemp()
    os.close(fd)
    self.addCleanup(safe_delete, input_jar_path)
    with open_zip(input_jar_path, 'w') as jar:
      for entry in entries:
        jar.writestr(entry, '0xCAFEBABE')
    return input_jar_path

  def test_assemble_default_rules(self):
    input_jar = self.populate_input_jar('org/pantsbuild/tools/fake/Main.class',
                                        'com/google/common/base/Function.class')

    rules = self.shader.assemble_binary_rules('org.pantsbuild.tools.fake.Main', input_jar)

    self.assertEqual(Shader.exclude_package('org.pantsbuild.tools.fake'), rules[0])
    self.assertIn(Shader.exclude_package('javax.annotation'), rules[1:-1])
    self.assertEqual(Shader.shade_package('com.google.common.base'), rules[-1])

  def test_assemble_default_rules_default_package(self):
    input_jar = self.populate_input_jar('main.class', 'com/google/common/base/Function.class')

    rules = self.shader.assemble_binary_rules('main', input_jar)

    self.assertEqual(Shader.exclude_package(), rules[0])
    self.assertIn(Shader.exclude_package('javax.annotation'), rules[1:-1])
    self.assertEqual(Shader.shade_package('com.google.common.base'), rules[-1])

  def test_assemble_custom_rules(self):
    input_jar = self.populate_input_jar('main.class')

    rules = self.shader.assemble_binary_rules('main', input_jar,
                                              custom_rules=[Shader.shade_class('bob'),
                                                            Shader.exclude_class('fred')])

    self.assertEqual(Shader.shade_class('bob'), rules[0])
    self.assertEqual(Shader.exclude_class('fred'), rules[1])
    self.assertEqual(Shader.exclude_package(), rules[2])
    self.assertIn(Shader.exclude_package('javax.annotation'), rules[3:])

  def test_runner_command(self):
    input_jar = self.populate_input_jar('main.class', 'com/google/common/base/Function.class')
    custom_rules = [Shader.exclude_package('log4j', recursive=True)]

    with self.shader.binary_shader(self.output_jar, 'main', input_jar,
                                   custom_rules=custom_rules) as shader:
      command = shader.command

      self.assertTrue(command.pop(0).endswith('java'))

      jar_or_cp = command.pop(0)
      self.assertIn(jar_or_cp, {'-cp', 'classpath', '-jar'})
      self.assertEqual(self.jarjar, os.path.abspath(command.pop(0)))

      if jar_or_cp != '-jar':
        # We don't really care what the name of the jarjar main class is - shader.command[2]
        command.pop(0)

      self.assertEqual('process', command.pop(0))

      rules_file = command.pop(0)
      self.assertTrue(os.path.exists(rules_file))
      with open(rules_file) as fp:
        lines = fp.read().splitlines()
        self.assertEqual('rule log4j.** log4j.@1', lines[0])  # The custom rule.
        self.assertEqual('rule * @1', lines[1])  # Exclude main's package.
        self.assertIn('rule javax.annotation.* javax.annotation.@1', lines)  # Exclude system.
        self.assertEqual('rule com.google.common.base.* {}com.google.common.base.@1'
                         .format(Shader.SHADE_PREFIX), lines[-1])  # Shade the rest.

      self.assertEqual(input_jar, command.pop(0))
      self.assertEqual(self.output_jar, command.pop(0))
Example #22
0
 def shader(self):
     if self._shader is None:
         jarjar = self.tool_jar('jarjar')
         self._shader = Shader(jarjar)
     return self._shader