fix: --all-starred now clones repos without --repositories

This commit is contained in:
Rodos
2025-12-07 21:21:14 +11:00
parent aba048a3e9
commit 6e2a7e521c
2 changed files with 167 additions and 8 deletions

View File

@@ -561,7 +561,7 @@ def get_github_host(args):
def read_file_contents(file_uri):
return open(file_uri[len(FILE_URI_PREFIX) :], "rt").readline().strip()
return open(file_uri[len(FILE_URI_PREFIX):], "rt").readline().strip()
def get_github_repo_url(args, repository):
@@ -1672,9 +1672,10 @@ def backup_repositories(args, output_directory, repositories):
repo_url = get_github_repo_url(args, repository)
include_gists = args.include_gists or args.include_starred_gists
include_starred = args.all_starred and repository.get("is_starred")
if (args.include_repository or args.include_everything) or (
include_gists and repository.get("is_gist")
):
) or include_starred:
repo_name = (
repository.get("name")
if not repository.get("is_gist")
@@ -2023,12 +2024,9 @@ def fetch_repository(
):
if bare_clone:
if os.path.exists(local_dir):
clone_exists = (
subprocess.check_output(
["git", "rev-parse", "--is-bare-repository"], cwd=local_dir
)
== b"true\n"
)
clone_exists = subprocess.check_output(
["git", "rev-parse", "--is-bare-repository"], cwd=local_dir
) == b"true\n"
else:
clone_exists = False
else:

161
tests/test_all_starred.py Normal file
View File

@@ -0,0 +1,161 @@
"""Tests for --all-starred flag behavior (issue #225)."""
import pytest
from unittest.mock import Mock, patch
from github_backup import github_backup
class TestAllStarredCloning:
"""Test suite for --all-starred repository cloning behavior.
Issue #225: --all-starred should clone starred repos without requiring --repositories.
"""
def _create_mock_args(self, **overrides):
"""Create a mock args object with sensible defaults."""
args = Mock()
args.user = "testuser"
args.output_directory = "/tmp/backup"
args.include_repository = False
args.include_everything = False
args.include_gists = False
args.include_starred_gists = False
args.all_starred = False
args.skip_existing = False
args.bare_clone = False
args.lfs_clone = False
args.no_prune = False
args.include_wiki = False
args.include_issues = False
args.include_issue_comments = False
args.include_issue_events = False
args.include_pulls = False
args.include_pull_comments = False
args.include_pull_commits = False
args.include_pull_details = False
args.include_labels = False
args.include_hooks = False
args.include_milestones = False
args.include_releases = False
args.include_assets = False
args.include_attachments = False
args.incremental = False
args.incremental_by_files = False
args.github_host = None
args.prefer_ssh = False
args.token_classic = None
args.token_fine = None
args.username = None
args.password = None
args.as_app = False
args.osx_keychain_item_name = None
args.osx_keychain_item_account = None
for key, value in overrides.items():
setattr(args, key, value)
return args
@patch('github_backup.github_backup.fetch_repository')
@patch('github_backup.github_backup.get_github_repo_url')
def test_all_starred_clones_without_repositories_flag(self, mock_get_url, mock_fetch):
"""--all-starred should clone starred repos without --repositories flag.
This is the core fix for issue #225.
"""
args = self._create_mock_args(all_starred=True)
mock_get_url.return_value = "https://github.com/otheruser/awesome-project.git"
# A starred repository (is_starred flag set by retrieve_repositories)
starred_repo = {
"name": "awesome-project",
"full_name": "otheruser/awesome-project",
"owner": {"login": "otheruser"},
"private": False,
"fork": False,
"has_wiki": False,
"is_starred": True, # This flag is set for starred repos
}
with patch('github_backup.github_backup.mkdir_p'):
github_backup.backup_repositories(args, "/tmp/backup", [starred_repo])
# fetch_repository should be called for the starred repo
assert mock_fetch.called, "--all-starred should trigger repository cloning"
mock_fetch.assert_called_once()
call_args = mock_fetch.call_args
assert call_args[0][0] == "awesome-project" # repo name
@patch('github_backup.github_backup.fetch_repository')
@patch('github_backup.github_backup.get_github_repo_url')
def test_starred_repo_not_cloned_without_all_starred_flag(self, mock_get_url, mock_fetch):
"""Starred repos should NOT be cloned if --all-starred is not set."""
args = self._create_mock_args(all_starred=False)
mock_get_url.return_value = "https://github.com/otheruser/awesome-project.git"
starred_repo = {
"name": "awesome-project",
"full_name": "otheruser/awesome-project",
"owner": {"login": "otheruser"},
"private": False,
"fork": False,
"has_wiki": False,
"is_starred": True,
}
with patch('github_backup.github_backup.mkdir_p'):
github_backup.backup_repositories(args, "/tmp/backup", [starred_repo])
# fetch_repository should NOT be called
assert not mock_fetch.called, "Starred repos should not be cloned without --all-starred"
@patch('github_backup.github_backup.fetch_repository')
@patch('github_backup.github_backup.get_github_repo_url')
def test_non_starred_repo_not_cloned_with_only_all_starred(self, mock_get_url, mock_fetch):
"""Non-starred repos should NOT be cloned when only --all-starred is set."""
args = self._create_mock_args(all_starred=True)
mock_get_url.return_value = "https://github.com/testuser/my-project.git"
# A regular (non-starred) repository
regular_repo = {
"name": "my-project",
"full_name": "testuser/my-project",
"owner": {"login": "testuser"},
"private": False,
"fork": False,
"has_wiki": False,
# No is_starred flag
}
with patch('github_backup.github_backup.mkdir_p'):
github_backup.backup_repositories(args, "/tmp/backup", [regular_repo])
# fetch_repository should NOT be called for non-starred repos
assert not mock_fetch.called, "Non-starred repos should not be cloned with only --all-starred"
@patch('github_backup.github_backup.fetch_repository')
@patch('github_backup.github_backup.get_github_repo_url')
def test_repositories_flag_still_works(self, mock_get_url, mock_fetch):
"""--repositories flag should still clone repos as before."""
args = self._create_mock_args(include_repository=True)
mock_get_url.return_value = "https://github.com/testuser/my-project.git"
regular_repo = {
"name": "my-project",
"full_name": "testuser/my-project",
"owner": {"login": "testuser"},
"private": False,
"fork": False,
"has_wiki": False,
}
with patch('github_backup.github_backup.mkdir_p'):
github_backup.backup_repositories(args, "/tmp/backup", [regular_repo])
# fetch_repository should be called
assert mock_fetch.called, "--repositories should trigger repository cloning"
if __name__ == "__main__":
pytest.main([__file__, "-v"])