diff --git a/build/typescript-model/generate-metadata.py b/build/typescript-model/generate-metadata.py new file mode 100644 index 000000000..07e7ef8c0 --- /dev/null +++ b/build/typescript-model/generate-metadata.py @@ -0,0 +1,106 @@ +# +# Copyright (c) 2021 Red Hat, Inc. +# This program and the accompanying materials are made +# available under the terms of the Eclipse Public License 2.0 +# which is available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# Red Hat, Inc. - initial API and implementation +# + +import os +import argparse +import yaml + + +def write_contents(filename: str, mode: str, contents: str) -> None: + """ + Write the string to the specified filename + """ + with open(filename, mode) as out: + out.write(contents) + + +def get_crd_metadata(output_path: str) -> None: + """ + Read in the devworkspace and devworkspace template crds and generate metadata into api/apis.ts + """ + crd_path = "crds" + typescript_contents = "" + devworkspace_crd_path = os.path.join(crd_path, 'workspace.devfile.io_devworkspaces.yaml') + with open(devworkspace_crd_path, 'r') as devfile_file: + yaml_data = yaml.load(devfile_file, Loader=yaml.FullLoader) + spec, group, kind, plural, singular, versions, latest_version, latest_api_version = extract_fields(yaml_data) + typescript_contents += generate_typescript(latest_api_version, group, kind, plural, singular, versions, + latest_version) + + devworkspacetemplate_crd_path = os.path.join(crd_path, 'workspace.devfile.io_devworkspacetemplates.yaml') + with open(devworkspacetemplate_crd_path, 'r') as devfile_file: + yaml_data = yaml.load(devfile_file, Loader=yaml.FullLoader) + spec, group, kind, plural, singular, versions, latest_version, latest_api_version = extract_fields(yaml_data) + typescript_contents += generate_typescript(latest_api_version, group, kind, plural, singular, versions, + latest_version) + + write_contents(os.path.join(output_path, "constants", "constants.ts"), "w", typescript_contents) + + +def extract_fields(yaml_data: {}) -> (str, str, str, str, str, [], str, str): + """ + Extract metadata from the crds + """ + spec = yaml_data['spec'] + group = spec['group'] + kind = spec['names']['kind'] + plural = spec['names']['plural'] + singular = spec['names']['singular'] + versions = [version['name'] for version in spec['versions']] + latest_version = versions[len(versions) - 1] + latest_api_version = "{}/{}".format(group, latest_version) + return spec, group, kind, plural, singular, versions, latest_version, latest_api_version + + +def generate_typescript(api_version: str, group: str, kind: str, plural: str, singular: str, versions: [], + latest_version: str) -> str: + """ + Export a string representation of the typescript + """ + return f""" +export const {singular + "ApiVersion"} = '{api_version}'; +export const {singular + "Group"} = '{group}'; +export const {singular + "Kind"} = '{kind}'; +export const {singular + "Plural"} = '{plural}'; +export const {singular + "Singular"} = '{singular}'; +export const {singular + "Versions"} = {versions}; +export const {singular + "LatestVersion"} = '{latest_version}'; + """ + + +def export_typescript_api(output_path: str) -> None: + """ + Export constants into api.ts + """ + export_contents = """ +export * from './constants/constants'; + """ + write_contents(os.path.join(output_path, "api.ts"), "a", export_contents) + + +if __name__ == "__main__": + # Get any additional metadata we can from the crds + parser = argparse.ArgumentParser(description='Generate metadata from crds') + parser.add_argument('-p', '--path', action='store', type=str, help='The path to the constants directory') + + args = parser.parse_args() + if not args.path: + parser.print_help() + parser.exit() + + path = args.path + + # Grab the metadata from the crds and put it into constants/constant.ts in typescript-model + get_crd_metadata(path) + + # Export constants/constant.ts so that you can import constants from the package + export_typescript_api(path) diff --git a/build/typescript-model/generate-swagger-json.py b/build/typescript-model/generate-swagger-json.py index abfca46de..5ccef45a0 100644 --- a/build/typescript-model/generate-swagger-json.py +++ b/build/typescript-model/generate-swagger-json.py @@ -13,6 +13,7 @@ import os import json + def write_json(filename: str, object: dict) -> None: """ Write the json object to the specified filename @@ -20,13 +21,14 @@ def write_json(filename: str, object: dict) -> None: with open(filename, 'w') as out: json.dump(object, out, sort_keys=False, indent=2, separators=(',', ': '), ensure_ascii=True) + def create_ref(path): """ Create a json definition reference to a specific path """ return '#/definitions/' + path -def consolidate_schemas() -> object: +def consolidate_schemas() -> dict: """ Consolidate all schemas into one json object """ diff --git a/build/typescript-model/generate.sh b/build/typescript-model/generate.sh index dd1b2ef9a..18e6c27f6 100755 --- a/build/typescript-model/generate.sh +++ b/build/typescript-model/generate.sh @@ -37,7 +37,7 @@ EOF sed -i 's/\"license\": \".*\"/"license": "EPL-2.0"/g' $WORK_DIR/typescript-models/package.json sed -i 's/\"@types\/bluebird\": \".*\"/"@types\/bluebird": "3.5.21"/g' $WORK_DIR/typescript-models/package.json echo "" > $WORK_DIR/typescript-models/.npmignore - echo "[INFO] Generated typescript model which now is availalbe in $WORK_DIR/typescript-models" + echo "[INFO] Generated typescript model which now is available in $WORK_DIR/typescript-models" } generate_swagger_json() { @@ -49,6 +49,13 @@ generate_swagger_json() { echo "[INFO] Generating Swagger JSON. It's in $WORK_DIR/typescript-models/swagger.json.unprocessed" } +generate_typescript_metadata() { + echo "[INFO] Generating typescript constants from crds ..." + mkdir -p $WORK_DIR/typescript-models/constants + python3 $SCRIPT_DIR/generate-metadata.py -p $WORK_DIR/typescript-models + echo "[INFO] Finished generating typescript constant from crds. They are available in $WORK_DIR/typescript-models/constants" +} + build_typescript_model() { echo "[INFO] Verify that generated model is buildable..." cd $WORK_DIR/typescript-models @@ -58,6 +65,7 @@ build_typescript_model() { generate_swagger_json k8s_client_gen +generate_typescript_metadata build_typescript_model echo "[INFO] Typescript model is successfully generated and verified."