From a3e1164e60cb20da7419538e374d40402c555377 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 16:56:53 +0000 Subject: [PATCH 01/33] chore: move relevant synthtool source into hermetic docker image --- .../library_generation.Dockerfile | 9 - library_generation/owlbot/synthtool/common.py | 52 ++ library_generation/owlbot/synthtool/java.py | 867 ++++++++++++++++++ 3 files changed, 919 insertions(+), 9 deletions(-) create mode 100644 library_generation/owlbot/synthtool/common.py create mode 100644 library_generation/owlbot/synthtool/java.py diff --git a/.cloudbuild/library_generation/library_generation.Dockerfile b/.cloudbuild/library_generation/library_generation.Dockerfile index 9de0bc1c2c..237978d3ff 100644 --- a/.cloudbuild/library_generation/library_generation.Dockerfile +++ b/.cloudbuild/library_generation/library_generation.Dockerfile @@ -17,7 +17,6 @@ FROM gcr.io/cloud-devrel-public-resources/python SHELL [ "/bin/bash", "-c" ] -ARG SYNTHTOOL_COMMITTISH=e36d2f164ca698f0264fb6f79ddc4b0fa024a940 ARG OWLBOT_CLI_COMMITTISH=ac84fa5c423a0069bbce3d2d869c9730c8fdf550 ARG PROTOC_VERSION=25.3 ENV HOME=/home @@ -49,14 +48,6 @@ WORKDIR /src RUN python -m pip install -r requirements.txt RUN python -m pip install . -# install synthtool -WORKDIR /tools -RUN git clone https://github.com/googleapis/synthtool -WORKDIR /tools/synthtool -RUN git checkout "${SYNTHTOOL_COMMITTISH}" -RUN python3 -m pip install --no-deps -e . -RUN python3 -m pip install -r requirements.in - # Install nvm with node and npm ENV NODE_VERSION 20.12.0 WORKDIR /home diff --git a/library_generation/owlbot/synthtool/common.py b/library_generation/owlbot/synthtool/common.py new file mode 100644 index 0000000000..876ca0c79d --- /dev/null +++ b/library_generation/owlbot/synthtool/common.py @@ -0,0 +1,52 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +from pathlib import Path +import re + + +def update_library_version(version: str, root_dir: str): + """ + Rewrites all metadata files in ./samples/generated to the version number argument + + """ + root_dir_path = Path(root_dir) + + snippet_metadata_files = get_sample_metadata_files(root_dir_path) + for file in snippet_metadata_files: + with open(file, "r+") as f: + data = json.load(f) + data["clientLibrary"]["version"] = version + f.seek(0) + json.dump(data, f, indent=4) + f.truncate() + + +def get_sample_metadata_files(dir: Path, regex: str = r"snippet_metadata"): + """ + Walks through samples/generated to find all snippet metadata files, appends them to a list + + Returns: + A list of all metadata files. + """ + metadata_files = [] + for path_object in dir.glob("**/*"): + if path_object.is_file(): + if re.search(regex, str(path_object)): + metadata_files.append(str(Path(path_object).resolve())) + if path_object.is_dir(): + get_sample_metadata_files(path_object) + + return metadata_files diff --git a/library_generation/owlbot/synthtool/java.py b/library_generation/owlbot/synthtool/java.py new file mode 100644 index 0000000000..93eaead612 --- /dev/null +++ b/library_generation/owlbot/synthtool/java.py @@ -0,0 +1,867 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import glob +import os +import xml.etree.ElementTree as ET +import re +import requests +import yaml +import synthtool as s +import synthtool.gcp as gcp +from synthtool import cache, shell +from synthtool.gcp import common, partials, pregenerated, samples, snippets +from synthtool.log import logger +from pathlib import Path +from typing import Any, Optional, Dict, Iterable, List +from datetime import date + +JAR_DOWNLOAD_URL = "https://github.com/google/google-java-format/releases/download/google-java-format-{version}/google-java-format-{version}-all-deps.jar" +DEFAULT_FORMAT_VERSION = "1.7" +CURRENT_YEAR = date.today().year +GOOD_LICENSE = f"""/* + * Copyright {CURRENT_YEAR} Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +""" +PROTOBUF_HEADER = "// Generated by the protocol buffer compiler. DO NOT EDIT!" +BAD_LICENSE = """/\\* + \\* Copyright \\d{4} Google LLC + \\* + \\* Licensed under the Apache License, Version 2.0 \\(the "License"\\); you may not use this file except + \\* in compliance with the License. You may obtain a copy of the License at + \\* + \\* http://www.apache.org/licenses/LICENSE-2.0 + \\* + \\* Unless required by applicable law or agreed to in writing, software distributed under the License + \\* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + \\* or implied. See the License for the specific language governing permissions and limitations under + \\* the License. + \\*/ +""" +DEFAULT_MIN_SUPPORTED_JAVA_VERSION = 8 +METADATA = "metadata" +LIBRARIES_BOM_VERSION = "libraries_bom_version" +LIBRARIES_BOM_VERSION_ENV_KEY = "SYNTHTOOL_LIBRARIES_BOM_VERSION" + + +def format_code( + path: str, version: str = DEFAULT_FORMAT_VERSION, times: int = 2 +) -> None: + """ + Runs the google-java-format jar against all .java files found within the + provided path. + """ + jar_name = f"google-java-format-{version}.jar" + jar = cache.get_cache_dir() / jar_name + if not jar.exists(): + _download_formatter(version, jar) + + # Find all .java files in path and run the formatter on them + files = list(glob.iglob(os.path.join(path, "**/*.java"), recursive=True)) + + # Run the formatter as a jar file + logger.info("Running java formatter on {} files".format(len(files))) + for _ in range(times): + shell.run(["java", "-jar", str(jar), "--replace"] + files) + + +def _download_formatter(version: str, dest: Path) -> None: + logger.info("Downloading java formatter") + url = JAR_DOWNLOAD_URL.format(version=version) + response = requests.get(url) + response.raise_for_status() + with open(dest, "wb") as fh: + fh.write(response.content) + + +HEADER_REGEX = re.compile("\\* Copyright \\d{4} Google LLC") + + +def _file_has_header(path: Path) -> bool: + """Return true if the file already contains a license header.""" + with open(path, "rt") as fp: + for line in fp: + if HEADER_REGEX.search(line): + return True + return False + + +def _filter_no_header(paths: Iterable[Path]) -> Iterable[Path]: + """Return a subset of files that do not already have a header.""" + for path in paths: + anchor = Path(path.anchor) + remainder = str(path.relative_to(path.anchor)) + for file in anchor.glob(remainder): + if not _file_has_header(file): + yield file + + +def fix_proto_headers(proto_root: Path) -> None: + """Helper to ensure that generated proto classes have appropriate license headers. + + If the file does not already contain a license header, inject one at the top of the file. + Some resource name classes may contain malformed license headers. In those cases, replace + those with our standard license header. + """ + s.replace( + _filter_no_header([proto_root / "src/**/*.java"]), + PROTOBUF_HEADER, + f"{GOOD_LICENSE}{PROTOBUF_HEADER}", + ) + # https://github.com/googleapis/gapic-generator/issues/3074 + s.replace( + [proto_root / "src/**/*Name.java", proto_root / "src/**/*Names.java"], + BAD_LICENSE, + GOOD_LICENSE, + ) + + +def fix_grpc_headers(grpc_root: Path, package_name: str = "unused") -> None: + """Helper to ensure that generated grpc stub classes have appropriate license headers. + + If the file does not already contain a license header, inject one at the top of the file. + """ + s.replace( + _filter_no_header([grpc_root / "src/**/*.java"]), + "^package (.*);", + f"{GOOD_LICENSE}package \\1;", + ) + + +def latest_maven_version(group_id: str, artifact_id: str) -> Optional[str]: + """Helper function to find the latest released version of a Maven artifact. + + Fetches metadata from Maven Central and parses out the latest released + version. + + Args: + group_id (str): The groupId of the Maven artifact + artifact_id (str): The artifactId of the Maven artifact + + Returns: + The latest version of the artifact as a string or None + """ + group_path = "/".join(group_id.split(".")) + url = ( + f"https://repo1.maven.org/maven2/{group_path}/{artifact_id}/maven-metadata.xml" + ) + response = requests.get(url) + if response.status_code >= 400: + return "0.0.0" + + return version_from_maven_metadata(response.text) + + +def version_from_maven_metadata(metadata: str) -> Optional[str]: + """Helper function to parse the latest released version from the Maven + metadata XML file. + + Args: + metadata (str): The XML contents of the Maven metadata file + + Returns: + The latest version of the artifact as a string or None + """ + root = ET.fromstring(metadata) + latest = root.find("./versioning/latest") + if latest is not None: + return latest.text + + return None + + +def _common_generation( + service: str, + version: str, + library: Path, + package_pattern: str, + suffix: str = "", + destination_name: str = None, + cloud_api: bool = True, + diregapic: bool = False, + preserve_gapic: bool = False, +): + """Helper function to execution the common generation cleanup actions. + + Fixes headers for protobuf classes and generated gRPC stub services. Copies + code and samples to their final destinations by convention. Runs the code + formatter on the generated code. + + Args: + service (str): Name of the service. + version (str): Service API version. + library (Path): Path to the temp directory with the generated library. + package_pattern (str): Package name template for fixing file headers. + suffix (str, optional): Suffix that the generated library folder. The + artman output differs from bazel's output directory. Defaults to "". + destination_name (str, optional): Override the service name for the + destination of the output code. Defaults to the service name. + preserve_gapic (bool, optional): Whether to preserve the gapic directory + prefix. Default False. + """ + + if destination_name is None: + destination_name = service + + cloud_prefix = "cloud-" if cloud_api else "" + package_name = package_pattern.format(service=service, version=version) + fix_proto_headers( + library / f"proto-google-{cloud_prefix}{service}-{version}{suffix}" + ) + fix_grpc_headers( + library / f"grpc-google-{cloud_prefix}{service}-{version}{suffix}", package_name + ) + + if preserve_gapic: + s.copy( + [library / f"gapic-google-{cloud_prefix}{service}-{version}{suffix}/src"], + f"gapic-google-{cloud_prefix}{destination_name}-{version}/src", + required=True, + ) + else: + s.copy( + [library / f"gapic-google-{cloud_prefix}{service}-{version}{suffix}/src"], + f"google-{cloud_prefix}{destination_name}/src", + required=True, + ) + + s.copy( + [library / f"grpc-google-{cloud_prefix}{service}-{version}{suffix}/src"], + f"grpc-google-{cloud_prefix}{destination_name}-{version}/src", + # For REST-only clients, like java-compute, gRPC artifact does not exist + required=(not diregapic), + ) + s.copy( + [library / f"proto-google-{cloud_prefix}{service}-{version}{suffix}/src"], + f"proto-google-{cloud_prefix}{destination_name}-{version}/src", + required=True, + ) + + if preserve_gapic: + format_code(f"gapic-google-{cloud_prefix}{destination_name}-{version}/src") + else: + format_code(f"google-{cloud_prefix}{destination_name}/src") + format_code(f"grpc-google-{cloud_prefix}{destination_name}-{version}/src") + format_code(f"proto-google-{cloud_prefix}{destination_name}-{version}/src") + + +def gapic_library( + service: str, + version: str, + config_pattern: str = "/google/cloud/{service}/artman_{service}_{version}.yaml", + package_pattern: str = "com.google.cloud.{service}.{version}", + gapic: gcp.GAPICGenerator = None, + destination_name: str = None, + diregapic: bool = False, + preserve_gapic: bool = False, + **kwargs, +) -> Path: + """Generate a Java library using the gapic-generator via artman via Docker. + + Generates code into a temp directory, fixes missing header fields, and + copies into the expected locations. + + Args: + service (str): Name of the service. + version (str): Service API version. + config_pattern (str, optional): Path template to artman config YAML + file. Defaults to "/google/cloud/{service}/artman_{service}_{version}.yaml" + package_pattern (str, optional): Package name template for fixing file + headers. Defaults to "com.google.cloud.{service}.{version}". + gapic (GAPICGenerator, optional): Generator instance. + destination_name (str, optional): Override the service name for the + destination of the output code. Defaults to the service name. + preserve_gapic (bool, optional): Whether to preserve the gapic directory + prefix. Default False. + **kwargs: Additional options for gapic.java_library() + + Returns: + The path to the temp directory containing the generated client. + """ + if gapic is None: + gapic = gcp.GAPICGenerator() + + library = gapic.java_library( + service=service, + version=version, + config_path=config_pattern.format(service=service, version=version), + artman_output_name="", + include_samples=True, + diregapic=diregapic, + **kwargs, + ) + + _common_generation( + service=service, + version=version, + library=library, + package_pattern=package_pattern, + destination_name=destination_name, + diregapic=diregapic, + preserve_gapic=preserve_gapic, + ) + + return library + + +def bazel_library( + service: str, + version: str, + package_pattern: str = "com.google.cloud.{service}.{version}", + gapic: gcp.GAPICBazel = None, + destination_name: str = None, + cloud_api: bool = True, + diregapic: bool = False, + preserve_gapic: bool = False, + **kwargs, +) -> Path: + """Generate a Java library using the gapic-generator via bazel. + + Generates code into a temp directory, fixes missing header fields, and + copies into the expected locations. + + Args: + service (str): Name of the service. + version (str): Service API version. + package_pattern (str, optional): Package name template for fixing file + headers. Defaults to "com.google.cloud.{service}.{version}". + gapic (GAPICBazel, optional): Generator instance. + destination_name (str, optional): Override the service name for the + destination of the output code. Defaults to the service name. + preserve_gapic (bool, optional): Whether to preserve the gapic directory + prefix. Default False. + **kwargs: Additional options for gapic.java_library() + + Returns: + The path to the temp directory containing the generated client. + """ + if gapic is None: + gapic = gcp.GAPICBazel() + + library = gapic.java_library( + service=service, version=version, diregapic=diregapic, **kwargs + ) + + _common_generation( + service=service, + version=version, + library=library / f"google-cloud-{service}-{version}-java", + package_pattern=package_pattern, + suffix="-java", + destination_name=destination_name, + cloud_api=cloud_api, + diregapic=diregapic, + preserve_gapic=preserve_gapic, + ) + + return library + + +def pregenerated_library( + path: str, + service: str, + version: str, + destination_name: str = None, + cloud_api: bool = True, +) -> Path: + """Generate a Java library using the gapic-generator via bazel. + + Generates code into a temp directory, fixes missing header fields, and + copies into the expected locations. + + Args: + path (str): Path in googleapis-gen to un-versioned generated code. + service (str): Name of the service. + version (str): Service API version. + destination_name (str, optional): Override the service name for the + destination of the output code. Defaults to the service name. + cloud_api (bool, optional): Whether or not this is a cloud API (for naming) + + Returns: + The path to the temp directory containing the generated client. + """ + generator = pregenerated.Pregenerated() + library = generator.generate(path) + + cloud_prefix = "cloud-" if cloud_api else "" + _common_generation( + service=service, + version=version, + library=library / f"google-{cloud_prefix}{service}-{version}-java", + package_pattern="unused", + suffix="-java", + destination_name=destination_name, + cloud_api=cloud_api, + ) + + return library + + +def _merge_release_please(destination_text: str): + config = yaml.safe_load(destination_text) + if "handleGHRelease" in config: + return destination_text + + config["handleGHRelease"] = True + + if "branches" in config: + for branch in config["branches"]: + branch["handleGHRelease"] = True + return yaml.dump(config) + + +def _merge_common_templates( + source_text: str, destination_text: str, file_path: Path +) -> str: + # keep any existing pom.xml + if file_path.match("pom.xml") or file_path.match("sync-repo-settings.yaml"): + logger.debug(f"existing pom file found ({file_path}) - keeping the existing") + return destination_text + + if file_path.match("release-please.yml"): + return _merge_release_please(destination_text) + + # by default return the newly generated content + return source_text + + +def _common_template_metadata() -> Dict[str, Any]: + metadata = {} # type: Dict[str, Any] + repo_metadata = common._load_repo_metadata() + if repo_metadata: + metadata["repo"] = repo_metadata + group_id, artifact_id = repo_metadata["distribution_name"].split(":") + + metadata["latest_version"] = latest_maven_version( + group_id=group_id, artifact_id=artifact_id + ) + + metadata["latest_bom_version"] = latest_maven_version( + group_id="com.google.cloud", + artifact_id="libraries-bom", + ) + + metadata["samples"] = samples.all_samples(["samples/**/src/main/java/**/*.java"]) + metadata["snippets"] = snippets.all_snippets( + ["samples/**/src/main/java/**/*.java", "samples/**/pom.xml"] + ) + if repo_metadata and "min_java_version" in repo_metadata: + metadata["min_java_version"] = repo_metadata["min_java_version"] + else: + metadata["min_java_version"] = DEFAULT_MIN_SUPPORTED_JAVA_VERSION + + return metadata + + +def common_templates( + excludes: List[str] = [], + template_path: Optional[Path] = None, + **kwargs, +) -> None: + """Generate common templates for a Java Library + + Fetches information about the repository from the .repo-metadata.json file, + information about the latest artifact versions and copies the files into + their expected location. + + Args: + :param excludes: List of template paths to ignore + :param template_path: + :param kwargs: Additional options for CommonTemplates.java_library() + """ + metadata = _common_template_metadata() + kwargs[METADATA] = metadata + + # Generate flat to tell this repository is a split repo that have migrated + # to monorepo. The owlbot.py in the monorepo sets monorepo=True. + monorepo = kwargs.get("monorepo", False) + kwargs["monorepo"] = monorepo + split_repo = not monorepo + repo_metadata = metadata["repo"] + repo_short = repo_metadata["repo_short"] + if os.getenv(LIBRARIES_BOM_VERSION_ENV_KEY, default=None) is not None: + kwargs[METADATA][LIBRARIES_BOM_VERSION] = os.getenv( + LIBRARIES_BOM_VERSION_ENV_KEY + ) + # Special libraries that are not GAPIC_AUTO but in the monorepo + special_libs_in_monorepo = [ + "java-translate", + "java-dns", + "java-notification", + "java-resourcemanager", + ] + kwargs["migrated_split_repo"] = split_repo and ( + repo_metadata["library_type"] == "GAPIC_AUTO" + or (repo_short and repo_short in special_libs_in_monorepo) + ) + logger.info( + "monorepo: {}, split_repo: {}, library_type: {}," + " repo_short: {}, migrated_split_repo: {}".format( + monorepo, + split_repo, + repo_metadata["library_type"], + repo_short, + kwargs["migrated_split_repo"], + ) + ) + + templates = gcp.CommonTemplates(template_path=template_path).java_library(**kwargs) + + # skip README generation on Kokoro (autosynth) + if os.environ.get("KOKORO_ROOT") is not None: + # README.md is now synthesized separately. This prevents synthtool from deleting the + # README as it's no longer generated here. + excludes.append("README.md") + + s.copy([templates], excludes=excludes, merge=_merge_common_templates) + + +def custom_templates(files: List[str], **kwargs) -> None: + """Generate custom template files + + Fetches information about the repository from the .repo-metadata.json file, + information about the latest artifact versions and copies the files into + their expected location. + + Args: + files (List[str], optional): List of template paths to include + **kwargs: Additional options for CommonTemplates.render() + """ + kwargs["metadata"] = _common_template_metadata() + kwargs["metadata"]["partials"] = partials.load_partials() + for file in files: + template = gcp.CommonTemplates().render(file, **kwargs) + s.copy([template]) + + +def remove_method(filename: str, signature: str): + """Helper to remove an entire method. + + Goes line-by-line to detect the start of the block. Determines + the end of the block by a closing brace at the same indentation + level. This requires the file to be correctly formatted. + + Example: consider the following class: + + class Example { + public void main(String[] args) { + System.out.println("Hello World"); + } + + public String foo() { + return "bar"; + } + } + + To remove the `main` method above, use: + + remove_method('path/to/file', 'public void main(String[] args)') + + Args: + filename (str): Path to source file + signature (str): Full signature of the method to remove. Example: + `public void main(String[] args)`. + """ + lines = [] + leading_regex = None + with open(filename, "r") as fp: + line = fp.readline() + while line: + # for each line, try to find the matching + regex = re.compile("(\\s*)" + re.escape(signature) + ".*") + match = regex.match(line) + if match: + leading_regex = re.compile(match.group(1) + "}") + line = fp.readline() + continue + + # not in a ignore block - preserve the line + if not leading_regex: + lines.append(line) + line = fp.readline() + continue + + # detect the closing tag based on the leading spaces + match = leading_regex.match(line) + if match: + # block is closed, resume capturing content + leading_regex = None + + line = fp.readline() + + with open(filename, "w") as fp: + for line in lines: + # print(line) + fp.write(line) + + +def copy_and_rename_method(filename: str, signature: str, before: str, after: str): + """Helper to make a copy an entire method and rename it. + + Goes line-by-line to detect the start of the block. Determines + the end of the block by a closing brace at the same indentation + level. This requires the file to be correctly formatted. + The method is copied over and renamed in the method signature. + The calls to both methods are separate and unaffected. + + Example: consider the following class: + + class Example { + public void main(String[] args) { + System.out.println("Hello World"); + } + + public String foo() { + return "bar"; + } + } + + To copy and rename the `main` method above, use: + + copy_and_rename_method('path/to/file', 'public void main(String[] args)', + 'main', 'foo1') + + Args: + filename (str): Path to source file + signature (str): Full signature of the method to remove. Example: + `public void main(String[] args)`. + before (str): name of the method to be copied + after (str): new name of the copied method + """ + lines = [] + method = [] + leading_regex = None + with open(filename, "r") as fp: + line = fp.readline() + while line: + # for each line, try to find the matching + regex = re.compile("(\\s*)" + re.escape(signature) + ".*") + match = regex.match(line) + if match: + leading_regex = re.compile(match.group(1) + "}") + lines.append(line) + method.append(line.replace(before, after)) + line = fp.readline() + continue + + lines.append(line) + # not in a ignore block - preserve the line + if leading_regex: + method.append(line) + else: + line = fp.readline() + continue + + # detect the closing tag based on the leading spaces + match = leading_regex.match(line) + if match: + # block is closed, resume capturing content + leading_regex = None + lines.append("\n") + lines.extend(method) + + line = fp.readline() + + with open(filename, "w") as fp: + for line in lines: + # print(line) + fp.write(line) + + +def add_javadoc(filename: str, signature: str, javadoc_type: str, content: List[str]): + """Helper to add a javadoc annoatation to a method. + + Goes line-by-line to detect the start of the block. + Then finds the existing method comment (if it exists). If the + comment already exists, it will append the javadoc annotation + to the javadoc block. Otherwise, it will create a new javadoc + comment block. + + Example: consider the following class: + + class Example { + public void main(String[] args) { + System.out.println("Hello World"); + } + + public String foo() { + return "bar"; + } + } + + To add a javadoc annotation the `main` method above, use: + + add_javadoc('path/to/file', 'public void main(String[] args)', + 'deprecated', 'Please use foo instead.') + + Args: + filename (str): Path to source file + signature (str): Full signature of the method to remove. Example: + `public void main(String[] args)`. + javadoc_type (str): The type of javadoc annotation. Example: `deprecated`. + content (List[str]): The javadoc lines + """ + lines: List[str] = [] + annotations: List[str] = [] + with open(filename, "r") as fp: + line = fp.readline() + while line: + # for each line, try to find the matching + regex = re.compile("(\\s*)" + re.escape(signature) + ".*") + match = regex.match(line) + if match: + leading_spaces = len(line) - len(line.lstrip()) + indent = leading_spaces * " " + last_line = lines.pop() + while last_line.lstrip() and last_line.lstrip()[0] == "@": + annotations.append(last_line) + last_line = lines.pop() + if last_line.strip() == "*/": + first = True + for content_line in content: + if first: + lines.append( + indent + + " * @" + + javadoc_type + + " " + + content_line + + "\n" + ) + first = False + else: + lines.append(indent + " * " + content_line + "\n") + lines.append(last_line) + else: + lines.append(last_line) + lines.append(indent + "/**\n") + first = True + for content_line in content: + if first: + lines.append( + indent + + " * @" + + javadoc_type + + " " + + content_line + + "\n" + ) + first = False + else: + lines.append(indent + " * " + content_line + "\n") + lines.append(indent + " */\n") + lines.extend(annotations[::-1]) + lines.append(line) + line = fp.readline() + + with open(filename, "w") as fp: + for line in lines: + # print(line) + fp.write(line) + + +def annotate_method(filename: str, signature: str, annotation: str): + """Helper to add an annotation to a method. + + Goes line-by-line to detect the start of the block. + Then adds the annotation above the found method signature. + + Example: consider the following class: + + class Example { + public void main(String[] args) { + System.out.println("Hello World"); + } + + public String foo() { + return "bar"; + } + } + + To add an annotation the `main` method above, use: + + annotate_method('path/to/file', 'public void main(String[] args)', + '@Generated()') + + Args: + filename (str): Path to source file + signature (str): Full signature of the method to remove. Example: + `public void main(String[] args)`. + annotation (str): Full annotation. Example: `@Deprecated` + """ + lines: List[str] = [] + with open(filename, "r") as fp: + line = fp.readline() + while line: + # for each line, try to find the matching + regex = re.compile("(\\s*)" + re.escape(signature) + ".*") + match = regex.match(line) + if match: + leading_spaces = len(line) - len(line.lstrip()) + indent = leading_spaces * " " + lines.append(indent + annotation + "\n") + lines.append(line) + line = fp.readline() + + with open(filename, "w") as fp: + for line in lines: + # print(line) + fp.write(line) + + +def deprecate_method(filename: str, signature: str, alternative: str): + """Helper to deprecate a method. + + Goes line-by-line to detect the start of the block. + Then adds the deprecation comment before the method signature. + The @Deprecation annotation is also added. + + Example: consider the following class: + + class Example { + public void main(String[] args) { + System.out.println("Hello World"); + } + + public String foo() { + return "bar"; + } + } + + To deprecate the `main` method above, use: + + deprecate_method('path/to/file', 'public void main(String[] args)', + DEPRECATION_WARNING.format(new_method="foo")) + + Args: + filename (str): Path to source file + signature (str): Full signature of the method to remove. Example: + `public void main(String[] args)`. + alternative: DEPRECATION WARNING: multiline javadoc comment with user + specified leading open/close comment tags + """ + add_javadoc(filename, signature, "deprecated", alternative.splitlines()) + annotate_method(filename, signature, "@Deprecated") From 75684bd9f33c4b912364e77468040bddfee298cd Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 17:38:53 +0000 Subject: [PATCH 02/33] restructure scripts --- .../owlbot/synthtool/gcp/common.py | 144 ++++++++++++++++++ .../synthtool/{ => languages}/common.py | 0 .../owlbot/synthtool/{ => languages}/java.py | 0 library_generation/owlbot/synthtool/setup.py | 13 ++ 4 files changed, 157 insertions(+) create mode 100644 library_generation/owlbot/synthtool/gcp/common.py rename library_generation/owlbot/synthtool/{ => languages}/common.py (100%) rename library_generation/owlbot/synthtool/{ => languages}/java.py (100%) create mode 100644 library_generation/owlbot/synthtool/setup.py diff --git a/library_generation/owlbot/synthtool/gcp/common.py b/library_generation/owlbot/synthtool/gcp/common.py new file mode 100644 index 0000000000..df949a9478 --- /dev/null +++ b/library_generation/owlbot/synthtool/gcp/common.py @@ -0,0 +1,144 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os +import re +import shutil +from pathlib import Path +from typing import Dict, List, Optional +import jinja2 + +from synthtool import shell, _tracked_paths +from synthtool.gcp import partials +from synthtool.log import logger +from synthtool.sources import git, templates + +TEMPLATES_URL: str = git.make_repo_clone_url("googleapis/synthtool") +DEFAULT_TEMPLATES_PATH = "synthtool/gcp/templates" +LOCAL_TEMPLATES: Optional[str] = os.environ.get("SYNTHTOOL_TEMPLATES") + + +class CommonTemplates: + def __init__(self, template_path: Optional[Path] = None): + if template_path: + self._template_root = template_path + elif LOCAL_TEMPLATES: + logger.debug(f"Using local templates at {LOCAL_TEMPLATES}") + self._template_root = Path(LOCAL_TEMPLATES) + else: + templates_git = git.clone(TEMPLATES_URL) + self._template_root = templates_git / DEFAULT_TEMPLATES_PATH + + self._templates = templates.Templates(self._template_root) + self.excludes = [] # type: List[str] + + def _generic_library(self, directory: str, relative_dir=None, **kwargs) -> Path: + # load common repo meta information (metadata that's not language specific). + if "metadata" in kwargs: + self._load_generic_metadata(kwargs["metadata"], relative_dir=relative_dir) + # if no samples were found, don't attempt to render a + # samples/README.md. + if "samples" not in kwargs["metadata"] or not kwargs["metadata"]["samples"]: + self.excludes.append("samples/README.md") + + t = templates.TemplateGroup(self._template_root / directory, self.excludes) + + if "repository" in kwargs["metadata"] and "repo" in kwargs["metadata"]: + kwargs["metadata"]["repo"]["default_branch"] = _get_default_branch_name( + kwargs["metadata"]["repository"] + ) + + result = t.render(**kwargs) + _tracked_paths.add(result) + + return result + + def java_library(self, **kwargs) -> Path: + # kwargs["metadata"] is required to load values from .repo-metadata.json + if "metadata" not in kwargs: + kwargs["metadata"] = {} + return self._generic_library("java_library", **kwargs) + + def render(self, template_name: str, **kwargs) -> Path: + template = self._templates.render(template_name, **kwargs) + _tracked_paths.add(template) + return template + + def _load_generic_metadata(self, metadata: Dict, relative_dir=None): + """ + loads additional meta information from .repo-metadata.json. + """ + metadata["partials"] = partials.load_partials() + + # Loads repo metadata information from the default location if it + # hasn't already been set. Some callers may have already loaded repo + # metadata, so we don't need to do it again or overwrite it. Also, only + # set the "repo" key. + if "repo" not in metadata: + metadata["repo"] = _load_repo_metadata(relative_dir=relative_dir) + + +def _load_repo_metadata( + relative_dir=None, metadata_file: str = "./.repo-metadata.json" +) -> Dict: + """Parse a metadata JSON file into a Dict. + + Currently, the defined fields are: + * `name` - The service's API name + * `name_pretty` - The service's API title. This will be used for generating titles on READMEs + * `product_documentation` - The product documentation on cloud.google.com + * `client_documentation` - The client library reference documentation + * `issue_tracker` - The public issue tracker for the product + * `release_level` - The release level of the client library. One of: alpha, beta, + ga, deprecated, preview, stable + * `language` - The repo language. One of dotnet, go, java, nodejs, php, python, ruby + * `repo` - The GitHub repo in the format {owner}/{repo} + * `distribution_name` - The language-idiomatic package/distribution name + * `api_id` - The API ID associated with the service. Fully qualified identifier use to + enable a service in the cloud platform (e.g. monitoring.googleapis.com) + * `requires_billing` - Whether or not the API requires billing to be configured on the + customer's acocunt + + Args: + metadata_file (str, optional): Path to the metadata json file + + Returns: + A dictionary of metadata. This may not necessarily include all the defined fields above. + """ + if relative_dir is not None: + if os.path.exists(Path(relative_dir, metadata_file).resolve()): + with open(Path(relative_dir, metadata_file).resolve()) as f: + return json.load(f) + elif os.path.exists(metadata_file): + with open(metadata_file) as f: + return json.load(f) + return {} + + +def _get_default_branch_name(repository_name: str) -> str: + """Read the default branch name from the environment. + + First checks environment variable DEFAULT_BRANCH_PATH. If found, it + reads the contents of the file at DEFAULT_BRANCH_PATH and returns it. + + Then checks environment varabile DEFAULT_BRANCH, and returns it if found. + """ + default_branch_path = os.getenv("DEFAULT_BRANCH_PATH") + if default_branch_path: + return Path(default_branch_path).read_text().strip() + + # This default should be switched to "main" once we've migrated + # the majority of our repositories: + return os.getenv("DEFAULT_BRANCH", "master") diff --git a/library_generation/owlbot/synthtool/common.py b/library_generation/owlbot/synthtool/languages/common.py similarity index 100% rename from library_generation/owlbot/synthtool/common.py rename to library_generation/owlbot/synthtool/languages/common.py diff --git a/library_generation/owlbot/synthtool/java.py b/library_generation/owlbot/synthtool/languages/java.py similarity index 100% rename from library_generation/owlbot/synthtool/java.py rename to library_generation/owlbot/synthtool/languages/java.py diff --git a/library_generation/owlbot/synthtool/setup.py b/library_generation/owlbot/synthtool/setup.py new file mode 100644 index 0000000000..e67d00aa64 --- /dev/null +++ b/library_generation/owlbot/synthtool/setup.py @@ -0,0 +1,13 @@ +""" +Package information of the transferred synthool scripts +""" + +from setuptools import setup + +setup( + name="synthtool", + version="0.1", + package_dir={ + "synthtool": ".", + }, +) From 30fa2c4c99f38f3ad463ccb70f8c114cff4d049b Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 17:50:56 +0000 Subject: [PATCH 03/33] simplify gcp.common --- .../owlbot/synthtool/gcp/common.py | 18 ++-- .../owlbot/synthtool/sources/templates.py | 84 +++++++++++++++++++ 2 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 library_generation/owlbot/synthtool/sources/templates.py diff --git a/library_generation/owlbot/synthtool/gcp/common.py b/library_generation/owlbot/synthtool/gcp/common.py index df949a9478..206d230127 100644 --- a/library_generation/owlbot/synthtool/gcp/common.py +++ b/library_generation/owlbot/synthtool/gcp/common.py @@ -15,6 +15,7 @@ import json import os import re +import sys import shutil from pathlib import Path from typing import Dict, List, Optional @@ -23,24 +24,19 @@ from synthtool import shell, _tracked_paths from synthtool.gcp import partials from synthtool.log import logger -from synthtool.sources import git, templates +from synthtool.sources import templates -TEMPLATES_URL: str = git.make_repo_clone_url("googleapis/synthtool") DEFAULT_TEMPLATES_PATH = "synthtool/gcp/templates" LOCAL_TEMPLATES: Optional[str] = os.environ.get("SYNTHTOOL_TEMPLATES") class CommonTemplates: def __init__(self, template_path: Optional[Path] = None): - if template_path: - self._template_root = template_path - elif LOCAL_TEMPLATES: - logger.debug(f"Using local templates at {LOCAL_TEMPLATES}") - self._template_root = Path(LOCAL_TEMPLATES) - else: - templates_git = git.clone(TEMPLATES_URL) - self._template_root = templates_git / DEFAULT_TEMPLATES_PATH - + if LOCAL_TEMPLATES is None: + logger.error("env var SYNTHTOOL_TEMPLATES must be set") + sys.exit(1) + logger.debug(f"Using local templates at {LOCAL_TEMPLATES}") + self._template_root = Path(LOCAL_TEMPLATES) self._templates = templates.Templates(self._template_root) self.excludes = [] # type: List[str] diff --git a/library_generation/owlbot/synthtool/sources/templates.py b/library_generation/owlbot/synthtool/sources/templates.py new file mode 100644 index 0000000000..dade78c5d4 --- /dev/null +++ b/library_generation/owlbot/synthtool/sources/templates.py @@ -0,0 +1,84 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Union, List +from pathlib import Path + +import jinja2 +import re + +from synthtool import log +from synthtool import tmp + + +PathOrStr = Union[str, Path] + + +def _make_env(location): + env = jinja2.Environment( + loader=jinja2.FileSystemLoader(str(location)), + autoescape=False, + keep_trailing_newline=True, + ) + return env + + +def _render_to_path(env, template_name, dest, params): + template = env.get_template(template_name) + + output = template.stream(**params) + + if template_name.endswith(".j2"): + template_name = template.name[:-3] + + dest = dest / template_name + dest.parent.mkdir(parents=True, exist_ok=True) + + with dest.open("w") as fh: + output.dump(fh) + + # Copy file mode over + source_path = Path(template.filename) + mode = source_path.stat().st_mode + dest.chmod(mode) + + return dest + + +class Templates: + def __init__(self, location: PathOrStr) -> None: + self.env = _make_env(location) + self.source_path = Path(location) + self.dir = tmp.tmpdir() + + def render(self, template_name: str, subdir: PathOrStr = ".", **kwargs) -> Path: + return _render_to_path(self.env, template_name, self.dir / subdir, kwargs) + + +class TemplateGroup: + def __init__(self, location: PathOrStr, excludes: List[str] = []) -> None: + self.env = _make_env(location) + self.dir = tmp.tmpdir() + self.excludes = excludes + + def render(self, subdir: PathOrStr = ".", **kwargs) -> Path: + for template_name in self.env.list_templates(): + if template_name not in self.excludes: + print(template_name) + _render_to_path(self.env, template_name, self.dir / subdir, kwargs) + else: + print(f"Skipping: {template_name}") + + return self.dir + From af71764fcb47f1e8973556cac3c7558e3083b65a Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 17:59:19 +0000 Subject: [PATCH 04/33] simplify java.py --- .../owlbot/synthtool/languages/java.py | 127 +----------------- 1 file changed, 1 insertion(+), 126 deletions(-) diff --git a/library_generation/owlbot/synthtool/languages/java.py b/library_generation/owlbot/synthtool/languages/java.py index 93eaead612..457fce4108 100644 --- a/library_generation/owlbot/synthtool/languages/java.py +++ b/library_generation/owlbot/synthtool/languages/java.py @@ -21,7 +21,7 @@ import synthtool as s import synthtool.gcp as gcp from synthtool import cache, shell -from synthtool.gcp import common, partials, pregenerated, samples, snippets +from synthtool.gcp import common, partials, samples, snippets from synthtool.log import logger from pathlib import Path from typing import Any, Optional, Dict, Iterable, List @@ -65,38 +65,6 @@ METADATA = "metadata" LIBRARIES_BOM_VERSION = "libraries_bom_version" LIBRARIES_BOM_VERSION_ENV_KEY = "SYNTHTOOL_LIBRARIES_BOM_VERSION" - - -def format_code( - path: str, version: str = DEFAULT_FORMAT_VERSION, times: int = 2 -) -> None: - """ - Runs the google-java-format jar against all .java files found within the - provided path. - """ - jar_name = f"google-java-format-{version}.jar" - jar = cache.get_cache_dir() / jar_name - if not jar.exists(): - _download_formatter(version, jar) - - # Find all .java files in path and run the formatter on them - files = list(glob.iglob(os.path.join(path, "**/*.java"), recursive=True)) - - # Run the formatter as a jar file - logger.info("Running java formatter on {} files".format(len(files))) - for _ in range(times): - shell.run(["java", "-jar", str(jar), "--replace"] + files) - - -def _download_formatter(version: str, dest: Path) -> None: - logger.info("Downloading java formatter") - url = JAR_DOWNLOAD_URL.format(version=version) - response = requests.get(url) - response.raise_for_status() - with open(dest, "wb") as fh: - fh.write(response.content) - - HEADER_REGEX = re.compile("\\* Copyright \\d{4} Google LLC") @@ -327,99 +295,6 @@ def gapic_library( return library -def bazel_library( - service: str, - version: str, - package_pattern: str = "com.google.cloud.{service}.{version}", - gapic: gcp.GAPICBazel = None, - destination_name: str = None, - cloud_api: bool = True, - diregapic: bool = False, - preserve_gapic: bool = False, - **kwargs, -) -> Path: - """Generate a Java library using the gapic-generator via bazel. - - Generates code into a temp directory, fixes missing header fields, and - copies into the expected locations. - - Args: - service (str): Name of the service. - version (str): Service API version. - package_pattern (str, optional): Package name template for fixing file - headers. Defaults to "com.google.cloud.{service}.{version}". - gapic (GAPICBazel, optional): Generator instance. - destination_name (str, optional): Override the service name for the - destination of the output code. Defaults to the service name. - preserve_gapic (bool, optional): Whether to preserve the gapic directory - prefix. Default False. - **kwargs: Additional options for gapic.java_library() - - Returns: - The path to the temp directory containing the generated client. - """ - if gapic is None: - gapic = gcp.GAPICBazel() - - library = gapic.java_library( - service=service, version=version, diregapic=diregapic, **kwargs - ) - - _common_generation( - service=service, - version=version, - library=library / f"google-cloud-{service}-{version}-java", - package_pattern=package_pattern, - suffix="-java", - destination_name=destination_name, - cloud_api=cloud_api, - diregapic=diregapic, - preserve_gapic=preserve_gapic, - ) - - return library - - -def pregenerated_library( - path: str, - service: str, - version: str, - destination_name: str = None, - cloud_api: bool = True, -) -> Path: - """Generate a Java library using the gapic-generator via bazel. - - Generates code into a temp directory, fixes missing header fields, and - copies into the expected locations. - - Args: - path (str): Path in googleapis-gen to un-versioned generated code. - service (str): Name of the service. - version (str): Service API version. - destination_name (str, optional): Override the service name for the - destination of the output code. Defaults to the service name. - cloud_api (bool, optional): Whether or not this is a cloud API (for naming) - - Returns: - The path to the temp directory containing the generated client. - """ - generator = pregenerated.Pregenerated() - library = generator.generate(path) - - cloud_prefix = "cloud-" if cloud_api else "" - _common_generation( - service=service, - version=version, - library=library / f"google-{cloud_prefix}{service}-{version}-java", - package_pattern="unused", - suffix="-java", - destination_name=destination_name, - cloud_api=cloud_api, - ) - - return library - - def _merge_release_please(destination_text: str): config = yaml.safe_load(destination_text) if "handleGHRelease" in config: From c61a80cb0adf60b8a67c0f72269d88b737104b1b Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 19:06:48 +0000 Subject: [PATCH 05/33] add transforms --- .../owlbot/synthtool/__init__.py | 36 ++ .../owlbot/synthtool/transforms.py | 334 ++++++++++++++++++ 2 files changed, 370 insertions(+) create mode 100644 library_generation/owlbot/synthtool/__init__.py create mode 100644 library_generation/owlbot/synthtool/transforms.py diff --git a/library_generation/owlbot/synthtool/__init__.py b/library_generation/owlbot/synthtool/__init__.py new file mode 100644 index 0000000000..6aee9a3967 --- /dev/null +++ b/library_generation/owlbot/synthtool/__init__.py @@ -0,0 +1,36 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Synthtool synthesizes libraries from disparate sources.""" + +import sys + +from synthtool.transforms import ( + move, + replace, + dont_overwrite, + get_staging_dirs, + remove_staging_dirs, +) + +copy = move + +__all__ = [ + "copy", + "move", + "replace", + "dont_overwrite", + "get_staging_dirs", + "remove_staging_dirs", +] diff --git a/library_generation/owlbot/synthtool/transforms.py b/library_generation/owlbot/synthtool/transforms.py new file mode 100644 index 0000000000..2d0af9a437 --- /dev/null +++ b/library_generation/owlbot/synthtool/transforms.py @@ -0,0 +1,334 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from pathlib import Path +import shutil +from typing import Callable, Iterable, Union, List, Optional +import os +import re +import sys + +from synthtool import _tracked_paths +from synthtool.log import logger +from synthtool import metadata + +PathOrStr = Union[str, Path] +ListOfPathsOrStrs = Iterable[Union[str, Path]] + + +class MissingSourceError(Exception): + pass + + +def _expand_paths(paths: ListOfPathsOrStrs, root: PathOrStr = None) -> Iterable[Path]: + """Given a list of globs/paths, expands them into a flat sequence, + expanding globs as necessary.""" + if paths is None: + return [] + + if isinstance(paths, (str, Path)): + paths = [paths] + + if root is None: + root = Path(".") + + # ensure root is a path + root = Path(root) + + # record name of synth script so we don't try to do transforms on it + synth_script_name = sys.argv[0] + + for path in paths: + if isinstance(path, Path): + if path.is_absolute(): + anchor = Path(path.anchor) + remainder = str(path.relative_to(path.anchor)) + yield from anchor.glob(remainder) + else: + yield from root.glob(str(path)) + else: + yield from ( + p + for p in root.glob(path) + if p.absolute() != Path(synth_script_name).absolute() + ) + + +def _filter_files(paths: Iterable[Path]) -> Iterable[Path]: + """Returns only the paths that are files (no directories).""" + + return (path for path in paths if path.is_file() and os.access(path, os.W_OK)) + + +def _merge_file( + source_path: Path, dest_path: Path, merge: Callable[[str, str, Path], str] +): + """ + Writes to the destination the result of merging the source with the + existing destination contents, using the given merge function. + + The merge function must take three arguments: the source contents, the + old destination contents, and a Path to the file to be written. + """ + + with source_path.open("r") as source_file: + source_text = source_file.read() + + with dest_path.open("r+") as dest_file: + dest_text = dest_file.read() + + final_text = merge(source_text, dest_text, dest_path) + + # use the source file's file permission mode + os.chmod(dest_path, os.stat(source_path).st_mode) + if final_text != dest_text: + dest_file.seek(0) + dest_file.write(final_text) + dest_file.truncate() + else: + dest_path.touch() + + +def _copy_dir_to_existing_dir( + source: Path, + destination: Path, + excludes: ListOfPathsOrStrs = None, + merge: Callable[[str, str, Path], str] = None, +) -> bool: + """ + copies files over existing files to an existing directory + this function does not copy empty directories. + + Returns: True if any files were copied, False otherwise. + """ + copied = False + + if not excludes: + excludes = [] + for root, _, files in os.walk(source): + for name in files: + rel_path = str(Path(root).relative_to(source)) + dest_dir = destination / rel_path + dest_path = dest_dir / name + exclude = [ + e + for e in excludes + if ( + Path(e) == _tracked_paths.relativize(root) + or Path(e) == _tracked_paths.relativize(Path(root) / name) + ) + ] + if not exclude: + os.makedirs(str(dest_dir), exist_ok=True) + source_path = Path(os.path.join(root, name)) + if merge is not None and dest_path.is_file(): + try: + _merge_file(source_path, dest_path, merge) + except Exception: + logger.exception( + "_merge_file failed for %s, fall back to copy", + source_path, + ) + shutil.copy2(str(source_path), str(dest_path)) + else: + shutil.copy2(str(source_path), str(dest_path)) + copied = True + + return copied + + +def dont_overwrite( + patterns: ListOfPathsOrStrs, +) -> Callable[[str, str, Path], str]: + """Returns a merge function that doesn't overwrite the specified files. + + Pass the return value to move() or copy() to avoid overwriting existing + files. + """ + + def merge(source_text: str, destinaton_text: str, file_path: Path) -> str: + for pattern in patterns: + if file_path.match(str(pattern)): + logger.debug(f"Preserving existing contents of {file_path}.") + return destinaton_text + return source_text + + return merge + + +def move( + sources: ListOfPathsOrStrs, + destination: PathOrStr = None, + excludes: ListOfPathsOrStrs = None, + merge: Callable[[str, str, Path], str] = None, + required: bool = False, +) -> bool: + """ + copy file(s) at source to current directory, preserving file mode. + + Args: + sources (ListOfPathsOrStrs): Glob pattern(s) to copy + destination (PathOrStr): Destination folder for copied files + excludes (ListOfPathsOrStrs): Glob pattern(s) of files to skip + merge (Callable[[str, str, Path], str]): Callback function for merging files + if there is an existing file. + required (bool): If required and no source files are copied, throws a MissingSourceError + + Returns: + True if any files were copied, False otherwise. + """ + copied = False + + for excluded_pattern in excludes or []: + metadata.add_pattern_excluded_during_copy(str(excluded_pattern)) + + for source in _expand_paths(sources): + if destination is None: + canonical_destination = _tracked_paths.relativize(source) + else: + canonical_destination = Path(destination) + + if excludes: + excludes = [ + _tracked_paths.relativize(e) for e in _expand_paths(excludes, source) + ] + else: + excludes = [] + if source.is_dir(): + copied = copied or _copy_dir_to_existing_dir( + source, canonical_destination, excludes=excludes, merge=merge + ) + elif source not in excludes: + # copy individual file + if merge is not None and canonical_destination.is_file(): + try: + _merge_file(source, canonical_destination, merge) + except Exception: + logger.exception( + "_merge_file failed for %s, fall back to copy", source + ) + shutil.copy2(source, canonical_destination) + else: + shutil.copy2(source, canonical_destination) + copied = True + + if not copied: + if required: + raise MissingSourceError( + f"No files in sources {sources} were copied. Does the source " + f"contain files?" + ) + else: + logger.warning( + f"No files in sources {sources} were copied. Does the source " + f"contain files?" + ) + + return copied + + +def _replace_in_file(path, expr, replacement): + try: + with path.open("r+") as fh: + return _replace_in_file_handle(fh, expr, replacement) + except UnicodeDecodeError: + pass # It's a binary file. Try again with a binary regular expression. + flags = expr.flags & ~re.UNICODE + expr = re.compile(expr.pattern.encode(), flags) + with path.open("rb+") as fh: + return _replace_in_file_handle(fh, expr, replacement.encode()) + + +def _replace_in_file_handle(fh, expr, replacement): + content = fh.read() + content, count = expr.subn(replacement, content) + + # Don't bother writing the file if we didn't change + # anything. + if count: + fh.seek(0) + fh.write(content) + fh.truncate() + return count + + +def replace( + sources: ListOfPathsOrStrs, before: str, after: str, flags: int = re.MULTILINE +) -> int: + """Replaces occurrences of before with after in all the given sources. + + Returns: + The number of times the text was found and replaced across all files. + """ + expr = re.compile(before, flags=flags or 0) + paths = _filter_files(_expand_paths(sources, ".")) + + if not paths: + logger.warning(f"No files were found in sources {sources} for replace()") + + count_replaced = 0 + for path in paths: + replaced = _replace_in_file(path, expr, after) + count_replaced += replaced + if replaced: + logger.info(f"Replaced {before!r} in {path}.") + + if not count_replaced: + logger.warning( + f"No replacements made in {sources} for pattern {before}, maybe " + "replacement is no longer needed?" + ) + return count_replaced + + +def get_staging_dirs( + default_version: Optional[str] = None, staging_path: Optional[str] = None +) -> List[Path]: + """Returns the list of directories, one per version, copied from + https://github.com/googleapis/googleapis-gen. Will return in lexical sorting + order with the exception of the default_version which will be last (if specified). + + Args: + default_version: the default version of the API. The directory for this version + will be the last item in the returned list if specified. + staging_path: the path to the staging directory. + + Returns: the empty list if no file were copied. + """ + + if staging_path: + staging = Path(staging_path) + else: + staging = Path("owl-bot-staging") + if staging.is_dir(): + # Collect the subdirectories of the staging directory. + versions = [v.name for v in staging.iterdir() if v.is_dir()] + # Reorder the versions so the default version always comes last. + versions = [v for v in versions if v != default_version] + versions.sort() + if default_version is not None: + versions += [default_version] + dirs = [staging / v for v in versions] + for dir in dirs: + _tracked_paths.add(dir) + return dirs + else: + return [] + + +def remove_staging_dirs(): + """Removes all the staging directories.""" + staging = Path("owl-bot-staging") + if staging.is_dir(): + shutil.rmtree(staging) From 13a27a9efefc4e9d43815b500fa78c4415ae4eef Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 19:16:20 +0000 Subject: [PATCH 06/33] fix runtime errors --- .../owlbot/synthtool/_tracked_paths.py | 39 +++++++++++++++++++ .../owlbot/synthtool/gcp/common.py | 6 ++- .../owlbot/synthtool/languages/java.py | 6 ++- .../owlbot/synthtool/sources/templates.py | 2 - .../owlbot/synthtool/transforms.py | 4 +- 5 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 library_generation/owlbot/synthtool/_tracked_paths.py diff --git a/library_generation/owlbot/synthtool/_tracked_paths.py b/library_generation/owlbot/synthtool/_tracked_paths.py new file mode 100644 index 0000000000..b72d7037fe --- /dev/null +++ b/library_generation/owlbot/synthtool/_tracked_paths.py @@ -0,0 +1,39 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tracked paths. + +This is a bit of a hack (imported from original synthtool library). +""" + +import pathlib + + +_tracked_paths = [] + + +def add(path): + _tracked_paths.append(pathlib.Path(path)) + # Reverse sort the list, so that the deepest paths get matched first. + _tracked_paths.sort(key=lambda s: -len(str(s))) + + +def relativize(path): + path = pathlib.Path(path) + for tracked_path in _tracked_paths: + try: + return path.relative_to(tracked_path) + except ValueError: + pass + raise ValueError(f"The root for {path} is not tracked.") diff --git a/library_generation/owlbot/synthtool/gcp/common.py b/library_generation/owlbot/synthtool/gcp/common.py index 206d230127..da46cf1b1c 100644 --- a/library_generation/owlbot/synthtool/gcp/common.py +++ b/library_generation/owlbot/synthtool/gcp/common.py @@ -20,12 +20,16 @@ from pathlib import Path from typing import Dict, List, Optional import jinja2 +import logging from synthtool import shell, _tracked_paths from synthtool.gcp import partials -from synthtool.log import logger from synthtool.sources import templates +logger = logging.getLogger(name) +logger.setLevel(logging.DEBUG) + + DEFAULT_TEMPLATES_PATH = "synthtool/gcp/templates" LOCAL_TEMPLATES: Optional[str] = os.environ.get("SYNTHTOOL_TEMPLATES") diff --git a/library_generation/owlbot/synthtool/languages/java.py b/library_generation/owlbot/synthtool/languages/java.py index 457fce4108..444fc11dca 100644 --- a/library_generation/owlbot/synthtool/languages/java.py +++ b/library_generation/owlbot/synthtool/languages/java.py @@ -20,13 +20,17 @@ import yaml import synthtool as s import synthtool.gcp as gcp +import logging from synthtool import cache, shell from synthtool.gcp import common, partials, samples, snippets -from synthtool.log import logger from pathlib import Path from typing import Any, Optional, Dict, Iterable, List from datetime import date +logger = logging.getLogger(name) +logger.setLevel(logging.DEBUG) + + JAR_DOWNLOAD_URL = "https://github.com/google/google-java-format/releases/download/google-java-format-{version}/google-java-format-{version}-all-deps.jar" DEFAULT_FORMAT_VERSION = "1.7" CURRENT_YEAR = date.today().year diff --git a/library_generation/owlbot/synthtool/sources/templates.py b/library_generation/owlbot/synthtool/sources/templates.py index dade78c5d4..7671bbbcd3 100644 --- a/library_generation/owlbot/synthtool/sources/templates.py +++ b/library_generation/owlbot/synthtool/sources/templates.py @@ -18,10 +18,8 @@ import jinja2 import re -from synthtool import log from synthtool import tmp - PathOrStr = Union[str, Path] diff --git a/library_generation/owlbot/synthtool/transforms.py b/library_generation/owlbot/synthtool/transforms.py index 2d0af9a437..c0dfe9ab78 100644 --- a/library_generation/owlbot/synthtool/transforms.py +++ b/library_generation/owlbot/synthtool/transforms.py @@ -18,14 +18,16 @@ import os import re import sys +import logging from synthtool import _tracked_paths -from synthtool.log import logger from synthtool import metadata PathOrStr = Union[str, Path] ListOfPathsOrStrs = Iterable[Union[str, Path]] +logger = logging.getLogger(name) +logger.setLevel(logging.DEBUG) class MissingSourceError(Exception): pass From 46c841cfd0e1906cccd4250b4c0d93a2fb74f132 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 19:19:00 +0000 Subject: [PATCH 07/33] exclude usage of metadata --- library_generation/owlbot/synthtool/transforms.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library_generation/owlbot/synthtool/transforms.py b/library_generation/owlbot/synthtool/transforms.py index c0dfe9ab78..e0173aa006 100644 --- a/library_generation/owlbot/synthtool/transforms.py +++ b/library_generation/owlbot/synthtool/transforms.py @@ -21,7 +21,6 @@ import logging from synthtool import _tracked_paths -from synthtool import metadata PathOrStr = Union[str, Path] ListOfPathsOrStrs = Iterable[Union[str, Path]] @@ -192,9 +191,6 @@ def move( """ copied = False - for excluded_pattern in excludes or []: - metadata.add_pattern_excluded_during_copy(str(excluded_pattern)) - for source in _expand_paths(sources): if destination is None: canonical_destination = _tracked_paths.relativize(source) From f2fb1174ea3b836ffd5be5567c0391045ff4ad09 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 19:22:23 +0000 Subject: [PATCH 08/33] fix logger creation --- library_generation/owlbot/synthtool/gcp/common.py | 2 +- library_generation/owlbot/synthtool/languages/java.py | 2 +- library_generation/owlbot/synthtool/transforms.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library_generation/owlbot/synthtool/gcp/common.py b/library_generation/owlbot/synthtool/gcp/common.py index da46cf1b1c..13aa5c0355 100644 --- a/library_generation/owlbot/synthtool/gcp/common.py +++ b/library_generation/owlbot/synthtool/gcp/common.py @@ -26,7 +26,7 @@ from synthtool.gcp import partials from synthtool.sources import templates -logger = logging.getLogger(name) +logger = logging.getLogger() logger.setLevel(logging.DEBUG) diff --git a/library_generation/owlbot/synthtool/languages/java.py b/library_generation/owlbot/synthtool/languages/java.py index 444fc11dca..0ac1ef9f80 100644 --- a/library_generation/owlbot/synthtool/languages/java.py +++ b/library_generation/owlbot/synthtool/languages/java.py @@ -27,7 +27,7 @@ from typing import Any, Optional, Dict, Iterable, List from datetime import date -logger = logging.getLogger(name) +logger = logging.getLogger() logger.setLevel(logging.DEBUG) diff --git a/library_generation/owlbot/synthtool/transforms.py b/library_generation/owlbot/synthtool/transforms.py index e0173aa006..e51f4668b3 100644 --- a/library_generation/owlbot/synthtool/transforms.py +++ b/library_generation/owlbot/synthtool/transforms.py @@ -25,7 +25,7 @@ PathOrStr = Union[str, Path] ListOfPathsOrStrs = Iterable[Union[str, Path]] -logger = logging.getLogger(name) +logger = logging.getLogger() logger.setLevel(logging.DEBUG) class MissingSourceError(Exception): From 420d7f4e92f1ac1404ebc39a78cc84a59c1c60be Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 19:25:32 +0000 Subject: [PATCH 09/33] remove unused cache and shell imports --- library_generation/owlbot/synthtool/gcp/common.py | 2 +- library_generation/owlbot/synthtool/languages/java.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/library_generation/owlbot/synthtool/gcp/common.py b/library_generation/owlbot/synthtool/gcp/common.py index 13aa5c0355..0710f1cef8 100644 --- a/library_generation/owlbot/synthtool/gcp/common.py +++ b/library_generation/owlbot/synthtool/gcp/common.py @@ -22,7 +22,7 @@ import jinja2 import logging -from synthtool import shell, _tracked_paths +from synthtool import _tracked_paths from synthtool.gcp import partials from synthtool.sources import templates diff --git a/library_generation/owlbot/synthtool/languages/java.py b/library_generation/owlbot/synthtool/languages/java.py index 0ac1ef9f80..7fbe50350e 100644 --- a/library_generation/owlbot/synthtool/languages/java.py +++ b/library_generation/owlbot/synthtool/languages/java.py @@ -21,7 +21,6 @@ import synthtool as s import synthtool.gcp as gcp import logging -from synthtool import cache, shell from synthtool.gcp import common, partials, samples, snippets from pathlib import Path from typing import Any, Optional, Dict, Iterable, List From 09af9a9686b5d7fe21efb661f5f15e4d03a9c253 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 19:33:23 +0000 Subject: [PATCH 10/33] bring partials.py into gcp/common.py --- .../owlbot/synthtool/gcp/common.py | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/library_generation/owlbot/synthtool/gcp/common.py b/library_generation/owlbot/synthtool/gcp/common.py index 0710f1cef8..c1723a6161 100644 --- a/library_generation/owlbot/synthtool/gcp/common.py +++ b/library_generation/owlbot/synthtool/gcp/common.py @@ -17,13 +17,13 @@ import re import sys import shutil +import yaml from pathlib import Path from typing import Dict, List, Optional import jinja2 import logging from synthtool import _tracked_paths -from synthtool.gcp import partials from synthtool.sources import templates logger = logging.getLogger() @@ -33,6 +33,14 @@ DEFAULT_TEMPLATES_PATH = "synthtool/gcp/templates" LOCAL_TEMPLATES: Optional[str] = os.environ.get("SYNTHTOOL_TEMPLATES") +# Originally brought from gcp/partials.py. +# These are the default locations to look up +_DEFAULT_PARTIAL_FILES = [ + ".readme-partials.yml", + ".readme-partials.yaml", + ".integration-partials.yaml", +] + class CommonTemplates: def __init__(self, template_path: Optional[Path] = None): @@ -80,7 +88,7 @@ def _load_generic_metadata(self, metadata: Dict, relative_dir=None): """ loads additional meta information from .repo-metadata.json. """ - metadata["partials"] = partials.load_partials() + metadata["partials"] = load_partials() # Loads repo metadata information from the default location if it # hasn't already been set. Some callers may have already loaded repo @@ -142,3 +150,25 @@ def _get_default_branch_name(repository_name: str) -> str: # This default should be switched to "main" once we've migrated # the majority of our repositories: return os.getenv("DEFAULT_BRANCH", "master") + +def load_partials(files: List[str] = []) -> Dict: + """ + hand-crafted artisanal markdown can be provided in a .readme-partials.yml. + The following fields are currently supported: + + body: custom body to include in the usage section of the document. + samples_body: an optional body to place below the table of contents + in samples/README.md. + introduction: a more thorough introduction than metadata["description"]. + title: provide markdown to use as a custom title. + deprecation_warning: a warning to indicate that the library has been + deprecated and a pointer to an alternate option + """ + result: Dict[str, Dict] = {} + cwd_path = Path(os.getcwd()) + for file in files + _DEFAULT_PARTIAL_FILES: + partials_file = cwd_path / file + if os.path.exists(partials_file): + with open(partials_file) as f: + result.update(yaml.load(f, Loader=yaml.SafeLoader)) + return result From b1d33e3aec3a83f8726025742a7e12d3570fb148 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 19:39:30 +0000 Subject: [PATCH 11/33] use transferred partials in java.py --- library_generation/owlbot/synthtool/languages/java.py | 4 ++-- library_generation/owlbot/synthtool/sources/templates.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library_generation/owlbot/synthtool/languages/java.py b/library_generation/owlbot/synthtool/languages/java.py index 7fbe50350e..fe6c3371d2 100644 --- a/library_generation/owlbot/synthtool/languages/java.py +++ b/library_generation/owlbot/synthtool/languages/java.py @@ -21,7 +21,7 @@ import synthtool as s import synthtool.gcp as gcp import logging -from synthtool.gcp import common, partials, samples, snippets +from synthtool.gcp import common, samples, snippets from pathlib import Path from typing import Any, Optional, Dict, Iterable, List from datetime import date @@ -429,7 +429,7 @@ def custom_templates(files: List[str], **kwargs) -> None: **kwargs: Additional options for CommonTemplates.render() """ kwargs["metadata"] = _common_template_metadata() - kwargs["metadata"]["partials"] = partials.load_partials() + kwargs["metadata"]["partials"] = common.load_partials() for file in files: template = gcp.CommonTemplates().render(file, **kwargs) s.copy([template]) diff --git a/library_generation/owlbot/synthtool/sources/templates.py b/library_generation/owlbot/synthtool/sources/templates.py index 7671bbbcd3..8402b3d39b 100644 --- a/library_generation/owlbot/synthtool/sources/templates.py +++ b/library_generation/owlbot/synthtool/sources/templates.py @@ -16,9 +16,9 @@ from pathlib import Path import jinja2 +import tempfile import re -from synthtool import tmp PathOrStr = Union[str, Path] @@ -58,7 +58,7 @@ class Templates: def __init__(self, location: PathOrStr) -> None: self.env = _make_env(location) self.source_path = Path(location) - self.dir = tmp.tmpdir() + self.dir = Path(tempfile.mkdtemp()) def render(self, template_name: str, subdir: PathOrStr = ".", **kwargs) -> Path: return _render_to_path(self.env, template_name, self.dir / subdir, kwargs) @@ -67,7 +67,7 @@ def render(self, template_name: str, subdir: PathOrStr = ".", **kwargs) -> Path: class TemplateGroup: def __init__(self, location: PathOrStr, excludes: List[str] = []) -> None: self.env = _make_env(location) - self.dir = tmp.tmpdir() + self.dir = Path(tempfile.mkdtemp()) self.excludes = excludes def render(self, subdir: PathOrStr = ".", **kwargs) -> Path: From fb3e39973f4b84f08b32b39915a9e9ef6aed03da Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 19:55:22 +0000 Subject: [PATCH 12/33] final adjustments, add samples and snippets --- .../owlbot/synthtool/gcp/samples.py | 91 +++++++++++++ .../owlbot/synthtool/gcp/snippets.py | 124 ++++++++++++++++++ .../owlbot/synthtool/languages/java.py | 61 +-------- 3 files changed, 216 insertions(+), 60 deletions(-) create mode 100644 library_generation/owlbot/synthtool/gcp/samples.py create mode 100644 library_generation/owlbot/synthtool/gcp/snippets.py diff --git a/library_generation/owlbot/synthtool/gcp/samples.py b/library_generation/owlbot/synthtool/gcp/samples.py new file mode 100644 index 0000000000..760fc06574 --- /dev/null +++ b/library_generation/owlbot/synthtool/gcp/samples.py @@ -0,0 +1,91 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import glob +import logging +import re +import os +import yaml +from typing import List, Dict + +logger = logging.getLogger() +logger.setLevel(logging.DEBUG) + + +def _read_sample_metadata_comment(sample_file: str) -> Dict: + """Additional meta-information can be provided through embedded comments: + + // sample-metadata: + // title: ACL (Access Control) + // description: Demonstrates setting access control rules. + // usage: node iam.js --help + """ + sample_metadata = {} # type: Dict[str, str] + with open(sample_file) as f: + contents = f.read() + match = re.search( + r"(?P// *sample-metadata:([^\n]+|\n//)+)", contents, re.DOTALL + ) + if match: + # the metadata yaml is stored in a comments, remove the + # prefix so that we can parse the yaml contained. + sample_metadata_string = re.sub(r"((#|//) ?)", "", match.group("metadata")) + try: + sample_metadata = yaml.load( + sample_metadata_string, Loader=yaml.SafeLoader + )["sample-metadata"] + except yaml.scanner.ScannerError: + # warn and continue on bad metadata + logger.warning(f"bad metadata detected in {sample_file}") + return sample_metadata + + +def _sample_metadata(file: str) -> Dict[str, str]: + metadata = { + "title": _decamelize(os.path.splitext(os.path.basename(file))[0]), + "file": file, + } + return {**metadata, **_read_sample_metadata_comment(file)} + + +def all_samples(sample_globs: List[str]) -> List[Dict[str, str]]: + """Walks samples directory and builds up samples data-structure + + Args: + sample_globs: (List[str]): List of path globs to search for samples + + Returns: + A list of sample metadata in the format: + { + "title": "Requester Pays", + "file": "samples/requesterPays.js" + } + The file path is the relative path from the repository root. + """ + files = [] + for sample_glob in sample_globs: + for file in glob.glob(sample_glob, recursive=True): + files.append(file) + return [_sample_metadata(file) for file in sorted(files)] + + +def _decamelize(value: str): + """Parser to convert fooBar.js to Foo Bar.""" + if not value: + return "" + str_decamelize = re.sub("^.", value[0].upper(), value) # apple -> Apple. + str_decamelize = re.sub( + "([A-Z]+)([A-Z])([a-z0-9])", r"\1 \2\3", str_decamelize + ) # ACLBatman -> ACL Batman. + return re.sub("([a-z0-9])([A-Z])", r"\1 \2", str_decamelize) # FooBar -> Foo Bar. diff --git a/library_generation/owlbot/synthtool/gcp/snippets.py b/library_generation/owlbot/synthtool/gcp/snippets.py new file mode 100644 index 0000000000..5db00656b5 --- /dev/null +++ b/library_generation/owlbot/synthtool/gcp/snippets.py @@ -0,0 +1,124 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import glob +import os +import re +from typing import Dict, List + +OPEN_SNIPPET_REGEX = r".*\[START ([a-z0-9_]+)\].*$" +CLOSE_SNIPPET_REGEX = r".*\[END ([a-z0-9_]+)\].*$" +OPEN_EXCLUDE_REGEX = r".*\[START_EXCLUDE\].*$" +CLOSE_EXCLUDE_REGEX = r".*\[END_EXCLUDE\].*$" + + +def _trim_leading_whitespace(lines: List[str]) -> List[str]: + """Trims leading, plain spaces from the snippet content. Finds the minimum + number of leading spaces, ignoring empty lines, and removes that number of + spaces from each line. + + Args: + lines (List[str]): Lines of content. These lines are newline terminated. + + Returns: + List of trimmed lines. + """ + + def number_of_leading_spaces(input: str) -> int: + return len(input) - len(input.lstrip(" ")) + + def is_empty_line(input: str) -> bool: + if re.match(r"^\s*$", input): + return True + return False + + leading_spaces = [ + number_of_leading_spaces(line) for line in lines if not is_empty_line(line) + ] + max_leading_spaces = min(leading_spaces) + return [ + "\n" if is_empty_line(line) else line[max_leading_spaces:] for line in lines + ] + + +def all_snippets_from_file(sample_file: str) -> Dict[str, str]: + """Reads in a sample file and parse out all contained snippets. + + Args: + sample_file (str): Sample file to parse. + + Returns: + Dictionary of snippet name to snippet code. + """ + if not os.path.exists(sample_file): + return {} + + snippet_lines = {} # type: Dict[str, List[str]] + open_snippets = set() + with open(sample_file) as f: + excluding = False + # Iterate over each line: + # - If the line matches an opening snippet tag, add that snippet tag to + # the set of open tags. + # - If the line matches a closing snippet tag, remove that snippet tag + # from the set of open tags. + # - If the line matches an opening exclude tag, record that we excluding + # content. + # - If the line matches a closing exclude tag, record that we are capturing + # content again. + # - Otherwise, if we are not excluding content, add the line to each of the + # open snippets + # + # This allows us to handle parsing nested or interleaved snippets and ignore + # blocks of code in the snippets + for line in f: + open_match = re.match(pattern=OPEN_SNIPPET_REGEX, string=line) + close_match = re.match(pattern=CLOSE_SNIPPET_REGEX, string=line) + open_exclude_match = re.match(pattern=OPEN_EXCLUDE_REGEX, string=line) + close_exclude_match = re.match(pattern=CLOSE_EXCLUDE_REGEX, string=line) + if open_match and not excluding: + open_snippets.add(open_match[1]) + if not open_match[1] in snippet_lines: + snippet_lines[open_match[1]] = [] + elif close_match and not excluding: + open_snippets.discard(close_match[1]) + elif open_exclude_match: + excluding = True + elif close_exclude_match: + excluding = False + elif not excluding: + for snippet in open_snippets: + snippet_lines[snippet].append(line) + + return { + snippet: "".join(_trim_leading_whitespace(lines)) + for snippet, lines in snippet_lines.items() + } + + +def all_snippets(snippet_globs: List[str]) -> Dict[str, str]: + """Walks the samples directory and parses snippets from each file. + + Args: + snippet_globs (List[str]): List of path globs to expand. + + Returns: + Dictionary of snippet name to snippet code. + """ + snippets = {} + for snippet_glob in snippet_globs: + for file in glob.glob(snippet_glob, recursive=True): + for snippet, code in all_snippets_from_file(file).items(): + snippets[snippet] = code + return snippets diff --git a/library_generation/owlbot/synthtool/languages/java.py b/library_generation/owlbot/synthtool/languages/java.py index fe6c3371d2..1cb0292145 100644 --- a/library_generation/owlbot/synthtool/languages/java.py +++ b/library_generation/owlbot/synthtool/languages/java.py @@ -239,65 +239,6 @@ def _common_generation( format_code(f"proto-google-{cloud_prefix}{destination_name}-{version}/src") -def gapic_library( - service: str, - version: str, - config_pattern: str = "/google/cloud/{service}/artman_{service}_{version}.yaml", - package_pattern: str = "com.google.cloud.{service}.{version}", - gapic: gcp.GAPICGenerator = None, - destination_name: str = None, - diregapic: bool = False, - preserve_gapic: bool = False, - **kwargs, -) -> Path: - """Generate a Java library using the gapic-generator via artman via Docker. - - Generates code into a temp directory, fixes missing header fields, and - copies into the expected locations. - - Args: - service (str): Name of the service. - version (str): Service API version. - config_pattern (str, optional): Path template to artman config YAML - file. Defaults to "/google/cloud/{service}/artman_{service}_{version}.yaml" - package_pattern (str, optional): Package name template for fixing file - headers. Defaults to "com.google.cloud.{service}.{version}". - gapic (GAPICGenerator, optional): Generator instance. - destination_name (str, optional): Override the service name for the - destination of the output code. Defaults to the service name. - preserve_gapic (bool, optional): Whether to preserve the gapic directory - prefix. Default False. - **kwargs: Additional options for gapic.java_library() - - Returns: - The path to the temp directory containing the generated client. - """ - if gapic is None: - gapic = gcp.GAPICGenerator() - - library = gapic.java_library( - service=service, - version=version, - config_path=config_pattern.format(service=service, version=version), - artman_output_name="", - include_samples=True, - diregapic=diregapic, - **kwargs, - ) - - _common_generation( - service=service, - version=version, - library=library, - package_pattern=package_pattern, - destination_name=destination_name, - diregapic=diregapic, - preserve_gapic=preserve_gapic, - ) - - return library - - def _merge_release_please(destination_text: str): config = yaml.safe_load(destination_text) if "handleGHRelease" in config: @@ -406,7 +347,7 @@ def common_templates( ) ) - templates = gcp.CommonTemplates(template_path=template_path).java_library(**kwargs) + templates = gcp.common.CommonTemplates(template_path=template_path).java_library(**kwargs) # skip README generation on Kokoro (autosynth) if os.environ.get("KOKORO_ROOT") is not None: From e4e1770e351b824786096a2c855fca02b562f394 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 20:24:23 +0000 Subject: [PATCH 13/33] add requirements files --- .../owlbot/synthtool/requirements.in | 12 + .../owlbot/synthtool/requirements.txt | 478 ++++++++++++++++++ 2 files changed, 490 insertions(+) create mode 100644 library_generation/owlbot/synthtool/requirements.in create mode 100644 library_generation/owlbot/synthtool/requirements.txt diff --git a/library_generation/owlbot/synthtool/requirements.in b/library_generation/owlbot/synthtool/requirements.in new file mode 100644 index 0000000000..a7de2c8017 --- /dev/null +++ b/library_generation/owlbot/synthtool/requirements.in @@ -0,0 +1,12 @@ +setuptools==65.5.1 + +nox +requests>=2.31.0 +pyyaml +jinja2 +deprecation +protobuf==3.20.2 +watchdog + +# some java processing requires xml handling +lxml diff --git a/library_generation/owlbot/synthtool/requirements.txt b/library_generation/owlbot/synthtool/requirements.txt new file mode 100644 index 0000000000..55bc63ce12 --- /dev/null +++ b/library_generation/owlbot/synthtool/requirements.txt @@ -0,0 +1,478 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile --generate-hashes requirements.in +# +argcomplete==3.4.0 \ + --hash=sha256:69a79e083a716173e5532e0fa3bef45f793f4e61096cf52b5a42c0211c8b8aa5 \ + --hash=sha256:c2abcdfe1be8ace47ba777d4fce319eb13bf8ad9dace8d085dcad6eded88057f + # via nox +certifi==2024.6.2 \ + --hash=sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516 \ + --hash=sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56 + # via requests +charset-normalizer==3.3.2 \ + --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ + --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ + --hash=sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786 \ + --hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \ + --hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \ + --hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \ + --hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \ + --hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \ + --hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \ + --hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \ + --hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \ + --hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \ + --hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \ + --hash=sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6 \ + --hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \ + --hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \ + --hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \ + --hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \ + --hash=sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714 \ + --hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \ + --hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \ + --hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \ + --hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \ + --hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \ + --hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \ + --hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \ + --hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \ + --hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \ + --hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \ + --hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \ + --hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \ + --hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \ + --hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \ + --hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \ + --hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \ + --hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \ + --hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \ + --hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \ + --hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \ + --hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \ + --hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \ + --hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \ + --hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \ + --hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \ + --hash=sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99 \ + --hash=sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c \ + --hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \ + --hash=sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811 \ + --hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \ + --hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \ + --hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \ + --hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \ + --hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \ + --hash=sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c \ + --hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \ + --hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \ + --hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \ + --hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \ + --hash=sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985 \ + --hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \ + --hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \ + --hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \ + --hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \ + --hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \ + --hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \ + --hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \ + --hash=sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8 \ + --hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \ + --hash=sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5 \ + --hash=sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5 \ + --hash=sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711 \ + --hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \ + --hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \ + --hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \ + --hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \ + --hash=sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4 \ + --hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \ + --hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \ + --hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \ + --hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \ + --hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \ + --hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \ + --hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \ + --hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \ + --hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \ + --hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \ + --hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \ + --hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \ + --hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \ + --hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561 + # via requests +colorlog==6.8.2 \ + --hash=sha256:3e3e079a41feb5a1b64f978b5ea4f46040a94f11f0e8bbb8261e3dbbeca64d44 \ + --hash=sha256:4dcbb62368e2800cb3c5abd348da7e53f6c362dda502ec27c560b2e58a66bd33 + # via nox +deprecation==2.1.0 \ + --hash=sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff \ + --hash=sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a + # via -r requirements.in +distlib==0.3.8 \ + --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ + --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 + # via virtualenv +filelock==3.15.4 \ + --hash=sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb \ + --hash=sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7 + # via virtualenv +idna==3.7 \ + --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ + --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 + # via requests +jinja2==3.1.4 \ + --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \ + --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d + # via -r requirements.in +lxml==5.2.2 \ + --hash=sha256:02437fb7308386867c8b7b0e5bc4cd4b04548b1c5d089ffb8e7b31009b961dc3 \ + --hash=sha256:02f6a8eb6512fdc2fd4ca10a49c341c4e109aa6e9448cc4859af5b949622715a \ + --hash=sha256:05f8757b03208c3f50097761be2dea0aba02e94f0dc7023ed73a7bb14ff11eb0 \ + --hash=sha256:06668e39e1f3c065349c51ac27ae430719d7806c026fec462e5693b08b95696b \ + --hash=sha256:07542787f86112d46d07d4f3c4e7c760282011b354d012dc4141cc12a68cef5f \ + --hash=sha256:08ea0f606808354eb8f2dfaac095963cb25d9d28e27edcc375d7b30ab01abbf6 \ + --hash=sha256:0969e92af09c5687d769731e3f39ed62427cc72176cebb54b7a9d52cc4fa3b73 \ + --hash=sha256:0a028b61a2e357ace98b1615fc03f76eb517cc028993964fe08ad514b1e8892d \ + --hash=sha256:0b3f5016e00ae7630a4b83d0868fca1e3d494c78a75b1c7252606a3a1c5fc2ad \ + --hash=sha256:13e69be35391ce72712184f69000cda04fc89689429179bc4c0ae5f0b7a8c21b \ + --hash=sha256:16a8326e51fcdffc886294c1e70b11ddccec836516a343f9ed0f82aac043c24a \ + --hash=sha256:19b4e485cd07b7d83e3fe3b72132e7df70bfac22b14fe4bf7a23822c3a35bff5 \ + --hash=sha256:1a2569a1f15ae6c8c64108a2cd2b4a858fc1e13d25846be0666fc144715e32ab \ + --hash=sha256:1a7aca7964ac4bb07680d5c9d63b9d7028cace3e2d43175cb50bba8c5ad33316 \ + --hash=sha256:1b590b39ef90c6b22ec0be925b211298e810b4856909c8ca60d27ffbca6c12e6 \ + --hash=sha256:1d8a701774dfc42a2f0b8ccdfe7dbc140500d1049e0632a611985d943fcf12df \ + --hash=sha256:1e275ea572389e41e8b039ac076a46cb87ee6b8542df3fff26f5baab43713bca \ + --hash=sha256:2304d3c93f2258ccf2cf7a6ba8c761d76ef84948d87bf9664e14d203da2cd264 \ + --hash=sha256:23441e2b5339bc54dc949e9e675fa35efe858108404ef9aa92f0456929ef6fe8 \ + --hash=sha256:23cfafd56887eaed93d07bc4547abd5e09d837a002b791e9767765492a75883f \ + --hash=sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b \ + --hash=sha256:2eb2227ce1ff998faf0cd7fe85bbf086aa41dfc5af3b1d80867ecfe75fb68df3 \ + --hash=sha256:2fb0ba3e8566548d6c8e7dd82a8229ff47bd8fb8c2da237607ac8e5a1b8312e5 \ + --hash=sha256:303f540ad2dddd35b92415b74b900c749ec2010e703ab3bfd6660979d01fd4ed \ + --hash=sha256:339ee4a4704bc724757cd5dd9dc8cf4d00980f5d3e6e06d5847c1b594ace68ab \ + --hash=sha256:33ce9e786753743159799fdf8e92a5da351158c4bfb6f2db0bf31e7892a1feb5 \ + --hash=sha256:343ab62e9ca78094f2306aefed67dcfad61c4683f87eee48ff2fd74902447726 \ + --hash=sha256:34e17913c431f5ae01d8658dbf792fdc457073dcdfbb31dc0cc6ab256e664a8d \ + --hash=sha256:364d03207f3e603922d0d3932ef363d55bbf48e3647395765f9bfcbdf6d23632 \ + --hash=sha256:38b67afb0a06b8575948641c1d6d68e41b83a3abeae2ca9eed2ac59892b36706 \ + --hash=sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8 \ + --hash=sha256:3b019d4ee84b683342af793b56bb35034bd749e4cbdd3d33f7d1107790f8c472 \ + --hash=sha256:3b6a30a9ab040b3f545b697cb3adbf3696c05a3a68aad172e3fd7ca73ab3c835 \ + --hash=sha256:3d1e35572a56941b32c239774d7e9ad724074d37f90c7a7d499ab98761bd80cf \ + --hash=sha256:3d98de734abee23e61f6b8c2e08a88453ada7d6486dc7cdc82922a03968928db \ + --hash=sha256:453d037e09a5176d92ec0fd282e934ed26d806331a8b70ab431a81e2fbabf56d \ + --hash=sha256:45f9494613160d0405682f9eee781c7e6d1bf45f819654eb249f8f46a2c22545 \ + --hash=sha256:4820c02195d6dfb7b8508ff276752f6b2ff8b64ae5d13ebe02e7667e035000b9 \ + --hash=sha256:49095a38eb333aaf44c06052fd2ec3b8f23e19747ca7ec6f6c954ffea6dbf7be \ + --hash=sha256:4aefd911793b5d2d7a921233a54c90329bf3d4a6817dc465f12ffdfe4fc7b8fe \ + --hash=sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905 \ + --hash=sha256:4c30a2f83677876465f44c018830f608fa3c6a8a466eb223535035fbc16f3438 \ + --hash=sha256:50127c186f191b8917ea2fb8b206fbebe87fd414a6084d15568c27d0a21d60db \ + --hash=sha256:50ccb5d355961c0f12f6cf24b7187dbabd5433f29e15147a67995474f27d1776 \ + --hash=sha256:519895c99c815a1a24a926d5b60627ce5ea48e9f639a5cd328bda0515ea0f10c \ + --hash=sha256:54401c77a63cc7d6dc4b4e173bb484f28a5607f3df71484709fe037c92d4f0ed \ + --hash=sha256:546cf886f6242dff9ec206331209db9c8e1643ae642dea5fdbecae2453cb50fd \ + --hash=sha256:55ce6b6d803890bd3cc89975fca9de1dff39729b43b73cb15ddd933b8bc20484 \ + --hash=sha256:56793b7a1a091a7c286b5f4aa1fe4ae5d1446fe742d00cdf2ffb1077865db10d \ + --hash=sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6 \ + --hash=sha256:5b8c041b6265e08eac8a724b74b655404070b636a8dd6d7a13c3adc07882ef30 \ + --hash=sha256:5e097646944b66207023bc3c634827de858aebc226d5d4d6d16f0b77566ea182 \ + --hash=sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61 \ + --hash=sha256:610b5c77428a50269f38a534057444c249976433f40f53e3b47e68349cca1425 \ + --hash=sha256:625e3ef310e7fa3a761d48ca7ea1f9d8718a32b1542e727d584d82f4453d5eeb \ + --hash=sha256:657a972f46bbefdbba2d4f14413c0d079f9ae243bd68193cb5061b9732fa54c1 \ + --hash=sha256:69ab77a1373f1e7563e0fb5a29a8440367dec051da6c7405333699d07444f511 \ + --hash=sha256:6a520b4f9974b0a0a6ed73c2154de57cdfd0c8800f4f15ab2b73238ffed0b36e \ + --hash=sha256:6d68ce8e7b2075390e8ac1e1d3a99e8b6372c694bbe612632606d1d546794207 \ + --hash=sha256:6dcc3d17eac1df7859ae01202e9bb11ffa8c98949dcbeb1069c8b9a75917e01b \ + --hash=sha256:6dfdc2bfe69e9adf0df4915949c22a25b39d175d599bf98e7ddf620a13678585 \ + --hash=sha256:739e36ef7412b2bd940f75b278749106e6d025e40027c0b94a17ef7968d55d56 \ + --hash=sha256:7429e7faa1a60cad26ae4227f4dd0459efde239e494c7312624ce228e04f6391 \ + --hash=sha256:74da9f97daec6928567b48c90ea2c82a106b2d500f397eeb8941e47d30b1ca85 \ + --hash=sha256:74e4f025ef3db1c6da4460dd27c118d8cd136d0391da4e387a15e48e5c975147 \ + --hash=sha256:75a9632f1d4f698b2e6e2e1ada40e71f369b15d69baddb8968dcc8e683839b18 \ + --hash=sha256:76acba4c66c47d27c8365e7c10b3d8016a7da83d3191d053a58382311a8bf4e1 \ + --hash=sha256:79d1fb9252e7e2cfe4de6e9a6610c7cbb99b9708e2c3e29057f487de5a9eaefa \ + --hash=sha256:7ce7ad8abebe737ad6143d9d3bf94b88b93365ea30a5b81f6877ec9c0dee0a48 \ + --hash=sha256:7ed07b3062b055d7a7f9d6557a251cc655eed0b3152b76de619516621c56f5d3 \ + --hash=sha256:7ff762670cada8e05b32bf1e4dc50b140790909caa8303cfddc4d702b71ea184 \ + --hash=sha256:8268cbcd48c5375f46e000adb1390572c98879eb4f77910c6053d25cc3ac2c67 \ + --hash=sha256:875a3f90d7eb5c5d77e529080d95140eacb3c6d13ad5b616ee8095447b1d22e7 \ + --hash=sha256:89feb82ca055af0fe797a2323ec9043b26bc371365847dbe83c7fd2e2f181c34 \ + --hash=sha256:8a7e24cb69ee5f32e003f50e016d5fde438010c1022c96738b04fc2423e61706 \ + --hash=sha256:8ab6a358d1286498d80fe67bd3d69fcbc7d1359b45b41e74c4a26964ca99c3f8 \ + --hash=sha256:8b8df03a9e995b6211dafa63b32f9d405881518ff1ddd775db4e7b98fb545e1c \ + --hash=sha256:8cf85a6e40ff1f37fe0f25719aadf443686b1ac7652593dc53c7ef9b8492b115 \ + --hash=sha256:8e8d351ff44c1638cb6e980623d517abd9f580d2e53bfcd18d8941c052a5a009 \ + --hash=sha256:9164361769b6ca7769079f4d426a41df6164879f7f3568be9086e15baca61466 \ + --hash=sha256:96e85aa09274955bb6bd483eaf5b12abadade01010478154b0ec70284c1b1526 \ + --hash=sha256:981a06a3076997adf7c743dcd0d7a0415582661e2517c7d961493572e909aa1d \ + --hash=sha256:9cd5323344d8ebb9fb5e96da5de5ad4ebab993bbf51674259dbe9d7a18049525 \ + --hash=sha256:9d6c6ea6a11ca0ff9cd0390b885984ed31157c168565702959c25e2191674a14 \ + --hash=sha256:a02d3c48f9bb1e10c7788d92c0c7db6f2002d024ab6e74d6f45ae33e3d0288a3 \ + --hash=sha256:a233bb68625a85126ac9f1fc66d24337d6e8a0f9207b688eec2e7c880f012ec0 \ + --hash=sha256:a2f6a1bc2460e643785a2cde17293bd7a8f990884b822f7bca47bee0a82fc66b \ + --hash=sha256:a6d17e0370d2516d5bb9062c7b4cb731cff921fc875644c3d751ad857ba9c5b1 \ + --hash=sha256:a6d2092797b388342c1bc932077ad232f914351932353e2e8706851c870bca1f \ + --hash=sha256:ab67ed772c584b7ef2379797bf14b82df9aa5f7438c5b9a09624dd834c1c1aaf \ + --hash=sha256:ac6540c9fff6e3813d29d0403ee7a81897f1d8ecc09a8ff84d2eea70ede1cdbf \ + --hash=sha256:ae4073a60ab98529ab8a72ebf429f2a8cc612619a8c04e08bed27450d52103c0 \ + --hash=sha256:ae791f6bd43305aade8c0e22f816b34f3b72b6c820477aab4d18473a37e8090b \ + --hash=sha256:aef5474d913d3b05e613906ba4090433c515e13ea49c837aca18bde190853dff \ + --hash=sha256:b0b3f2df149efb242cee2ffdeb6674b7f30d23c9a7af26595099afaf46ef4e88 \ + --hash=sha256:b128092c927eaf485928cec0c28f6b8bead277e28acf56800e972aa2c2abd7a2 \ + --hash=sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40 \ + --hash=sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716 \ + --hash=sha256:b47633251727c8fe279f34025844b3b3a3e40cd1b198356d003aa146258d13a2 \ + --hash=sha256:b537bd04d7ccd7c6350cdaaaad911f6312cbd61e6e6045542f781c7f8b2e99d2 \ + --hash=sha256:b5e4ef22ff25bfd4ede5f8fb30f7b24446345f3e79d9b7455aef2836437bc38a \ + --hash=sha256:b74b9ea10063efb77a965a8d5f4182806fbf59ed068b3c3fd6f30d2ac7bee734 \ + --hash=sha256:bb2dc4898180bea79863d5487e5f9c7c34297414bad54bcd0f0852aee9cfdb87 \ + --hash=sha256:bbc4b80af581e18568ff07f6395c02114d05f4865c2812a1f02f2eaecf0bfd48 \ + --hash=sha256:bcc98f911f10278d1daf14b87d65325851a1d29153caaf146877ec37031d5f36 \ + --hash=sha256:be49ad33819d7dcc28a309b86d4ed98e1a65f3075c6acd3cd4fe32103235222b \ + --hash=sha256:bec4bd9133420c5c52d562469c754f27c5c9e36ee06abc169612c959bd7dbb07 \ + --hash=sha256:c2faf60c583af0d135e853c86ac2735ce178f0e338a3c7f9ae8f622fd2eb788c \ + --hash=sha256:c689d0d5381f56de7bd6966a4541bff6e08bf8d3871bbd89a0c6ab18aa699573 \ + --hash=sha256:c7079d5eb1c1315a858bbf180000757db8ad904a89476653232db835c3114001 \ + --hash=sha256:cb3942960f0beb9f46e2a71a3aca220d1ca32feb5a398656be934320804c0df9 \ + --hash=sha256:cd9e78285da6c9ba2d5c769628f43ef66d96ac3085e59b10ad4f3707980710d3 \ + --hash=sha256:cf2a978c795b54c539f47964ec05e35c05bd045db5ca1e8366988c7f2fe6b3ce \ + --hash=sha256:d14a0d029a4e176795cef99c056d58067c06195e0c7e2dbb293bf95c08f772a3 \ + --hash=sha256:d237ba6664b8e60fd90b8549a149a74fcc675272e0e95539a00522e4ca688b04 \ + --hash=sha256:d26a618ae1766279f2660aca0081b2220aca6bd1aa06b2cf73f07383faf48927 \ + --hash=sha256:d28cb356f119a437cc58a13f8135ab8a4c8ece18159eb9194b0d269ec4e28083 \ + --hash=sha256:d4ed0c7cbecde7194cd3228c044e86bf73e30a23505af852857c09c24e77ec5d \ + --hash=sha256:d83e2d94b69bf31ead2fa45f0acdef0757fa0458a129734f59f67f3d2eb7ef32 \ + --hash=sha256:d8bbcd21769594dbba9c37d3c819e2d5847656ca99c747ddb31ac1701d0c0ed9 \ + --hash=sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f \ + --hash=sha256:dc911208b18842a3a57266d8e51fc3cfaccee90a5351b92079beed912a7914c2 \ + --hash=sha256:dfa7c241073d8f2b8e8dbc7803c434f57dbb83ae2a3d7892dd068d99e96efe2c \ + --hash=sha256:e282aedd63c639c07c3857097fc0e236f984ceb4089a8b284da1c526491e3f3d \ + --hash=sha256:e290d79a4107d7d794634ce3e985b9ae4f920380a813717adf61804904dc4393 \ + --hash=sha256:e3d9d13603410b72787579769469af730c38f2f25505573a5888a94b62b920f8 \ + --hash=sha256:e481bba1e11ba585fb06db666bfc23dbe181dbafc7b25776156120bf12e0d5a6 \ + --hash=sha256:e49b052b768bb74f58c7dda4e0bdf7b79d43a9204ca584ffe1fb48a6f3c84c66 \ + --hash=sha256:eb00b549b13bd6d884c863554566095bf6fa9c3cecb2e7b399c4bc7904cb33b5 \ + --hash=sha256:ec87c44f619380878bd49ca109669c9f221d9ae6883a5bcb3616785fa8f94c97 \ + --hash=sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196 \ + --hash=sha256:f11ae142f3a322d44513de1018b50f474f8f736bc3cd91d969f464b5bfef8836 \ + --hash=sha256:f2a09f6184f17a80897172863a655467da2b11151ec98ba8d7af89f17bf63dae \ + --hash=sha256:f5b65529bb2f21ac7861a0e94fdbf5dc0daab41497d18223b46ee8515e5ad297 \ + --hash=sha256:f60fdd125d85bf9c279ffb8e94c78c51b3b6a37711464e1f5f31078b45002421 \ + --hash=sha256:f61efaf4bed1cc0860e567d2ecb2363974d414f7f1f124b1df368bbf183453a6 \ + --hash=sha256:f90e552ecbad426eab352e7b2933091f2be77115bb16f09f78404861c8322981 \ + --hash=sha256:f956196ef61369f1685d14dad80611488d8dc1ef00be57c0c5a03064005b0f30 \ + --hash=sha256:fb91819461b1b56d06fa4bcf86617fac795f6a99d12239fb0c68dbeba41a0a30 \ + --hash=sha256:fbc9d316552f9ef7bba39f4edfad4a734d3d6f93341232a9dddadec4f15d425f \ + --hash=sha256:ff69a9a0b4b17d78170c73abe2ab12084bdf1691550c5629ad1fe7849433f324 \ + --hash=sha256:ffb2be176fed4457e445fe540617f0252a72a8bc56208fd65a690fdb1f57660b + # via -r requirements.in +markupsafe==2.1.5 \ + --hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \ + --hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \ + --hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \ + --hash=sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3 \ + --hash=sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532 \ + --hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \ + --hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \ + --hash=sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df \ + --hash=sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4 \ + --hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \ + --hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \ + --hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \ + --hash=sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8 \ + --hash=sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371 \ + --hash=sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2 \ + --hash=sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465 \ + --hash=sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52 \ + --hash=sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6 \ + --hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \ + --hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \ + --hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \ + --hash=sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0 \ + --hash=sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029 \ + --hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \ + --hash=sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a \ + --hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \ + --hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \ + --hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \ + --hash=sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf \ + --hash=sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9 \ + --hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \ + --hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \ + --hash=sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3 \ + --hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \ + --hash=sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46 \ + --hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \ + --hash=sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a \ + --hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \ + --hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \ + --hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \ + --hash=sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea \ + --hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \ + --hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \ + --hash=sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e \ + --hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \ + --hash=sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f \ + --hash=sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50 \ + --hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \ + --hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \ + --hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \ + --hash=sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff \ + --hash=sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2 \ + --hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \ + --hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \ + --hash=sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf \ + --hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \ + --hash=sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5 \ + --hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \ + --hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \ + --hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68 + # via jinja2 +nox==2024.4.15 \ + --hash=sha256:6492236efa15a460ecb98e7b67562a28b70da006ab0be164e8821177577c0565 \ + --hash=sha256:ecf6700199cdfa9e5ea0a41ff5e6ef4641d09508eda6edb89d9987864115817f + # via -r requirements.in +packaging==24.1 \ + --hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \ + --hash=sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124 + # via + # deprecation + # nox +platformdirs==4.2.2 \ + --hash=sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee \ + --hash=sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3 + # via virtualenv +protobuf==3.20.2 \ + --hash=sha256:03d76b7bd42ac4a6e109742a4edf81ffe26ffd87c5993126d894fe48a120396a \ + --hash=sha256:09e25909c4297d71d97612f04f41cea8fa8510096864f2835ad2f3b3df5a5559 \ + --hash=sha256:18e34a10ae10d458b027d7638a599c964b030c1739ebd035a1dfc0e22baa3bfe \ + --hash=sha256:291fb4307094bf5ccc29f424b42268640e00d5240bf0d9b86bf3079f7576474d \ + --hash=sha256:2c0b040d0b5d5d207936ca2d02f00f765906622c07d3fa19c23a16a8ca71873f \ + --hash=sha256:384164994727f274cc34b8abd41a9e7e0562801361ee77437099ff6dfedd024b \ + --hash=sha256:3cb608e5a0eb61b8e00fe641d9f0282cd0eedb603be372f91f163cbfbca0ded0 \ + --hash=sha256:5d9402bf27d11e37801d1743eada54372f986a372ec9679673bfcc5c60441151 \ + --hash=sha256:712dca319eee507a1e7df3591e639a2b112a2f4a62d40fe7832a16fd19151750 \ + --hash=sha256:7a5037af4e76c975b88c3becdf53922b5ffa3f2cddf657574a4920a3b33b80f3 \ + --hash=sha256:8228e56a865c27163d5d1d1771d94b98194aa6917bcfb6ce139cbfa8e3c27334 \ + --hash=sha256:84a1544252a933ef07bb0b5ef13afe7c36232a774affa673fc3636f7cee1db6c \ + --hash=sha256:84fe5953b18a383fd4495d375fe16e1e55e0a3afe7b4f7b4d01a3a0649fcda9d \ + --hash=sha256:9c673c8bfdf52f903081816b9e0e612186684f4eb4c17eeb729133022d6032e3 \ + --hash=sha256:a9e5ae5a8e8985c67e8944c23035a0dff2c26b0f5070b2f55b217a1c33bbe8b1 \ + --hash=sha256:b4fdb29c5a7406e3f7ef176b2a7079baa68b5b854f364c21abe327bbeec01cdb \ + --hash=sha256:c184485e0dfba4dfd451c3bd348c2e685d6523543a0f91b9fd4ae90eb09e8422 \ + --hash=sha256:c9cdf251c582c16fd6a9f5e95836c90828d51b0069ad22f463761d27c6c19019 \ + --hash=sha256:e39cf61bb8582bda88cdfebc0db163b774e7e03364bbf9ce1ead13863e81e359 \ + --hash=sha256:e8fbc522303e09036c752a0afcc5c0603e917222d8bedc02813fd73b4b4ed804 \ + --hash=sha256:f34464ab1207114e73bba0794d1257c150a2b89b7a9faf504e00af7c9fd58978 \ + --hash=sha256:f52dabc96ca99ebd2169dadbe018824ebda08a795c7684a0b7d203a290f3adb0 + # via -r requirements.in +pyyaml==6.0.1 \ + --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \ + --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ + --hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \ + --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \ + --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \ + --hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \ + --hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \ + --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \ + --hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \ + --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \ + --hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \ + --hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \ + --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \ + --hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \ + --hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \ + --hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \ + --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \ + --hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \ + --hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \ + --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \ + --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \ + --hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \ + --hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \ + --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \ + --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \ + --hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \ + --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ + --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ + --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ + --hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \ + --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ + --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ + --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ + --hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \ + --hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \ + --hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \ + --hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \ + --hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \ + --hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \ + --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \ + --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \ + --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \ + --hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \ + --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \ + --hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \ + --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \ + --hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \ + --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \ + --hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \ + --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ + --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f + # via -r requirements.in +requests==2.32.3 \ + --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ + --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 + # via -r requirements.in +urllib3==2.2.2 \ + --hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \ + --hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168 + # via requests +virtualenv==20.26.3 \ + --hash=sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a \ + --hash=sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589 + # via nox +watchdog==4.0.1 \ + --hash=sha256:0144c0ea9997b92615af1d94afc0c217e07ce2c14912c7b1a5731776329fcfc7 \ + --hash=sha256:03e70d2df2258fb6cb0e95bbdbe06c16e608af94a3ffbd2b90c3f1e83eb10767 \ + --hash=sha256:093b23e6906a8b97051191a4a0c73a77ecc958121d42346274c6af6520dec175 \ + --hash=sha256:123587af84260c991dc5f62a6e7ef3d1c57dfddc99faacee508c71d287248459 \ + --hash=sha256:17e32f147d8bf9657e0922c0940bcde863b894cd871dbb694beb6704cfbd2fb5 \ + --hash=sha256:206afc3d964f9a233e6ad34618ec60b9837d0582b500b63687e34011e15bb429 \ + --hash=sha256:4107ac5ab936a63952dea2a46a734a23230aa2f6f9db1291bf171dac3ebd53c6 \ + --hash=sha256:4513ec234c68b14d4161440e07f995f231be21a09329051e67a2118a7a612d2d \ + --hash=sha256:611be3904f9843f0529c35a3ff3fd617449463cb4b73b1633950b3d97fa4bfb7 \ + --hash=sha256:62c613ad689ddcb11707f030e722fa929f322ef7e4f18f5335d2b73c61a85c28 \ + --hash=sha256:667f3c579e813fcbad1b784db7a1aaa96524bed53437e119f6a2f5de4db04235 \ + --hash=sha256:6e8c70d2cd745daec2a08734d9f63092b793ad97612470a0ee4cbb8f5f705c57 \ + --hash=sha256:7577b3c43e5909623149f76b099ac49a1a01ca4e167d1785c76eb52fa585745a \ + --hash=sha256:998d2be6976a0ee3a81fb8e2777900c28641fb5bfbd0c84717d89bca0addcdc5 \ + --hash=sha256:a3c2c317a8fb53e5b3d25790553796105501a235343f5d2bf23bb8649c2c8709 \ + --hash=sha256:ab998f567ebdf6b1da7dc1e5accfaa7c6992244629c0fdaef062f43249bd8dee \ + --hash=sha256:ac7041b385f04c047fcc2951dc001671dee1b7e0615cde772e84b01fbf68ee84 \ + --hash=sha256:bca36be5707e81b9e6ce3208d92d95540d4ca244c006b61511753583c81c70dd \ + --hash=sha256:c9904904b6564d4ee8a1ed820db76185a3c96e05560c776c79a6ce5ab71888ba \ + --hash=sha256:cad0bbd66cd59fc474b4a4376bc5ac3fc698723510cbb64091c2a793b18654db \ + --hash=sha256:d10a681c9a1d5a77e75c48a3b8e1a9f2ae2928eda463e8d33660437705659682 \ + --hash=sha256:d4925e4bf7b9bddd1c3de13c9b8a2cdb89a468f640e66fbfabaf735bd85b3e35 \ + --hash=sha256:d7b9f5f3299e8dd230880b6c55504a1f69cf1e4316275d1b215ebdd8187ec88d \ + --hash=sha256:da2dfdaa8006eb6a71051795856bedd97e5b03e57da96f98e375682c48850645 \ + --hash=sha256:dddba7ca1c807045323b6af4ff80f5ddc4d654c8bce8317dde1bd96b128ed253 \ + --hash=sha256:e7921319fe4430b11278d924ef66d4daa469fafb1da679a2e48c935fa27af193 \ + --hash=sha256:e93f451f2dfa433d97765ca2634628b789b49ba8b504fdde5837cdcf25fdb53b \ + --hash=sha256:eebaacf674fa25511e8867028d281e602ee6500045b57f43b08778082f7f8b44 \ + --hash=sha256:ef0107bbb6a55f5be727cfc2ef945d5676b97bffb8425650dadbb184be9f9a2b \ + --hash=sha256:f0de0f284248ab40188f23380b03b59126d1479cd59940f2a34f8852db710625 \ + --hash=sha256:f27279d060e2ab24c0aa98363ff906d2386aa6c4dc2f1a374655d4e02a6c5e5e \ + --hash=sha256:f8affdf3c0f0466e69f5b3917cdd042f89c8c63aebdb9f7c078996f607cdb0f5 + # via -r requirements.in + +# WARNING: The following packages were not pinned, but pip requires them to be +# pinned when the requirements file includes hashes and the requirement is not +# satisfied by a package already installed. Consider using the --allow-unsafe flag. +# setuptools From d93093da2510aebfba90368acbb3715659315478 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 20:24:55 +0000 Subject: [PATCH 14/33] install java-only synthool in dockerfile --- .../library_generation/library_generation.Dockerfile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.cloudbuild/library_generation/library_generation.Dockerfile b/.cloudbuild/library_generation/library_generation.Dockerfile index 237978d3ff..0e177287fa 100644 --- a/.cloudbuild/library_generation/library_generation.Dockerfile +++ b/.cloudbuild/library_generation/library_generation.Dockerfile @@ -43,11 +43,16 @@ RUN ln -s $(which python3.11) /usr/local/bin/python RUN ln -s $(which python3.11) /usr/local/bin/python3 RUN python -m pip install --upgrade pip -# install scripts as a python package +# install main scripts as a python package WORKDIR /src RUN python -m pip install -r requirements.txt RUN python -m pip install . +# install java-only synthtool scripts as a python package +WORKDIR /src/owlbot/synthtool +RUN python -m pip install -r requirements.txt +RUN python -m pip install . + # Install nvm with node and npm ENV NODE_VERSION 20.12.0 WORKDIR /home From 80e008d442c06a17626c0ffe3220341990145ba3 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 21:04:27 +0000 Subject: [PATCH 15/33] remove unused languages/common.py --- .../owlbot/synthtool/languages/common.py | 52 ------------------- 1 file changed, 52 deletions(-) delete mode 100644 library_generation/owlbot/synthtool/languages/common.py diff --git a/library_generation/owlbot/synthtool/languages/common.py b/library_generation/owlbot/synthtool/languages/common.py deleted file mode 100644 index 876ca0c79d..0000000000 --- a/library_generation/owlbot/synthtool/languages/common.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright 2018 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -from pathlib import Path -import re - - -def update_library_version(version: str, root_dir: str): - """ - Rewrites all metadata files in ./samples/generated to the version number argument - - """ - root_dir_path = Path(root_dir) - - snippet_metadata_files = get_sample_metadata_files(root_dir_path) - for file in snippet_metadata_files: - with open(file, "r+") as f: - data = json.load(f) - data["clientLibrary"]["version"] = version - f.seek(0) - json.dump(data, f, indent=4) - f.truncate() - - -def get_sample_metadata_files(dir: Path, regex: str = r"snippet_metadata"): - """ - Walks through samples/generated to find all snippet metadata files, appends them to a list - - Returns: - A list of all metadata files. - """ - metadata_files = [] - for path_object in dir.glob("**/*"): - if path_object.is_file(): - if re.search(regex, str(path_object)): - metadata_files.append(str(Path(path_object).resolve())) - if path_object.is_dir(): - get_sample_metadata_files(path_object) - - return metadata_files From 5fd8f9e55934a4d27020f7510a2face588bff703 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 21:14:54 +0000 Subject: [PATCH 16/33] add changes of https://github.com/googleapis/synthtool/commit/696c4bff721f5541cd75fdc97d413f8f39d2a2c1 --- library_generation/owlbot/synthtool/languages/java.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library_generation/owlbot/synthtool/languages/java.py b/library_generation/owlbot/synthtool/languages/java.py index 1cb0292145..00fdb903ba 100644 --- a/library_generation/owlbot/synthtool/languages/java.py +++ b/library_generation/owlbot/synthtool/languages/java.py @@ -69,6 +69,8 @@ LIBRARIES_BOM_VERSION = "libraries_bom_version" LIBRARIES_BOM_VERSION_ENV_KEY = "SYNTHTOOL_LIBRARIES_BOM_VERSION" HEADER_REGEX = re.compile("\\* Copyright \\d{4} Google LLC") +LIBRARY_VERSION = "library_version" +LIBRARY_VERSION_ENV_KEY = "SYNTHTOOL_LIBRARY_VERSION" def _file_has_header(path: Path) -> bool: @@ -325,6 +327,7 @@ def common_templates( kwargs[METADATA][LIBRARIES_BOM_VERSION] = os.getenv( LIBRARIES_BOM_VERSION_ENV_KEY ) + kwargs[METADATA][LIBRARY_VERSION] = os.getenv(LIBRARY_VERSION_ENV_KEY) # Special libraries that are not GAPIC_AUTO but in the monorepo special_libs_in_monorepo = [ "java-translate", From 635d92a9f6cb67e5715809d893c7c462230a9ebd Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Wed, 3 Jul 2024 21:16:49 +0000 Subject: [PATCH 17/33] lint --- library_generation/owlbot/synthtool/gcp/common.py | 5 +++-- library_generation/owlbot/synthtool/languages/java.py | 4 +++- library_generation/owlbot/synthtool/sources/templates.py | 1 - library_generation/owlbot/synthtool/transforms.py | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/library_generation/owlbot/synthtool/gcp/common.py b/library_generation/owlbot/synthtool/gcp/common.py index c1723a6161..7bee3589a5 100644 --- a/library_generation/owlbot/synthtool/gcp/common.py +++ b/library_generation/owlbot/synthtool/gcp/common.py @@ -45,8 +45,8 @@ class CommonTemplates: def __init__(self, template_path: Optional[Path] = None): if LOCAL_TEMPLATES is None: - logger.error("env var SYNTHTOOL_TEMPLATES must be set") - sys.exit(1) + logger.error("env var SYNTHTOOL_TEMPLATES must be set") + sys.exit(1) logger.debug(f"Using local templates at {LOCAL_TEMPLATES}") self._template_root = Path(LOCAL_TEMPLATES) self._templates = templates.Templates(self._template_root) @@ -151,6 +151,7 @@ def _get_default_branch_name(repository_name: str) -> str: # the majority of our repositories: return os.getenv("DEFAULT_BRANCH", "master") + def load_partials(files: List[str] = []) -> Dict: """ hand-crafted artisanal markdown can be provided in a .readme-partials.yml. diff --git a/library_generation/owlbot/synthtool/languages/java.py b/library_generation/owlbot/synthtool/languages/java.py index 00fdb903ba..f8fc56e0b8 100644 --- a/library_generation/owlbot/synthtool/languages/java.py +++ b/library_generation/owlbot/synthtool/languages/java.py @@ -350,7 +350,9 @@ def common_templates( ) ) - templates = gcp.common.CommonTemplates(template_path=template_path).java_library(**kwargs) + templates = gcp.common.CommonTemplates(template_path=template_path).java_library( + **kwargs + ) # skip README generation on Kokoro (autosynth) if os.environ.get("KOKORO_ROOT") is not None: diff --git a/library_generation/owlbot/synthtool/sources/templates.py b/library_generation/owlbot/synthtool/sources/templates.py index 8402b3d39b..3ba5391f49 100644 --- a/library_generation/owlbot/synthtool/sources/templates.py +++ b/library_generation/owlbot/synthtool/sources/templates.py @@ -79,4 +79,3 @@ def render(self, subdir: PathOrStr = ".", **kwargs) -> Path: print(f"Skipping: {template_name}") return self.dir - diff --git a/library_generation/owlbot/synthtool/transforms.py b/library_generation/owlbot/synthtool/transforms.py index e51f4668b3..2720fc4bd6 100644 --- a/library_generation/owlbot/synthtool/transforms.py +++ b/library_generation/owlbot/synthtool/transforms.py @@ -28,6 +28,7 @@ logger = logging.getLogger() logger.setLevel(logging.DEBUG) + class MissingSourceError(Exception): pass From 8dbdd909bb7ca6acdebbe0f6eb2bea5456ab8eba Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Thu, 4 Jul 2024 15:28:34 +0000 Subject: [PATCH 18/33] remove unused transforms function --- .../owlbot/synthtool/transforms.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/library_generation/owlbot/synthtool/transforms.py b/library_generation/owlbot/synthtool/transforms.py index 2720fc4bd6..cf87995847 100644 --- a/library_generation/owlbot/synthtool/transforms.py +++ b/library_generation/owlbot/synthtool/transforms.py @@ -150,25 +150,6 @@ def _copy_dir_to_existing_dir( return copied -def dont_overwrite( - patterns: ListOfPathsOrStrs, -) -> Callable[[str, str, Path], str]: - """Returns a merge function that doesn't overwrite the specified files. - - Pass the return value to move() or copy() to avoid overwriting existing - files. - """ - - def merge(source_text: str, destinaton_text: str, file_path: Path) -> str: - for pattern in patterns: - if file_path.match(str(pattern)): - logger.debug(f"Preserving existing contents of {file_path}.") - return destinaton_text - return source_text - - return merge - - def move( sources: ListOfPathsOrStrs, destination: PathOrStr = None, From b25bd6028ecd02a4c4d8c526c12f01b85d1fe556 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Thu, 4 Jul 2024 15:33:34 +0000 Subject: [PATCH 19/33] merge setup.py files --- .../owlbot/synthtool/__init__.py | 2 -- library_generation/owlbot/synthtool/setup.py | 13 --------- library_generation/setup.py | 2 ++ .../test/resources/goldens/owlbot-golden.py | 29 ++++++++++--------- 4 files changed, 18 insertions(+), 28 deletions(-) delete mode 100644 library_generation/owlbot/synthtool/setup.py diff --git a/library_generation/owlbot/synthtool/__init__.py b/library_generation/owlbot/synthtool/__init__.py index 6aee9a3967..6e5f1f12e2 100644 --- a/library_generation/owlbot/synthtool/__init__.py +++ b/library_generation/owlbot/synthtool/__init__.py @@ -19,7 +19,6 @@ from synthtool.transforms import ( move, replace, - dont_overwrite, get_staging_dirs, remove_staging_dirs, ) @@ -30,7 +29,6 @@ "copy", "move", "replace", - "dont_overwrite", "get_staging_dirs", "remove_staging_dirs", ] diff --git a/library_generation/owlbot/synthtool/setup.py b/library_generation/owlbot/synthtool/setup.py deleted file mode 100644 index e67d00aa64..0000000000 --- a/library_generation/owlbot/synthtool/setup.py +++ /dev/null @@ -1,13 +0,0 @@ -""" -Package information of the transferred synthool scripts -""" - -from setuptools import setup - -setup( - name="synthtool", - version="0.1", - package_dir={ - "synthtool": ".", - }, -) diff --git a/library_generation/setup.py b/library_generation/setup.py index 240d9264b3..9f78194241 100755 --- a/library_generation/setup.py +++ b/library_generation/setup.py @@ -9,6 +9,7 @@ version="0.1", package_dir={ "library_generation": ".", + "synthtool": "owlbot/synthtool", }, package_data={ "library_generation": [ @@ -25,5 +26,6 @@ "owlbot/templates/poms/*.j2", "owlbot/templates/java_library/**/*", ], + "synthtool": ["owlbot/synthtool/**/*"], }, ) diff --git a/library_generation/test/resources/goldens/owlbot-golden.py b/library_generation/test/resources/goldens/owlbot-golden.py index 2ba11e6bba..7559eaf034 100644 --- a/library_generation/test/resources/goldens/owlbot-golden.py +++ b/library_generation/test/resources/goldens/owlbot-golden.py @@ -21,16 +21,19 @@ s.move(library) s.remove_staging_dirs() -java.common_templates(monorepo=True, excludes=[ - ".github/*", - ".kokoro/*", - "samples/*", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.md", - "LICENSE", - "SECURITY.md", - "java.header", - "license-checks.xml", - "renovate.json", - ".gitignore" -]) \ No newline at end of file +java.common_templates( + monorepo=True, + excludes=[ + ".github/*", + ".kokoro/*", + "samples/*", + "CODE_OF_CONDUCT.md", + "CONTRIBUTING.md", + "LICENSE", + "SECURITY.md", + "java.header", + "license-checks.xml", + "renovate.json", + ".gitignore", + ], +) From 643f957d8f26dc363756aad200b4749d4b6a71f4 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Thu, 4 Jul 2024 15:42:38 +0000 Subject: [PATCH 20/33] remove unused default_branch function --- .../owlbot/synthtool/gcp/common.py | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/library_generation/owlbot/synthtool/gcp/common.py b/library_generation/owlbot/synthtool/gcp/common.py index 7bee3589a5..b115665af6 100644 --- a/library_generation/owlbot/synthtool/gcp/common.py +++ b/library_generation/owlbot/synthtool/gcp/common.py @@ -63,11 +63,6 @@ def _generic_library(self, directory: str, relative_dir=None, **kwargs) -> Path: t = templates.TemplateGroup(self._template_root / directory, self.excludes) - if "repository" in kwargs["metadata"] and "repo" in kwargs["metadata"]: - kwargs["metadata"]["repo"]["default_branch"] = _get_default_branch_name( - kwargs["metadata"]["repository"] - ) - result = t.render(**kwargs) _tracked_paths.add(result) @@ -135,23 +130,6 @@ def _load_repo_metadata( return {} -def _get_default_branch_name(repository_name: str) -> str: - """Read the default branch name from the environment. - - First checks environment variable DEFAULT_BRANCH_PATH. If found, it - reads the contents of the file at DEFAULT_BRANCH_PATH and returns it. - - Then checks environment varabile DEFAULT_BRANCH, and returns it if found. - """ - default_branch_path = os.getenv("DEFAULT_BRANCH_PATH") - if default_branch_path: - return Path(default_branch_path).read_text().strip() - - # This default should be switched to "main" once we've migrated - # the majority of our repositories: - return os.getenv("DEFAULT_BRANCH", "master") - - def load_partials(files: List[str] = []) -> Dict: """ hand-crafted artisanal markdown can be provided in a .readme-partials.yml. From f03aac3286541fa5f81c4ed03ee888a805e7cc6e Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Thu, 4 Jul 2024 15:46:52 +0000 Subject: [PATCH 21/33] merge requirements file --- .../owlbot/synthtool/requirements.in | 12 - .../owlbot/synthtool/requirements.txt | 478 ------------------ library_generation/requirements.txt | 6 + 3 files changed, 6 insertions(+), 490 deletions(-) delete mode 100644 library_generation/owlbot/synthtool/requirements.in delete mode 100644 library_generation/owlbot/synthtool/requirements.txt diff --git a/library_generation/owlbot/synthtool/requirements.in b/library_generation/owlbot/synthtool/requirements.in deleted file mode 100644 index a7de2c8017..0000000000 --- a/library_generation/owlbot/synthtool/requirements.in +++ /dev/null @@ -1,12 +0,0 @@ -setuptools==65.5.1 - -nox -requests>=2.31.0 -pyyaml -jinja2 -deprecation -protobuf==3.20.2 -watchdog - -# some java processing requires xml handling -lxml diff --git a/library_generation/owlbot/synthtool/requirements.txt b/library_generation/owlbot/synthtool/requirements.txt deleted file mode 100644 index 55bc63ce12..0000000000 --- a/library_generation/owlbot/synthtool/requirements.txt +++ /dev/null @@ -1,478 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile --generate-hashes requirements.in -# -argcomplete==3.4.0 \ - --hash=sha256:69a79e083a716173e5532e0fa3bef45f793f4e61096cf52b5a42c0211c8b8aa5 \ - --hash=sha256:c2abcdfe1be8ace47ba777d4fce319eb13bf8ad9dace8d085dcad6eded88057f - # via nox -certifi==2024.6.2 \ - --hash=sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516 \ - --hash=sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56 - # via requests -charset-normalizer==3.3.2 \ - --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ - --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ - --hash=sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786 \ - --hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \ - --hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \ - --hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \ - --hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \ - --hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \ - --hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \ - --hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \ - --hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \ - --hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \ - --hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \ - --hash=sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6 \ - --hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \ - --hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \ - --hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \ - --hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \ - --hash=sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714 \ - --hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \ - --hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \ - --hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \ - --hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \ - --hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \ - --hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \ - --hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \ - --hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \ - --hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \ - --hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \ - --hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \ - --hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \ - --hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \ - --hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \ - --hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \ - --hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \ - --hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \ - --hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \ - --hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \ - --hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \ - --hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \ - --hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \ - --hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \ - --hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \ - --hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \ - --hash=sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99 \ - --hash=sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c \ - --hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \ - --hash=sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811 \ - --hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \ - --hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \ - --hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \ - --hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \ - --hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \ - --hash=sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c \ - --hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \ - --hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \ - --hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \ - --hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \ - --hash=sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985 \ - --hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \ - --hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \ - --hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \ - --hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \ - --hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \ - --hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \ - --hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \ - --hash=sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8 \ - --hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \ - --hash=sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5 \ - --hash=sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5 \ - --hash=sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711 \ - --hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \ - --hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \ - --hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \ - --hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \ - --hash=sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4 \ - --hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \ - --hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \ - --hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \ - --hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \ - --hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \ - --hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \ - --hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \ - --hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \ - --hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \ - --hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \ - --hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \ - --hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \ - --hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \ - --hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561 - # via requests -colorlog==6.8.2 \ - --hash=sha256:3e3e079a41feb5a1b64f978b5ea4f46040a94f11f0e8bbb8261e3dbbeca64d44 \ - --hash=sha256:4dcbb62368e2800cb3c5abd348da7e53f6c362dda502ec27c560b2e58a66bd33 - # via nox -deprecation==2.1.0 \ - --hash=sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff \ - --hash=sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a - # via -r requirements.in -distlib==0.3.8 \ - --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ - --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 - # via virtualenv -filelock==3.15.4 \ - --hash=sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb \ - --hash=sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7 - # via virtualenv -idna==3.7 \ - --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ - --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 - # via requests -jinja2==3.1.4 \ - --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \ - --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d - # via -r requirements.in -lxml==5.2.2 \ - --hash=sha256:02437fb7308386867c8b7b0e5bc4cd4b04548b1c5d089ffb8e7b31009b961dc3 \ - --hash=sha256:02f6a8eb6512fdc2fd4ca10a49c341c4e109aa6e9448cc4859af5b949622715a \ - --hash=sha256:05f8757b03208c3f50097761be2dea0aba02e94f0dc7023ed73a7bb14ff11eb0 \ - --hash=sha256:06668e39e1f3c065349c51ac27ae430719d7806c026fec462e5693b08b95696b \ - --hash=sha256:07542787f86112d46d07d4f3c4e7c760282011b354d012dc4141cc12a68cef5f \ - --hash=sha256:08ea0f606808354eb8f2dfaac095963cb25d9d28e27edcc375d7b30ab01abbf6 \ - --hash=sha256:0969e92af09c5687d769731e3f39ed62427cc72176cebb54b7a9d52cc4fa3b73 \ - --hash=sha256:0a028b61a2e357ace98b1615fc03f76eb517cc028993964fe08ad514b1e8892d \ - --hash=sha256:0b3f5016e00ae7630a4b83d0868fca1e3d494c78a75b1c7252606a3a1c5fc2ad \ - --hash=sha256:13e69be35391ce72712184f69000cda04fc89689429179bc4c0ae5f0b7a8c21b \ - --hash=sha256:16a8326e51fcdffc886294c1e70b11ddccec836516a343f9ed0f82aac043c24a \ - --hash=sha256:19b4e485cd07b7d83e3fe3b72132e7df70bfac22b14fe4bf7a23822c3a35bff5 \ - --hash=sha256:1a2569a1f15ae6c8c64108a2cd2b4a858fc1e13d25846be0666fc144715e32ab \ - --hash=sha256:1a7aca7964ac4bb07680d5c9d63b9d7028cace3e2d43175cb50bba8c5ad33316 \ - --hash=sha256:1b590b39ef90c6b22ec0be925b211298e810b4856909c8ca60d27ffbca6c12e6 \ - --hash=sha256:1d8a701774dfc42a2f0b8ccdfe7dbc140500d1049e0632a611985d943fcf12df \ - --hash=sha256:1e275ea572389e41e8b039ac076a46cb87ee6b8542df3fff26f5baab43713bca \ - --hash=sha256:2304d3c93f2258ccf2cf7a6ba8c761d76ef84948d87bf9664e14d203da2cd264 \ - --hash=sha256:23441e2b5339bc54dc949e9e675fa35efe858108404ef9aa92f0456929ef6fe8 \ - --hash=sha256:23cfafd56887eaed93d07bc4547abd5e09d837a002b791e9767765492a75883f \ - --hash=sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b \ - --hash=sha256:2eb2227ce1ff998faf0cd7fe85bbf086aa41dfc5af3b1d80867ecfe75fb68df3 \ - --hash=sha256:2fb0ba3e8566548d6c8e7dd82a8229ff47bd8fb8c2da237607ac8e5a1b8312e5 \ - --hash=sha256:303f540ad2dddd35b92415b74b900c749ec2010e703ab3bfd6660979d01fd4ed \ - --hash=sha256:339ee4a4704bc724757cd5dd9dc8cf4d00980f5d3e6e06d5847c1b594ace68ab \ - --hash=sha256:33ce9e786753743159799fdf8e92a5da351158c4bfb6f2db0bf31e7892a1feb5 \ - --hash=sha256:343ab62e9ca78094f2306aefed67dcfad61c4683f87eee48ff2fd74902447726 \ - --hash=sha256:34e17913c431f5ae01d8658dbf792fdc457073dcdfbb31dc0cc6ab256e664a8d \ - --hash=sha256:364d03207f3e603922d0d3932ef363d55bbf48e3647395765f9bfcbdf6d23632 \ - --hash=sha256:38b67afb0a06b8575948641c1d6d68e41b83a3abeae2ca9eed2ac59892b36706 \ - --hash=sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8 \ - --hash=sha256:3b019d4ee84b683342af793b56bb35034bd749e4cbdd3d33f7d1107790f8c472 \ - --hash=sha256:3b6a30a9ab040b3f545b697cb3adbf3696c05a3a68aad172e3fd7ca73ab3c835 \ - --hash=sha256:3d1e35572a56941b32c239774d7e9ad724074d37f90c7a7d499ab98761bd80cf \ - --hash=sha256:3d98de734abee23e61f6b8c2e08a88453ada7d6486dc7cdc82922a03968928db \ - --hash=sha256:453d037e09a5176d92ec0fd282e934ed26d806331a8b70ab431a81e2fbabf56d \ - --hash=sha256:45f9494613160d0405682f9eee781c7e6d1bf45f819654eb249f8f46a2c22545 \ - --hash=sha256:4820c02195d6dfb7b8508ff276752f6b2ff8b64ae5d13ebe02e7667e035000b9 \ - --hash=sha256:49095a38eb333aaf44c06052fd2ec3b8f23e19747ca7ec6f6c954ffea6dbf7be \ - --hash=sha256:4aefd911793b5d2d7a921233a54c90329bf3d4a6817dc465f12ffdfe4fc7b8fe \ - --hash=sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905 \ - --hash=sha256:4c30a2f83677876465f44c018830f608fa3c6a8a466eb223535035fbc16f3438 \ - --hash=sha256:50127c186f191b8917ea2fb8b206fbebe87fd414a6084d15568c27d0a21d60db \ - --hash=sha256:50ccb5d355961c0f12f6cf24b7187dbabd5433f29e15147a67995474f27d1776 \ - --hash=sha256:519895c99c815a1a24a926d5b60627ce5ea48e9f639a5cd328bda0515ea0f10c \ - --hash=sha256:54401c77a63cc7d6dc4b4e173bb484f28a5607f3df71484709fe037c92d4f0ed \ - --hash=sha256:546cf886f6242dff9ec206331209db9c8e1643ae642dea5fdbecae2453cb50fd \ - --hash=sha256:55ce6b6d803890bd3cc89975fca9de1dff39729b43b73cb15ddd933b8bc20484 \ - --hash=sha256:56793b7a1a091a7c286b5f4aa1fe4ae5d1446fe742d00cdf2ffb1077865db10d \ - --hash=sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6 \ - --hash=sha256:5b8c041b6265e08eac8a724b74b655404070b636a8dd6d7a13c3adc07882ef30 \ - --hash=sha256:5e097646944b66207023bc3c634827de858aebc226d5d4d6d16f0b77566ea182 \ - --hash=sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61 \ - --hash=sha256:610b5c77428a50269f38a534057444c249976433f40f53e3b47e68349cca1425 \ - --hash=sha256:625e3ef310e7fa3a761d48ca7ea1f9d8718a32b1542e727d584d82f4453d5eeb \ - --hash=sha256:657a972f46bbefdbba2d4f14413c0d079f9ae243bd68193cb5061b9732fa54c1 \ - --hash=sha256:69ab77a1373f1e7563e0fb5a29a8440367dec051da6c7405333699d07444f511 \ - --hash=sha256:6a520b4f9974b0a0a6ed73c2154de57cdfd0c8800f4f15ab2b73238ffed0b36e \ - --hash=sha256:6d68ce8e7b2075390e8ac1e1d3a99e8b6372c694bbe612632606d1d546794207 \ - --hash=sha256:6dcc3d17eac1df7859ae01202e9bb11ffa8c98949dcbeb1069c8b9a75917e01b \ - --hash=sha256:6dfdc2bfe69e9adf0df4915949c22a25b39d175d599bf98e7ddf620a13678585 \ - --hash=sha256:739e36ef7412b2bd940f75b278749106e6d025e40027c0b94a17ef7968d55d56 \ - --hash=sha256:7429e7faa1a60cad26ae4227f4dd0459efde239e494c7312624ce228e04f6391 \ - --hash=sha256:74da9f97daec6928567b48c90ea2c82a106b2d500f397eeb8941e47d30b1ca85 \ - --hash=sha256:74e4f025ef3db1c6da4460dd27c118d8cd136d0391da4e387a15e48e5c975147 \ - --hash=sha256:75a9632f1d4f698b2e6e2e1ada40e71f369b15d69baddb8968dcc8e683839b18 \ - --hash=sha256:76acba4c66c47d27c8365e7c10b3d8016a7da83d3191d053a58382311a8bf4e1 \ - --hash=sha256:79d1fb9252e7e2cfe4de6e9a6610c7cbb99b9708e2c3e29057f487de5a9eaefa \ - --hash=sha256:7ce7ad8abebe737ad6143d9d3bf94b88b93365ea30a5b81f6877ec9c0dee0a48 \ - --hash=sha256:7ed07b3062b055d7a7f9d6557a251cc655eed0b3152b76de619516621c56f5d3 \ - --hash=sha256:7ff762670cada8e05b32bf1e4dc50b140790909caa8303cfddc4d702b71ea184 \ - --hash=sha256:8268cbcd48c5375f46e000adb1390572c98879eb4f77910c6053d25cc3ac2c67 \ - --hash=sha256:875a3f90d7eb5c5d77e529080d95140eacb3c6d13ad5b616ee8095447b1d22e7 \ - --hash=sha256:89feb82ca055af0fe797a2323ec9043b26bc371365847dbe83c7fd2e2f181c34 \ - --hash=sha256:8a7e24cb69ee5f32e003f50e016d5fde438010c1022c96738b04fc2423e61706 \ - --hash=sha256:8ab6a358d1286498d80fe67bd3d69fcbc7d1359b45b41e74c4a26964ca99c3f8 \ - --hash=sha256:8b8df03a9e995b6211dafa63b32f9d405881518ff1ddd775db4e7b98fb545e1c \ - --hash=sha256:8cf85a6e40ff1f37fe0f25719aadf443686b1ac7652593dc53c7ef9b8492b115 \ - --hash=sha256:8e8d351ff44c1638cb6e980623d517abd9f580d2e53bfcd18d8941c052a5a009 \ - --hash=sha256:9164361769b6ca7769079f4d426a41df6164879f7f3568be9086e15baca61466 \ - --hash=sha256:96e85aa09274955bb6bd483eaf5b12abadade01010478154b0ec70284c1b1526 \ - --hash=sha256:981a06a3076997adf7c743dcd0d7a0415582661e2517c7d961493572e909aa1d \ - --hash=sha256:9cd5323344d8ebb9fb5e96da5de5ad4ebab993bbf51674259dbe9d7a18049525 \ - --hash=sha256:9d6c6ea6a11ca0ff9cd0390b885984ed31157c168565702959c25e2191674a14 \ - --hash=sha256:a02d3c48f9bb1e10c7788d92c0c7db6f2002d024ab6e74d6f45ae33e3d0288a3 \ - --hash=sha256:a233bb68625a85126ac9f1fc66d24337d6e8a0f9207b688eec2e7c880f012ec0 \ - --hash=sha256:a2f6a1bc2460e643785a2cde17293bd7a8f990884b822f7bca47bee0a82fc66b \ - --hash=sha256:a6d17e0370d2516d5bb9062c7b4cb731cff921fc875644c3d751ad857ba9c5b1 \ - --hash=sha256:a6d2092797b388342c1bc932077ad232f914351932353e2e8706851c870bca1f \ - --hash=sha256:ab67ed772c584b7ef2379797bf14b82df9aa5f7438c5b9a09624dd834c1c1aaf \ - --hash=sha256:ac6540c9fff6e3813d29d0403ee7a81897f1d8ecc09a8ff84d2eea70ede1cdbf \ - --hash=sha256:ae4073a60ab98529ab8a72ebf429f2a8cc612619a8c04e08bed27450d52103c0 \ - --hash=sha256:ae791f6bd43305aade8c0e22f816b34f3b72b6c820477aab4d18473a37e8090b \ - --hash=sha256:aef5474d913d3b05e613906ba4090433c515e13ea49c837aca18bde190853dff \ - --hash=sha256:b0b3f2df149efb242cee2ffdeb6674b7f30d23c9a7af26595099afaf46ef4e88 \ - --hash=sha256:b128092c927eaf485928cec0c28f6b8bead277e28acf56800e972aa2c2abd7a2 \ - --hash=sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40 \ - --hash=sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716 \ - --hash=sha256:b47633251727c8fe279f34025844b3b3a3e40cd1b198356d003aa146258d13a2 \ - --hash=sha256:b537bd04d7ccd7c6350cdaaaad911f6312cbd61e6e6045542f781c7f8b2e99d2 \ - --hash=sha256:b5e4ef22ff25bfd4ede5f8fb30f7b24446345f3e79d9b7455aef2836437bc38a \ - --hash=sha256:b74b9ea10063efb77a965a8d5f4182806fbf59ed068b3c3fd6f30d2ac7bee734 \ - --hash=sha256:bb2dc4898180bea79863d5487e5f9c7c34297414bad54bcd0f0852aee9cfdb87 \ - --hash=sha256:bbc4b80af581e18568ff07f6395c02114d05f4865c2812a1f02f2eaecf0bfd48 \ - --hash=sha256:bcc98f911f10278d1daf14b87d65325851a1d29153caaf146877ec37031d5f36 \ - --hash=sha256:be49ad33819d7dcc28a309b86d4ed98e1a65f3075c6acd3cd4fe32103235222b \ - --hash=sha256:bec4bd9133420c5c52d562469c754f27c5c9e36ee06abc169612c959bd7dbb07 \ - --hash=sha256:c2faf60c583af0d135e853c86ac2735ce178f0e338a3c7f9ae8f622fd2eb788c \ - --hash=sha256:c689d0d5381f56de7bd6966a4541bff6e08bf8d3871bbd89a0c6ab18aa699573 \ - --hash=sha256:c7079d5eb1c1315a858bbf180000757db8ad904a89476653232db835c3114001 \ - --hash=sha256:cb3942960f0beb9f46e2a71a3aca220d1ca32feb5a398656be934320804c0df9 \ - --hash=sha256:cd9e78285da6c9ba2d5c769628f43ef66d96ac3085e59b10ad4f3707980710d3 \ - --hash=sha256:cf2a978c795b54c539f47964ec05e35c05bd045db5ca1e8366988c7f2fe6b3ce \ - --hash=sha256:d14a0d029a4e176795cef99c056d58067c06195e0c7e2dbb293bf95c08f772a3 \ - --hash=sha256:d237ba6664b8e60fd90b8549a149a74fcc675272e0e95539a00522e4ca688b04 \ - --hash=sha256:d26a618ae1766279f2660aca0081b2220aca6bd1aa06b2cf73f07383faf48927 \ - --hash=sha256:d28cb356f119a437cc58a13f8135ab8a4c8ece18159eb9194b0d269ec4e28083 \ - --hash=sha256:d4ed0c7cbecde7194cd3228c044e86bf73e30a23505af852857c09c24e77ec5d \ - --hash=sha256:d83e2d94b69bf31ead2fa45f0acdef0757fa0458a129734f59f67f3d2eb7ef32 \ - --hash=sha256:d8bbcd21769594dbba9c37d3c819e2d5847656ca99c747ddb31ac1701d0c0ed9 \ - --hash=sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f \ - --hash=sha256:dc911208b18842a3a57266d8e51fc3cfaccee90a5351b92079beed912a7914c2 \ - --hash=sha256:dfa7c241073d8f2b8e8dbc7803c434f57dbb83ae2a3d7892dd068d99e96efe2c \ - --hash=sha256:e282aedd63c639c07c3857097fc0e236f984ceb4089a8b284da1c526491e3f3d \ - --hash=sha256:e290d79a4107d7d794634ce3e985b9ae4f920380a813717adf61804904dc4393 \ - --hash=sha256:e3d9d13603410b72787579769469af730c38f2f25505573a5888a94b62b920f8 \ - --hash=sha256:e481bba1e11ba585fb06db666bfc23dbe181dbafc7b25776156120bf12e0d5a6 \ - --hash=sha256:e49b052b768bb74f58c7dda4e0bdf7b79d43a9204ca584ffe1fb48a6f3c84c66 \ - --hash=sha256:eb00b549b13bd6d884c863554566095bf6fa9c3cecb2e7b399c4bc7904cb33b5 \ - --hash=sha256:ec87c44f619380878bd49ca109669c9f221d9ae6883a5bcb3616785fa8f94c97 \ - --hash=sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196 \ - --hash=sha256:f11ae142f3a322d44513de1018b50f474f8f736bc3cd91d969f464b5bfef8836 \ - --hash=sha256:f2a09f6184f17a80897172863a655467da2b11151ec98ba8d7af89f17bf63dae \ - --hash=sha256:f5b65529bb2f21ac7861a0e94fdbf5dc0daab41497d18223b46ee8515e5ad297 \ - --hash=sha256:f60fdd125d85bf9c279ffb8e94c78c51b3b6a37711464e1f5f31078b45002421 \ - --hash=sha256:f61efaf4bed1cc0860e567d2ecb2363974d414f7f1f124b1df368bbf183453a6 \ - --hash=sha256:f90e552ecbad426eab352e7b2933091f2be77115bb16f09f78404861c8322981 \ - --hash=sha256:f956196ef61369f1685d14dad80611488d8dc1ef00be57c0c5a03064005b0f30 \ - --hash=sha256:fb91819461b1b56d06fa4bcf86617fac795f6a99d12239fb0c68dbeba41a0a30 \ - --hash=sha256:fbc9d316552f9ef7bba39f4edfad4a734d3d6f93341232a9dddadec4f15d425f \ - --hash=sha256:ff69a9a0b4b17d78170c73abe2ab12084bdf1691550c5629ad1fe7849433f324 \ - --hash=sha256:ffb2be176fed4457e445fe540617f0252a72a8bc56208fd65a690fdb1f57660b - # via -r requirements.in -markupsafe==2.1.5 \ - --hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \ - --hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \ - --hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \ - --hash=sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3 \ - --hash=sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532 \ - --hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \ - --hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \ - --hash=sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df \ - --hash=sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4 \ - --hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \ - --hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \ - --hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \ - --hash=sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8 \ - --hash=sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371 \ - --hash=sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2 \ - --hash=sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465 \ - --hash=sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52 \ - --hash=sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6 \ - --hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \ - --hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \ - --hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \ - --hash=sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0 \ - --hash=sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029 \ - --hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \ - --hash=sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a \ - --hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \ - --hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \ - --hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \ - --hash=sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf \ - --hash=sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9 \ - --hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \ - --hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \ - --hash=sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3 \ - --hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \ - --hash=sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46 \ - --hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \ - --hash=sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a \ - --hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \ - --hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \ - --hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \ - --hash=sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea \ - --hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \ - --hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \ - --hash=sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e \ - --hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \ - --hash=sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f \ - --hash=sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50 \ - --hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \ - --hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \ - --hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \ - --hash=sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff \ - --hash=sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2 \ - --hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \ - --hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \ - --hash=sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf \ - --hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \ - --hash=sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5 \ - --hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \ - --hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \ - --hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68 - # via jinja2 -nox==2024.4.15 \ - --hash=sha256:6492236efa15a460ecb98e7b67562a28b70da006ab0be164e8821177577c0565 \ - --hash=sha256:ecf6700199cdfa9e5ea0a41ff5e6ef4641d09508eda6edb89d9987864115817f - # via -r requirements.in -packaging==24.1 \ - --hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \ - --hash=sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124 - # via - # deprecation - # nox -platformdirs==4.2.2 \ - --hash=sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee \ - --hash=sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3 - # via virtualenv -protobuf==3.20.2 \ - --hash=sha256:03d76b7bd42ac4a6e109742a4edf81ffe26ffd87c5993126d894fe48a120396a \ - --hash=sha256:09e25909c4297d71d97612f04f41cea8fa8510096864f2835ad2f3b3df5a5559 \ - --hash=sha256:18e34a10ae10d458b027d7638a599c964b030c1739ebd035a1dfc0e22baa3bfe \ - --hash=sha256:291fb4307094bf5ccc29f424b42268640e00d5240bf0d9b86bf3079f7576474d \ - --hash=sha256:2c0b040d0b5d5d207936ca2d02f00f765906622c07d3fa19c23a16a8ca71873f \ - --hash=sha256:384164994727f274cc34b8abd41a9e7e0562801361ee77437099ff6dfedd024b \ - --hash=sha256:3cb608e5a0eb61b8e00fe641d9f0282cd0eedb603be372f91f163cbfbca0ded0 \ - --hash=sha256:5d9402bf27d11e37801d1743eada54372f986a372ec9679673bfcc5c60441151 \ - --hash=sha256:712dca319eee507a1e7df3591e639a2b112a2f4a62d40fe7832a16fd19151750 \ - --hash=sha256:7a5037af4e76c975b88c3becdf53922b5ffa3f2cddf657574a4920a3b33b80f3 \ - --hash=sha256:8228e56a865c27163d5d1d1771d94b98194aa6917bcfb6ce139cbfa8e3c27334 \ - --hash=sha256:84a1544252a933ef07bb0b5ef13afe7c36232a774affa673fc3636f7cee1db6c \ - --hash=sha256:84fe5953b18a383fd4495d375fe16e1e55e0a3afe7b4f7b4d01a3a0649fcda9d \ - --hash=sha256:9c673c8bfdf52f903081816b9e0e612186684f4eb4c17eeb729133022d6032e3 \ - --hash=sha256:a9e5ae5a8e8985c67e8944c23035a0dff2c26b0f5070b2f55b217a1c33bbe8b1 \ - --hash=sha256:b4fdb29c5a7406e3f7ef176b2a7079baa68b5b854f364c21abe327bbeec01cdb \ - --hash=sha256:c184485e0dfba4dfd451c3bd348c2e685d6523543a0f91b9fd4ae90eb09e8422 \ - --hash=sha256:c9cdf251c582c16fd6a9f5e95836c90828d51b0069ad22f463761d27c6c19019 \ - --hash=sha256:e39cf61bb8582bda88cdfebc0db163b774e7e03364bbf9ce1ead13863e81e359 \ - --hash=sha256:e8fbc522303e09036c752a0afcc5c0603e917222d8bedc02813fd73b4b4ed804 \ - --hash=sha256:f34464ab1207114e73bba0794d1257c150a2b89b7a9faf504e00af7c9fd58978 \ - --hash=sha256:f52dabc96ca99ebd2169dadbe018824ebda08a795c7684a0b7d203a290f3adb0 - # via -r requirements.in -pyyaml==6.0.1 \ - --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \ - --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ - --hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \ - --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \ - --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \ - --hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \ - --hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \ - --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \ - --hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \ - --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \ - --hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \ - --hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \ - --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \ - --hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \ - --hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \ - --hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \ - --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \ - --hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \ - --hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \ - --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \ - --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \ - --hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \ - --hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \ - --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \ - --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \ - --hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \ - --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ - --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ - --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ - --hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \ - --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ - --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ - --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ - --hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \ - --hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \ - --hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \ - --hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \ - --hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \ - --hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \ - --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \ - --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \ - --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \ - --hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \ - --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \ - --hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \ - --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \ - --hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \ - --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \ - --hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \ - --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ - --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f - # via -r requirements.in -requests==2.32.3 \ - --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ - --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 - # via -r requirements.in -urllib3==2.2.2 \ - --hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \ - --hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168 - # via requests -virtualenv==20.26.3 \ - --hash=sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a \ - --hash=sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589 - # via nox -watchdog==4.0.1 \ - --hash=sha256:0144c0ea9997b92615af1d94afc0c217e07ce2c14912c7b1a5731776329fcfc7 \ - --hash=sha256:03e70d2df2258fb6cb0e95bbdbe06c16e608af94a3ffbd2b90c3f1e83eb10767 \ - --hash=sha256:093b23e6906a8b97051191a4a0c73a77ecc958121d42346274c6af6520dec175 \ - --hash=sha256:123587af84260c991dc5f62a6e7ef3d1c57dfddc99faacee508c71d287248459 \ - --hash=sha256:17e32f147d8bf9657e0922c0940bcde863b894cd871dbb694beb6704cfbd2fb5 \ - --hash=sha256:206afc3d964f9a233e6ad34618ec60b9837d0582b500b63687e34011e15bb429 \ - --hash=sha256:4107ac5ab936a63952dea2a46a734a23230aa2f6f9db1291bf171dac3ebd53c6 \ - --hash=sha256:4513ec234c68b14d4161440e07f995f231be21a09329051e67a2118a7a612d2d \ - --hash=sha256:611be3904f9843f0529c35a3ff3fd617449463cb4b73b1633950b3d97fa4bfb7 \ - --hash=sha256:62c613ad689ddcb11707f030e722fa929f322ef7e4f18f5335d2b73c61a85c28 \ - --hash=sha256:667f3c579e813fcbad1b784db7a1aaa96524bed53437e119f6a2f5de4db04235 \ - --hash=sha256:6e8c70d2cd745daec2a08734d9f63092b793ad97612470a0ee4cbb8f5f705c57 \ - --hash=sha256:7577b3c43e5909623149f76b099ac49a1a01ca4e167d1785c76eb52fa585745a \ - --hash=sha256:998d2be6976a0ee3a81fb8e2777900c28641fb5bfbd0c84717d89bca0addcdc5 \ - --hash=sha256:a3c2c317a8fb53e5b3d25790553796105501a235343f5d2bf23bb8649c2c8709 \ - --hash=sha256:ab998f567ebdf6b1da7dc1e5accfaa7c6992244629c0fdaef062f43249bd8dee \ - --hash=sha256:ac7041b385f04c047fcc2951dc001671dee1b7e0615cde772e84b01fbf68ee84 \ - --hash=sha256:bca36be5707e81b9e6ce3208d92d95540d4ca244c006b61511753583c81c70dd \ - --hash=sha256:c9904904b6564d4ee8a1ed820db76185a3c96e05560c776c79a6ce5ab71888ba \ - --hash=sha256:cad0bbd66cd59fc474b4a4376bc5ac3fc698723510cbb64091c2a793b18654db \ - --hash=sha256:d10a681c9a1d5a77e75c48a3b8e1a9f2ae2928eda463e8d33660437705659682 \ - --hash=sha256:d4925e4bf7b9bddd1c3de13c9b8a2cdb89a468f640e66fbfabaf735bd85b3e35 \ - --hash=sha256:d7b9f5f3299e8dd230880b6c55504a1f69cf1e4316275d1b215ebdd8187ec88d \ - --hash=sha256:da2dfdaa8006eb6a71051795856bedd97e5b03e57da96f98e375682c48850645 \ - --hash=sha256:dddba7ca1c807045323b6af4ff80f5ddc4d654c8bce8317dde1bd96b128ed253 \ - --hash=sha256:e7921319fe4430b11278d924ef66d4daa469fafb1da679a2e48c935fa27af193 \ - --hash=sha256:e93f451f2dfa433d97765ca2634628b789b49ba8b504fdde5837cdcf25fdb53b \ - --hash=sha256:eebaacf674fa25511e8867028d281e602ee6500045b57f43b08778082f7f8b44 \ - --hash=sha256:ef0107bbb6a55f5be727cfc2ef945d5676b97bffb8425650dadbb184be9f9a2b \ - --hash=sha256:f0de0f284248ab40188f23380b03b59126d1479cd59940f2a34f8852db710625 \ - --hash=sha256:f27279d060e2ab24c0aa98363ff906d2386aa6c4dc2f1a374655d4e02a6c5e5e \ - --hash=sha256:f8affdf3c0f0466e69f5b3917cdd042f89c8c63aebdb9f7c078996f607cdb0f5 - # via -r requirements.in - -# WARNING: The following packages were not pinned, but pip requires them to be -# pinned when the requirements file includes hashes and the requirement is not -# satisfied by a package already installed. Consider using the --allow-unsafe flag. -# setuptools diff --git a/library_generation/requirements.txt b/library_generation/requirements.txt index d31cff9fca..ac9810d84c 100644 --- a/library_generation/requirements.txt +++ b/library_generation/requirements.txt @@ -17,3 +17,9 @@ typing==3.7.4.3 parameterized==0.9.0 # used in parameterized test colorlog==6.8.2 watchdog==4.0.1 +nox==2024.4.15 +requests==2.32.3 +setuptools==65.5.1 +jinja2==3.1.4 +deprecation==2.1.0 +protobuf==3.20.2 From 3c6d02a5ef8156815c3b859cd12156e7111d6c7b Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Thu, 4 Jul 2024 15:49:13 +0000 Subject: [PATCH 22/33] use base requirements file --- library_generation/requirements.in | 27 ++ library_generation/requirements.txt | 589 ++++++++++++++++++++++++++-- 2 files changed, 591 insertions(+), 25 deletions(-) create mode 100644 library_generation/requirements.in diff --git a/library_generation/requirements.in b/library_generation/requirements.in new file mode 100644 index 0000000000..720ef9fc34 --- /dev/null +++ b/library_generation/requirements.in @@ -0,0 +1,27 @@ +# add new packages here and run `pip-compile requirements.in --generate-hashes` to +# generate an entry with hashes in requirements.txt +absl-py==2.1.0 +attr==0.3.2 +attrs==23.2.0 +black==24.4.2 +click==8.1.7 +gitdb==4.0.11 +GitPython==3.1.43 +Jinja2==3.1.4 +lxml==5.2.2 +MarkupSafe==2.1.5 +mypy-extensions==1.0.0 +packaging==23.2 +pathspec==0.12.1 +PyYAML==6.0.1 +smmap==5.0.1 +typing==3.7.4.3 +parameterized==0.9.0 # used in parameterized test +colorlog==6.8.2 +watchdog==4.0.1 +nox==2024.4.15 +requests==2.32.3 +setuptools==65.5.1 +jinja2==3.1.4 +deprecation==2.1.0 +protobuf==3.20.2 diff --git a/library_generation/requirements.txt b/library_generation/requirements.txt index ac9810d84c..279bacd357 100644 --- a/library_generation/requirements.txt +++ b/library_generation/requirements.txt @@ -1,25 +1,564 @@ -absl-py==2.1.0 -attr==0.3.2 -attrs==23.2.0 -black==24.4.2 -click==8.1.7 -gitdb==4.0.11 -GitPython==3.1.43 -Jinja2==3.1.4 -lxml==5.2.2 -MarkupSafe==2.1.5 -mypy-extensions==1.0.0 -packaging==23.2 -pathspec==0.12.1 -PyYAML==6.0.1 -smmap==5.0.1 -typing==3.7.4.3 -parameterized==0.9.0 # used in parameterized test -colorlog==6.8.2 -watchdog==4.0.1 -nox==2024.4.15 -requests==2.32.3 -setuptools==65.5.1 -jinja2==3.1.4 -deprecation==2.1.0 -protobuf==3.20.2 +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile --generate-hashes requirements.in +# +absl-py==2.1.0 \ + --hash=sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308 \ + --hash=sha256:7820790efbb316739cde8b4e19357243fc3608a152024288513dd968d7d959ff + # via -r requirements.in +argcomplete==3.4.0 \ + --hash=sha256:69a79e083a716173e5532e0fa3bef45f793f4e61096cf52b5a42c0211c8b8aa5 \ + --hash=sha256:c2abcdfe1be8ace47ba777d4fce319eb13bf8ad9dace8d085dcad6eded88057f + # via nox +attr==0.3.2 \ + --hash=sha256:1ceebca768181cdcce9827611b1d728e592be5d293911539ea3d0b0bfa1146f4 \ + --hash=sha256:4f4bffeea8c27387bde446675a7ac24f3b8fea1075f12d849b5f5c5181fc8336 + # via -r requirements.in +attrs==23.2.0 \ + --hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \ + --hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1 + # via -r requirements.in +black==24.4.2 \ + --hash=sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474 \ + --hash=sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1 \ + --hash=sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0 \ + --hash=sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8 \ + --hash=sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96 \ + --hash=sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1 \ + --hash=sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04 \ + --hash=sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021 \ + --hash=sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94 \ + --hash=sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d \ + --hash=sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c \ + --hash=sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7 \ + --hash=sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c \ + --hash=sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc \ + --hash=sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7 \ + --hash=sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d \ + --hash=sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c \ + --hash=sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741 \ + --hash=sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce \ + --hash=sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb \ + --hash=sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063 \ + --hash=sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e + # via -r requirements.in +certifi==2024.7.4 \ + --hash=sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b \ + --hash=sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90 + # via requests +charset-normalizer==3.3.2 \ + --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ + --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ + --hash=sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786 \ + --hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \ + --hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \ + --hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \ + --hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \ + --hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \ + --hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \ + --hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \ + --hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \ + --hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \ + --hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \ + --hash=sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6 \ + --hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \ + --hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \ + --hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \ + --hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \ + --hash=sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714 \ + --hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \ + --hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \ + --hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \ + --hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \ + --hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \ + --hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \ + --hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \ + --hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \ + --hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \ + --hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \ + --hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \ + --hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \ + --hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \ + --hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \ + --hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \ + --hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \ + --hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \ + --hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \ + --hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \ + --hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \ + --hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \ + --hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \ + --hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \ + --hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \ + --hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \ + --hash=sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99 \ + --hash=sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c \ + --hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \ + --hash=sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811 \ + --hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \ + --hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \ + --hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \ + --hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \ + --hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \ + --hash=sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c \ + --hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \ + --hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \ + --hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \ + --hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \ + --hash=sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985 \ + --hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \ + --hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \ + --hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \ + --hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \ + --hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \ + --hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \ + --hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \ + --hash=sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8 \ + --hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \ + --hash=sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5 \ + --hash=sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5 \ + --hash=sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711 \ + --hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \ + --hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \ + --hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \ + --hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \ + --hash=sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4 \ + --hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \ + --hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \ + --hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \ + --hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \ + --hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \ + --hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \ + --hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \ + --hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \ + --hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \ + --hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \ + --hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \ + --hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \ + --hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \ + --hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561 + # via requests +click==8.1.7 \ + --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ + --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de + # via + # -r requirements.in + # black +colorlog==6.8.2 \ + --hash=sha256:3e3e079a41feb5a1b64f978b5ea4f46040a94f11f0e8bbb8261e3dbbeca64d44 \ + --hash=sha256:4dcbb62368e2800cb3c5abd348da7e53f6c362dda502ec27c560b2e58a66bd33 + # via + # -r requirements.in + # nox +deprecation==2.1.0 \ + --hash=sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff \ + --hash=sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a + # via -r requirements.in +distlib==0.3.8 \ + --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ + --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 + # via virtualenv +filelock==3.15.4 \ + --hash=sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb \ + --hash=sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7 + # via virtualenv +gitdb==4.0.11 \ + --hash=sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4 \ + --hash=sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b + # via + # -r requirements.in + # gitpython +gitpython==3.1.43 \ + --hash=sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c \ + --hash=sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff + # via -r requirements.in +idna==3.7 \ + --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ + --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 + # via requests +jinja2==3.1.4 \ + --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \ + --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d + # via -r requirements.in +lxml==5.2.2 \ + --hash=sha256:02437fb7308386867c8b7b0e5bc4cd4b04548b1c5d089ffb8e7b31009b961dc3 \ + --hash=sha256:02f6a8eb6512fdc2fd4ca10a49c341c4e109aa6e9448cc4859af5b949622715a \ + --hash=sha256:05f8757b03208c3f50097761be2dea0aba02e94f0dc7023ed73a7bb14ff11eb0 \ + --hash=sha256:06668e39e1f3c065349c51ac27ae430719d7806c026fec462e5693b08b95696b \ + --hash=sha256:07542787f86112d46d07d4f3c4e7c760282011b354d012dc4141cc12a68cef5f \ + --hash=sha256:08ea0f606808354eb8f2dfaac095963cb25d9d28e27edcc375d7b30ab01abbf6 \ + --hash=sha256:0969e92af09c5687d769731e3f39ed62427cc72176cebb54b7a9d52cc4fa3b73 \ + --hash=sha256:0a028b61a2e357ace98b1615fc03f76eb517cc028993964fe08ad514b1e8892d \ + --hash=sha256:0b3f5016e00ae7630a4b83d0868fca1e3d494c78a75b1c7252606a3a1c5fc2ad \ + --hash=sha256:13e69be35391ce72712184f69000cda04fc89689429179bc4c0ae5f0b7a8c21b \ + --hash=sha256:16a8326e51fcdffc886294c1e70b11ddccec836516a343f9ed0f82aac043c24a \ + --hash=sha256:19b4e485cd07b7d83e3fe3b72132e7df70bfac22b14fe4bf7a23822c3a35bff5 \ + --hash=sha256:1a2569a1f15ae6c8c64108a2cd2b4a858fc1e13d25846be0666fc144715e32ab \ + --hash=sha256:1a7aca7964ac4bb07680d5c9d63b9d7028cace3e2d43175cb50bba8c5ad33316 \ + --hash=sha256:1b590b39ef90c6b22ec0be925b211298e810b4856909c8ca60d27ffbca6c12e6 \ + --hash=sha256:1d8a701774dfc42a2f0b8ccdfe7dbc140500d1049e0632a611985d943fcf12df \ + --hash=sha256:1e275ea572389e41e8b039ac076a46cb87ee6b8542df3fff26f5baab43713bca \ + --hash=sha256:2304d3c93f2258ccf2cf7a6ba8c761d76ef84948d87bf9664e14d203da2cd264 \ + --hash=sha256:23441e2b5339bc54dc949e9e675fa35efe858108404ef9aa92f0456929ef6fe8 \ + --hash=sha256:23cfafd56887eaed93d07bc4547abd5e09d837a002b791e9767765492a75883f \ + --hash=sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b \ + --hash=sha256:2eb2227ce1ff998faf0cd7fe85bbf086aa41dfc5af3b1d80867ecfe75fb68df3 \ + --hash=sha256:2fb0ba3e8566548d6c8e7dd82a8229ff47bd8fb8c2da237607ac8e5a1b8312e5 \ + --hash=sha256:303f540ad2dddd35b92415b74b900c749ec2010e703ab3bfd6660979d01fd4ed \ + --hash=sha256:339ee4a4704bc724757cd5dd9dc8cf4d00980f5d3e6e06d5847c1b594ace68ab \ + --hash=sha256:33ce9e786753743159799fdf8e92a5da351158c4bfb6f2db0bf31e7892a1feb5 \ + --hash=sha256:343ab62e9ca78094f2306aefed67dcfad61c4683f87eee48ff2fd74902447726 \ + --hash=sha256:34e17913c431f5ae01d8658dbf792fdc457073dcdfbb31dc0cc6ab256e664a8d \ + --hash=sha256:364d03207f3e603922d0d3932ef363d55bbf48e3647395765f9bfcbdf6d23632 \ + --hash=sha256:38b67afb0a06b8575948641c1d6d68e41b83a3abeae2ca9eed2ac59892b36706 \ + --hash=sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8 \ + --hash=sha256:3b019d4ee84b683342af793b56bb35034bd749e4cbdd3d33f7d1107790f8c472 \ + --hash=sha256:3b6a30a9ab040b3f545b697cb3adbf3696c05a3a68aad172e3fd7ca73ab3c835 \ + --hash=sha256:3d1e35572a56941b32c239774d7e9ad724074d37f90c7a7d499ab98761bd80cf \ + --hash=sha256:3d98de734abee23e61f6b8c2e08a88453ada7d6486dc7cdc82922a03968928db \ + --hash=sha256:453d037e09a5176d92ec0fd282e934ed26d806331a8b70ab431a81e2fbabf56d \ + --hash=sha256:45f9494613160d0405682f9eee781c7e6d1bf45f819654eb249f8f46a2c22545 \ + --hash=sha256:4820c02195d6dfb7b8508ff276752f6b2ff8b64ae5d13ebe02e7667e035000b9 \ + --hash=sha256:49095a38eb333aaf44c06052fd2ec3b8f23e19747ca7ec6f6c954ffea6dbf7be \ + --hash=sha256:4aefd911793b5d2d7a921233a54c90329bf3d4a6817dc465f12ffdfe4fc7b8fe \ + --hash=sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905 \ + --hash=sha256:4c30a2f83677876465f44c018830f608fa3c6a8a466eb223535035fbc16f3438 \ + --hash=sha256:50127c186f191b8917ea2fb8b206fbebe87fd414a6084d15568c27d0a21d60db \ + --hash=sha256:50ccb5d355961c0f12f6cf24b7187dbabd5433f29e15147a67995474f27d1776 \ + --hash=sha256:519895c99c815a1a24a926d5b60627ce5ea48e9f639a5cd328bda0515ea0f10c \ + --hash=sha256:54401c77a63cc7d6dc4b4e173bb484f28a5607f3df71484709fe037c92d4f0ed \ + --hash=sha256:546cf886f6242dff9ec206331209db9c8e1643ae642dea5fdbecae2453cb50fd \ + --hash=sha256:55ce6b6d803890bd3cc89975fca9de1dff39729b43b73cb15ddd933b8bc20484 \ + --hash=sha256:56793b7a1a091a7c286b5f4aa1fe4ae5d1446fe742d00cdf2ffb1077865db10d \ + --hash=sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6 \ + --hash=sha256:5b8c041b6265e08eac8a724b74b655404070b636a8dd6d7a13c3adc07882ef30 \ + --hash=sha256:5e097646944b66207023bc3c634827de858aebc226d5d4d6d16f0b77566ea182 \ + --hash=sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61 \ + --hash=sha256:610b5c77428a50269f38a534057444c249976433f40f53e3b47e68349cca1425 \ + --hash=sha256:625e3ef310e7fa3a761d48ca7ea1f9d8718a32b1542e727d584d82f4453d5eeb \ + --hash=sha256:657a972f46bbefdbba2d4f14413c0d079f9ae243bd68193cb5061b9732fa54c1 \ + --hash=sha256:69ab77a1373f1e7563e0fb5a29a8440367dec051da6c7405333699d07444f511 \ + --hash=sha256:6a520b4f9974b0a0a6ed73c2154de57cdfd0c8800f4f15ab2b73238ffed0b36e \ + --hash=sha256:6d68ce8e7b2075390e8ac1e1d3a99e8b6372c694bbe612632606d1d546794207 \ + --hash=sha256:6dcc3d17eac1df7859ae01202e9bb11ffa8c98949dcbeb1069c8b9a75917e01b \ + --hash=sha256:6dfdc2bfe69e9adf0df4915949c22a25b39d175d599bf98e7ddf620a13678585 \ + --hash=sha256:739e36ef7412b2bd940f75b278749106e6d025e40027c0b94a17ef7968d55d56 \ + --hash=sha256:7429e7faa1a60cad26ae4227f4dd0459efde239e494c7312624ce228e04f6391 \ + --hash=sha256:74da9f97daec6928567b48c90ea2c82a106b2d500f397eeb8941e47d30b1ca85 \ + --hash=sha256:74e4f025ef3db1c6da4460dd27c118d8cd136d0391da4e387a15e48e5c975147 \ + --hash=sha256:75a9632f1d4f698b2e6e2e1ada40e71f369b15d69baddb8968dcc8e683839b18 \ + --hash=sha256:76acba4c66c47d27c8365e7c10b3d8016a7da83d3191d053a58382311a8bf4e1 \ + --hash=sha256:79d1fb9252e7e2cfe4de6e9a6610c7cbb99b9708e2c3e29057f487de5a9eaefa \ + --hash=sha256:7ce7ad8abebe737ad6143d9d3bf94b88b93365ea30a5b81f6877ec9c0dee0a48 \ + --hash=sha256:7ed07b3062b055d7a7f9d6557a251cc655eed0b3152b76de619516621c56f5d3 \ + --hash=sha256:7ff762670cada8e05b32bf1e4dc50b140790909caa8303cfddc4d702b71ea184 \ + --hash=sha256:8268cbcd48c5375f46e000adb1390572c98879eb4f77910c6053d25cc3ac2c67 \ + --hash=sha256:875a3f90d7eb5c5d77e529080d95140eacb3c6d13ad5b616ee8095447b1d22e7 \ + --hash=sha256:89feb82ca055af0fe797a2323ec9043b26bc371365847dbe83c7fd2e2f181c34 \ + --hash=sha256:8a7e24cb69ee5f32e003f50e016d5fde438010c1022c96738b04fc2423e61706 \ + --hash=sha256:8ab6a358d1286498d80fe67bd3d69fcbc7d1359b45b41e74c4a26964ca99c3f8 \ + --hash=sha256:8b8df03a9e995b6211dafa63b32f9d405881518ff1ddd775db4e7b98fb545e1c \ + --hash=sha256:8cf85a6e40ff1f37fe0f25719aadf443686b1ac7652593dc53c7ef9b8492b115 \ + --hash=sha256:8e8d351ff44c1638cb6e980623d517abd9f580d2e53bfcd18d8941c052a5a009 \ + --hash=sha256:9164361769b6ca7769079f4d426a41df6164879f7f3568be9086e15baca61466 \ + --hash=sha256:96e85aa09274955bb6bd483eaf5b12abadade01010478154b0ec70284c1b1526 \ + --hash=sha256:981a06a3076997adf7c743dcd0d7a0415582661e2517c7d961493572e909aa1d \ + --hash=sha256:9cd5323344d8ebb9fb5e96da5de5ad4ebab993bbf51674259dbe9d7a18049525 \ + --hash=sha256:9d6c6ea6a11ca0ff9cd0390b885984ed31157c168565702959c25e2191674a14 \ + --hash=sha256:a02d3c48f9bb1e10c7788d92c0c7db6f2002d024ab6e74d6f45ae33e3d0288a3 \ + --hash=sha256:a233bb68625a85126ac9f1fc66d24337d6e8a0f9207b688eec2e7c880f012ec0 \ + --hash=sha256:a2f6a1bc2460e643785a2cde17293bd7a8f990884b822f7bca47bee0a82fc66b \ + --hash=sha256:a6d17e0370d2516d5bb9062c7b4cb731cff921fc875644c3d751ad857ba9c5b1 \ + --hash=sha256:a6d2092797b388342c1bc932077ad232f914351932353e2e8706851c870bca1f \ + --hash=sha256:ab67ed772c584b7ef2379797bf14b82df9aa5f7438c5b9a09624dd834c1c1aaf \ + --hash=sha256:ac6540c9fff6e3813d29d0403ee7a81897f1d8ecc09a8ff84d2eea70ede1cdbf \ + --hash=sha256:ae4073a60ab98529ab8a72ebf429f2a8cc612619a8c04e08bed27450d52103c0 \ + --hash=sha256:ae791f6bd43305aade8c0e22f816b34f3b72b6c820477aab4d18473a37e8090b \ + --hash=sha256:aef5474d913d3b05e613906ba4090433c515e13ea49c837aca18bde190853dff \ + --hash=sha256:b0b3f2df149efb242cee2ffdeb6674b7f30d23c9a7af26595099afaf46ef4e88 \ + --hash=sha256:b128092c927eaf485928cec0c28f6b8bead277e28acf56800e972aa2c2abd7a2 \ + --hash=sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40 \ + --hash=sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716 \ + --hash=sha256:b47633251727c8fe279f34025844b3b3a3e40cd1b198356d003aa146258d13a2 \ + --hash=sha256:b537bd04d7ccd7c6350cdaaaad911f6312cbd61e6e6045542f781c7f8b2e99d2 \ + --hash=sha256:b5e4ef22ff25bfd4ede5f8fb30f7b24446345f3e79d9b7455aef2836437bc38a \ + --hash=sha256:b74b9ea10063efb77a965a8d5f4182806fbf59ed068b3c3fd6f30d2ac7bee734 \ + --hash=sha256:bb2dc4898180bea79863d5487e5f9c7c34297414bad54bcd0f0852aee9cfdb87 \ + --hash=sha256:bbc4b80af581e18568ff07f6395c02114d05f4865c2812a1f02f2eaecf0bfd48 \ + --hash=sha256:bcc98f911f10278d1daf14b87d65325851a1d29153caaf146877ec37031d5f36 \ + --hash=sha256:be49ad33819d7dcc28a309b86d4ed98e1a65f3075c6acd3cd4fe32103235222b \ + --hash=sha256:bec4bd9133420c5c52d562469c754f27c5c9e36ee06abc169612c959bd7dbb07 \ + --hash=sha256:c2faf60c583af0d135e853c86ac2735ce178f0e338a3c7f9ae8f622fd2eb788c \ + --hash=sha256:c689d0d5381f56de7bd6966a4541bff6e08bf8d3871bbd89a0c6ab18aa699573 \ + --hash=sha256:c7079d5eb1c1315a858bbf180000757db8ad904a89476653232db835c3114001 \ + --hash=sha256:cb3942960f0beb9f46e2a71a3aca220d1ca32feb5a398656be934320804c0df9 \ + --hash=sha256:cd9e78285da6c9ba2d5c769628f43ef66d96ac3085e59b10ad4f3707980710d3 \ + --hash=sha256:cf2a978c795b54c539f47964ec05e35c05bd045db5ca1e8366988c7f2fe6b3ce \ + --hash=sha256:d14a0d029a4e176795cef99c056d58067c06195e0c7e2dbb293bf95c08f772a3 \ + --hash=sha256:d237ba6664b8e60fd90b8549a149a74fcc675272e0e95539a00522e4ca688b04 \ + --hash=sha256:d26a618ae1766279f2660aca0081b2220aca6bd1aa06b2cf73f07383faf48927 \ + --hash=sha256:d28cb356f119a437cc58a13f8135ab8a4c8ece18159eb9194b0d269ec4e28083 \ + --hash=sha256:d4ed0c7cbecde7194cd3228c044e86bf73e30a23505af852857c09c24e77ec5d \ + --hash=sha256:d83e2d94b69bf31ead2fa45f0acdef0757fa0458a129734f59f67f3d2eb7ef32 \ + --hash=sha256:d8bbcd21769594dbba9c37d3c819e2d5847656ca99c747ddb31ac1701d0c0ed9 \ + --hash=sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f \ + --hash=sha256:dc911208b18842a3a57266d8e51fc3cfaccee90a5351b92079beed912a7914c2 \ + --hash=sha256:dfa7c241073d8f2b8e8dbc7803c434f57dbb83ae2a3d7892dd068d99e96efe2c \ + --hash=sha256:e282aedd63c639c07c3857097fc0e236f984ceb4089a8b284da1c526491e3f3d \ + --hash=sha256:e290d79a4107d7d794634ce3e985b9ae4f920380a813717adf61804904dc4393 \ + --hash=sha256:e3d9d13603410b72787579769469af730c38f2f25505573a5888a94b62b920f8 \ + --hash=sha256:e481bba1e11ba585fb06db666bfc23dbe181dbafc7b25776156120bf12e0d5a6 \ + --hash=sha256:e49b052b768bb74f58c7dda4e0bdf7b79d43a9204ca584ffe1fb48a6f3c84c66 \ + --hash=sha256:eb00b549b13bd6d884c863554566095bf6fa9c3cecb2e7b399c4bc7904cb33b5 \ + --hash=sha256:ec87c44f619380878bd49ca109669c9f221d9ae6883a5bcb3616785fa8f94c97 \ + --hash=sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196 \ + --hash=sha256:f11ae142f3a322d44513de1018b50f474f8f736bc3cd91d969f464b5bfef8836 \ + --hash=sha256:f2a09f6184f17a80897172863a655467da2b11151ec98ba8d7af89f17bf63dae \ + --hash=sha256:f5b65529bb2f21ac7861a0e94fdbf5dc0daab41497d18223b46ee8515e5ad297 \ + --hash=sha256:f60fdd125d85bf9c279ffb8e94c78c51b3b6a37711464e1f5f31078b45002421 \ + --hash=sha256:f61efaf4bed1cc0860e567d2ecb2363974d414f7f1f124b1df368bbf183453a6 \ + --hash=sha256:f90e552ecbad426eab352e7b2933091f2be77115bb16f09f78404861c8322981 \ + --hash=sha256:f956196ef61369f1685d14dad80611488d8dc1ef00be57c0c5a03064005b0f30 \ + --hash=sha256:fb91819461b1b56d06fa4bcf86617fac795f6a99d12239fb0c68dbeba41a0a30 \ + --hash=sha256:fbc9d316552f9ef7bba39f4edfad4a734d3d6f93341232a9dddadec4f15d425f \ + --hash=sha256:ff69a9a0b4b17d78170c73abe2ab12084bdf1691550c5629ad1fe7849433f324 \ + --hash=sha256:ffb2be176fed4457e445fe540617f0252a72a8bc56208fd65a690fdb1f57660b + # via -r requirements.in +markupsafe==2.1.5 \ + --hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \ + --hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \ + --hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \ + --hash=sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3 \ + --hash=sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532 \ + --hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \ + --hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \ + --hash=sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df \ + --hash=sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4 \ + --hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \ + --hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \ + --hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \ + --hash=sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8 \ + --hash=sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371 \ + --hash=sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2 \ + --hash=sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465 \ + --hash=sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52 \ + --hash=sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6 \ + --hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \ + --hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \ + --hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \ + --hash=sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0 \ + --hash=sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029 \ + --hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \ + --hash=sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a \ + --hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \ + --hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \ + --hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \ + --hash=sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf \ + --hash=sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9 \ + --hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \ + --hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \ + --hash=sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3 \ + --hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \ + --hash=sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46 \ + --hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \ + --hash=sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a \ + --hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \ + --hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \ + --hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \ + --hash=sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea \ + --hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \ + --hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \ + --hash=sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e \ + --hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \ + --hash=sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f \ + --hash=sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50 \ + --hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \ + --hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \ + --hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \ + --hash=sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff \ + --hash=sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2 \ + --hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \ + --hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \ + --hash=sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf \ + --hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \ + --hash=sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5 \ + --hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \ + --hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \ + --hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68 + # via + # -r requirements.in + # jinja2 +mypy-extensions==1.0.0 \ + --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ + --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782 + # via + # -r requirements.in + # black +nox==2024.4.15 \ + --hash=sha256:6492236efa15a460ecb98e7b67562a28b70da006ab0be164e8821177577c0565 \ + --hash=sha256:ecf6700199cdfa9e5ea0a41ff5e6ef4641d09508eda6edb89d9987864115817f + # via -r requirements.in +packaging==23.2 \ + --hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \ + --hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7 + # via + # -r requirements.in + # black + # deprecation + # nox +parameterized==0.9.0 \ + --hash=sha256:4e0758e3d41bea3bbd05ec14fc2c24736723f243b28d702081aef438c9372b1b \ + --hash=sha256:7fc905272cefa4f364c1a3429cbbe9c0f98b793988efb5bf90aac80f08db09b1 + # via -r requirements.in +pathspec==0.12.1 \ + --hash=sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08 \ + --hash=sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712 + # via + # -r requirements.in + # black +platformdirs==4.2.2 \ + --hash=sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee \ + --hash=sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3 + # via + # black + # virtualenv +protobuf==3.20.2 \ + --hash=sha256:03d76b7bd42ac4a6e109742a4edf81ffe26ffd87c5993126d894fe48a120396a \ + --hash=sha256:09e25909c4297d71d97612f04f41cea8fa8510096864f2835ad2f3b3df5a5559 \ + --hash=sha256:18e34a10ae10d458b027d7638a599c964b030c1739ebd035a1dfc0e22baa3bfe \ + --hash=sha256:291fb4307094bf5ccc29f424b42268640e00d5240bf0d9b86bf3079f7576474d \ + --hash=sha256:2c0b040d0b5d5d207936ca2d02f00f765906622c07d3fa19c23a16a8ca71873f \ + --hash=sha256:384164994727f274cc34b8abd41a9e7e0562801361ee77437099ff6dfedd024b \ + --hash=sha256:3cb608e5a0eb61b8e00fe641d9f0282cd0eedb603be372f91f163cbfbca0ded0 \ + --hash=sha256:5d9402bf27d11e37801d1743eada54372f986a372ec9679673bfcc5c60441151 \ + --hash=sha256:712dca319eee507a1e7df3591e639a2b112a2f4a62d40fe7832a16fd19151750 \ + --hash=sha256:7a5037af4e76c975b88c3becdf53922b5ffa3f2cddf657574a4920a3b33b80f3 \ + --hash=sha256:8228e56a865c27163d5d1d1771d94b98194aa6917bcfb6ce139cbfa8e3c27334 \ + --hash=sha256:84a1544252a933ef07bb0b5ef13afe7c36232a774affa673fc3636f7cee1db6c \ + --hash=sha256:84fe5953b18a383fd4495d375fe16e1e55e0a3afe7b4f7b4d01a3a0649fcda9d \ + --hash=sha256:9c673c8bfdf52f903081816b9e0e612186684f4eb4c17eeb729133022d6032e3 \ + --hash=sha256:a9e5ae5a8e8985c67e8944c23035a0dff2c26b0f5070b2f55b217a1c33bbe8b1 \ + --hash=sha256:b4fdb29c5a7406e3f7ef176b2a7079baa68b5b854f364c21abe327bbeec01cdb \ + --hash=sha256:c184485e0dfba4dfd451c3bd348c2e685d6523543a0f91b9fd4ae90eb09e8422 \ + --hash=sha256:c9cdf251c582c16fd6a9f5e95836c90828d51b0069ad22f463761d27c6c19019 \ + --hash=sha256:e39cf61bb8582bda88cdfebc0db163b774e7e03364bbf9ce1ead13863e81e359 \ + --hash=sha256:e8fbc522303e09036c752a0afcc5c0603e917222d8bedc02813fd73b4b4ed804 \ + --hash=sha256:f34464ab1207114e73bba0794d1257c150a2b89b7a9faf504e00af7c9fd58978 \ + --hash=sha256:f52dabc96ca99ebd2169dadbe018824ebda08a795c7684a0b7d203a290f3adb0 + # via -r requirements.in +pyyaml==6.0.1 \ + --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \ + --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ + --hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \ + --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \ + --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \ + --hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \ + --hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \ + --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \ + --hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \ + --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \ + --hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \ + --hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \ + --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \ + --hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \ + --hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \ + --hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \ + --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \ + --hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \ + --hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \ + --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \ + --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \ + --hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \ + --hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \ + --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \ + --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \ + --hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \ + --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ + --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ + --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ + --hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \ + --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ + --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ + --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ + --hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \ + --hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \ + --hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \ + --hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \ + --hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \ + --hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \ + --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \ + --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \ + --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \ + --hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \ + --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \ + --hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \ + --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \ + --hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \ + --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \ + --hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \ + --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ + --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f + # via -r requirements.in +requests==2.32.3 \ + --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ + --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 + # via -r requirements.in +smmap==5.0.1 \ + --hash=sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62 \ + --hash=sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da + # via + # -r requirements.in + # gitdb +typing==3.7.4.3 \ + --hash=sha256:1187fb9c82fd670d10aa07bbb6cfcfe4bdda42d6fab8d5134f04e8c4d0b71cc9 \ + --hash=sha256:283d868f5071ab9ad873e5e52268d611e851c870a2ba354193026f2dfb29d8b5 + # via -r requirements.in +urllib3==2.2.2 \ + --hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \ + --hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168 + # via requests +virtualenv==20.26.3 \ + --hash=sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a \ + --hash=sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589 + # via nox +watchdog==4.0.1 \ + --hash=sha256:0144c0ea9997b92615af1d94afc0c217e07ce2c14912c7b1a5731776329fcfc7 \ + --hash=sha256:03e70d2df2258fb6cb0e95bbdbe06c16e608af94a3ffbd2b90c3f1e83eb10767 \ + --hash=sha256:093b23e6906a8b97051191a4a0c73a77ecc958121d42346274c6af6520dec175 \ + --hash=sha256:123587af84260c991dc5f62a6e7ef3d1c57dfddc99faacee508c71d287248459 \ + --hash=sha256:17e32f147d8bf9657e0922c0940bcde863b894cd871dbb694beb6704cfbd2fb5 \ + --hash=sha256:206afc3d964f9a233e6ad34618ec60b9837d0582b500b63687e34011e15bb429 \ + --hash=sha256:4107ac5ab936a63952dea2a46a734a23230aa2f6f9db1291bf171dac3ebd53c6 \ + --hash=sha256:4513ec234c68b14d4161440e07f995f231be21a09329051e67a2118a7a612d2d \ + --hash=sha256:611be3904f9843f0529c35a3ff3fd617449463cb4b73b1633950b3d97fa4bfb7 \ + --hash=sha256:62c613ad689ddcb11707f030e722fa929f322ef7e4f18f5335d2b73c61a85c28 \ + --hash=sha256:667f3c579e813fcbad1b784db7a1aaa96524bed53437e119f6a2f5de4db04235 \ + --hash=sha256:6e8c70d2cd745daec2a08734d9f63092b793ad97612470a0ee4cbb8f5f705c57 \ + --hash=sha256:7577b3c43e5909623149f76b099ac49a1a01ca4e167d1785c76eb52fa585745a \ + --hash=sha256:998d2be6976a0ee3a81fb8e2777900c28641fb5bfbd0c84717d89bca0addcdc5 \ + --hash=sha256:a3c2c317a8fb53e5b3d25790553796105501a235343f5d2bf23bb8649c2c8709 \ + --hash=sha256:ab998f567ebdf6b1da7dc1e5accfaa7c6992244629c0fdaef062f43249bd8dee \ + --hash=sha256:ac7041b385f04c047fcc2951dc001671dee1b7e0615cde772e84b01fbf68ee84 \ + --hash=sha256:bca36be5707e81b9e6ce3208d92d95540d4ca244c006b61511753583c81c70dd \ + --hash=sha256:c9904904b6564d4ee8a1ed820db76185a3c96e05560c776c79a6ce5ab71888ba \ + --hash=sha256:cad0bbd66cd59fc474b4a4376bc5ac3fc698723510cbb64091c2a793b18654db \ + --hash=sha256:d10a681c9a1d5a77e75c48a3b8e1a9f2ae2928eda463e8d33660437705659682 \ + --hash=sha256:d4925e4bf7b9bddd1c3de13c9b8a2cdb89a468f640e66fbfabaf735bd85b3e35 \ + --hash=sha256:d7b9f5f3299e8dd230880b6c55504a1f69cf1e4316275d1b215ebdd8187ec88d \ + --hash=sha256:da2dfdaa8006eb6a71051795856bedd97e5b03e57da96f98e375682c48850645 \ + --hash=sha256:dddba7ca1c807045323b6af4ff80f5ddc4d654c8bce8317dde1bd96b128ed253 \ + --hash=sha256:e7921319fe4430b11278d924ef66d4daa469fafb1da679a2e48c935fa27af193 \ + --hash=sha256:e93f451f2dfa433d97765ca2634628b789b49ba8b504fdde5837cdcf25fdb53b \ + --hash=sha256:eebaacf674fa25511e8867028d281e602ee6500045b57f43b08778082f7f8b44 \ + --hash=sha256:ef0107bbb6a55f5be727cfc2ef945d5676b97bffb8425650dadbb184be9f9a2b \ + --hash=sha256:f0de0f284248ab40188f23380b03b59126d1479cd59940f2a34f8852db710625 \ + --hash=sha256:f27279d060e2ab24c0aa98363ff906d2386aa6c4dc2f1a374655d4e02a6c5e5e \ + --hash=sha256:f8affdf3c0f0466e69f5b3917cdd042f89c8c63aebdb9f7c078996f607cdb0f5 + # via -r requirements.in + +# WARNING: The following packages were not pinned, but pip requires them to be +# pinned when the requirements file includes hashes and the requirement is not +# satisfied by a package already installed. Consider using the --allow-unsafe flag. +# setuptools From 5d99c6932a8f1f0fbe1e482897514795f577d886 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Thu, 4 Jul 2024 15:56:56 +0000 Subject: [PATCH 23/33] remove installation of synthool in favor of combined installation --- .cloudbuild/library_generation/library_generation.Dockerfile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.cloudbuild/library_generation/library_generation.Dockerfile b/.cloudbuild/library_generation/library_generation.Dockerfile index 0e177287fa..2629c092aa 100644 --- a/.cloudbuild/library_generation/library_generation.Dockerfile +++ b/.cloudbuild/library_generation/library_generation.Dockerfile @@ -48,11 +48,6 @@ WORKDIR /src RUN python -m pip install -r requirements.txt RUN python -m pip install . -# install java-only synthtool scripts as a python package -WORKDIR /src/owlbot/synthtool -RUN python -m pip install -r requirements.txt -RUN python -m pip install . - # Install nvm with node and npm ENV NODE_VERSION 20.12.0 WORKDIR /home From fd39dad88553b6b893b1e2f4cccd560dd1632dde Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Thu, 4 Jul 2024 16:02:10 +0000 Subject: [PATCH 24/33] remove unused function --- library_generation/owlbot/synthtool/languages/java.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/library_generation/owlbot/synthtool/languages/java.py b/library_generation/owlbot/synthtool/languages/java.py index f8fc56e0b8..dcd7dc8a32 100644 --- a/library_generation/owlbot/synthtool/languages/java.py +++ b/library_generation/owlbot/synthtool/languages/java.py @@ -354,12 +354,6 @@ def common_templates( **kwargs ) - # skip README generation on Kokoro (autosynth) - if os.environ.get("KOKORO_ROOT") is not None: - # README.md is now synthesized separately. This prevents synthtool from deleting the - # README as it's no longer generated here. - excludes.append("README.md") - s.copy([templates], excludes=excludes, merge=_merge_common_templates) From 35e27dabc832e3e5c52baecf4eebcc27c1820848 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Thu, 4 Jul 2024 16:11:07 +0000 Subject: [PATCH 25/33] use variable names for java.py --- .../owlbot/synthtool/languages/java.py | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/library_generation/owlbot/synthtool/languages/java.py b/library_generation/owlbot/synthtool/languages/java.py index dcd7dc8a32..4540a10bcf 100644 --- a/library_generation/owlbot/synthtool/languages/java.py +++ b/library_generation/owlbot/synthtool/languages/java.py @@ -201,44 +201,47 @@ def _common_generation( cloud_prefix = "cloud-" if cloud_api else "" package_name = package_pattern.format(service=service, version=version) + proto_library_name=f"proto-google-{cloud_prefix}{service}-{version}" + grpc_library_name=f"grpc-google-{cloud_prefix}{service}-{version}" + gapic_library_name=f"gapic-google-{cloud_prefix}{service}-{version}" fix_proto_headers( - library / f"proto-google-{cloud_prefix}{service}-{version}{suffix}" + library / f'{proto_library_name}{suffix}' ) fix_grpc_headers( - library / f"grpc-google-{cloud_prefix}{service}-{version}{suffix}", package_name + library / f'{grpc_library_name}{suffix}', package_name ) if preserve_gapic: s.copy( - [library / f"gapic-google-{cloud_prefix}{service}-{version}{suffix}/src"], - f"gapic-google-{cloud_prefix}{destination_name}-{version}/src", + [library / f"{gapic_library_name}{suffix}/src"], + f"{gapic_library_name}/src", required=True, ) else: s.copy( - [library / f"gapic-google-{cloud_prefix}{service}-{version}{suffix}/src"], + [library / f"{gapic_library_name}{suffix}/src"], f"google-{cloud_prefix}{destination_name}/src", required=True, ) s.copy( - [library / f"grpc-google-{cloud_prefix}{service}-{version}{suffix}/src"], - f"grpc-google-{cloud_prefix}{destination_name}-{version}/src", + [library / f"{grpc_library_name}{suffix}/src"], + f"{grpc_library_name}/src", # For REST-only clients, like java-compute, gRPC artifact does not exist required=(not diregapic), ) s.copy( - [library / f"proto-google-{cloud_prefix}{service}-{version}{suffix}/src"], - f"proto-google-{cloud_prefix}{destination_name}-{version}/src", + [library / f"{proto_library_name}{suffix}/src"], + f"{proto_library_name}/src", required=True, ) if preserve_gapic: - format_code(f"gapic-google-{cloud_prefix}{destination_name}-{version}/src") + format_code(f"{gapic_library_name}/src") else: format_code(f"google-{cloud_prefix}{destination_name}/src") - format_code(f"grpc-google-{cloud_prefix}{destination_name}-{version}/src") - format_code(f"proto-google-{cloud_prefix}{destination_name}-{version}/src") + format_code(f"{grpc_library_name}/src") + format_code(f"{proto_library_name}/src") def _merge_release_please(destination_text: str): From 605266d6fcf2d8c1d76b82a14229cc9b4afc5c58 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Thu, 4 Jul 2024 16:13:56 +0000 Subject: [PATCH 26/33] use variables for key references in java.py --- .../owlbot/synthtool/languages/java.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/library_generation/owlbot/synthtool/languages/java.py b/library_generation/owlbot/synthtool/languages/java.py index 4540a10bcf..ace1965802 100644 --- a/library_generation/owlbot/synthtool/languages/java.py +++ b/library_generation/owlbot/synthtool/languages/java.py @@ -245,15 +245,17 @@ def _common_generation( def _merge_release_please(destination_text: str): + handle_gh_release_key="handleGHRelease" + branches_key="branches" config = yaml.safe_load(destination_text) - if "handleGHRelease" in config: + if handle_gh_release_key in config: return destination_text - config["handleGHRelease"] = True + config[handle_gh_release_key] = True - if "branches" in config: - for branch in config["branches"]: - branch["handleGHRelease"] = True + if branches_key in config: + for branch in config[branches_key]: + branch[handle_gh_release_key] = True return yaml.dump(config) From c7f86e2a75cb55223b8876c523b2bc80f628cc7c Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Fri, 5 Jul 2024 14:57:45 +0000 Subject: [PATCH 27/33] remove duplicated dependency --- library_generation/requirements.in | 1 - 1 file changed, 1 deletion(-) diff --git a/library_generation/requirements.in b/library_generation/requirements.in index 720ef9fc34..e6be07b58a 100644 --- a/library_generation/requirements.in +++ b/library_generation/requirements.in @@ -7,7 +7,6 @@ black==24.4.2 click==8.1.7 gitdb==4.0.11 GitPython==3.1.43 -Jinja2==3.1.4 lxml==5.2.2 MarkupSafe==2.1.5 mypy-extensions==1.0.0 From 66980652bee367c47aaf059ac46df6a5639f6180 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Fri, 5 Jul 2024 14:58:27 +0000 Subject: [PATCH 28/33] lint --- .../owlbot/synthtool/languages/java.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/library_generation/owlbot/synthtool/languages/java.py b/library_generation/owlbot/synthtool/languages/java.py index ace1965802..9e6dcaeed4 100644 --- a/library_generation/owlbot/synthtool/languages/java.py +++ b/library_generation/owlbot/synthtool/languages/java.py @@ -201,15 +201,11 @@ def _common_generation( cloud_prefix = "cloud-" if cloud_api else "" package_name = package_pattern.format(service=service, version=version) - proto_library_name=f"proto-google-{cloud_prefix}{service}-{version}" - grpc_library_name=f"grpc-google-{cloud_prefix}{service}-{version}" - gapic_library_name=f"gapic-google-{cloud_prefix}{service}-{version}" - fix_proto_headers( - library / f'{proto_library_name}{suffix}' - ) - fix_grpc_headers( - library / f'{grpc_library_name}{suffix}', package_name - ) + proto_library_name = f"proto-google-{cloud_prefix}{service}-{version}" + grpc_library_name = f"grpc-google-{cloud_prefix}{service}-{version}" + gapic_library_name = f"gapic-google-{cloud_prefix}{service}-{version}" + fix_proto_headers(library / f"{proto_library_name}{suffix}") + fix_grpc_headers(library / f"{grpc_library_name}{suffix}", package_name) if preserve_gapic: s.copy( @@ -245,8 +241,8 @@ def _common_generation( def _merge_release_please(destination_text: str): - handle_gh_release_key="handleGHRelease" - branches_key="branches" + handle_gh_release_key = "handleGHRelease" + branches_key = "branches" config = yaml.safe_load(destination_text) if handle_gh_release_key in config: return destination_text From 065273e4e9adbd726bad109a444de0906077df1b Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Fri, 5 Jul 2024 15:11:17 +0000 Subject: [PATCH 29/33] restore format of golden owlbot.py --- .../test/resources/goldens/owlbot-golden.py | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/library_generation/test/resources/goldens/owlbot-golden.py b/library_generation/test/resources/goldens/owlbot-golden.py index 7559eaf034..2ba11e6bba 100644 --- a/library_generation/test/resources/goldens/owlbot-golden.py +++ b/library_generation/test/resources/goldens/owlbot-golden.py @@ -21,19 +21,16 @@ s.move(library) s.remove_staging_dirs() -java.common_templates( - monorepo=True, - excludes=[ - ".github/*", - ".kokoro/*", - "samples/*", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.md", - "LICENSE", - "SECURITY.md", - "java.header", - "license-checks.xml", - "renovate.json", - ".gitignore", - ], -) +java.common_templates(monorepo=True, excludes=[ + ".github/*", + ".kokoro/*", + "samples/*", + "CODE_OF_CONDUCT.md", + "CONTRIBUTING.md", + "LICENSE", + "SECURITY.md", + "java.header", + "license-checks.xml", + "renovate.json", + ".gitignore" +]) \ No newline at end of file From 6186e790b0621209669b2518caf40aff5263dda9 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Fri, 5 Jul 2024 15:30:20 +0000 Subject: [PATCH 30/33] reduce unnecessary dependencies --- library_generation/requirements.in | 2 -- library_generation/requirements.txt | 29 ----------------------------- 2 files changed, 31 deletions(-) diff --git a/library_generation/requirements.in b/library_generation/requirements.in index e6be07b58a..980a77376a 100644 --- a/library_generation/requirements.in +++ b/library_generation/requirements.in @@ -22,5 +22,3 @@ nox==2024.4.15 requests==2.32.3 setuptools==65.5.1 jinja2==3.1.4 -deprecation==2.1.0 -protobuf==3.20.2 diff --git a/library_generation/requirements.txt b/library_generation/requirements.txt index 279bacd357..eaf8f4a33b 100644 --- a/library_generation/requirements.txt +++ b/library_generation/requirements.txt @@ -152,10 +152,6 @@ colorlog==6.8.2 \ # via # -r requirements.in # nox -deprecation==2.1.0 \ - --hash=sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff \ - --hash=sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a - # via -r requirements.in distlib==0.3.8 \ --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 @@ -406,7 +402,6 @@ packaging==23.2 \ # via # -r requirements.in # black - # deprecation # nox parameterized==0.9.0 \ --hash=sha256:4e0758e3d41bea3bbd05ec14fc2c24736723f243b28d702081aef438c9372b1b \ @@ -424,30 +419,6 @@ platformdirs==4.2.2 \ # via # black # virtualenv -protobuf==3.20.2 \ - --hash=sha256:03d76b7bd42ac4a6e109742a4edf81ffe26ffd87c5993126d894fe48a120396a \ - --hash=sha256:09e25909c4297d71d97612f04f41cea8fa8510096864f2835ad2f3b3df5a5559 \ - --hash=sha256:18e34a10ae10d458b027d7638a599c964b030c1739ebd035a1dfc0e22baa3bfe \ - --hash=sha256:291fb4307094bf5ccc29f424b42268640e00d5240bf0d9b86bf3079f7576474d \ - --hash=sha256:2c0b040d0b5d5d207936ca2d02f00f765906622c07d3fa19c23a16a8ca71873f \ - --hash=sha256:384164994727f274cc34b8abd41a9e7e0562801361ee77437099ff6dfedd024b \ - --hash=sha256:3cb608e5a0eb61b8e00fe641d9f0282cd0eedb603be372f91f163cbfbca0ded0 \ - --hash=sha256:5d9402bf27d11e37801d1743eada54372f986a372ec9679673bfcc5c60441151 \ - --hash=sha256:712dca319eee507a1e7df3591e639a2b112a2f4a62d40fe7832a16fd19151750 \ - --hash=sha256:7a5037af4e76c975b88c3becdf53922b5ffa3f2cddf657574a4920a3b33b80f3 \ - --hash=sha256:8228e56a865c27163d5d1d1771d94b98194aa6917bcfb6ce139cbfa8e3c27334 \ - --hash=sha256:84a1544252a933ef07bb0b5ef13afe7c36232a774affa673fc3636f7cee1db6c \ - --hash=sha256:84fe5953b18a383fd4495d375fe16e1e55e0a3afe7b4f7b4d01a3a0649fcda9d \ - --hash=sha256:9c673c8bfdf52f903081816b9e0e612186684f4eb4c17eeb729133022d6032e3 \ - --hash=sha256:a9e5ae5a8e8985c67e8944c23035a0dff2c26b0f5070b2f55b217a1c33bbe8b1 \ - --hash=sha256:b4fdb29c5a7406e3f7ef176b2a7079baa68b5b854f364c21abe327bbeec01cdb \ - --hash=sha256:c184485e0dfba4dfd451c3bd348c2e685d6523543a0f91b9fd4ae90eb09e8422 \ - --hash=sha256:c9cdf251c582c16fd6a9f5e95836c90828d51b0069ad22f463761d27c6c19019 \ - --hash=sha256:e39cf61bb8582bda88cdfebc0db163b774e7e03364bbf9ce1ead13863e81e359 \ - --hash=sha256:e8fbc522303e09036c752a0afcc5c0603e917222d8bedc02813fd73b4b4ed804 \ - --hash=sha256:f34464ab1207114e73bba0794d1257c150a2b89b7a9faf504e00af7c9fd58978 \ - --hash=sha256:f52dabc96ca99ebd2169dadbe018824ebda08a795c7684a0b7d203a290f3adb0 - # via -r requirements.in pyyaml==6.0.1 \ --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \ --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ From 6ab904b8e73b92df13ceb0a219f26f55b5dd1cab Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Fri, 5 Jul 2024 15:56:00 +0000 Subject: [PATCH 31/33] pin typing extensions --- library_generation/requirements.in | 1 + library_generation/requirements.txt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/library_generation/requirements.in b/library_generation/requirements.in index 980a77376a..03e1609d76 100644 --- a/library_generation/requirements.in +++ b/library_generation/requirements.in @@ -22,3 +22,4 @@ nox==2024.4.15 requests==2.32.3 setuptools==65.5.1 jinja2==3.1.4 +typing-extensions==4.0.1 # used to pin to a specific version instead of >= (prevents error in pip install) diff --git a/library_generation/requirements.txt b/library_generation/requirements.txt index eaf8f4a33b..01e3891312 100644 --- a/library_generation/requirements.txt +++ b/library_generation/requirements.txt @@ -486,6 +486,10 @@ typing==3.7.4.3 \ --hash=sha256:1187fb9c82fd670d10aa07bbb6cfcfe4bdda42d6fab8d5134f04e8c4d0b71cc9 \ --hash=sha256:283d868f5071ab9ad873e5e52268d611e851c870a2ba354193026f2dfb29d8b5 # via -r requirements.in +typing-extensions==4.0.1 \ + --hash=sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e \ + --hash=sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b + # via -r requirements.in urllib3==2.2.2 \ --hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \ --hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168 From 0780ad11df9a01970388662dc0e54e7dcdba7f0d Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Fri, 5 Jul 2024 19:50:38 +0000 Subject: [PATCH 32/33] enrich comment of the typing-extensions dependency in requirements.in --- library_generation/requirements.in | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library_generation/requirements.in b/library_generation/requirements.in index 03e1609d76..0e2b25238d 100644 --- a/library_generation/requirements.in +++ b/library_generation/requirements.in @@ -22,4 +22,7 @@ nox==2024.4.15 requests==2.32.3 setuptools==65.5.1 jinja2==3.1.4 -typing-extensions==4.0.1 # used to pin to a specific version instead of >= (prevents error in pip install) +# typing-extensions is a transitive dependency. If we run `pip-compile ... --generate-hashes` it will produce +# a list where typing extensions is pinned to >=4.0.1. This will produce an error saying "all requirements +# must have their versions pinned with ==". The following line pins the dependency to a specific version via == +typing-extensions==4.0.1 From 7c56ce02724758ad373115c7b179792b712f92e8 Mon Sep 17 00:00:00 2001 From: diegomarquezp Date: Mon, 8 Jul 2024 12:58:57 +0000 Subject: [PATCH 33/33] make snippet bot to ignore the synthtool snippet script --- .github/snippet-bot.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/snippet-bot.yml b/.github/snippet-bot.yml index 9458774ff0..84a9e461c2 100644 --- a/.github/snippet-bot.yml +++ b/.github/snippet-bot.yml @@ -5,3 +5,4 @@ ignoreFiles: - test/** - showcase/** - library_generation/owlbot/templates/java_library/samples/install-without-bom/pom.xml + - library_generation/owlbot/synthtool/gcp/snippets.py