Skip to content

Commit

Permalink
Added git commands
Browse files Browse the repository at this point in the history
- gitpython added as a prod requirement
- GitError raised when git command fails
- added functions encompassing key functionality
  • Loading branch information
coordt committed Jun 14, 2022
1 parent 8177838 commit 291b9aa
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 31 deletions.
30 changes: 15 additions & 15 deletions cookie_composer/composition.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,21 @@ def write_composition(layers: List[LayerConfig], destination: Union[str, Path]):
yaml.dump_all(dict_layers, f)


def write_rendered_composition(composition: RenderedComposition):
"""
Write the composition file using the rendered layers to the appropriate.
Args:
composition: The rendered composition object to export
"""
layers = []
for rendered_layer in composition.layers:
layers.append(rendered_layer.layer)

composition_file = composition.render_dir / composition.rendered_name / ".composition.yaml"
write_composition(layers, composition_file)


def get_merge_strategy(path: Path, merge_strategies: Dict[str, str]) -> str:
"""
Return the merge strategy of the path based on the layer configured rules.
Expand Down Expand Up @@ -261,18 +276,3 @@ def get_merge_strategy(path: Path, merge_strategies: Dict[str, str]) -> str:
break

return strategy


def write_rendered_composition(composition: RenderedComposition):
"""
Write the composition file using the rendered layers to the appropriate.
Args:
composition: The rendered composition object to export
"""
layers = []
for rendered_layer in composition.layers:
layers.append(rendered_layer.layer)

composition_file = composition.render_dir / composition.rendered_name / ".composition.yaml"
write_composition(layers, composition_file)
6 changes: 6 additions & 0 deletions cookie_composer/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,9 @@ def __init__(
msg = f"There was a problem merging {origin} and {destination} using {strategy}: {error_message}"
super().__init__(msg)
super().__init__(error_message)


class GitError(Exception):
"""There was a problem doing git operations."""

pass
82 changes: 82 additions & 0 deletions cookie_composer/git_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""Functions for using git."""
from ctypes import Union
from pathlib import Path

from git import InvalidGitRepositoryError, Repo

from cookie_composer.exceptions import GitError


def get_repo(project_dir: Union[str, Path]) -> Repo:
"""
Get the git Repo object for a directory.
Args:
project_dir: The directory containing the .git folder
Raises:
GitError: If the directory is not a git repo
Returns:
The GitPython Repo object
"""
try:
return Repo(str(project_dir))
except InvalidGitRepositoryError as e:
raise GitError("Some cookie composer commands only work on git repositories.") from e


def branch_exists(repo: Repo, branch_name: str) -> bool:
"""
Does the branch exist in the repo?
Args:
repo: The repository to check
branch_name: The name of the branch to check for
Returns:
``True`` if the branch exists
"""
return branch_name in repo.refs


def remote_branch_exists(repo: Repo, branch_name: str, remote_name: str = "origin") -> bool:
"""
Does the branch exist in the remote repo?
Args:
repo: The repository to check
branch_name: The name of the branch to check for
remote_name: The name of the remote reference. Defaults to ``origin``
Returns:
``True`` if the branch exists in the remote repository
"""
return branch_name in repo.remotes[remote_name].refs


def checkout_branch(repo: Repo, branch_name: str, remote_name: str = "origin"):
"""Checkout a local or remote branch."""
if repo.is_dirty():
raise GitError(
"Cookie composer cannot apply updates on an unclean git project."
" Please make sure your git working tree is clean before proceeding."
)
repo.remotes[0].fetch()
if branch_exists(repo, branch_name):
repo.heads[branch_name].checkout()
elif remote_branch_exists(repo, branch_name, remote_name):
repo.create_head(branch_name, f"origin/{branch_name}")
repo.heads[branch_name].checkout()


