Skip to content

Commit

Permalink
Add docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
KangarooKoala committed Jul 16, 2024
1 parent 1e17563 commit 7bf00dd
Showing 1 changed file with 78 additions and 2 deletions.
80 changes: 78 additions & 2 deletions upstream_utils/upstream_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,14 @@ def git_am(patch, use_threeway=False, ignore_whitespace=False):


def has_git_rev(rev):
"""Checks whether the Git repository in the current directory has the given revision.
Keyword arguments:
rev -- The revision to check
Returns:
True if the revision exists, otherwise False.
"""
cmd = ["git", "rev-parse", "--verify", "-q", rev]
return subprocess.run(cmd, stdout=subprocess.DEVNULL).returncode == 0

Expand All @@ -212,17 +220,31 @@ def __init__(
self,
name,
url,
old_tag,
tag,
patch_list,
copy_upstream_src,
patch_options={},
*,
pre_patch_hook=None,
pre_patch_commits=0,
):
"""Initializes a Lib instance.
Keyword arguments:
name -- The name of the library.
url -- The URL of the upstream repository.
tag -- The tag in the upstream repository to use. Can be any <commit-ish> (e.g., commit hash or tag).
patch_list -- The list of patches in the patch directory to apply.
copy_upstream_src -- A callable that takes the path to the wpilib root and copies the files from the clone of the upstream into the appropriate thirdparty directory. Will only be called when the current directory is the upstream clone.
patch_options -- The dictionary of options to use when applying patches. Corresponds to the parameters of git_am.
Keyword-only arguments:
pre_patch_hook -- Optional callable taking no parameters that will be called before applying patches.
pre_patch_commits -- Number of commits added by pre_patch_hook.
"""
self.name = name
self.url = url
self.old_tag = old_tag
self.old_tag = tag
self.patch_list = patch_list
self.copy_upstream_src = copy_upstream_src
self.patch_options = patch_options
Expand All @@ -231,6 +253,7 @@ def __init__(
self.wpilib_root = get_repo_root()

def check_patches(self):
"""Checks the patch list supplied to the constructor against the patches in the patch directory."""
patch_directory_patches = set()
patch_directory = os.path.join(
self.wpilib_root, f"upstream_utils/{self.name}_patches"
Expand Down Expand Up @@ -260,6 +283,14 @@ def check_patches(self):
)

def get_repo_path(self, tempdir=None):
"""Returns the path to the clone of the upstream repository.
Keyword argument:
tempdir -- The path to the temporary directory to use. If None (the default), uses tempfile.gettempdir().
Returns:
The path to the clone of the upstream repository. Will be absolute if tempdir is absolute.
"""
if tempdir is None:
tempdir = tempfile.gettempdir()
repo = os.path.basename(self.url)
Expand All @@ -268,6 +299,11 @@ def get_repo_path(self, tempdir=None):
return dest

def open_repo(self, *, err_msg_if_absent):
"""Changes the current working directory to the upstream repository. If err_msg_if_absent is not None and the upstream repository does not exist, the program exits with return code 1.
Keyword-only argument:
err_msg_if_absent -- The error message to print to stderr if the upstream repository does not exist. If None, the upstream repository will be cloned without emitting any warnings.
"""
os.chdir(tempfile.gettempdir())

dest = self.get_repo_path(os.getcwd())
Expand All @@ -283,6 +319,11 @@ def open_repo(self, *, err_msg_if_absent):
os.chdir(dest)

def get_root_tags(self):
"""Returns a list of potential root tags.
Returns:
A list of the potential root tags.
"""
root_tag_output = subprocess.run(
["git", "tag", "--list", "upstream_utils_root-*"],
capture_output=True,
Expand All @@ -291,6 +332,11 @@ def get_root_tags(self):
return root_tag_output.splitlines()

def get_root_tag(self):
"""Returns the root tag (the default tag to apply the patches relative to). If there are multiple candidates, prints an error to stderr and the program exits with return code 1.
Returns:
The root tag.
"""
root_tags = self.get_root_tags()
if len(root_tags) == 0:
print(
Expand All @@ -307,6 +353,11 @@ def get_root_tag(self):
return root_tags[0]

def set_root_tag(self, tag):
"""Sets the root tag, deleting any potential candidates first.
Keyword argument:
tag -- The tag to set as the root tag.
"""
root_tags = self.get_root_tags()

if len(root_tags) > 1:
Expand All @@ -318,6 +369,7 @@ def set_root_tag(self, tag):
subprocess.run(["git", "tag", f"upstream_utils_root-{tag}", tag])

def apply_patches(self):
"""Applies the patches listed in the patch list to the current directory."""
if self.pre_patch_hook is not None:
self.pre_patch_hook()

Expand All @@ -330,6 +382,11 @@ def apply_patches(self):
)

def replace_tag(self, tag):
"""Replaces the tag in the script.
Keyword argument:
tag -- The tag to replace the script tag with.
"""
path = os.path.join(self.wpilib_root, f"upstream_utils/{self.name}.py")
with open(path, "r") as file:
lines = file.readlines()
Expand All @@ -349,6 +406,7 @@ def replace_tag(self, tag):
file.writelines(lines)

def info(self):
"""Prints info about the library to stdout."""
print(f"Repository name: {self.name}")
print(f"Upstream URL: {self.url}")
print(f"Upstream tag: {self.old_tag}")
Expand All @@ -359,13 +417,15 @@ def info(self):
print(f"WPILib root: {self.wpilib_root}")

def clone(self):
"""Clones the upstream repository and sets it up."""
self.open_repo(err_msg_if_absent=None)

subprocess.run(["git", "switch", "--detach", self.old_tag])

self.set_root_tag(self.old_tag)

def reset(self):
"""Resets the clone of the upstream repository to the state specified by the script and patches."""
self.open_repo(
err_msg_if_absent='There\'s nothing to reset. Run the "clone" command first.'
)
Expand All @@ -377,6 +437,11 @@ def reset(self):
self.apply_patches()

def rebase(self, new_tag):
"""Rebases the patches.
Keyword argument:
new_tag -- The tag to rebase onto.
"""
self.open_repo(
err_msg_if_absent='There\'s nothing to rebase. Run the "clone" command first.'
)
Expand All @@ -399,6 +464,11 @@ def rebase(self, new_tag):
)

def format_patch(self, tag=None):
"""Generates patch files for the upstream repository and moves them into the patch directory.
Keyword argument:
tag -- The tag of the commit of the upstream repository the patch commit were applied onto. If None (the default), the root tag will be used.
"""
self.open_repo(
err_msg_if_absent='There\'s nothing to run format-patch on. Run the "clone" and "rebase" commands first.'
)
Expand Down Expand Up @@ -451,6 +521,7 @@ def format_patch(self, tag=None):
self.replace_tag(script_tag)

def copy_upstream_to_thirdparty(self):
"""Copies files from the upstream repository into the thirdparty directory."""
self.open_repo(
err_msg_if_absent='There\'s no repository to copy from. Run the "clone" command first.'
)
Expand All @@ -462,6 +533,11 @@ def copy_upstream_to_thirdparty(self):
self.copy_upstream_src(self.wpilib_root)

def main(self, argv=sys.argv[1:]):
"""Processes the given arguments.
Keyword argument:
argv -- The arguments to process. Defaults to the arguments passed to the program.
"""
parser = argparse.ArgumentParser(
description=f"CLI manager of the {self.name} upstream library"
)
Expand Down

0 comments on commit 7bf00dd

Please sign in to comment.