diff --git a/.evergreen/scripts/resync-all-specs.py b/.evergreen/scripts/resync-all-specs.py index 8e58e56da2..1996d5d634 100644 --- a/.evergreen/scripts/resync-all-specs.py +++ b/.evergreen/scripts/resync-all-specs.py @@ -6,7 +6,6 @@ import subprocess from argparse import Namespace from subprocess import CalledProcessError -from typing import Optional def resync_specs(directory: pathlib.Path, errored: dict[str, str]) -> None: @@ -32,14 +31,27 @@ def resync_specs(directory: pathlib.Path, errored: dict[str, str]) -> None: def apply_patches(errored): print("Beginning to apply patches") - subprocess.run(["bash", "./.evergreen/remove-unimplemented-tests.sh"], check=True) # noqa: S603, S607 + subprocess.run( + ["bash", "./.evergreen/remove-unimplemented-tests.sh"], # noqa: S603, S607 + check=True, + ) try: - subprocess.run( - ["git apply -R --allow-empty --whitespace=fix ./.evergreen/spec-patch/*"], # noqa: S607 - shell=True, # noqa: S602 - check=True, - stderr=subprocess.PIPE, - ) + # Avoid shell=True by passing arguments as a list. + # Note: glob expansion doesn't work in shell=False, so we use a list of files. + patches = [str(p) for p in pathlib.Path("./.evergreen/spec-patch/").glob("*")] + if patches: + subprocess.run( + [ # noqa: S603, S607 + "git", + "apply", + "-R", + "--allow-empty", + "--whitespace=fix", + *patches, + ], + check=True, + stderr=subprocess.PIPE, + ) except CalledProcessError as exc: errored["applying patches"] = exc.stderr @@ -73,17 +85,24 @@ def check_new_spec_directories(directory: pathlib.Path) -> list[str]: return list(spec_set - test_set) -def write_summary(errored: dict[str, str], new: list[str], filename: Optional[str]) -> None: +def write_summary(errored: dict[str, str], new: list[str], filename: str | None) -> None: """Generate the PR description""" pr_body = "" + # Avoid shell=True and complex pipes by using Python to process git output process = subprocess.run( - ["git diff --name-only | awk -F'/' '{print $2}' | sort | uniq"], # noqa: S607 - shell=True, # noqa: S602 + ["git", "diff", "--name-only"], # noqa: S603, S607 capture_output=True, text=True, check=True, ) - succeeded = process.stdout.strip().split() + changed_files = process.stdout.strip().splitlines() + succeeded_set = set() + for f in changed_files: + parts = f.split("/") + if len(parts) > 1: + succeeded_set.add(parts[1]) + succeeded = sorted(succeeded_set) + if len(succeeded) > 0: pr_body += "The following specs were changed:\n -" pr_body += "\n -".join(succeeded) @@ -120,7 +139,9 @@ def main(args: Namespace): description="Python Script to resync all specs and generate summary for PR." ) parser.add_argument( - "--filename", help="Name of file for the summary to be written into.", default=None + "--filename", + help="Name of file for the summary to be written into.", + default=None, ) args = parser.parse_args() main(args) diff --git a/doc/conf.py b/doc/conf.py index 063429cd98..6d648ca503 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -88,6 +88,8 @@ linkcheck_ignore = [ "https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-monitoring.md#requesting-an-immediate-check", "https://github.com/mongodb/specifications/blob/master/source/transactions-convenient-api/transactions-convenient-api.md#handling-errors-inside-the-callback", + "https://github.com/mongodb/specifications/blob/master/source/uri-options/uri-options.md", + "https://github.com/mongodb/specifications/blob/master/source/uri-options/uri-options.md", "https://github.com/mongodb/libmongocrypt/blob/master/bindings/python/README.rst#installing-from-source", r"https://wiki.centos.org/[\w/]*", r"https://sourceforge.net/", @@ -186,8 +188,8 @@ ("index", "PyMongo.tex", "PyMongo Documentation", "Michael Dirolf", "manual"), ] -# The name of an image file (relative to this directory) to place at the top of -# the title page. +# The name of an image file (relative to this directory) to place at the top +# of the title page. # latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts,