def test_env_or_val(env_var, default, args, typ, kwargs, set_env_to, expected): if set_env_to is None: if env_var in os.environ: del os.environ[env_var] else: os.environ[env_var] = set_env_to assert env_or_val(env_var, default, *args, __type=typ, **kwargs) == expected
import logging import click import jsonpath_ng from apigentools.commands.command import Command, run_command_with_config from apigentools.utils import env_or_val log = logging.getLogger(__name__) @click.group(invoke_without_command=True) @click.option( "-f", "--full-spec-file", default=env_or_val("APIGENTOOLS_FULL_SPEC_FILE", "full_spec.yaml"), help= "Name of the OpenAPI full spec file to write (default: 'full_spec.yaml'). " + "Note that if some languages override config's spec_sections, additional " + "files will be generated with name pattern 'full_spec.<lang>.yaml'", ) @click.option( "-L", "--list-languages", is_flag=True, help="List only what languages are supported", ) @click.option("-V", "--list-versions", is_flag=True,
def get_cli_parser(): p = argparse.ArgumentParser( description= "Manipulate OpenAPI specs and generate code using openapi-generator", ) p.add_argument( '--git-via-https', action='store_true', default=env_or_val('APIGENTOOLS_GIT_VIA_HTTPS', False, __type=bool), help= 'Use HTTPS for interacting with the git repositories. Otherwise use SSH.' ) p.add_argument( "-r", "--spec-repo-dir", default=env_or_val("APIGENTOOLS_SPEC_REPO_DIR", "."), help="Switch to this directory before doing anything else", ) p.add_argument( "-c", "--config-dir", default=env_or_val("APIGENTOOLS_CONFIG_DIR", constants.DEFAULT_CONFIG_DIR), help="Path to config directory (default: '{}')".format( constants.DEFAULT_CONFIG_DIR), ) p.add_argument( "-v", "--verbose", default=env_or_val("APIGENTOOLS_VERBOSE", False, __type=bool), action='store_true', help="Whether or not to log the generation in verbose mode", ) p.add_argument( "-g", "--generated-code-dir", default=env_or_val("APIGENTOOLS_GENERATED_CODE_DIR", constants.DEFAULT_GENERATED_CODE_DIR), help= "Path to directory where to save the generated source code (default: '{}')" .format(constants.DEFAULT_GENERATED_CODE_DIR), ) p.add_argument( "-l", "--languages", action="append", default=env_or_val("APIGENTOOLS_LANG", None), help= "The language to run the specified action against. These must match what the config in the spec repo contains. Ex: 'apigentools -l go -l java test' (Default: None to run all)", ) p.add_argument( "-av", "--api-versions", action="append", default=env_or_val("APIGENTOOLS_API_VERSION", None), help= "The API version to run the specified action against. These must match what the config in the spec repo contains. Ex: 'apigentools -av v1 -av v2 test' (Default: None to run all)", ) sp = p.add_subparsers(dest="action", required=True) generate_parser = sp.add_parser("generate", help="Generate client code") generate_parser.add_argument( "-s", "--spec-dir", default=env_or_val("APIGENTOOLS_SPEC_DIR", constants.DEFAULT_SPEC_DIR), help="Path to directory with OpenAPI specs (default: '{}')".format( constants.DEFAULT_SPEC_DIR), ) generate_parser.add_argument( '--clone-repo', action='store_true', default=env_or_val('APIGENTOOLS_SKIP_PULL_REPO', False, __type=bool), help= "When specified, generate the client without first cloning the target repository", ) generate_parser.add_argument( "-f", "--full-spec-file", default=env_or_val("APIGENTOOLS_FULL_SPEC_FILE", "full_spec.yaml"), help= "Name of the OpenAPI full spec file to write (default: 'full_spec.yaml')", ) generate_parser.add_argument( "--additional-stamp", nargs="*", help= "Additional components to add to the 'apigentoolsStamp' variable passed to templates", default=env_or_val("APIGENTOOLS_ADDITIONAL_STAMP", [], __type=list), ) generate_parser.add_argument( "-i", "--generated-with-image", default=env_or_val("APIGENTOOLS_IMAGE", None), help= "Override the tag of the image with which the client code was generated", ) generate_parser.add_argument( "-d", "--downstream-templates-dir", default=env_or_val("APIGENTOOLS_DOWNSTREAM_TEMPLATES_DIR", constants.DEFAULT_DOWNSTREAM_TEMPLATES_DIR), help="Path to directory with downstream templates (default: '{}')". format(constants.DEFAULT_DOWNSTREAM_TEMPLATES_DIR), ) template_group = generate_parser.add_mutually_exclusive_group() template_group.add_argument( "-t", "--template-dir", default=env_or_val("APIGENTOOLS_TEMPLATES_DIR", constants.DEFAULT_TEMPLATES_DIR), help= "Path to directory with processed upstream templates (default: '{}')". format(constants.DEFAULT_TEMPLATES_DIR), ) template_group.add_argument( "--builtin-templates", action="store_true", default=False, help="Use unpatched upstream templates", ) templates_parser = sp.add_parser( "templates", help="Get upstream templates and apply downstream patches", ) templates_parser.add_argument( "-o", "--output-dir", default=env_or_val("APIGENTOOLS_TEMPLATES_DIR", constants.DEFAULT_TEMPLATES_DIR), help= "Path to directory where to put processed upstream templates (default: {})" .format(constants.DEFAULT_TEMPLATES_DIR), ) templates_parser.add_argument( "-p", "--template-patches-dir", default=env_or_val("APIGENTOOLS_TEMPLATE_PATCHES_DIR", constants.DEFAULT_TEMPLATE_PATCHES_DIR), help="Directory with patches for upstream templates (default: '{}')". format(constants.DEFAULT_TEMPLATE_PATCHES_DIR), ) templates_source = templates_parser.add_subparsers( dest="templates_source", required=True, help="Source of upstream templates") jar_parser = templates_source.add_parser( "openapi-jar", help="Obtain upstream templates from openapi-generator jar", ) jar_parser.add_argument( "jar_path", nargs="?", default=env_or_val("APIGENTOOLS_OPENAPI_JAR", constants.OPENAPI_JAR), help="Path to openapi-generator jar file", ) local_parser = templates_source.add_parser( "local-dir", help= "Obtain upstream templates from a local directory (e.g. an openapi-generator git checkout)", ) local_parser.add_argument( "local_path", help="Path to directory with openapi-generator upstream templates", ) git_parser = templates_source.add_parser( "openapi-git", help="Obtain upstream templates from openapi-generator git repository", ) git_parser.add_argument( "-u", "--repo_url", default=constants.OPENAPI_GENERATOR_GIT, help="URL of the openapi-generator repo (default: '{}')".format( constants.OPENAPI_GENERATOR_GIT), ) git_parser.add_argument( "git_committish", default="master", nargs="?", help= "Git 'committish' to check out before obtaining templates (default: 'master')" ) validate_parser = sp.add_parser( "validate", help="Validate OpenAPI spec", ) # these are duplicated with generate_parser, we should deduplicate validate_parser.add_argument( "-s", "--spec-dir", default=env_or_val("APIGENTOOLS_SPEC_DIR", constants.DEFAULT_SPEC_DIR), help="Path to directory with OpenAPI specs (default: '{}')".format( constants.DEFAULT_SPEC_DIR), ) validate_parser.add_argument( "-f", "--full-spec-file", default=env_or_val("APIGENTOOLS_FULL_SPEC_FILE", "full_spec.yaml"), help= "Name of the OpenAPI full spec file to write (default: 'full_spec.yaml')", ) test_parser = sp.add_parser("test", help="Run tests for generated source code") test_parser.add_argument( "--no-cache", action="store_true", default=env_or_val("APIGENTOOLS_TEST_BUILD_NO_CACHE", False, __type=bool), help="Build test image with --no-cache option", ) test_parser.add_argument( "-g", "--generated-code-dir", default=env_or_val("APIGENTOOLS_GENERATED_CODE_DIR", constants.DEFAULT_GENERATED_CODE_DIR), help= "Path to directory where to save the generated source code (default: '{}')" .format(constants.DEFAULT_GENERATED_CODE_DIR), ) test_parser.add_argument( "--container-env", nargs="*", default=env_or_val("APIGENTOOLS_CONTAINER_ENV", [], __type=list), help= "Additional environment variables to pass to containers running the tests, " + "for example `--container-env API_KEY=123 OTHER_KEY=234`. Note that apigentools " + "contains additional logic to treat these values as sensitive and avoid logging " + "them during runtime. (NOTE: if the testing container itself prints this value, " + "it *will* be logged as part of the test output by apigentools).") split_parser = sp.add_parser( "split", help="Split single OpenAPI spec file into multiple files") split_parser.add_argument( "-i", "--input-file", required=True, help="Path to the OpenAPI full spec file to split", ) split_parser.add_argument( "-s", "--spec-dir", default=env_or_val("APIGENTOOLS_SPEC_DIR", constants.DEFAULT_SPEC_DIR), help="Path to directory with OpenAPI specs (default: '{}')".format( constants.DEFAULT_SPEC_DIR), ) split_parser.add_argument( "-v", "--api-version", default=env_or_val("APIGENTOOLS_SPLIT_SPEC_VERSION", "v1"), help="Version of API that the input spec describes (default: 'v1')", ) push_parser = sp.add_parser( "push", help= "Push the generated source code into each git repository specified in the config", ) push_parser.add_argument( '--push-commit-msg', help= 'Message to use for the commit when pushing the auto generated clients', default=env_or_val("APIGENTOOLS_COMMIT_MSG", '')) init_parser = sp.add_parser( "init", help="Initialize a new spec repo", ) init_parser.add_argument( "projectdir", help= "Directory to create the new project in (will be created if it doesn't exist)", ) init_parser.add_argument( "-g", "--no-git-repo", help="Don't initialize a git repository in the project directory", default=False, action="store_true", ) return p
import time import click from apigentools.commands.command import Command, run_command_with_config from apigentools.utils import change_cwd, get_current_commit, run_command, env_or_val log = logging.getLogger(__name__) @click.command() @click.option( "--default-branch", help= "Default branch of client repo - if it doesn't exist, it will be created and pushed to instead of a new feature branch", default=env_or_val("APIGENTOOLS_DEFAULT_PUSH_BRANCH", "master"), ) @click.option( "--dry-run", help="Do a dry run of push (don't actually create and push new branches)", is_flag=True, default=False, ) @click.option( "--push-commit-msg", help= "Message to use for the commit when pushing the auto generated clients", default=env_or_val("APIGENTOOLS_COMMIT_MSG", ""), ) @click.option( "--skip-if-no-changes",
import subprocess import click from apigentools.commands.command import Command, run_command_with_config from apigentools.constants import REDACTED_OUT_SECRET from apigentools.utils import run_command, env_or_val log = logging.getLogger(__name__) @click.command() @click.option( "--no-cache", is_flag=True, default=env_or_val("APIGENTOOLS_TEST_BUILD_NO_CACHE", False, __type=bool), help="Build test image with --no-cache option", ) @click.option( "--container-env", multiple=True, default=env_or_val("APIGENTOOLS_CONTAINER_ENV", [], __type=list), help= "Additional environment variables to pass to containers running the tests, " + "for example `--container-env API_KEY=123 --container-env OTHER_KEY=234`. Note that apigentools " + "contains additional logic to treat these values as sensitive and avoid logging " + "them during runtime. (NOTE: if the testing container itself prints this value, " + "it *will* be logged as part of the test output by apigentools).",
write_full_spec, env_or_val, change_cwd, ) log = logging.getLogger(__name__) REPO_SSH_URL = "[email protected]:{}/{}.git" REPO_HTTPS_URL = "https://{}github.com/{}/{}.git" @click.command() @click.option( "--clone-repo", is_flag=True, default=env_or_val("APIGENTOOLS_PULL_REPO", False, __type=bool), help= "When specified, clones the client repository before running code generation", ) @click.option( "--branch", default=env_or_val("APIGENTOOLS_PULL_REPO_BRANCH", None), help= "When specified, changes the client repository branch before running code generation", ) @click.option( "--is-ancestor", default=env_or_val("APIGENTOOLS_IS_ANCESTOR", None), help= "Checks that the --branch is ancestor of specified base branch (default: None). " "Useful to enforce in CI that the feature branch is on top of master branch: "
from apigentools import constants from apigentools.commands.command import Command, run_command_with_config from apigentools.commands.validate import ValidateCommand from apigentools.constants import HEADER_FILE_NAME, SHARED_FILE_NAME from apigentools.utils import env_or_val log = logging.getLogger(__name__) @click.command() @click.argument("input-file") @click.option( "-v", "--api-version", default=env_or_val("APIGENTOOLS_SPLIT_SPEC_VERSION", "v1"), help="Version of API that the input spec describes (default: 'v1')", ) @click.pass_context def split(ctx, **kwargs): """Split single specified input-file OpenAPI spec file into multiple files""" run_command_with_config(SplitCommand, ctx, **kwargs) class SplitCommand(Command): def get_shared_section_name(self): return os.path.splitext(SHARED_FILE_NAME)[0] def deduplicate_tags(self, all_sections, all_tags): """Find all tags that appear in more than one section and move them to the ``shared`` section.