refactor(git): migrate repository creation to core.git commands
Some checks failed
Mark stable commit / test-unit (push) Has been cancelled
Mark stable commit / test-integration (push) Has been cancelled
Mark stable commit / test-env-virtual (push) Has been cancelled
Mark stable commit / test-env-nix (push) Has been cancelled
Mark stable commit / test-e2e (push) Has been cancelled
Mark stable commit / test-virgin-user (push) Has been cancelled
Mark stable commit / test-virgin-root (push) Has been cancelled
Mark stable commit / lint-shell (push) Has been cancelled
Mark stable commit / lint-python (push) Has been cancelled
Mark stable commit / mark-stable (push) Has been cancelled
Some checks failed
Mark stable commit / test-unit (push) Has been cancelled
Mark stable commit / test-integration (push) Has been cancelled
Mark stable commit / test-env-virtual (push) Has been cancelled
Mark stable commit / test-env-nix (push) Has been cancelled
Mark stable commit / test-e2e (push) Has been cancelled
Mark stable commit / test-virgin-user (push) Has been cancelled
Mark stable commit / test-virgin-root (push) Has been cancelled
Mark stable commit / lint-shell (push) Has been cancelled
Mark stable commit / lint-python (push) Has been cancelled
Mark stable commit / mark-stable (push) Has been cancelled
- Replace direct subprocess git calls with core.git commands (init, add_all, commit, branch_move, push_upstream) - Introduce add_all, init, and branch_move command wrappers with preview support - Use git config queries via get_config_value instead of shell access - Preserve main → master fallback logic with explicit error handling - Improve error transparency while keeping previous non-fatal behavior https://chatgpt.com/share/69414b77-b4d4-800f-a189-463b489664b3
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
|
# src/pkgmgr/actions/repository/create.py
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Any, Dict, Optional, Tuple
|
from typing import Any, Dict, Optional, Tuple
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
@@ -14,6 +14,16 @@ from pkgmgr.actions.mirror.setup_cmd import setup_mirrors
|
|||||||
from pkgmgr.actions.repository.scaffold import render_default_templates
|
from pkgmgr.actions.repository.scaffold import render_default_templates
|
||||||
from pkgmgr.core.command.alias import generate_alias
|
from pkgmgr.core.command.alias import generate_alias
|
||||||
from pkgmgr.core.config.save import save_user_config
|
from pkgmgr.core.config.save import save_user_config
|
||||||
|
from pkgmgr.core.git.commands import (
|
||||||
|
GitCommitError,
|
||||||
|
GitPushUpstreamError,
|
||||||
|
add_all,
|
||||||
|
branch_move,
|
||||||
|
commit,
|
||||||
|
init,
|
||||||
|
push_upstream,
|
||||||
|
)
|
||||||
|
from pkgmgr.core.git.queries import get_config_value
|
||||||
|
|
||||||
Repository = Dict[str, Any]
|
Repository = Dict[str, Any]
|
||||||
|
|
||||||
@@ -28,27 +38,6 @@ class RepoParts:
|
|||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
def _run(cmd: str, cwd: str, preview: bool) -> None:
|
|
||||||
if preview:
|
|
||||||
print(f"[Preview] Would run in {cwd}: {cmd}")
|
|
||||||
return
|
|
||||||
subprocess.run(cmd, cwd=cwd, shell=True, check=True)
|
|
||||||
|
|
||||||
|
|
||||||
def _git_get(key: str) -> str:
|
|
||||||
try:
|
|
||||||
out = subprocess.run(
|
|
||||||
f"git config --get {key}",
|
|
||||||
shell=True,
|
|
||||||
check=False,
|
|
||||||
capture_output=True,
|
|
||||||
text=True,
|
|
||||||
)
|
|
||||||
return (out.stdout or "").strip()
|
|
||||||
except Exception:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
|
||||||
def _split_host_port(host_with_port: str) -> Tuple[str, Optional[str]]:
|
def _split_host_port(host_with_port: str) -> Tuple[str, Optional[str]]:
|
||||||
if ":" in host_with_port:
|
if ":" in host_with_port:
|
||||||
host, port = host_with_port.split(":", 1)
|
host, port = host_with_port.split(":", 1)
|
||||||
@@ -116,28 +105,27 @@ def _write_default_mirrors(repo_dir: str, primary: str, name: str, preview: bool
|
|||||||
|
|
||||||
|
|
||||||
def _git_init_and_initial_commit(repo_dir: str, preview: bool) -> None:
|
def _git_init_and_initial_commit(repo_dir: str, preview: bool) -> None:
|
||||||
_run("git init", cwd=repo_dir, preview=preview)
|
init(cwd=repo_dir, preview=preview)
|
||||||
_run("git add -A", cwd=repo_dir, preview=preview)
|
add_all(cwd=repo_dir, preview=preview)
|
||||||
|
|
||||||
if preview:
|
try:
|
||||||
print(f'[Preview] Would run in {repo_dir}: git commit -m "Initial commit"')
|
commit("Initial commit", cwd=repo_dir, preview=preview)
|
||||||
return
|
except GitCommitError as exc:
|
||||||
|
print(f"[WARN] Initial commit failed (continuing): {exc}")
|
||||||
subprocess.run('git commit -m "Initial commit"', cwd=repo_dir, shell=True, check=False)
|
|
||||||
|
|
||||||
|
|
||||||
def _git_push_main_or_master(repo_dir: str, preview: bool) -> None:
|
def _git_push_main_or_master(repo_dir: str, preview: bool) -> None:
|
||||||
_run("git branch -M main", cwd=repo_dir, preview=preview)
|
|
||||||
try:
|
try:
|
||||||
_run("git push -u origin main", cwd=repo_dir, preview=preview)
|
branch_move("main", cwd=repo_dir, preview=preview)
|
||||||
|
push_upstream("origin", "main", cwd=repo_dir, preview=preview)
|
||||||
return
|
return
|
||||||
except subprocess.CalledProcessError:
|
except GitPushUpstreamError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_run("git branch -M master", cwd=repo_dir, preview=preview)
|
branch_move("master", cwd=repo_dir, preview=preview)
|
||||||
_run("git push -u origin master", cwd=repo_dir, preview=preview)
|
push_upstream("origin", "master", cwd=repo_dir, preview=preview)
|
||||||
except subprocess.CalledProcessError as exc:
|
except GitPushUpstreamError as exc:
|
||||||
print(f"[WARN] Push failed: {exc}")
|
print(f"[WARN] Push failed: {exc}")
|
||||||
|
|
||||||
|
|
||||||
@@ -157,8 +145,8 @@ def create_repo(
|
|||||||
base_dir = os.path.expanduser(str(directories.get("repositories", "~/Repositories")))
|
base_dir = os.path.expanduser(str(directories.get("repositories", "~/Repositories")))
|
||||||
repo_dir = os.path.join(base_dir, parts.host, parts.owner, parts.name)
|
repo_dir = os.path.join(base_dir, parts.host, parts.owner, parts.name)
|
||||||
|
|
||||||
author_name = _git_get("user.name") or "Unknown Author"
|
author_name = get_config_value("user.name") or "Unknown Author"
|
||||||
author_email = _git_get("user.email") or "unknown@example.invalid"
|
author_email = get_config_value("user.email") or "unknown@example.invalid"
|
||||||
|
|
||||||
homepage = _repo_homepage(parts.host, parts.owner, parts.name)
|
homepage = _repo_homepage(parts.host, parts.owner, parts.name)
|
||||||
primary_url = _build_default_primary_url(parts)
|
primary_url = _build_default_primary_url(parts)
|
||||||
|
|||||||
@@ -1,27 +1,31 @@
|
|||||||
|
# src/pkgmgr/core/git/commands/__init__.py
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from .add import GitAddError, add
|
from .add import GitAddError, add
|
||||||
|
from .add_all import GitAddAllError, add_all
|
||||||
|
from .add_remote import GitAddRemoteError, add_remote
|
||||||
|
from .add_remote_push_url import GitAddRemotePushUrlError, add_remote_push_url
|
||||||
|
from .branch_move import GitBranchMoveError, branch_move
|
||||||
from .checkout import GitCheckoutError, checkout
|
from .checkout import GitCheckoutError, checkout
|
||||||
|
from .clone import GitCloneError, clone
|
||||||
from .commit import GitCommitError, commit
|
from .commit import GitCommitError, commit
|
||||||
from .create_branch import GitCreateBranchError, create_branch
|
from .create_branch import GitCreateBranchError, create_branch
|
||||||
from .delete_local_branch import GitDeleteLocalBranchError, delete_local_branch
|
from .delete_local_branch import GitDeleteLocalBranchError, delete_local_branch
|
||||||
from .delete_remote_branch import GitDeleteRemoteBranchError, delete_remote_branch
|
from .delete_remote_branch import GitDeleteRemoteBranchError, delete_remote_branch
|
||||||
from .fetch import GitFetchError, fetch
|
from .fetch import GitFetchError, fetch
|
||||||
|
from .init import GitInitError, init
|
||||||
from .merge_no_ff import GitMergeError, merge_no_ff
|
from .merge_no_ff import GitMergeError, merge_no_ff
|
||||||
from .pull import GitPullError, pull
|
from .pull import GitPullError, pull
|
||||||
from .pull_ff_only import GitPullFfOnlyError, pull_ff_only
|
from .pull_ff_only import GitPullFfOnlyError, pull_ff_only
|
||||||
from .push import GitPushError, push
|
from .push import GitPushError, push
|
||||||
from .push_upstream import GitPushUpstreamError, push_upstream
|
from .push_upstream import GitPushUpstreamError, push_upstream
|
||||||
|
|
||||||
from .add_remote import GitAddRemoteError, add_remote
|
|
||||||
from .add_remote_push_url import GitAddRemotePushUrlError, add_remote_push_url
|
|
||||||
from .set_remote_url import GitSetRemoteUrlError, set_remote_url
|
from .set_remote_url import GitSetRemoteUrlError, set_remote_url
|
||||||
from .tag_annotated import GitTagAnnotatedError, tag_annotated
|
from .tag_annotated import GitTagAnnotatedError, tag_annotated
|
||||||
from .tag_force_annotated import GitTagForceAnnotatedError, tag_force_annotated
|
from .tag_force_annotated import GitTagForceAnnotatedError, tag_force_annotated
|
||||||
from .clone import GitCloneError, clone
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"add",
|
"add",
|
||||||
|
"add_all",
|
||||||
"fetch",
|
"fetch",
|
||||||
"checkout",
|
"checkout",
|
||||||
"pull",
|
"pull",
|
||||||
@@ -39,7 +43,10 @@ __all__ = [
|
|||||||
"tag_annotated",
|
"tag_annotated",
|
||||||
"tag_force_annotated",
|
"tag_force_annotated",
|
||||||
"clone",
|
"clone",
|
||||||
|
"init",
|
||||||
|
"branch_move",
|
||||||
"GitAddError",
|
"GitAddError",
|
||||||
|
"GitAddAllError",
|
||||||
"GitFetchError",
|
"GitFetchError",
|
||||||
"GitCheckoutError",
|
"GitCheckoutError",
|
||||||
"GitPullError",
|
"GitPullError",
|
||||||
@@ -57,4 +64,6 @@ __all__ = [
|
|||||||
"GitTagAnnotatedError",
|
"GitTagAnnotatedError",
|
||||||
"GitTagForceAnnotatedError",
|
"GitTagForceAnnotatedError",
|
||||||
"GitCloneError",
|
"GitCloneError",
|
||||||
|
"GitInitError",
|
||||||
|
"GitBranchMoveError",
|
||||||
]
|
]
|
||||||
|
|||||||
22
src/pkgmgr/core/git/commands/add_all.py
Normal file
22
src/pkgmgr/core/git/commands/add_all.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# src/pkgmgr/core/git/commands/add_all.py
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from ..errors import GitError, GitCommandError
|
||||||
|
from ..run import run
|
||||||
|
|
||||||
|
|
||||||
|
class GitAddAllError(GitCommandError):
|
||||||
|
"""Raised when `git add -A` fails."""
|
||||||
|
|
||||||
|
|
||||||
|
def add_all(*, cwd: str = ".", preview: bool = False) -> None:
|
||||||
|
"""
|
||||||
|
Stage all changes (tracked + untracked).
|
||||||
|
|
||||||
|
Equivalent to:
|
||||||
|
git add -A
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
run(["add", "-A"], cwd=cwd, preview=preview)
|
||||||
|
except GitError as exc:
|
||||||
|
raise GitAddAllError("Failed to stage all changes with `git add -A`.", cwd=cwd) from exc
|
||||||
22
src/pkgmgr/core/git/commands/branch_move.py
Normal file
22
src/pkgmgr/core/git/commands/branch_move.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# src/pkgmgr/core/git/commands/branch_move.py
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from ..errors import GitError, GitCommandError
|
||||||
|
from ..run import run
|
||||||
|
|
||||||
|
|
||||||
|
class GitBranchMoveError(GitCommandError):
|
||||||
|
"""Raised when renaming/moving a branch fails."""
|
||||||
|
|
||||||
|
|
||||||
|
def branch_move(branch: str, *, cwd: str = ".", preview: bool = False) -> None:
|
||||||
|
"""
|
||||||
|
Rename the current branch to `branch`, creating it if needed.
|
||||||
|
|
||||||
|
Equivalent to:
|
||||||
|
git branch -M <branch>
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
run(["branch", "-M", branch], cwd=cwd, preview=preview)
|
||||||
|
except GitError as exc:
|
||||||
|
raise GitBranchMoveError(f"Failed to move/rename current branch to {branch!r}.", cwd=cwd) from exc
|
||||||
22
src/pkgmgr/core/git/commands/init.py
Normal file
22
src/pkgmgr/core/git/commands/init.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# src/pkgmgr/core/git/commands/init.py
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from ..errors import GitError, GitCommandError
|
||||||
|
from ..run import run
|
||||||
|
|
||||||
|
|
||||||
|
class GitInitError(GitCommandError):
|
||||||
|
"""Raised when `git init` fails."""
|
||||||
|
|
||||||
|
|
||||||
|
def init(*, cwd: str = ".", preview: bool = False) -> None:
|
||||||
|
"""
|
||||||
|
Initialize a repository.
|
||||||
|
|
||||||
|
Equivalent to:
|
||||||
|
git init
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
run(["init"], cwd=cwd, preview=preview)
|
||||||
|
except GitError as exc:
|
||||||
|
raise GitInitError("Failed to initialize git repository.", cwd=cwd) from exc
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# src/pkgmgr/core/git/commands/push_upstream.py
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from ..errors import GitError, GitCommandError
|
from ..errors import GitError, GitCommandError
|
||||||
@@ -8,14 +9,21 @@ class GitPushUpstreamError(GitCommandError):
|
|||||||
"""Raised when pushing a branch with upstream tracking fails."""
|
"""Raised when pushing a branch with upstream tracking fails."""
|
||||||
|
|
||||||
|
|
||||||
def push_upstream(remote: str, branch: str, cwd: str = ".") -> None:
|
def push_upstream(
|
||||||
|
remote: str,
|
||||||
|
branch: str,
|
||||||
|
*,
|
||||||
|
cwd: str = ".",
|
||||||
|
preview: bool = False,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Push a branch and set upstream tracking.
|
Push a branch and set upstream tracking.
|
||||||
|
|
||||||
Equivalent to: git push -u <remote> <branch>
|
Equivalent to:
|
||||||
|
git push -u <remote> <branch>
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
run(["push", "-u", remote, branch], cwd=cwd)
|
run(["push", "-u", remote, branch], cwd=cwd, preview=preview)
|
||||||
except GitError as exc:
|
except GitError as exc:
|
||||||
raise GitPushUpstreamError(
|
raise GitPushUpstreamError(
|
||||||
f"Failed to push branch {branch!r} to {remote!r} with upstream tracking.",
|
f"Failed to push branch {branch!r} to {remote!r} with upstream tracking.",
|
||||||
|
|||||||
Reference in New Issue
Block a user