def test_check_duplicate_conflicting_protos_error(self): file1 = self.create_file('src1/foo.proto', dedent(''' package com.example.test_proto; message Foo{value=1;} ''')) # Create an .proto file in a different directory that has a different definition file2 = self.create_file('src2/foo.proto', dedent(''' package com.example.test_proto; message Foo{} ''')) task = self.create_task(self.context()) test_logger = self.MockLogger() sources_by_base = OrderedDict() sources_by_base[os.path.join(self.build_root, 'src1')] = [file1] sources_by_base[os.path.join(self.build_root, 'src2')] = [file2] check_duplicate_conflicting_protos(task, sources_by_base, [file1, file2], test_logger) self.assertEquals(1, len(test_logger._warn)) self.assertRegexpMatches(test_logger._warn[0], 'Arbitrarily favoring proto 1') self.assertEquals(1, len(test_logger._error)) self.assertRegexpMatches(test_logger._error[0], '^Proto conflict detected.*\n.*src1/foo.proto\n.*src2/foo.proto')
def test_check_duplicate_conflicting_protos_warn(self): file1 = self.create_file('src1/foo.proto', dedent(''' package com.example.test_proto; message Foo{} ''')) # Create an identical .proto file in a different directory file2 = self.create_file('src2/foo.proto', dedent(''' package com.example.test_proto; message Foo{} ''')) task = self.create_task(self.context()) test_logger = self.MockLogger() sources_by_base = OrderedDict() sources_by_base[os.path.join(self.build_root, 'src1')] = [file1] sources_by_base[os.path.join(self.build_root, 'src2')] = [file2] check_duplicate_conflicting_protos(task, sources_by_base, [file1, file2], test_logger) self.assertEquals(2, len(test_logger._warn), '\n'.join([re.sub('\\n', '\\\\n', s) for s in test_logger._warn])) self.assertRegexpMatches(test_logger._warn[0], '^Proto duplication detected.*\n.*src1/foo.proto\n.*src2/foo.proto') self.assertRegexpMatches(test_logger._warn[1], 'Arbitrarily favoring proto 1') self.assertEquals([], test_logger._error)
def execute_codegen(self, targets): # Invoke the generator once per target. Because the wire compiler has flags that try to reduce # the amount of code emitted, Invoking them all together will break if one target specifies a # service_writer and another does not, or if one specifies roots and another does not. for target in targets: sources_by_base = self._calculate_sources([target]) if self.codegen_strategy.name() == 'isolated': sources = OrderedSet(target.sources_relative_to_buildroot()) else: sources = OrderedSet( itertools.chain.from_iterable(sources_by_base.values())) if not self.validate_sources_present(sources, [target]): continue relative_sources = OrderedSet() for source in sources: source_root = SourceRoot.find_by_path(source) if not source_root: source_root = SourceRoot.find(target) relative_source = os.path.relpath(source, source_root) relative_sources.add(relative_source) check_duplicate_conflicting_protos(self, sources_by_base, relative_sources, self.context.log) args = ['--java_out={0}'.format(self.codegen_workdir(target))] # Add all params in payload to args if target.payload.get_field_value('no_options'): args.append('--no_options') service_writer = target.payload.service_writer if service_writer: args.append('--service_writer={0}'.format(service_writer)) registry_class = target.payload.registry_class if registry_class: args.append('--registry_class={0}'.format(registry_class)) if target.payload.roots: args.append('--roots={0}'.format(','.join( target.payload.roots))) if target.payload.enum_options: args.append('--enum_options={0}'.format(','.join( target.payload.enum_options))) args.append('--proto_path={0}'.format( os.path.join(get_buildroot(), SourceRoot.find(target)))) args.extend(relative_sources) result = util.execute_java( classpath=self.tool_classpath('wire-compiler'), main='com.squareup.wire.WireCompiler', args=args) if result != 0: raise TaskError( 'Wire compiler exited non-zero ({0})'.format(result))
def execute_codegen(self, targets): # Invoke the generator once per target. Because the wire compiler has flags that try to reduce # the amount of code emitted, Invoking them all together will break if one target specifies a # service_writer and another does not, or if one specifies roots and another does not. for target in targets: sources_by_base = self._calculate_sources([target]) if self.codegen_strategy.name() == 'isolated': sources = OrderedSet(target.sources_relative_to_buildroot()) else: sources = OrderedSet(itertools.chain.from_iterable(sources_by_base.values())) if not self.validate_sources_present(sources, [target]): continue relative_sources = OrderedSet() for source in sources: source_root = SourceRoot.find_by_path(source) if not source_root: source_root = SourceRoot.find(target) relative_source = os.path.relpath(source, source_root) relative_sources.add(relative_source) check_duplicate_conflicting_protos(self, sources_by_base, relative_sources, self.context.log) args = ['--java_out={0}'.format(self.codegen_workdir(target))] # Add all params in payload to args if target.payload.get_field_value('no_options'): args.append('--no_options') service_writer = target.payload.service_writer if service_writer: args.append('--service_writer={0}'.format(service_writer)) registry_class = target.payload.registry_class if registry_class: args.append('--registry_class={0}'.format(registry_class)) if target.payload.roots: args.append('--roots={0}'.format(','.join(target.payload.roots))) if target.payload.enum_options: args.append('--enum_options={0}'.format(','.join(target.payload.enum_options))) args.append('--proto_path={0}'.format(os.path.join(get_buildroot(), SourceRoot.find(target)))) args.extend(relative_sources) result = util.execute_java(classpath=self.tool_classpath('wire-compiler'), main='com.squareup.wire.WireCompiler', args=args) if result != 0: raise TaskError('Wire compiler exited non-zero ({0})'.format(result))
def genlang(self, lang, targets): # Invoke the generator once per target. Because the wire compiler has flags that try to reduce # the amount of code emitted, Invoking them all together will break if one target specifies a # service_writer and another does not, or if one specifies roots and another does not. for target in targets: sources_by_base = self._calculate_sources([target]) sources = OrderedSet(itertools.chain.from_iterable(sources_by_base.values())) relative_sources = OrderedSet() for source in sources: source_root = SourceRoot.find_by_path(source) if not source_root: source_root = SourceRoot.find(target) relative_source = os.path.relpath(source, source_root) relative_sources.add(relative_source) check_duplicate_conflicting_protos(self, sources_by_base, relative_sources, self.context.log) if lang != "java": raise TaskError("Unrecognized wire gen lang: {0}".format(lang)) args = ["--java_out={0}".format(self.java_out)] # Add all params in payload to args if target.payload.get_field_value("no_options"): args.append("--no_options") service_writer = target.payload.service_writer if service_writer: args.append("--service_writer={0}".format(service_writer)) registry_class = target.payload.registry_class if registry_class: args.append("--registry_class={0}".format(registry_class)) for root in target.payload.roots: args.append("--roots={0}".format(root)) for enum_option in target.payload.enum_options: args.append("--enum_options={0}".format(enum_option)) args.append("--proto_path={0}".format(os.path.join(get_buildroot(), SourceRoot.find(target)))) args.extend(relative_sources) result = util.execute_java( classpath=self.tool_classpath("wire-compiler"), main="com.squareup.wire.WireCompiler", args=args ) if result != 0: raise TaskError("Wire compiler exited non-zero ({0})".format(result))
def format_args_for_target(self, target): """Calculate the arguments to pass to the command line for a single target.""" sources_by_base = self._calculate_sources([target]) if self.codegen_strategy.name() == 'isolated': sources = OrderedSet(target.sources_relative_to_buildroot()) else: sources = OrderedSet( itertools.chain.from_iterable(sources_by_base.values())) if not self.validate_sources_present(sources, [target]): return None relative_sources = OrderedSet() for source in sources: source_root = SourceRoot.find_by_path(source) if not source_root: source_root = SourceRoot.find(target) relative_source = os.path.relpath(source, source_root) relative_sources.add(relative_source) check_duplicate_conflicting_protos(self, sources_by_base, relative_sources, self.context.log) args = ['--java_out={0}'.format(self.codegen_workdir(target))] # Add all params in payload to args if target.payload.get_field_value('no_options'): args.append('--no_options') def append_service_opts(service_type_name, service_type_value, options_values): """Append --service_writer or --service_factory args as appropriate. :param str service_type_name: the target parameter/option prefix :param str service_type_value: class passed to the --service_x= option :param list options_values: string options to be passed with --service_x_opt """ if service_type_value: args.append('--{0}={1}'.format(service_type_name, service_type_value)) if options_values: for opt in options_values: args.append('--{0}_opt'.format(service_type_name)) args.append(opt) # A check is done in the java_wire_library target to make sure only one of --service_writer or # --service_factory is specified. if self.wire_compiler_version < Revision(2, 0): if target.payload.service_factory: raise TaskError( '{spec} used service_factory, which is not available before Wire 2.0. You ' 'should use service_writer instead.'.format( spec=target.address.spec)) append_service_opts('service_writer', target.payload.service_writer, target.payload.service_writer_options) else: if target.payload.service_writer: raise TaskError( '{spec} used service_writer, which is not available after Wire 2.0. You ' 'should use service_factory instead.'.format( spec=target.address.spec)) append_service_opts('service_factory', target.payload.service_factory, target.payload.service_factory_options) registry_class = target.payload.registry_class if registry_class: args.append('--registry_class={0}'.format(registry_class)) if target.payload.roots: args.append('--roots={0}'.format(','.join(target.payload.roots))) if target.payload.enum_options: args.append('--enum_options={0}'.format(','.join( target.payload.enum_options))) if self.wire_compiler_version < Revision(2, 0): args.append('--proto_path={0}'.format( os.path.join(get_buildroot(), SourceRoot.find(target)))) else: # NB(gmalmquist): Support for multiple --proto_paths was introduced in Wire 2.0. for path in self._calculate_proto_paths(target): args.append('--proto_path={0}'.format(path)) args.extend(relative_sources) return args
def format_args_for_target(self, target): """Calculate the arguments to pass to the command line for a single target.""" sources_by_base = self._calculate_sources([target]) if self.codegen_strategy.name() == "isolated": sources = OrderedSet(target.sources_relative_to_buildroot()) else: sources = OrderedSet(itertools.chain.from_iterable(sources_by_base.values())) if not self.validate_sources_present(sources, [target]): return None relative_sources = OrderedSet() for source in sources: source_root = SourceRoot.find_by_path(source) if not source_root: source_root = SourceRoot.find(target) relative_source = os.path.relpath(source, source_root) relative_sources.add(relative_source) check_duplicate_conflicting_protos(self, sources_by_base, relative_sources, self.context.log) args = ["--java_out={0}".format(self.codegen_workdir(target))] # Add all params in payload to args if target.payload.get_field_value("no_options"): args.append("--no_options") def append_service_opts(service_type_name, service_type_value, options_values): """Append --service_writer or --service_factory args as appropriate. :param str service_type_name: the target parameter/option prefix :param str service_type_value: class passed to the --service_x= option :param list options_values: string options to be passed with --service_x_opt """ if service_type_value: args.append("--{0}={1}".format(service_type_name, service_type_value)) if options_values: for opt in options_values: args.append("--{0}_opt".format(service_type_name)) args.append(opt) # A check is done in the java_wire_library target to make sure only one of --service_writer or # --service_factory is specified. if self.wire_compiler_version < Revision(2, 0): if target.payload.service_factory: raise TaskError( "{spec} used service_factory, which is not available before Wire 2.0. You " "should use service_writer instead.".format(spec=target.address.spec) ) append_service_opts("service_writer", target.payload.service_writer, target.payload.service_writer_options) else: if target.payload.service_writer: raise TaskError( "{spec} used service_writer, which is not available after Wire 2.0. You " "should use service_factory instead.".format(spec=target.address.spec) ) append_service_opts( "service_factory", target.payload.service_factory, target.payload.service_factory_options ) registry_class = target.payload.registry_class if registry_class: args.append("--registry_class={0}".format(registry_class)) if target.payload.roots: args.append("--roots={0}".format(",".join(target.payload.roots))) if target.payload.enum_options: args.append("--enum_options={0}".format(",".join(target.payload.enum_options))) if self.wire_compiler_version < Revision(2, 0): args.append("--proto_path={0}".format(os.path.join(get_buildroot(), SourceRoot.find(target)))) else: # NB(gmalmquist): Support for multiple --proto_paths was introduced in Wire 2.0. for path in self._calculate_proto_paths(target): args.append("--proto_path={0}".format(path)) args.extend(relative_sources) return args