diff --git a/artman/cli/main.py b/artman/cli/main.py index d5beb5f0..d82911f9 100644 --- a/artman/cli/main.py +++ b/artman/cli/main.py @@ -179,6 +179,11 @@ def parse_args(*args): type=str, help='[Required] Name of the artifact for artman to generate. Must ' 'match an artifact in the artman config yaml.') + parser_generate.add_argument( + '--aspect', + type=str, + default=None, + help='[Optional] Aspect of output to generate: ALL, CODE, or PACKAGE') # `publish` sub-command. parser_publish = subparsers.add_parser('publish', help='Publish artifact') @@ -187,6 +192,11 @@ def parse_args(*args): type=str, help='[Required] Name of the artifact for artman to generate. Must ' 'match an artifact in the artman config yaml.') + parser_publish.add_argument( + '--aspect', + type=str, + default=None, + help='[Optional] Aspect of output to generate: ALL, CODE, or PACKAGE') parser_publish.add_argument( '--target', type=str, @@ -276,7 +286,7 @@ def normalize_flags(flags, user_config): try: artifact_config = loader.load_artifact_config( - artman_config_path, flags.artifact_name) + artman_config_path, flags.artifact_name, flags.aspect) except ValueError as ve: logger.error('Artifact config loading failed with `%s`' % ve) sys.exit(96) @@ -292,6 +302,7 @@ def normalize_flags(flags, user_config): # Set the pipeline artifact_type = artifact_config.type pipeline_args['artifact_type'] = Artifact.Type.Name(artifact_type) + pipeline_args['aspect'] = Artifact.Aspect.Name(artifact_config.aspect) if artifact_type == Artifact.GAPIC_ONLY: pipeline_name = 'GapicOnlyClientPipeline' pipeline_args['language'] = language diff --git a/artman/config/loader.py b/artman/config/loader.py index 2b874c6b..46ced6e3 100644 --- a/artman/config/loader.py +++ b/artman/config/loader.py @@ -54,7 +54,7 @@ } -def load_artifact_config(artman_config_path, artifact_name): +def load_artifact_config(artman_config_path, artifact_name, aspect=None): artman_config = _read_artman_config(artman_config_path) artifact_config = Artifact() artifact_config.CopyFrom(artman_config.common) @@ -70,6 +70,9 @@ def load_artifact_config(artman_config_path, artifact_name): loaded_artifact.MergeFrom(artifact) break + if aspect: + loaded_artifact.aspect = Artifact.Aspect.Value(aspect) + artifact_config.MergeFrom(loaded_artifact) _validate_artifact_config(artifact_config) return _normalize_artifact_config( diff --git a/artman/config/proto/config.proto b/artman/config/proto/config.proto index 73cfbe7b..cf67d2a3 100644 --- a/artman/config/proto/config.proto +++ b/artman/config/proto/config.proto @@ -207,7 +207,7 @@ message Artifact { // This artifact type will only generate a GRPC library without GAPIC layer. GRPC = 2; - // This artifact type will generate a protobuf library using protobuf + // This artifact type will generate a protobuf library using the protobuf // compiler. PROTOBUF = 3; @@ -326,4 +326,17 @@ message Artifact { // Discovery Document. The path can be an absolute path or a path relative // to the artman config yaml. string discovery_doc = 16; + + enum Aspect { + // Generate both the code and packaging files for a library + ALL = 0; + + // Generate only the code for a library + CODE = 1; + + // Generate only the packaging files for a library + PACKAGE = 2; + } + + Aspect aspect = 17; } diff --git a/artman/config/proto/config_pb2.py b/artman/config/proto/config_pb2.py index 1d432224..56d3101e 100644 --- a/artman/config/proto/config_pb2.py +++ b/artman/config/proto/config_pb2.py @@ -19,7 +19,7 @@ package='googleapis.artman', syntax='proto3', serialized_options=None, - serialized_pb=_b('\n\x0c\x63onfig.proto\x12\x11googleapis.artman\"e\n\x06\x43onfig\x12+\n\x06\x63ommon\x18\x01 \x01(\x0b\x32\x1b.googleapis.artman.Artifact\x12.\n\tartifacts\x18\x02 \x03(\x0b\x32\x1b.googleapis.artman.Artifact\"\x83\x0b\n\x08\x41rtifact\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x10\n\x08\x61pi_name\x18\x02 \x01(\t\x12\x13\n\x0b\x61pi_version\x18\x03 \x01(\t\x12\x19\n\x11organization_name\x18\x04 \x01(\t\x12?\n\rrelease_level\x18\x05 \x01(\x0e\x32(.googleapis.artman.Artifact.ReleaseLevel\x12\x17\n\x0fsrc_proto_paths\x18\x06 \x03(\t\x12?\n\nproto_deps\x18\x07 \x03(\x0b\x32+.googleapis.artman.Artifact.ProtoDependency\x12\x44\n\x0ftest_proto_deps\x18\x08 \x03(\x0b\x32+.googleapis.artman.Artifact.ProtoDependency\x12\x14\n\x0cservice_yaml\x18\t \x01(\t\x12\x12\n\ngapic_yaml\x18\n \x01(\t\x12.\n\x04type\x18\x0c \x01(\x0e\x32 .googleapis.artman.Artifact.Type\x12\x36\n\x08language\x18\r \x01(\x0e\x32$.googleapis.artman.Artifact.Language\x12\x43\n\x0fpackage_version\x18\x0e \x01(\x0b\x32*.googleapis.artman.Artifact.PackageVersion\x12\x42\n\x0fpublish_targets\x18\x0f \x03(\x0b\x32).googleapis.artman.Artifact.PublishTarget\x12\x15\n\rdiscovery_doc\x18\x10 \x01(\t\x1a\x33\n\x0fProtoDependency\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nproto_path\x18\x02 \x01(\t\x1a]\n\x0ePackageVersion\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x1c\n\x14grpc_dep_lower_bound\x18\x02 \x01(\t\x12\x1c\n\x14grpc_dep_upper_bound\x18\x03 \x01(\t\x1a\xb7\x02\n\rPublishTarget\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x10\n\x08location\x18\x02 \x01(\t\x12<\n\x04type\x18\x03 \x01(\x0e\x32..googleapis.artman.Artifact.PublishTarget.Type\x12V\n\x12\x64irectory_mappings\x18\x04 \x03(\x0b\x32:.googleapis.artman.Artifact.PublishTarget.DirectoryMapping\x1a;\n\x10\x44irectoryMapping\x12\x0b\n\x03src\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x65st\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\"3\n\x04Type\x12\x1f\n\x1bPUBLISHING_TYPE_UNSPECIFIED\x10\x00\x12\n\n\x06GITHUB\x10\x01\"J\n\x0cReleaseLevel\x12\x1d\n\x19RELEASE_LEVEL_UNSPECIFIED\x10\x00\x12\x06\n\x02GA\x10\x01\x12\x08\n\x04\x42\x45TA\x10\x02\x12\t\n\x05\x41LPHA\x10\x03\"r\n\x04Type\x12\t\n\x05GAPIC\x10\x00\x12\x10\n\x0cGAPIC_CONFIG\x10\x01\x12\x08\n\x04GRPC\x10\x02\x12\x0c\n\x08PROTOBUF\x10\x03\x12\x0e\n\nDISCOGAPIC\x10\x04\x12\x15\n\x11\x44ISCOGAPIC_CONFIG\x10\x05\x12\x0e\n\nGAPIC_ONLY\x10\x63\"m\n\x08Language\x12\x18\n\x14LANGUAGE_UNSPECIFIED\x10\x00\x12\x08\n\x04JAVA\x10\x01\x12\n\n\x06PYTHON\x10\x02\x12\n\n\x06NODEJS\x10\x03\x12\x06\n\x02GO\x10\x04\x12\x07\n\x03PHP\x10\x05\x12\n\n\x06\x43SHARP\x10\x06\x12\x08\n\x04RUBY\x10\x07J\x04\x08\x0b\x10\x0cR\x11import_proto_pathb\x06proto3') + serialized_pb=_b('\n\x0c\x63onfig.proto\x12\x11googleapis.artman\"e\n\x06\x43onfig\x12+\n\x06\x63ommon\x18\x01 \x01(\x0b\x32\x1b.googleapis.artman.Artifact\x12.\n\tartifacts\x18\x02 \x03(\x0b\x32\x1b.googleapis.artman.Artifact\"\xe1\x0b\n\x08\x41rtifact\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x10\n\x08\x61pi_name\x18\x02 \x01(\t\x12\x13\n\x0b\x61pi_version\x18\x03 \x01(\t\x12\x19\n\x11organization_name\x18\x04 \x01(\t\x12?\n\rrelease_level\x18\x05 \x01(\x0e\x32(.googleapis.artman.Artifact.ReleaseLevel\x12\x17\n\x0fsrc_proto_paths\x18\x06 \x03(\t\x12?\n\nproto_deps\x18\x07 \x03(\x0b\x32+.googleapis.artman.Artifact.ProtoDependency\x12\x44\n\x0ftest_proto_deps\x18\x08 \x03(\x0b\x32+.googleapis.artman.Artifact.ProtoDependency\x12\x14\n\x0cservice_yaml\x18\t \x01(\t\x12\x12\n\ngapic_yaml\x18\n \x01(\t\x12.\n\x04type\x18\x0c \x01(\x0e\x32 .googleapis.artman.Artifact.Type\x12\x36\n\x08language\x18\r \x01(\x0e\x32$.googleapis.artman.Artifact.Language\x12\x43\n\x0fpackage_version\x18\x0e \x01(\x0b\x32*.googleapis.artman.Artifact.PackageVersion\x12\x42\n\x0fpublish_targets\x18\x0f \x03(\x0b\x32).googleapis.artman.Artifact.PublishTarget\x12\x15\n\rdiscovery_doc\x18\x10 \x01(\t\x12\x32\n\x06\x61spect\x18\x11 \x01(\x0e\x32\".googleapis.artman.Artifact.Aspect\x1a\x33\n\x0fProtoDependency\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nproto_path\x18\x02 \x01(\t\x1a]\n\x0ePackageVersion\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x1c\n\x14grpc_dep_lower_bound\x18\x02 \x01(\t\x12\x1c\n\x14grpc_dep_upper_bound\x18\x03 \x01(\t\x1a\xb7\x02\n\rPublishTarget\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x10\n\x08location\x18\x02 \x01(\t\x12<\n\x04type\x18\x03 \x01(\x0e\x32..googleapis.artman.Artifact.PublishTarget.Type\x12V\n\x12\x64irectory_mappings\x18\x04 \x03(\x0b\x32:.googleapis.artman.Artifact.PublishTarget.DirectoryMapping\x1a;\n\x10\x44irectoryMapping\x12\x0b\n\x03src\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x65st\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\"3\n\x04Type\x12\x1f\n\x1bPUBLISHING_TYPE_UNSPECIFIED\x10\x00\x12\n\n\x06GITHUB\x10\x01\"J\n\x0cReleaseLevel\x12\x1d\n\x19RELEASE_LEVEL_UNSPECIFIED\x10\x00\x12\x06\n\x02GA\x10\x01\x12\x08\n\x04\x42\x45TA\x10\x02\x12\t\n\x05\x41LPHA\x10\x03\"r\n\x04Type\x12\t\n\x05GAPIC\x10\x00\x12\x10\n\x0cGAPIC_CONFIG\x10\x01\x12\x08\n\x04GRPC\x10\x02\x12\x0c\n\x08PROTOBUF\x10\x03\x12\x0e\n\nDISCOGAPIC\x10\x04\x12\x15\n\x11\x44ISCOGAPIC_CONFIG\x10\x05\x12\x0e\n\nGAPIC_ONLY\x10\x63\"m\n\x08Language\x12\x18\n\x14LANGUAGE_UNSPECIFIED\x10\x00\x12\x08\n\x04JAVA\x10\x01\x12\n\n\x06PYTHON\x10\x02\x12\n\n\x06NODEJS\x10\x03\x12\x06\n\x02GO\x10\x04\x12\x07\n\x03PHP\x10\x05\x12\n\n\x06\x43SHARP\x10\x06\x12\x08\n\x04RUBY\x10\x07\"(\n\x06\x41spect\x12\x07\n\x03\x41LL\x10\x00\x12\x08\n\x04\x43ODE\x10\x01\x12\x0b\n\x07PACKAGE\x10\x02J\x04\x08\x0b\x10\x0cR\x11import_proto_pathb\x06proto3') ) @@ -41,8 +41,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=1171, - serialized_end=1222, + serialized_start=1223, + serialized_end=1274, ) _sym_db.RegisterEnumDescriptor(_ARTIFACT_PUBLISHTARGET_TYPE) @@ -71,8 +71,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=1224, - serialized_end=1298, + serialized_start=1276, + serialized_end=1350, ) _sym_db.RegisterEnumDescriptor(_ARTIFACT_RELEASELEVEL) @@ -113,8 +113,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=1300, - serialized_end=1414, + serialized_start=1352, + serialized_end=1466, ) _sym_db.RegisterEnumDescriptor(_ARTIFACT_TYPE) @@ -159,11 +159,37 @@ ], containing_type=None, serialized_options=None, - serialized_start=1416, - serialized_end=1525, + serialized_start=1468, + serialized_end=1577, ) _sym_db.RegisterEnumDescriptor(_ARTIFACT_LANGUAGE) +_ARTIFACT_ASPECT = _descriptor.EnumDescriptor( + name='Aspect', + full_name='googleapis.artman.Artifact.Aspect', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='ALL', index=0, number=0, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='CODE', index=1, number=1, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='PACKAGE', index=2, number=2, + serialized_options=None, + type=None), + ], + containing_type=None, + serialized_options=None, + serialized_start=1579, + serialized_end=1619, +) +_sym_db.RegisterEnumDescriptor(_ARTIFACT_ASPECT) + _CONFIG = _descriptor.Descriptor( name='Config', @@ -236,8 +262,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=762, - serialized_end=813, + serialized_start=814, + serialized_end=865, ) _ARTIFACT_PACKAGEVERSION = _descriptor.Descriptor( @@ -280,8 +306,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=815, - serialized_end=908, + serialized_start=867, + serialized_end=960, ) _ARTIFACT_PUBLISHTARGET_DIRECTORYMAPPING = _descriptor.Descriptor( @@ -324,8 +350,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1110, - serialized_end=1169, + serialized_start=1162, + serialized_end=1221, ) _ARTIFACT_PUBLISHTARGET = _descriptor.Descriptor( @@ -376,8 +402,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=911, - serialized_end=1222, + serialized_start=963, + serialized_end=1274, ) _ARTIFACT = _descriptor.Descriptor( @@ -492,6 +518,13 @@ message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='aspect', full_name='googleapis.artman.Artifact.aspect', index=15, + number=17, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], @@ -500,6 +533,7 @@ _ARTIFACT_RELEASELEVEL, _ARTIFACT_TYPE, _ARTIFACT_LANGUAGE, + _ARTIFACT_ASPECT, ], serialized_options=None, is_extendable=False, @@ -508,7 +542,7 @@ oneofs=[ ], serialized_start=139, - serialized_end=1550, + serialized_end=1644, ) _CONFIG.fields_by_name['common'].message_type = _ARTIFACT @@ -527,9 +561,11 @@ _ARTIFACT.fields_by_name['language'].enum_type = _ARTIFACT_LANGUAGE _ARTIFACT.fields_by_name['package_version'].message_type = _ARTIFACT_PACKAGEVERSION _ARTIFACT.fields_by_name['publish_targets'].message_type = _ARTIFACT_PUBLISHTARGET +_ARTIFACT.fields_by_name['aspect'].enum_type = _ARTIFACT_ASPECT _ARTIFACT_RELEASELEVEL.containing_type = _ARTIFACT _ARTIFACT_TYPE.containing_type = _ARTIFACT _ARTIFACT_LANGUAGE.containing_type = _ARTIFACT +_ARTIFACT_ASPECT.containing_type = _ARTIFACT DESCRIPTOR.message_types_by_name['Config'] = _CONFIG DESCRIPTOR.message_types_by_name['Artifact'] = _ARTIFACT _sym_db.RegisterFileDescriptor(DESCRIPTOR) diff --git a/artman/pipelines/gapic_generation.py b/artman/pipelines/gapic_generation.py index 7c84bacc..2127b8cb 100644 --- a/artman/pipelines/gapic_generation.py +++ b/artman/pipelines/gapic_generation.py @@ -23,7 +23,7 @@ # kwargs required by GAPIC code gen -_GAPIC_REQUIRED = ['service_yaml', 'gapic_yaml', 'language', 'publish'] +_GAPIC_REQUIRED = ['service_yaml', 'gapic_yaml', 'language', 'aspect', 'publish'] _DISCOGAPIC_REQUIRED = ['gapic_yaml', 'language', 'publish'] @@ -77,7 +77,7 @@ class GapicOnlyClientPipeline(code_gen.CodeGenerationPipelineBase): """ def __init__(self, language, **kwargs): super(GapicOnlyClientPipeline, self).__init__( - GapicOnlyTaskFactory(), + GapicOnlyTaskFactory(**kwargs), language=language, **kwargs ) @@ -88,9 +88,6 @@ class GapicClientPipeline(code_gen.CodeGenerationPipelineBase): This is intended to be the only command that needs to run to generate a complete GAPIC. - - Exception: In Java, the GrpcClientPipeline must still be - run explicitly. """ def __init__(self, language, **kwargs): super(GapicClientPipeline, self).__init__( @@ -99,6 +96,7 @@ def __init__(self, language, **kwargs): **kwargs ) + class DiscoGapicClientPipeline(code_gen.CodeGenerationPipelineBase): """The pipeline for generating a complete GAPIC from a Discovery document. @@ -191,9 +189,9 @@ def _get_grpc_codegen_tasks(self, language, **kw): list: A list of Task subclasses defined by the GRPC task factory. """ - # Instantiate the GRPC task factory. - grpc_factory = grpc_gen.GRPC_TASK_FACTORY_DICT[language]() - return grpc_factory.get_grpc_codegen_tasks(language=language, **kw) + grpc_factory = grpc_gen.ProtoGenTaskFactory(gen_grpc=True, + language=language, **kw) + return grpc_factory.get_grpc_codegen_tasks(**kw) def _get_packaging_tasks(self, language, **kw): """Return the code generation tasks for packaging @@ -284,8 +282,8 @@ def get_invalid_kwargs(self): class GapicOnlyTaskFactory(GapicTaskFactory): """A task factory describing GAPIC_ONLY generation tasks.""" - def _get_grpc_codegen_tasks(self, language, **kw): + def _get_grpc_codegen_tasks(self, **kw): return[] - def _get_packaging_tasks(self, language, **kw): + def _get_packaging_tasks(self, **kw): return [] diff --git a/artman/pipelines/grpc_generation.py b/artman/pipelines/grpc_generation.py index bcf66bfc..1a8a0d13 100644 --- a/artman/pipelines/grpc_generation.py +++ b/artman/pipelines/grpc_generation.py @@ -25,17 +25,27 @@ class GrpcClientPipeline(code_gen.CodeGenerationPipelineBase): def __init__(self, **kwargs): super(GrpcClientPipeline, self).__init__( - get_grpc_task_factory(kwargs), **kwargs) + ProtoGenTaskFactory(gen_grpc=True, **kwargs), **kwargs) class ProtoClientPipeline(code_gen.CodeGenerationPipelineBase): def __init__(self, **kwargs): super(ProtoClientPipeline, self).__init__( - get_proto_task_factory(kwargs), **kwargs) + ProtoGenTaskFactory(gen_grpc=False, **kwargs), **kwargs) -class GrpcTaskFactoryBase(code_gen.TaskFactoryBase): +class ProtoGenTaskFactory(code_gen.TaskFactoryBase): + + def __init__(self, gen_grpc, **kwargs): + if 'language' not in kwargs: + raise ValueError('Valid `language` argument required for gRPC codegen') + if 'aspect' not in kwargs: + raise ValueError('Valid `aspect` argument required for gRPC codegen') + self.language = kwargs['language'] + self.gen_grpc = gen_grpc + self.gen_code = kwargs['aspect'] == 'ALL' or kwargs['aspect'] == 'CODE' + self.gen_pkg = kwargs['aspect'] == 'ALL' or kwargs['aspect'] == 'PACKAGE' def get_tasks(self, **kwargs): tasks = self.get_grpc_codegen_tasks(**kwargs) @@ -43,138 +53,70 @@ def get_tasks(self, **kwargs): return task_utils.instantiate_tasks(tasks, kwargs) def get_grpc_codegen_tasks(self, **kwargs): - return [] - - def get_validate_kwargs(self): - return code_gen.COMMON_REQUIRED - - def get_invalid_kwargs(self): - return [] - - -class _RubyGrpcTaskFactory(GrpcTaskFactoryBase): - - def get_grpc_codegen_tasks(self, **kwargs): - return [ - protoc_tasks.ProtoAndGrpcCodeGenTask, - protoc_tasks.RubyGrpcCopyTask, - ] - - -class _JavaGrpcTaskFactory(GrpcTaskFactoryBase): - - def get_grpc_codegen_tasks(self, **kwargs): - return [ - protoc_tasks.ProtoDescGenTask, - protoc_tasks.ProtoCodeGenTask, - protoc_tasks.GrpcCodeGenTask, - package_metadata_tasks.PackageMetadataConfigGenTask, - package_metadata_tasks.ProtoPackageMetadataGenTask, - package_metadata_tasks.GrpcPackageMetadataGenTask, - protoc_tasks.JavaProtoCopyTask, - ] - -class _JavaProtoTaskFactory(GrpcTaskFactoryBase): - - def get_grpc_codegen_tasks(self, **kwargs): - return [ - protoc_tasks.ProtoDescGenTask, - protoc_tasks.ProtoCodeGenTask, - package_metadata_tasks.PackageMetadataConfigGenTask, - package_metadata_tasks.ProtoPackageMetadataGenTask, - protoc_tasks.JavaProtoCopyTask, - ] - - -class _PythonGrpcTaskFactory(GrpcTaskFactoryBase): - - def get_grpc_codegen_tasks(self, **kwargs): - return [ - python_grpc_tasks.PythonChangePackageTask, - protoc_tasks.ProtoDescGenTask, - protoc_tasks.ProtoAndGrpcCodeGenTask, - package_metadata_tasks.PackageMetadataConfigGenTask, - python_grpc_tasks.PythonMoveProtosTask, - ] - - -class _GoGrpcTaskFactory(GrpcTaskFactoryBase): - """Responsible for the protobuf/gRPC flow for Go language.""" - - def get_grpc_codegen_tasks(self, **kwargs): + methods = { + 'java': self._get_grpc_codegen_tasks_java, + 'python': self._get_grpc_codegen_tasks_python, + 'go': self._get_grpc_codegen_tasks_go, + 'ruby': self._get_grpc_codegen_tasks_ruby, + 'php': self._get_grpc_codegen_tasks_php, + 'csharp': self._get_grpc_codegen_tasks_csharp, + 'nodejs': self._get_grpc_codegen_tasks_nodejs + } + return methods[self.language](**kwargs) + + def _get_grpc_codegen_tasks_java(self, **kwargs): + tasks = [protoc_tasks.ProtoDescGenTask] + if self.gen_code: + tasks.append(protoc_tasks.ProtoCodeGenTask) + if self.gen_grpc: + tasks.append(protoc_tasks.GrpcCodeGenTask) + tasks.append(package_metadata_tasks.PackageMetadataConfigGenTask) + if self.gen_pkg: + tasks.append(package_metadata_tasks.ProtoPackageMetadataGenTask) + if self.gen_grpc: + tasks.append(package_metadata_tasks.GrpcPackageMetadataGenTask) + tasks.append(protoc_tasks.JavaProtoCopyTask) + return tasks + + def _get_grpc_codegen_tasks_python(self, **kwargs): + tasks = [python_grpc_tasks.PythonChangePackageTask] + tasks.append(protoc_tasks.ProtoDescGenTask) + if self.gen_code: + tasks.append(protoc_tasks.ProtoAndGrpcCodeGenTask) + if self.gen_pkg: + tasks.append(package_metadata_tasks.PackageMetadataConfigGenTask) + tasks.append(python_grpc_tasks.PythonMoveProtosTask) + return tasks + + def _get_grpc_codegen_tasks_go(self, **kwargs): return [ protoc_tasks.ProtoAndGrpcCodeGenTask, protoc_tasks.GoCopyTask, ] - def get_validate_kwargs(self): - return ['gapic_yaml', 'gapic_code_dir'] + code_gen.COMMON_REQUIRED - - -class _CSharpGrpcTaskFactory(GrpcTaskFactoryBase): - - def get_grpc_codegen_tasks(self, **kwargs): + def _get_grpc_codegen_tasks_ruby(self, **kwargs): return [ - protoc_tasks.ProtoCodeGenTask, - protoc_tasks.GrpcCodeGenTask, + protoc_tasks.ProtoAndGrpcCodeGenTask, + protoc_tasks.RubyGrpcCopyTask, ] - -class _PhpGrpcTaskFactory(GrpcTaskFactoryBase): - - def get_grpc_codegen_tasks(self, **kwargs): + def _get_grpc_codegen_tasks_php(self, **kwargs): return [ protoc_tasks.ProtoAndGrpcCodeGenTask, protoc_tasks.PhpGrpcRenameTask, protoc_tasks.PhpGrpcMoveTask, ] + def _get_grpc_codegen_tasks_csharp(self, **kwargs): + return [protoc_tasks.ProtoCodeGenTask, protoc_tasks.GrpcCodeGenTask] + def _get_grpc_codegen_tasks_nodejs(self, **kwargs): + return [protoc_tasks.NodeJsProtoCopyTask] -class _NodeJsGrpcTaskFactory(GrpcTaskFactoryBase): - - def get_grpc_codegen_tasks(self, **kwargs): - return [ - protoc_tasks.NodeJsProtoCopyTask, - ] - - -GRPC_TASK_FACTORY_DICT = { - 'java': _JavaGrpcTaskFactory, - 'python': _PythonGrpcTaskFactory, - 'go': _GoGrpcTaskFactory, - 'ruby': _RubyGrpcTaskFactory, - 'php': _PhpGrpcTaskFactory, - 'csharp': _CSharpGrpcTaskFactory, - 'nodejs': _NodeJsGrpcTaskFactory, -} - - -PROTO_TASK_FACTORY_DICT = { - 'java': _JavaProtoTaskFactory, -} - - -def get_grpc_task_factory(kwargs): - if 'language' not in kwargs: - raise ValueError('Valid --language argument required for gRPC codegen') - - language = kwargs['language'] - cls = GRPC_TASK_FACTORY_DICT.get(language) - if cls: - return cls() - else: - raise ValueError('No gRPC task factory found for language: ' - + language) - - -def get_proto_task_factory(kwargs): - if 'language' not in kwargs: - raise ValueError('Valid --language argument required for gRPC codegen') + def get_validate_kwargs(self): + if self.language == 'go': + return ['gapic_yaml', 'gapic_code_dir'] + code_gen.COMMON_REQUIRED + else: + return code_gen.COMMON_REQUIRED - language = kwargs['language'] - cls = PROTO_TASK_FACTORY_DICT.get(language) - if cls: - return cls() - else: - raise ValueError('No proto task factory found for language: ' - + language) + def get_invalid_kwargs(self): + return [] diff --git a/artman/tasks/gapic_tasks.py b/artman/tasks/gapic_tasks.py index 486e5be7..7c6e537a 100644 --- a/artman/tasks/gapic_tasks.py +++ b/artman/tasks/gapic_tasks.py @@ -102,7 +102,8 @@ class GapicCodeGenTask(task_base.TaskBase): def execute(self, language, toolkit_path, descriptor_set, service_yaml, gapic_yaml, package_metadata_yaml, - gapic_code_dir, api_name, api_version, organization_name): + gapic_code_dir, api_name, api_version, organization_name, + aspect): existing = glob.glob('%s/*' % gapic_code_dir) if existing: self.exec_command(['rm', '-r'] + existing) @@ -116,8 +117,19 @@ def execute(self, language, toolkit_path, descriptor_set, service_yaml, if service_yaml: args = args + ['--service_yaml=' + os.path.abspath(service_yaml)] args = args + gapic_args + + gapic_artifact = '' + if aspect == 'ALL': + gapic_artifact = 'LEGACY_GAPIC_AND_PACKAGE' + elif aspect == 'CODE': + gapic_artifact = 'GAPIC_CODE' + elif aspect == 'PACKAGE': + gapic_artifact = 'GAPIC_PACKAGE' + else: + raise ValueError('GapicCodeGenTask: no generation turned on') + self.exec_command( - task_utils.gapic_gen_task(toolkit_path, ['LEGACY_GAPIC_AND_PACKAGE'] + args)) + task_utils.gapic_gen_task(toolkit_path, [gapic_artifact] + args)) return gapic_code_dir diff --git a/test/cli/test_main.py b/test/cli/test_main.py index dd781197..3bc0c0d9 100644 --- a/test/cli/test_main.py +++ b/test/cli/test_main.py @@ -45,11 +45,13 @@ def test_minimal_args(self): assert flags.root_dir is '' assert flags.local is False assert flags.artifact_name == 'python_gapic' + assert flags.aspect is None assert flags.image == main.ARTMAN_DOCKER_IMAGE flags = main.parse_args('publish', '--target=staging', 'python_gapic') assert flags.config == 'artman.yaml' assert flags.artifact_name == 'python_gapic' + assert flags.aspect is None assert flags.github_username is None assert flags.github_token is None assert flags.target == 'staging' @@ -65,6 +67,7 @@ def setUp(self): subcommand='generate', github_username='test', github_token='testtoken', artifact_name='python_gapic', + aspect=None, output_dir='./artman-genfiles', dry_run=False, local_repo_dir=None, diff --git a/test/pipelines/test_code_generation.py b/test/pipelines/test_code_generation.py index 20a55261..65db0c97 100644 --- a/test/pipelines/test_code_generation.py +++ b/test/pipelines/test_code_generation.py @@ -45,11 +45,11 @@ def test_do_build_flow(self): with mock.patch.object(CGPB, 'validate_kwargs') as validate: cgpb = CGPB( gapic_generation.GapicTaskFactory(), - language='python', publish='noop' + language='python', publish='noop', aspect='ALL' ) validate.assert_called_once() flow = cgpb.do_build_flow(language='python', publish='noop', - gapic_code_dir='output') + gapic_code_dir='output', aspect='ALL') assert isinstance(flow, linear_flow.Flow) assert len(flow) == 9 @@ -58,11 +58,11 @@ def test_do_build_flow_disco(self): with mock.patch.object(CGPB, 'validate_kwargs') as validate: cgpb = CGPB( gapic_generation.DiscoGapicTaskFactory(), - language='java', publish='noop' + language='java', publish='noop', aspect='ALL' ) validate.assert_called_once() flow = cgpb.do_build_flow(language='java', publish='noop', - gapic_code_dir='output') + gapic_code_dir='output', aspect='ALL') assert isinstance(flow, linear_flow.Flow) assert len(flow) == 6 @@ -71,10 +71,11 @@ def test_do_build_flow_no_gapic(self): with mock.patch.object(CGPB, 'validate_kwargs') as validate: cgpb = CGPB( gapic_generation.GapicTaskFactory(), - language='python', publish='noop' + language='python', publish='noop', aspect='ALL' ) validate.assert_called_once() - flow = cgpb.do_build_flow(language='python', publish='noop') + flow = cgpb.do_build_flow(language='python', publish='noop', + aspect='ALL') assert isinstance(flow, linear_flow.Flow) assert len(flow) == 7 @@ -85,6 +86,7 @@ def test_validation(self, does_not_exist, does_exist): gcpb = code_generation.CodeGenerationPipelineBase(gtf, language='python', publish='noop', + aspect='ALL', ) does_exist.assert_called_once() does_not_exist.assert_called_once() diff --git a/test/pipelines/test_gapic_generation.py b/test/pipelines/test_gapic_generation.py index a2ca5fd1..c6ced50d 100644 --- a/test/pipelines/test_gapic_generation.py +++ b/test/pipelines/test_gapic_generation.py @@ -82,21 +82,3 @@ def test_get_tasks(self): instantiated_tasks = self._gctf.get_tasks() for task, class_ in zip(instantiated_tasks, expected): assert isinstance(task, class_) - - -class GapicTaskFactoryTests(unittest.TestCase): - def test_grpc_codegen_java(self): - gtf = gapic_generation.GapicTaskFactory() - grpc_tf = grpc_generation.GRPC_TASK_FACTORY_DICT['java'] - with mock.patch.object(grpc_tf, 'get_grpc_codegen_tasks') as get: - tasks_ = gtf._get_grpc_codegen_tasks(language='java') - assert tasks_ == get.return_value - get.assert_called_once_with(language='java') - - def test_grpc_codegen_python(self): - gtf = gapic_generation.GapicTaskFactory() - grpc_tf = grpc_generation.GRPC_TASK_FACTORY_DICT['python'] - with mock.patch.object(grpc_tf, 'get_grpc_codegen_tasks') as get: - tasks_ = gtf._get_grpc_codegen_tasks(language='python') - assert tasks_ == get.return_value - get.assert_called_once_with(language='python') diff --git a/test/pipelines/test_grpc_generation.py b/test/pipelines/test_grpc_generation.py index 96932432..c0179840 100644 --- a/test/pipelines/test_grpc_generation.py +++ b/test/pipelines/test_grpc_generation.py @@ -24,25 +24,11 @@ from artman.pipelines import grpc_generation -class GrpcClientPipelineTests(unittest.TestCase): - @mock.patch.object(grpc_generation, 'get_grpc_task_factory') - @mock.patch.object(code_generation.CodeGenerationPipelineBase, '__init__') - def test_constructor(self, cgpb, ggtf): - grpc_generation.GrpcClientPipeline(foo='bar') - cgpb.assert_called_once_with(ggtf(), foo='bar') - - -class ProtoClientPipelineTests(unittest.TestCase): - @mock.patch.object(grpc_generation, 'get_proto_task_factory') - @mock.patch.object(code_generation.CodeGenerationPipelineBase, '__init__') - def test_constructor(self, cgpb, gptf): - grpc_generation.ProtoClientPipeline(foo='bar') - cgpb.assert_called_once_with(gptf(), foo='bar') - - -class GrpcTaskFactoryBaseTests(unittest.TestCase): +class ProtoGenTaskFactoryTests(unittest.TestCase): def setUp(self): - self._gtfb = grpc_generation.GrpcTaskFactoryBase() + self._gtfb = grpc_generation.ProtoGenTaskFactory(gen_grpc=True, + language='java', + aspect='ALL') def test_get_validate_kwargs(self): COMMON_REQUIRED = code_generation.COMMON_REQUIRED diff --git a/test/tasks/test_gapic.py b/test/tasks/test_gapic.py index c207f27d..31bacf61 100644 --- a/test/tasks/test_gapic.py +++ b/test/tasks/test_gapic.py @@ -156,7 +156,8 @@ def test_execute(self, exec_command, check_output): organization_name='google-cloud', package_metadata_yaml='/path/to/pmy.yaml', service_yaml='/path/to/service.yaml', - toolkit_path='/path/to/toolkit' + toolkit_path='/path/to/toolkit', + aspect='ALL', ) expected_cmds = [ ' '.join(['java -cp',