feat: add git pull subcommand
This commit is contained in:
parent
4746e3b3b1
commit
9dd2405c47
10 changed files with 101 additions and 15 deletions
|
|
@ -1 +1 @@
|
||||||
__version__ = "0.5.1a2"
|
__version__ = "0.6.0"
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@ from halig.commands.git.base import GitBaseCommand
|
||||||
|
|
||||||
|
|
||||||
class GitCommitCommand(GitBaseCommand):
|
class GitCommitCommand(GitBaseCommand):
|
||||||
|
def __init__(self, message: str | None = None, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.message = message or self.settings.default_commit_message
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Add all .age files to git and commit them using gitpython"""
|
"""Add all .age files to git and commit them using gitpython"""
|
||||||
self.repo.index.add(
|
self.repo.index.add(
|
||||||
|
|
|
||||||
19
halig/commands/git/pull.py
Normal file
19
halig/commands/git/pull.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
from halig.commands.git.base import GitBaseCommand
|
||||||
|
|
||||||
|
|
||||||
|
class GitPullCommand(GitBaseCommand):
|
||||||
|
def __init__(
|
||||||
|
self, remotes: list[str] | None = None, ref: str | None = None, *args, **kwargs
|
||||||
|
):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.remotes = remotes
|
||||||
|
self.ref = ref
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
"""Pull all changes from the remote git repo"""
|
||||||
|
if not self.remotes:
|
||||||
|
self.repo.remotes.origin.pull(self.ref or "main")
|
||||||
|
return
|
||||||
|
|
||||||
|
for remote in self.remotes:
|
||||||
|
self.repo.remotes[remote].pull(self.ref or "main")
|
||||||
|
|
@ -2,11 +2,15 @@ from halig.commands.git.base import GitBaseCommand
|
||||||
|
|
||||||
|
|
||||||
class GitPushCommand(GitBaseCommand):
|
class GitPushCommand(GitBaseCommand):
|
||||||
def run(self, remotes: list[str] | None = None):
|
def __init__(self, remotes: list[str] | None = None, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.remotes = remotes
|
||||||
|
|
||||||
|
def run(self):
|
||||||
"""Push all changes to the remote git repo"""
|
"""Push all changes to the remote git repo"""
|
||||||
if not remotes:
|
if not self.remotes:
|
||||||
self.repo.remotes.origin.push()
|
self.repo.remotes.origin.push()
|
||||||
return
|
return
|
||||||
|
|
||||||
for remote in remotes:
|
for remote in self.remotes:
|
||||||
self.repo.remotes[remote].push()
|
self.repo.remotes[remote].push()
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ when new public keys have been added to the config file and you want the notes
|
||||||
to be seen by the new pairing private keys"""
|
to be seen by the new pairing private keys"""
|
||||||
COMMANDS_GIT_COMMIT_HELP = "Commit all .age files to git"
|
COMMANDS_GIT_COMMIT_HELP = "Commit all .age files to git"
|
||||||
COMMANDS_GIT_PUSH_HELP = "Push all .age files to git"
|
COMMANDS_GIT_PUSH_HELP = "Push all .age files to git"
|
||||||
|
COMMANDS_GIT_PULL_HELP = "Pull all .age files from git"
|
||||||
|
|
||||||
# OPTIONS
|
# OPTIONS
|
||||||
OPTION_CONFIG_HELP = "Configuration file. Must be YAML and schema compatible"
|
OPTION_CONFIG_HELP = "Configuration file. Must be YAML and schema compatible"
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ from halig import literals
|
||||||
from halig.__version__ import __version__
|
from halig.__version__ import __version__
|
||||||
from halig.commands.edit import EditCommand
|
from halig.commands.edit import EditCommand
|
||||||
from halig.commands.git.commit import GitCommitCommand
|
from halig.commands.git.commit import GitCommitCommand
|
||||||
|
from halig.commands.git.pull import GitPullCommand
|
||||||
from halig.commands.git.push import GitPushCommand
|
from halig.commands.git.push import GitPushCommand
|
||||||
from halig.commands.import_unencrypted import ImportCommand
|
from halig.commands.import_unencrypted import ImportCommand
|
||||||
from halig.commands.notebooks import NotebooksCommand
|
from halig.commands.notebooks import NotebooksCommand
|
||||||
|
|
@ -168,10 +169,21 @@ def git_commit(
|
||||||
|
|
||||||
@git_app.command(name="push", help=literals.COMMANDS_GIT_PUSH_HELP)
|
@git_app.command(name="push", help=literals.COMMANDS_GIT_PUSH_HELP)
|
||||||
def git_push(
|
def git_push(
|
||||||
|
remotes: list[str] | None = None,
|
||||||
config: Path | None = config_option,
|
config: Path | None = config_option,
|
||||||
):
|
):
|
||||||
settings = load_from_file(config)
|
settings = load_from_file(config)
|
||||||
command = GitPushCommand(settings=settings)
|
command = GitPushCommand(settings=settings, remotes=remotes)
|
||||||
|
command.run()
|
||||||
|
|
||||||
|
|
||||||
|
@git_app.command(name="pull", help=literals.COMMANDS_GIT_PULL_HELP)
|
||||||
|
def git_pull(
|
||||||
|
remotes: list[str] | None = None,
|
||||||
|
config: Path | None = config_option,
|
||||||
|
):
|
||||||
|
settings = load_from_file(config)
|
||||||
|
command = GitPullCommand(settings=settings, remotes=remotes)
|
||||||
command.run()
|
command.run()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ from halig.settings import Settings
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def command(settings: Settings):
|
def command(settings: Settings):
|
||||||
return GitCommitCommand(settings)
|
return GitCommitCommand(settings=settings)
|
||||||
|
|
||||||
|
|
||||||
def test_repo_is_not_initialized(settings):
|
def test_repo_is_not_initialized(settings):
|
||||||
|
|
@ -16,7 +16,7 @@ def test_repo_is_not_initialized(settings):
|
||||||
initializes the repo upon instantiation"""
|
initializes the repo upon instantiation"""
|
||||||
|
|
||||||
assert not (settings.notebooks_root_path / ".git").is_dir()
|
assert not (settings.notebooks_root_path / ".git").is_dir()
|
||||||
GitCommitCommand(settings)
|
GitCommitCommand(settings=settings)
|
||||||
assert (settings.notebooks_root_path / ".git").is_dir()
|
assert (settings.notebooks_root_path / ".git").is_dir()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ def test_repo_is_initialized(settings):
|
||||||
p = subprocess.Popen(["git", "init"], cwd=settings.notebooks_root_path)
|
p = subprocess.Popen(["git", "init"], cwd=settings.notebooks_root_path)
|
||||||
p.wait()
|
p.wait()
|
||||||
assert (settings.notebooks_root_path / ".git").is_dir()
|
assert (settings.notebooks_root_path / ".git").is_dir()
|
||||||
GitCommitCommand(settings)
|
GitCommitCommand(settings=settings)
|
||||||
assert (settings.notebooks_root_path / ".git").is_dir()
|
assert (settings.notebooks_root_path / ".git").is_dir()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
37
tests/commands/test_git/test_pull.py
Normal file
37
tests/commands/test_git/test_pull.py
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from git import Repo
|
||||||
|
|
||||||
|
from halig.commands.git.pull import GitPullCommand
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def command(settings, faker):
|
||||||
|
"""Configure a local remote for testing located at settings.notebooks_root_path/../remote, push some .age files to
|
||||||
|
that remote
|
||||||
|
"""
|
||||||
|
command = GitPullCommand(settings=settings)
|
||||||
|
|
||||||
|
new_path = shutil.copytree(settings.notebooks_root_path, settings.notebooks_root_path / "../remote")
|
||||||
|
new_path = new_path.resolve()
|
||||||
|
|
||||||
|
command.repo.create_remote("origin", str(new_path))
|
||||||
|
|
||||||
|
remote_repo = Repo(new_path)
|
||||||
|
for _ in range(10):
|
||||||
|
random_age_file = new_path / f"{faker.word()}.age"
|
||||||
|
random_age_file.touch()
|
||||||
|
remote_repo.index.add([str(random_age_file)])
|
||||||
|
remote_repo.index.commit("Update notebooks")
|
||||||
|
|
||||||
|
return command
|
||||||
|
|
||||||
|
def test_pull_from_origin(command):
|
||||||
|
command.run()
|
||||||
|
|
||||||
|
def test_pull_from_custom_origin(settings, command):
|
||||||
|
remote_path = settings.notebooks_root_path / "../remote"
|
||||||
|
command.repo.create_remote("custom", str(remote_path.resolve()))
|
||||||
|
command.remotes = ["custom"]
|
||||||
|
command.run()
|
||||||
|
|
@ -9,29 +9,30 @@ from halig.commands.git.push import GitPushCommand
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def command(settings, faker):
|
def command(settings, faker):
|
||||||
"""Configure a local remote for testing"""
|
"""Configure a local remote for testing"""
|
||||||
commit_command = GitCommitCommand(settings)
|
commit_command = GitCommitCommand(settings=settings)
|
||||||
new_path = shutil.copytree(settings.notebooks_root_path , settings.notebooks_root_path / "../remote")
|
new_path = shutil.copytree(settings.notebooks_root_path, settings.notebooks_root_path / "../remote")
|
||||||
new_path = new_path.resolve()
|
new_path = new_path.resolve()
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
random_age_file = settings.notebooks_root_path / f"{faker.word()}.age"
|
random_age_file = settings.notebooks_root_path / f"{faker.word()}.age"
|
||||||
random_age_file.touch()
|
random_age_file.touch()
|
||||||
commit_command.run()
|
commit_command.run()
|
||||||
|
|
||||||
push_command = GitPushCommand(settings)
|
push_command = GitPushCommand(settings=settings)
|
||||||
|
|
||||||
push_command.repo.create_remote("origin", str(new_path))
|
push_command.repo.create_remote("origin", str(new_path))
|
||||||
|
|
||||||
return push_command
|
return push_command
|
||||||
|
|
||||||
|
|
||||||
def test_push_to_origin(settings, command):
|
def test_push_to_origin(command):
|
||||||
"""Test that the command pushes to the origin remote"""
|
"""Test that the command pushes to the origin remote"""
|
||||||
command.run()
|
command.run()
|
||||||
|
|
||||||
|
|
||||||
def test_push_to_custom_remote(settings, command):
|
def test_push_to_custom_remote(settings, command):
|
||||||
"""Test that the command pushes to a custom remote"""
|
"""Test that the command pushes to a custom remote"""
|
||||||
|
|
||||||
remote_path = settings.notebooks_root_path / "../remote"
|
remote_path = settings.notebooks_root_path / "../remote"
|
||||||
command.repo.create_remote("custom", str(remote_path.resolve()))
|
command.repo.create_remote("custom", str(remote_path.resolve()))
|
||||||
|
command.remotes = ["custom"]
|
||||||
command.run(remotes=["custom"])
|
command.run()
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ from halig.settings import Settings, load_from_file
|
||||||
|
|
||||||
|
|
||||||
def test_settings_from_env(settings: Settings, notebooks_root_path_envvar):
|
def test_settings_from_env(settings: Settings, notebooks_root_path_envvar):
|
||||||
from_env_settings = Settings(recipient_paths=settings.recipient_paths, identity_paths=settings.identity_paths) # type: ignore[call-arg]
|
from_env_settings = Settings(recipient_paths=settings.recipient_paths,
|
||||||
|
identity_paths=settings.identity_paths) # type: ignore[call-arg]
|
||||||
assert from_env_settings.notebooks_root_path == settings.notebooks_root_path
|
assert from_env_settings.notebooks_root_path == settings.notebooks_root_path
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -29,3 +30,10 @@ def test_load_from_non_existing_file_path_raises_file_not_found_error(halig_conf
|
||||||
file = halig_config_path / "some_invalid_file.yml"
|
file = halig_config_path / "some_invalid_file.yml"
|
||||||
with pytest.raises(FileNotFoundError, match=f"File {file} does not exist"):
|
with pytest.raises(FileNotFoundError, match=f"File {file} does not exist"):
|
||||||
load_from_file(file)
|
load_from_file(file)
|
||||||
|
|
||||||
|
|
||||||
|
def test_settings_identity_paths_is_not_list_is_converted(settings):
|
||||||
|
s = Settings(identity_paths=settings.identity_paths[0], recipient_paths=settings.recipient_paths[0],
|
||||||
|
notebooks_root_path=settings.notebooks_root_path)
|
||||||
|
assert s.identity_paths == [settings.identity_paths[0]]
|
||||||
|
assert s.recipient_paths == [settings.recipient_paths[0]]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue