Esempio n. 1
0
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
Esempio n. 2
0
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,
Esempio n. 3
0
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
Esempio n. 4
0
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",
Esempio n. 5
0
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).",
Esempio n. 6
0
    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: "
Esempio n. 7
0
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.