def branch_from_first_commit(repo: Repo, branch_name: str):
"""Create and checkout a branch from the repo's first commit."""
if repo.is_dirty():
raise GitError(
"Cookie composer cannot apply updates on an unclean git project."
" Please make sure your git working tree is clean before proceeding."
)
first_commit = list(repo.iter_commits("HEAD", max_parents=0, max_count=1))[0]
repo.create_head(branch_name, first_commit.hexsha)
repo.heads[branch_name].checkout()
2 changes: 1 addition & 1 deletion requirements/cookiecutter.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ python-slugify==6.1.2
# via -r cookiecutter.in
pyyaml==6.0
# via -r cookiecutter.in
requests==2.27.1
requests==2.28.0
# via -r cookiecutter.in
six==1.16.0
# via python-dateutil
Expand Down
22 changes: 14 additions & 8 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ distlib==0.3.4
# via
# -r test.txt
# virtualenv
docutils==0.17.1
docutils==0.18.1
# via
# -r docs.txt
# myst-parser
Expand All @@ -96,9 +96,13 @@ ghp-import==2.1.0
git-fame==1.15.1
# via -r dev.in
gitdb==4.0.9
# via gitpython
# via
# -r test.txt
# gitpython
gitpython==3.1.27
# via generate-changelog
# via
# -r test.txt
# generate-changelog
identify==2.5.1
# via
# -r test.txt
Expand Down Expand Up @@ -162,7 +166,7 @@ mypy-extensions==0.4.3
# via
# -r test.txt
# black
myst-parser==0.17.2
myst-parser==0.18.0
# via -r docs.txt
nodeenv==1.6.0
# via
Expand Down Expand Up @@ -249,7 +253,7 @@ pyyaml==6.0
# -r test.txt
# myst-parser
# pre-commit
requests==2.27.1
requests==2.28.0
# via
# -r docs.txt
# -r test.txt
Expand Down Expand Up @@ -277,7 +281,9 @@ six==1.16.0
# python-dateutil
# virtualenv
smmap==5.0.0
# via gitdb
# via
# -r test.txt
# gitdb
snowballstemmer==2.2.0
# via
# -r docs.txt
Expand All @@ -286,7 +292,7 @@ soupsieve==2.3.2.post1
# via
# -r docs.txt
# beautifulsoup4
sphinx==4.5.0
sphinx==5.0.1
# via
# -r docs.txt
# furo
Expand All @@ -295,7 +301,7 @@ sphinx==4.5.0
# sphinx-basic-ng
# sphinx-click
# sphinx-copybutton
sphinx-autodoc-typehints==1.18.2
sphinx-autodoc-typehints==1.18.3
# via -r docs.txt
sphinx-basic-ng==0.0.1a11
# via
Expand Down
10 changes: 5 additions & 5 deletions requirements/docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ click==8.1.3
# via
# -c test.txt
# sphinx-click
docutils==0.17.1
docutils==0.18.1
# via
# myst-parser
# sphinx
Expand Down Expand Up @@ -58,7 +58,7 @@ mdit-py-plugins==0.3.0
# via myst-parser
mdurl==0.1.1
# via markdown-it-py
myst-parser==0.17.2
myst-parser==0.18.0
# via -r docs.in
packaging==21.3
# via
Expand All @@ -83,7 +83,7 @@ pyyaml==6.0
# via
# -c test.txt
# myst-parser
requests==2.27.1
requests==2.28.0
# via
# -c test.txt
# sphinx
Expand All @@ -95,7 +95,7 @@ snowballstemmer==2.2.0
# via sphinx
soupsieve==2.3.2.post1
# via beautifulsoup4
sphinx==4.5.0
sphinx==5.0.1
# via
# -r docs.in
# furo
Expand All @@ -104,7 +104,7 @@ sphinx==4.5.0
# sphinx-basic-ng
# sphinx-click
# sphinx-copybutton
sphinx-autodoc-typehints==1.18.2
sphinx-autodoc-typehints==1.18.3
# via -r docs.in
sphinx-basic-ng==0.0.1a11
# via furo
Expand Down
1 change: 1 addition & 0 deletions requirements/prod.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
-r cookiecutter.txt

fsspec
gitpython
pydantic
requests
rich-click
Expand Down
8 changes: 7 additions & 1 deletion requirements/prod.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ commonmark==0.9.1
# via rich
fsspec==2022.5.0
# via -r prod.in
gitdb==4.0.9
# via gitpython
gitpython==3.1.27
# via -r prod.in
idna==3.3
# via
# -r cookiecutter.txt
Expand All @@ -56,7 +60,7 @@ python-slugify==6.1.2
# via -r cookiecutter.txt
pyyaml==6.0
# via -r cookiecutter.txt
requests==2.27.1
requests==2.28.0
# via
# -r cookiecutter.txt
# -r prod.in
Expand All @@ -72,6 +76,8 @@ six==1.16.0
# via
# -r cookiecutter.txt
# python-dateutil
smmap==5.0.0
# via gitdb
text-unidecode==1.3
# via
# -r cookiecutter.txt
Expand Down
12 changes: 11 additions & 1 deletion requirements/test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ flake8==4.0.1
# via -r test.in
fsspec==2022.5.0
# via -r prod.txt
gitdb==4.0.9
# via
# -r prod.txt
# gitpython
gitpython==3.1.27
# via -r prod.txt
identify==2.5.1
# via pre-commit
idna==3.3
Expand Down Expand Up @@ -118,7 +124,7 @@ pyyaml==6.0
# via
# -r prod.txt
# pre-commit
requests==2.27.1
requests==2.28.0
# via -r prod.txt
rich==12.4.4
# via
Expand All @@ -137,6 +143,10 @@ six==1.16.0
# -r prod.txt
# python-dateutil
# virtualenv
smmap==5.0.0
# via
# -r prod.txt
# gitdb
text-unidecode==1.3
# via
# -r prod.txt
Expand Down

0 comments on commit 291b9aa

Please sign in to comment.