コード例 #1
0
    def run(self):
        cmd_result = 0
        versions = self.args.api_versions or self.config.spec_versions
        for version in versions:
            fs_path = write_full_spec(self.config, self.args.spec_dir, version,
                                      self.args.full_spec_file)
            if not self.validate_spec(fs_path):
                cmd_result = 1

        return cmd_result
コード例 #2
0
def test_write_full_spec_section_not_found(tmpdir):
    specdir = tmpdir.mkdir("spec")
    v1dir = specdir.mkdir("v1")
    header = str(v1dir.join("header.yaml"))
    nope = str(v1dir.join("nope.yaml"))

    with open(header, "w") as f:
        f.write("{}")

    with pytest.raises(SpecSectionNotFoundError) as e:
        write_full_spec(
            str(specdir),
            "v1",
            ["header.yaml", "nope.yaml"],
            str(v1dir.join("full.yaml")),
        )
    assert (str(
        e.value
    ) == f"Spec section 'nope.yaml' not found for api version 'v1' ({nope})")
コード例 #3
0
ファイル: generate.py プロジェクト: enbashi/apigentools
    def run(self):
        fs_paths = {}

        versions = self.args.api_versions or self.config.spec_versions
        languages = self.args.languages or self.config.languages
        pull_repo = self.args.clone_repo

        # first, generate full spec for all major versions of the API
        for version in versions:
            fs_paths[version] = write_full_spec(self.config,
                                                self.args.spec_dir, version,
                                                self.args.full_spec_file)

        missing_templates = self.get_missing_templates(languages)
        if missing_templates and not self.args.builtin_templates:
            log.error(
                "Missing templates for %s; please run `apigentools templates` first",
                ", ".join(missing_templates))
            return 1

        # cache codegen version
        if self.get_codegen_version() is None:
            log.error("Failed to get codegen version, exiting")
            return 1

        # now, for each language generate a client library for every major version that is explicitly
        # listed in its settings (meaning that we can have languages that don't support all major
        # API versions)
        for language in languages:
            language_config = self.config.get_language_config(language)

            # Clone the language target repo into the output directory
            if pull_repo:
                self.pull_repository(language_config)

            for version in language_config.spec_versions:
                log.info("Generation in %s, spec version %s", language,
                         version)
                language_oapi_config_path = os.path.join(
                    self.args.config_dir, LANGUAGE_OAPI_CONFIGS,
                    "{lang}_{v}.json".format(lang=language, v=version))
                with open(language_oapi_config_path) as lcp:
                    language_oapi_config = json.load(lcp)
                version_output_dir = self.get_generated_lang_version_dir(
                    language, version)

                generate_cmd = [
                    self.config.codegen_exec,
                    "generate",
                    "--http-user-agent",
                    "{c}/{v}/{l}".format(
                        c=self.config.user_agent_client_name,
                        v=self.get_version_from_lang_oapi_config(
                            language_oapi_config),
                        l=language),
                    "-g",
                    language,
                    "-c",
                    language_oapi_config_path,
                    "-i",
                    fs_paths[version],
                    "-o",
                    version_output_dir,
                    "--additional-properties",
                    "apigentoolsStamp='{stamp}'".format(
                        stamp=self.get_stamp()),
                ]

                if not self.args.builtin_templates:
                    generate_cmd.extend(
                        ["-t",
                         os.path.join(self.args.template_dir, language)])

                os.makedirs(version_output_dir, exist_ok=True)
                self.run_language_commands(language, "pre", version_output_dir)

                run_command(generate_cmd,
                            additional_env=language_config.command_env)

                self.run_language_commands(language, "post",
                                           version_output_dir)

                self.render_downstream_templates(
                    language,
                    self.args.downstream_templates_dir,
                )

            # Write the apigentools.info file once per language
            # after each nested folder has been created
            self.write_dot_apigentools_info(language)

        return 0
