github-repository-sync 0.0.2__tar.gz → 0.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {github_repository_sync-0.0.2 → github_repository_sync-0.0.3}/PKG-INFO +7 -1
- {github_repository_sync-0.0.2 → github_repository_sync-0.0.3}/README.md +6 -0
- {github_repository_sync-0.0.2 → github_repository_sync-0.0.3}/pyproject.toml +1 -1
- {github_repository_sync-0.0.2 → github_repository_sync-0.0.3}/src/github_repository_sync.egg-info/PKG-INFO +7 -1
- {github_repository_sync-0.0.2 → github_repository_sync-0.0.3}/src/github_repository_sync.py +10 -6
- {github_repository_sync-0.0.2 → github_repository_sync-0.0.3}/tests/test_github_repository_sync.py +9 -2
- {github_repository_sync-0.0.2 → github_repository_sync-0.0.3}/setup.cfg +0 -0
- {github_repository_sync-0.0.2 → github_repository_sync-0.0.3}/src/github_repository_sync.egg-info/SOURCES.txt +0 -0
- {github_repository_sync-0.0.2 → github_repository_sync-0.0.3}/src/github_repository_sync.egg-info/dependency_links.txt +0 -0
- {github_repository_sync-0.0.2 → github_repository_sync-0.0.3}/src/github_repository_sync.egg-info/entry_points.txt +0 -0
- {github_repository_sync-0.0.2 → github_repository_sync-0.0.3}/src/github_repository_sync.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: github-repository-sync
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: Synchronize local repositories for a GitHub organization.
|
|
5
5
|
Author: Kaizten Analytics
|
|
6
6
|
License-Expression: LicenseRef-Proprietary
|
|
@@ -130,6 +130,7 @@ state files.
|
|
|
130
130
|
|
|
131
131
|
After repository processing starts, every run prints aggregate counts for:
|
|
132
132
|
|
|
133
|
+
- all repositories returned for the GitHub organization;
|
|
133
134
|
- repositories processed;
|
|
134
135
|
- repositories already local and missing locally;
|
|
135
136
|
- repositories cloned and pulled successfully;
|
|
@@ -144,6 +145,11 @@ upstream. Each repository is counted at most once in the error total, even if
|
|
|
144
145
|
more than one operation failed. Dry runs additionally report the numbers of
|
|
145
146
|
planned pulls and clones.
|
|
146
147
|
|
|
148
|
+
The GitHub organization total is the first summary metric. It includes every
|
|
149
|
+
repository returned by the current authenticated GitHub query, including
|
|
150
|
+
archived and disabled repositories, and is not reduced by `--exclude-archived`
|
|
151
|
+
or `--limit`.
|
|
152
|
+
|
|
147
153
|
Failures during repository processing produce a nonzero exit status after the
|
|
148
154
|
summary is printed. Startup failures, such as an invalid root or failed SSH
|
|
149
155
|
preflight, occur before processing and therefore do not print a summary.
|
|
@@ -119,6 +119,7 @@ state files.
|
|
|
119
119
|
|
|
120
120
|
After repository processing starts, every run prints aggregate counts for:
|
|
121
121
|
|
|
122
|
+
- all repositories returned for the GitHub organization;
|
|
122
123
|
- repositories processed;
|
|
123
124
|
- repositories already local and missing locally;
|
|
124
125
|
- repositories cloned and pulled successfully;
|
|
@@ -133,6 +134,11 @@ upstream. Each repository is counted at most once in the error total, even if
|
|
|
133
134
|
more than one operation failed. Dry runs additionally report the numbers of
|
|
134
135
|
planned pulls and clones.
|
|
135
136
|
|
|
137
|
+
The GitHub organization total is the first summary metric. It includes every
|
|
138
|
+
repository returned by the current authenticated GitHub query, including
|
|
139
|
+
archived and disabled repositories, and is not reduced by `--exclude-archived`
|
|
140
|
+
or `--limit`.
|
|
141
|
+
|
|
136
142
|
Failures during repository processing produce a nonzero exit status after the
|
|
137
143
|
summary is printed. Startup failures, such as an invalid root or failed SSH
|
|
138
144
|
preflight, occur before processing and therefore do not print a summary.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: github-repository-sync
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: Synchronize local repositories for a GitHub organization.
|
|
5
5
|
Author: Kaizten Analytics
|
|
6
6
|
License-Expression: LicenseRef-Proprietary
|
|
@@ -130,6 +130,7 @@ state files.
|
|
|
130
130
|
|
|
131
131
|
After repository processing starts, every run prints aggregate counts for:
|
|
132
132
|
|
|
133
|
+
- all repositories returned for the GitHub organization;
|
|
133
134
|
- repositories processed;
|
|
134
135
|
- repositories already local and missing locally;
|
|
135
136
|
- repositories cloned and pulled successfully;
|
|
@@ -144,6 +145,11 @@ upstream. Each repository is counted at most once in the error total, even if
|
|
|
144
145
|
more than one operation failed. Dry runs additionally report the numbers of
|
|
145
146
|
planned pulls and clones.
|
|
146
147
|
|
|
148
|
+
The GitHub organization total is the first summary metric. It includes every
|
|
149
|
+
repository returned by the current authenticated GitHub query, including
|
|
150
|
+
archived and disabled repositories, and is not reduced by `--exclude-archived`
|
|
151
|
+
or `--limit`.
|
|
152
|
+
|
|
147
153
|
Failures during repository processing produce a nonzero exit status after the
|
|
148
154
|
summary is printed. Startup failures, such as an invalid root or failed SSH
|
|
149
155
|
preflight, occur before processing and therefore do not print a summary.
|
|
@@ -820,21 +820,24 @@ def sync_existing_repository(repo_name: str, repo_path: Path, dry_run: bool) ->
|
|
|
820
820
|
)
|
|
821
821
|
|
|
822
822
|
|
|
823
|
-
def print_sync_summary(
|
|
823
|
+
def print_sync_summary(
|
|
824
|
+
results: list[RepositoryResult], dry_run: bool, organization_repository_count: int
|
|
825
|
+
) -> None:
|
|
824
826
|
"""Print aggregate counts and actionable repository details."""
|
|
825
827
|
cloned = [result for result in results if result.cloned]
|
|
826
828
|
needs_push = [result for result in results if result.needs_push]
|
|
827
829
|
|
|
828
|
-
print("
|
|
830
|
+
print("🏁 Summary:")
|
|
829
831
|
print("-----------")
|
|
832
|
+
print(f"🏢 Repositories in GitHub organization: {organization_repository_count}")
|
|
830
833
|
print(f"📦 Repositories processed: {len(results)}")
|
|
831
|
-
print(f"
|
|
834
|
+
print(f"👌 Repositories already local: {sum(result.was_local for result in results)}")
|
|
832
835
|
print(f"📁 Repositories missing locally: {sum(not result.was_local for result in results)}")
|
|
833
|
-
print(f"
|
|
836
|
+
print(f"⮺ Repositories cloned: {len(cloned)}")
|
|
834
837
|
for result in cloned:
|
|
835
838
|
print(f"- {result.repo_name}: {result.path}")
|
|
836
839
|
print(f"📥 Repositories pulled: {sum(result.pulled for result in results)}")
|
|
837
|
-
print(f"
|
|
840
|
+
print(f"⚠️ Repositories needing push/local attention: {len(needs_push)}")
|
|
838
841
|
for result in needs_push:
|
|
839
842
|
print(f"- {result.repo_name}: {result.path}")
|
|
840
843
|
print(f"📁 Repositories skipped because dirty: {sum(result.skipped_dirty for result in results)}")
|
|
@@ -926,6 +929,7 @@ def main() -> int:
|
|
|
926
929
|
org_repos = fetch_org_repositories(args.github_api, args.org, args.token)
|
|
927
930
|
source = "GitHub API"
|
|
928
931
|
|
|
932
|
+
organization_repository_count = len(org_repos)
|
|
929
933
|
active_repos = [
|
|
930
934
|
repo
|
|
931
935
|
for repo in org_repos
|
|
@@ -1037,7 +1041,7 @@ def main() -> int:
|
|
|
1037
1041
|
|
|
1038
1042
|
print("\n")
|
|
1039
1043
|
|
|
1040
|
-
print_sync_summary(results, args.dry_run)
|
|
1044
|
+
print_sync_summary(results, args.dry_run, organization_repository_count)
|
|
1041
1045
|
return 1 if state_write_error or any(result.errors for result in results) else 0
|
|
1042
1046
|
|
|
1043
1047
|
|
{github_repository_sync-0.0.2 → github_repository_sync-0.0.3}/tests/test_github_repository_sync.py
RENAMED
|
@@ -557,9 +557,12 @@ class SyncOrgRepositoriesTests(unittest.TestCase):
|
|
|
557
557
|
stdout = io.StringIO()
|
|
558
558
|
|
|
559
559
|
with redirect_stdout(stdout):
|
|
560
|
-
sync.print_sync_summary(results, dry_run=True)
|
|
560
|
+
sync.print_sync_summary(results, dry_run=True, organization_repository_count=8)
|
|
561
561
|
|
|
562
562
|
output = stdout.getvalue()
|
|
563
|
+
output_lines = output.splitlines()
|
|
564
|
+
self.assertEqual(output_lines[2], "🏢 Repositories in GitHub organization: 8")
|
|
565
|
+
self.assertEqual(output_lines[3], "📦 Repositories processed: 3")
|
|
563
566
|
self.assertIn("Repositories processed: 3", output)
|
|
564
567
|
self.assertIn("Repositories already local: 1", output)
|
|
565
568
|
self.assertIn("Repositories missing locally: 2", output)
|
|
@@ -657,6 +660,7 @@ class SyncOrgRepositoriesTests(unittest.TestCase):
|
|
|
657
660
|
saved_state = save_state.call_args.args[1]
|
|
658
661
|
self.assertGreater(saved_state["missing"].last_changed_at, old_clone_time)
|
|
659
662
|
output = stdout.getvalue()
|
|
663
|
+
self.assertIn("Repositories in GitHub organization: 3", output)
|
|
660
664
|
self.assertIn("[1/2] Processing local", output)
|
|
661
665
|
self.assertIn("[2/2] Processing missing", output)
|
|
662
666
|
self.assertIn("Repositories processed: 2", output)
|
|
@@ -777,6 +781,7 @@ class SyncOrgRepositoriesTests(unittest.TestCase):
|
|
|
777
781
|
)
|
|
778
782
|
output = stdout.getvalue()
|
|
779
783
|
self.assertIn("Selected 2 of 3 repositories with --limit=2", output)
|
|
784
|
+
self.assertIn("Repositories in GitHub organization: 3", output)
|
|
780
785
|
self.assertIn("1 repositories missing locally", output)
|
|
781
786
|
self.assertIn("[1/2] Processing unknown", output)
|
|
782
787
|
self.assertIn("[2/2] Processing new", output)
|
|
@@ -789,6 +794,7 @@ class SyncOrgRepositoriesTests(unittest.TestCase):
|
|
|
789
794
|
def test_main_returns_nonzero_when_state_cannot_be_saved(self):
|
|
790
795
|
with tempfile.TemporaryDirectory() as directory:
|
|
791
796
|
stderr = io.StringIO()
|
|
797
|
+
stdout = io.StringIO()
|
|
792
798
|
with (
|
|
793
799
|
mock.patch.object(
|
|
794
800
|
sys,
|
|
@@ -810,13 +816,14 @@ class SyncOrgRepositoriesTests(unittest.TestCase):
|
|
|
810
816
|
mock.patch.object(
|
|
811
817
|
sync, "save_repository_state", side_effect=OSError("read-only")
|
|
812
818
|
),
|
|
813
|
-
redirect_stdout(
|
|
819
|
+
redirect_stdout(stdout),
|
|
814
820
|
redirect_stderr(stderr),
|
|
815
821
|
):
|
|
816
822
|
return_code = sync.main()
|
|
817
823
|
|
|
818
824
|
self.assertEqual(return_code, 1)
|
|
819
825
|
self.assertIn("could not save repository state", stderr.getvalue())
|
|
826
|
+
self.assertIn("Repositories in GitHub organization: 0", stdout.getvalue())
|
|
820
827
|
|
|
821
828
|
def test_main_reports_missing_root(self):
|
|
822
829
|
missing = Path("/tmp/github-repository-sync-definitely-missing")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|