From dea0c341213c995eff7e9298a39847f14ca3ceca Mon Sep 17 00:00:00 2001 From: blakeNaccarato Date: Wed, 16 Aug 2023 16:51:07 -0700 Subject: [PATCH] Implement dependency bumping --- .github/workflows/main.yml | 7 +- .gitmodules | 3 + .tools/requirements/requirements_both.txt | 1 + .tools/scripts/update_requirements.py | 86 +++++++++++++++++++++++ boilercore | 1 + 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 .tools/scripts/update_requirements.py create mode 160000 boilercore diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 58414be4..776e63eb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -43,7 +43,12 @@ jobs: python-version: "3.11" install-project: false - run: "copier update --defaults --vcs-ref $(git rev-parse HEAD:template)" - shell: "pwsh" + - run: "python .tools/scripts/update_requirements.py" + - name: "Check whether bumped requirements install properly" + run: |- + pip install . + pip install --requirement .tools/requirements/requirements.txt --requirement .tools/requirements/requirements_ci.txt + pip install --no-deps --requirement .tools/requirements/requirements_nodeps.txt - uses: "stefanzweifel/git-auto-commit-action@v4.16.0" with: commit_message: "Update project from template." diff --git a/.gitmodules b/.gitmodules index 4b17a770..c8eaaa43 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "typings"] path = typings url = https://github.com/blakeNaccarato/pylance-stubs-unofficial.git +[submodule "boilercore"] + path = boilercore + url = https://github.com/blakeNaccarato/boilercore diff --git a/.tools/requirements/requirements_both.txt b/.tools/requirements/requirements_both.txt index 1bb10e62..31f6809a 100644 --- a/.tools/requirements/requirements_both.txt +++ b/.tools/requirements/requirements_both.txt @@ -6,6 +6,7 @@ # Template copier==8.1.0 +dulwich==0.21.5 # Build flit==3.9.0 diff --git a/.tools/scripts/update_requirements.py b/.tools/scripts/update_requirements.py new file mode 100644 index 00000000..15857330 --- /dev/null +++ b/.tools/scripts/update_requirements.py @@ -0,0 +1,86 @@ +"""Update requirements versions which are coupled to others.""" + +from contextlib import closing +from dataclasses import dataclass +from pathlib import Path +from re import MULTILINE, VERBOSE, Pattern, compile + +from dulwich.porcelain import submodule_list +from dulwich.repo import Repo + + +def main(): + requirements_files = [ + Path("pyproject.toml"), + *sorted(Path(".tools/requirements").glob("requirements*.txt")), + ] + with closing(repo := Repo(str(Path.cwd()))): + submodules = [Submodule(*item) for item in list(submodule_list(repo))] + dependency_relation = r"(?P[=~>]=)" # ==, ~=, or >= + for file in requirements_files: + original_content = content = file.read_text("utf-8") + if pandas_match := compile_specific( + rf""" + pandas # pandas + (\[[\w,]+\])? # e.g. [hdf5,performance] (optional) + {dependency_relation} # e.g. == + (?P[\w\d\.]*) # e.g. 2.0.2 + """ + ).search(content): + content = compile_specific( + rf""" + (?Ppandas-stubs) # pandas-stubs + {dependency_relation} # e.g. ~= + (?P[\w\d\.]*) # e.g. 2.0.2 + """ + ).sub( + repl=rf"\g\g\g{pandas_match['version']}\g", + string=content, + ) + for sub in submodules: + content = compile_specific( + rf""" + {sub.name}@ # name@ + (?Pgit\+https://github\.com/) # git+https://github.com/ + (?P\w+/) # org/ + {sub.name}@ # name@ + (?P\w+) # + $""" + ).sub( + repl=rf"\g{sub.name}@\g\g{sub.name}@{sub.commit}\g", + string=content, + ) + if content != original_content: + file.write_text(encoding="utf-8", data=content) + + +@dataclass +class Submodule: + """Represents a git submodule.""" + + name: str + """The submodule name.""" + commit: str + """The commit hash currently tracked by the submodule.""" + + def __post_init__(self): + """Handle byte strings reported by some submodule sources, like dulwich.""" + # dulwich.porcelain.submodule_list returns bytes + if isinstance(self.name, bytes): + self.name = self.name.decode("utf-8") + + +def compile_specific(pattern: str) -> Pattern[str]: + """Compile verbose, multi-line regex pattern with a specific prefix and suffix.""" + return compile( + flags=VERBOSE | MULTILINE, + pattern=rf"""^ + (?P\s*['"])? # Optional `"` as in pyproject.toml + {pattern} + (?P['"],)? # Optional `",` as in pyproject.toml + $""", + ) + + +if __name__ == "__main__": + main() diff --git a/boilercore b/boilercore new file mode 160000 index 00000000..78aba44a --- /dev/null +++ b/boilercore @@ -0,0 +1 @@ +Subproject commit 78aba44ad7bd6a5e52622510d89cefcee330db72