Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions utils/update_checkout/tests/test_clone.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# ===----------------------------------------------------------------------===#

import os
import shutil

from . import scheme_mock

Expand Down Expand Up @@ -56,6 +57,39 @@ def test_clone_with_additional_scheme(self):
# Test that we're actually checking out the 'extra' scheme based on the output
self.assertIn("git checkout refs/heads/main", output)

def test_clone_missing_repos(self):
output = self.call(
[
self.update_checkout_path,
"--config",
self.config_path,
"--source-root",
self.source_root,
"--clone",
]
)
self.assertNotIn(
"You don't have all swift sources. Call this script with --clone to get them.",
output,
)

repo = self.get_all_repos()[0]
repo_path = os.path.join(self.source_root, repo)
shutil.rmtree(repo_path)
output = self.call(
[
self.update_checkout_path,
"--config",
self.config_path,
"--source-root",
self.source_root,
]
)
self.assertIn(
"You don't have all swift sources. Call this script with --clone to get them.",
output,
)


class SchemeWithMissingRepoTestCase(scheme_mock.SchemeMockTestCase):
def __init__(self, *args, **kwargs):
Expand Down
52 changes: 41 additions & 11 deletions utils/update_checkout/update_checkout/update_checkout.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,46 @@ def _is_any_repository_locked(pool_args: List[UpdateArguments]) -> Set[str]:
return locked_repositories


def _check_missing_clones(
args: CliArguments, config: Dict[str, Any], scheme_map: Dict[str, Any]
):
"""
Verify that all repositories defined in the scheme map are present in the
source root directory. If a repository is missing—and not explicitly skipped—
the user is prompted to re-run the script with the `--clone` option.

This function also respects per-repository platform restrictions: if the
current platform is not listed for a repo, that repo is ignored.

Args:
args (CliArguments): Parsed CLI arguments.
config (Dict[str, Any]): deserialized `update-checkout-config.json`.
scheme_map (Dict[str, str] | None): map of repo names to branches to check out.

Returns:
Prints a warning if any required repository is missing.
"""

directory_contents = {path.name for path in args.source_root.iterdir()}
current_platform = platform.system()

for repo in scheme_map:
repo_config = config["repos"].get(repo, {})

if (
"platforms" in repo_config
and current_platform not in repo_config["platforms"]
):
continue

if repo not in directory_contents and repo not in args.skip_repository_list:
print(
"You don't have all swift sources. "
"Call this script with --clone to get them."
)
return


def _move_llvm_project_to_first_index(
pool_args: Union[List[UpdateArguments], List[AdditionalSwiftSourcesArguments]],
):
Expand Down Expand Up @@ -855,17 +895,7 @@ def main() -> int:
dump_repo_hashes(args, config, args.dump_hashes_config)
return 0

# Quick check whether somebody is calling update in an empty directory
directory_contents = args.source_root.iterdir()
if not (
"cmark" in directory_contents
or "llvm" in directory_contents
or "clang" in directory_contents
):
print(
"You don't have all swift sources. "
"Call this script with --clone to get them."
)
_check_missing_clones(args=args, config=config, scheme_map=scheme_map)

skipped_repositories, update_results = update_all_repositories(
args, config, scheme_name, scheme_map, cross_repos_pr
Expand Down