style(dependencies): run ruff formatter

This commit is contained in:
Carlo Sala 2024-05-09 17:20:09 +02:00
parent 83110e8ce1
commit 13c8a10e39
2 changed files with 378 additions and 329 deletions
.editorconfig
.github/workflows/dependencies

View file

@ -6,3 +6,6 @@ insert_final_newline = true
charset = utf-8
indent_size = 2
indent_style = space
[*.py]
indent_size = 4

View file

@ -1,12 +1,14 @@
import os
import shutil
import subprocess
import sys
import requests
import shutil
import yaml
import timeit
from copy import deepcopy
from typing import Optional, TypedDict
import requests
import yaml
# Get TMP_DIR variable from environment
TMP_DIR = os.path.join(os.environ.get("TMP_DIR", "/tmp"), "ohmyzsh")
# Relative path to dependencies.yml file
@ -14,17 +16,17 @@ DEPS_YAML_FILE = ".github/dependencies.yml"
# Dry run flag
DRY_RUN = os.environ.get("DRY_RUN", "0") == "1"
import timeit
class CodeTimer:
def __init__(self, name=None):
self.name = " '" + name + "'" if name else ''
self.name = " '" + name + "'" if name else ""
def __enter__(self):
self.start = timeit.default_timer()
def __exit__(self, exc_type, exc_value, traceback):
self.took = (timeit.default_timer() - self.start) * 1000.0
print('Code block' + self.name + ' took: ' + str(self.took) + ' ms')
print("Code block" + self.name + " took: " + str(self.took) + " ms")
### YAML representation
@ -34,8 +36,9 @@ def str_presenter(dumper, data):
Ref: https://stackoverflow.com/a/33300001
"""
if len(data.splitlines()) > 1: # check for multiline string
return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|')
return dumper.represent_scalar('tag:yaml.org,2002:str', data)
return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|")
return dumper.represent_scalar("tag:yaml.org,2002:str", data)
yaml.add_representer(str, str_presenter)
yaml.representer.SafeRepresenter.add_representer(str, str_presenter)
@ -49,9 +52,11 @@ class DependencyDict(TypedDict):
precopy: Optional[str]
postcopy: Optional[str]
class DependencyYAML(TypedDict):
dependencies: dict[str, DependencyDict]
class UpdateStatus(TypedDict):
has_updates: bool
version: Optional[str]
@ -78,19 +83,18 @@ class CommandRunner:
if result.returncode != 0:
raise CommandRunner.Exception(
f"{stage} command failed with exit code {result.returncode}", returncode=result.returncode,
f"{stage} command failed with exit code {result.returncode}",
returncode=result.returncode,
stage=stage,
stdout=result.stdout.decode("utf-8"),
stderr=result.stderr.decode("utf-8")
stderr=result.stderr.decode("utf-8"),
)
return result
class DependencyStore:
store: DependencyYAML = {
"dependencies": {}
}
store: DependencyYAML = {"dependencies": {}}
@staticmethod
def set(data: DependencyYAML):
@ -136,7 +140,7 @@ class Dependency:
def __str__(self):
output: str = ""
for key in DependencyDict.__dict__['__annotations__'].keys():
for key in DependencyDict.__dict__["__annotations__"].keys():
if key not in self.values:
output += f"{key}: None\n"
continue
@ -176,7 +180,9 @@ class Dependency:
branch = Git.create_branch(self.path, new_version)
# Update dependencies.yml file
self.__update_yaml(f"tag:{new_version}" if is_tag else status["version"])
self.__update_yaml(
f"tag:{new_version}" if is_tag else status["version"]
)
# Update dependency files
self.__apply_upstream_changes()
@ -195,7 +201,7 @@ class Dependency:
Update for **{self.desc}**: update to version [{new_version}]({status['head_url']}).
Check out the [list of changes]({status['compare_url']}).
"""
""",
)
# Clean up repository
@ -205,7 +211,10 @@ Check out the [list of changes]({status['compare_url']}).
match type(e):
case CommandRunner.Exception:
# Print error message
print(f"Error running {e.stage} command: {e.returncode}", file=sys.stderr)
print(
f"Error running {e.stage} command: {e.returncode}",
file=sys.stderr,
)
print(e.stderr, file=sys.stderr)
case shutil.Error:
print(f"Error copying files: {e}", file=sys.stderr)
@ -213,22 +222,23 @@ Check out the [list of changes]({status['compare_url']}).
try:
Git.clean_repo()
except CommandRunner.Exception as e:
print(f"Error reverting repository to clean state: {e}", file=sys.stderr)
print(
f"Error reverting repository to clean state: {e}",
file=sys.stderr,
)
sys.exit(1)
# Create a GitHub issue to notify maintainer
title = f"{self.path}: update to {new_version}"
body = (
f"""## Description
body = f"""## Description
There is a new version of `{self.name}` {self.kind} available.
New version: [{new_version}]({status['head_url']})
Check out the [list of changes]({status['compare_url']}).
"""
)
print(f"Creating GitHub issue", file=sys.stderr)
print("Creating GitHub issue", file=sys.stderr)
print(f"{title}\n\n{body}", file=sys.stderr)
GitHub.create_issue(title, body)
except Exception as e:
@ -240,11 +250,7 @@ Check out the [list of changes]({status['compare_url']}).
def __apply_upstream_changes(self) -> None:
# Patterns to ignore in copying files from upstream repo
GLOBAL_IGNORE = [
".git",
".github",
".gitignore"
]
GLOBAL_IGNORE = [".git", ".github", ".gitignore"]
path = os.path.abspath(self.path)
precopy = self.values.get("precopy")
@ -261,18 +267,32 @@ Check out the [list of changes]({status['compare_url']}).
# Run precopy on tmp repo
if precopy is not None:
print("Running precopy script:", end="\n ", file=sys.stderr)
print(precopy.replace("\n", "\n ", precopy.count("\n") - 1), file=sys.stderr)
CommandRunner.run_or_fail(["bash", "-c", precopy], cwd=repo_dir, stage="Precopy")
print(
precopy.replace("\n", "\n ", precopy.count("\n") - 1), file=sys.stderr
)
CommandRunner.run_or_fail(
["bash", "-c", precopy], cwd=repo_dir, stage="Precopy"
)
# Copy files from upstream repo
print(f"Copying files from {repo_dir} to {path}", file=sys.stderr)
shutil.copytree(repo_dir, path, dirs_exist_ok=True, ignore=shutil.ignore_patterns(*GLOBAL_IGNORE))
shutil.copytree(
repo_dir,
path,
dirs_exist_ok=True,
ignore=shutil.ignore_patterns(*GLOBAL_IGNORE),
)
# Run postcopy on our repository
if postcopy is not None:
print("Running postcopy script:", end="\n ", file=sys.stderr)
print(postcopy.replace("\n", "\n ", postcopy.count("\n") - 1), file=sys.stderr)
CommandRunner.run_or_fail(["bash", "-c", postcopy], cwd=path, stage="Postcopy")
print(
postcopy.replace("\n", "\n ", postcopy.count("\n") - 1),
file=sys.stderr,
)
CommandRunner.run_or_fail(
["bash", "-c", postcopy], cwd=path, stage="Postcopy"
)
class Git:
@ -286,18 +306,28 @@ class Git:
# Clone repo in tmp directory and checkout branch
if not os.path.exists(repo_dir):
print(f"Cloning {remote_url} to {repo_dir} and checking out {branch}", file=sys.stderr)
CommandRunner.run_or_fail(["git", "clone", "--depth=1", "-b", branch, remote_url, repo_dir], stage="Clone")
print(
f"Cloning {remote_url} to {repo_dir} and checking out {branch}",
file=sys.stderr,
)
CommandRunner.run_or_fail(
["git", "clone", "--depth=1", "-b", branch, remote_url, repo_dir],
stage="Clone",
)
@staticmethod
def create_branch(path: str, version: str):
# Get current branch name
result = CommandRunner.run_or_fail(["git", "rev-parse", "--abbrev-ref", "HEAD"], stage="GetDefaultBranch")
result = CommandRunner.run_or_fail(
["git", "rev-parse", "--abbrev-ref", "HEAD"], stage="GetDefaultBranch"
)
Git.default_branch = result.stdout.decode("utf-8").strip()
# Create new branch and return created branch name
branch_name = f"update/{path}/{version}"
CommandRunner.run_or_fail(["git", "checkout", "-b", branch_name], stage="CreateBranch")
CommandRunner.run_or_fail(
["git", "checkout", "-b", branch_name], stage="CreateBranch"
)
return branch_name
@staticmethod
@ -315,22 +345,35 @@ class Git:
clean_env["GIT_CONFIG_NOSYSTEM"] = "1"
# Commit with settings above
CommandRunner.run_or_fail([
CommandRunner.run_or_fail(
[
"git",
"-c", f"user.name={user_name}",
"-c", f"user.email={user_email}",
"-c",
f"user.name={user_name}",
"-c",
f"user.email={user_email}",
"commit",
"-m", f"feat({scope}): update to {version}"
], stage="CreateCommit", env=clean_env)
"-m",
f"feat({scope}): update to {version}",
],
stage="CreateCommit",
env=clean_env,
)
@staticmethod
def push(branch: str):
CommandRunner.run_or_fail(["git", "push", "-u", "origin", branch], stage="PushBranch")
CommandRunner.run_or_fail(
["git", "push", "-u", "origin", branch], stage="PushBranch"
)
@staticmethod
def clean_repo():
CommandRunner.run_or_fail(["git", "reset", "--hard", "HEAD"], stage="ResetRepository")
CommandRunner.run_or_fail(["git", "checkout", Git.default_branch], stage="CheckoutDefaultBranch")
CommandRunner.run_or_fail(
["git", "reset", "--hard", "HEAD"], stage="ResetRepository"
)
CommandRunner.run_or_fail(
["git", "checkout", Git.default_branch], stage="CheckoutDefaultBranch"
)
class GitHub:
@ -369,7 +412,9 @@ class GitHub:
}
else:
# If the request was not successful, raise an exception
raise Exception(f"GitHub API request failed with status code {response.status_code}: {response.json()}")
raise Exception(
f"GitHub API request failed with status code {response.status_code}: {response.json()}"
)
@staticmethod
def check_updates(repo, branch, version) -> UpdateStatus:
@ -399,21 +444,17 @@ class GitHub:
"version": data["commits"][-1]["sha"],
"compare_url": data["permalink_url"],
"head_ref": data["commits"][-1]["sha"],
"head_url": data["commits"][-1]["html_url"]
"head_url": data["commits"][-1]["html_url"],
}
else:
# If the request was not successful, raise an exception
raise Exception(f"GitHub API request failed with status code {response.status_code}: {response.json()}")
raise Exception(
f"GitHub API request failed with status code {response.status_code}: {response.json()}"
)
@staticmethod
def create_issue(title: str, body: str) -> None:
cmd = [
"gh",
"issue",
"create",
"-t", title,
"-b", body
]
cmd = ["gh", "issue", "create", "-t", title, "-b", body]
CommandRunner.run_or_fail(cmd, stage="CreateIssue")
@staticmethod
@ -422,10 +463,14 @@ class GitHub:
"gh",
"pr",
"create",
"-B", Git.default_branch,
"-H", branch,
"-t", title,
"-b", body
"-B",
Git.default_branch,
"-H",
branch,
"-t",
title,
"-b",
body,
]
CommandRunner.run_or_fail(cmd, stage="CreatePullRequest")
@ -436,7 +481,7 @@ def main():
data: DependencyYAML = yaml.safe_load(yaml_file)
if "dependencies" not in data:
raise Exception(f"dependencies.yml not properly formatted")
raise Exception("dependencies.yml not properly formatted")
# Cache YAML version
DependencyStore.set(data)
@ -446,5 +491,6 @@ def main():
dependency = Dependency(path, dependencies[path])
dependency.update_or_notify()
if __name__ == "__main__":
main()