コード例 #4
0
ファイル: generate.py プロジェクト: DataDog/apigentools
    def run(self):
        info = collections.defaultdict(dict)
        fs_files = set()

        # first, generate full spec for all major versions of the API
        for language, version, fs_file in self.yield_lang_version_specfile():
            info[language][version] = fs_file

            if fs_file in fs_files:
                log.info(f"Reuse {fs_file} for {language} and {version}")
                continue
            fs_files.add(fs_file)

            # Generate full spec file is needed
            write_full_spec(
                constants.SPEC_REPO_SPEC_DIR,
                version,
                self.config.get_language_config(language).spec_sections_for(
                    version),
                fs_file,
            )
            log.info(f"Generated {fs_file} for {language}/{version}")

        pull_repo = self.args.get("clone_repo")

        # now, for each language generate a client library for every major version that is explicitly
        # listed in its settings (meaning that we can have languages that don't support all major
        # API versions)
        for language, versions in info.items():
            language_config = self.config.get_language_config(language)
            general_chevron_vars = language_config.chevron_vars_for()
            general_chevron_vars["stamp"] = self.get_stamp()

            # Clone the language target repo into the output directory
            if pull_repo:
                self.pull_repository(language_config,
                                     branch=self.args.get("branch"))

            if self.args.get("delete_generated_files"):
                self.remove_generated_files(language_config)

            for version, input_spec in versions.items():
                if self.args.get("skip_templates"):
                    log.info("Skipping templates processing for {}/{}".format(
                        language, version))
                else:
                    tpl_cmd_args = copy.deepcopy(self.args)
                    tpl_cmd_args["languages"] = [language]
                    tpl_cmd_args["api_versions"] = [version]
                    template_cmd = TemplatesCommand(self.config, tpl_cmd_args)
                    retval = template_cmd.run()
                    if retval != 0:
                        return retval
                log.info("Generation in %s/%s", language, version)
                version_output_dir = language_config.generated_lang_version_dir_for(
                    version)
                os.makedirs(version_output_dir, exist_ok=True)
                self.run_language_commands(
                    language,
                    version,
                    version_output_dir,
                    language_config.chevron_vars_for(version, input_spec),
                )
                self.write_dot_apigentools_info(language_config, version)

            self.render_downstream_templates(
                language_config, language_config.chevron_vars_for())

        return 0
コード例 #5
0
def test_write_full_spec(tmpdir):
    s1 = {
        "components": {
            "schemas": {
                "MySchema": {
                    "type": "object",
                },
            },
        },
        "paths": {
            "/api/v1/foo": {
                "get": {
                    "operationId": "getFoo",
                    "summary": "get",
                },
            },
        },
    }
    s2 = {
        "components": {
            "schemas": {
                "MyOtherSchema": {
                    "type": "string",
                },
            },
        },
        "paths": {
            "/api/v1/foo": {  # add a new operation to the same path
                "post": {
                    "operationId": "postFoo",
                    "summary": "post",
                },
            },
        },
    }
    header = {
        "servers": [{
            "url": "http://base.url"
        }],
    }

    expected = {
        "components": {
            "callbacks": {},
            "examples": {},
            "headers": {},
            "links": {},
            "parameters": {},
            "requestBodies": {},
            "responses": {},
            "schemas": {
                "MySchema": {
                    "type": "object",
                },
                "MyOtherSchema": {
                    "type": "string",
                },
            },
            "securitySchemes": {},
        },
        "paths": {
            "/api/v1/foo": {
                "get": {
                    "operationId": "getFoo",
                    "summary": "get",
                },
                "post": {
                    "operationId": "postFoo",
                    "summary": "post",
                },
            },
        },
        "security": [],
        "servers": [{
            "url": "http://base.url"
        }],
        "tags": [],
    }
    specdir = tmpdir.mkdir("spec")
    versiondir = specdir.mkdir("v1")
    p1 = os.path.join(str(versiondir), "s1.yaml")
    p2 = os.path.join(str(versiondir), "s2.yaml")
    header_file = os.path.join(str(versiondir), "header.yaml")

    with open(p1, "w") as f:
        yaml.dump(s1, f)

    with open(p2, "w") as f:
        yaml.dump(s2, f)

    with open(header_file, "w") as f:
        yaml.dump(header, f)

    written = write_full_spec(
        str(specdir),
        "v1",
        ["header.yaml", "s1.yaml", "s2.yaml"],
        os.path.join(str(versiondir), "full.yaml"),
    )

    with open(written, "r") as f:
        assert yaml.load(f) == expected