#!/usr/bin/env python # utils/update-checkout - Utility to update your local checkouts -*- python -*- # # This source file is part of the Swift.org open source project # # Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See http://swift.org/LICENSE.txt for license information # See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors from __future__ import print_function import argparse import os import sys sys.path.append(os.path.dirname(__file__)) from SwiftBuildSupport import ( SWIFT_SOURCE_ROOT, WorkingDirectory, check_call, check_output, ) # noqa (E402 module level import not at top of file) REPOSITORIES = { 'llvm': 'apple/swift-llvm', 'clang': 'apple/swift-clang', 'swift': 'apple/swift-swift', 'lldb': 'apple/swift-lldb', 'cmark': 'apple/swift-cmark', 'llbuild': 'apple/swift-llbuild', 'swiftpm': 'apple/swift-package-manager', 'compiler-rt': 'apple/swift-compiler-rt', 'swift-corelibs-xctest': 'apple/swift-corelibs-xctest', 'swift-corelibs-foundation': 'apple/swift-corelibs-foundation', 'swift-corelibs-libdispatch': 'apple/swift-corelibs-libdispatch', 'swift-integration-tests': 'apple/swift-integration-tests', } NEXT_BRANCHES = { 'llvm': 'stable-next', 'clang': 'stable-next', 'swift': 'master-next', 'lldb': 'master-next', 'cmark': 'master', 'llbuild': 'master', 'swiftpm': 'master', 'swift-corelibs-xctest': 'master', 'swift-corelibs-foundation': 'master', 'swift-corelibs-libdispatch': 'master', 'swift-integration-tests': 'master', } def update_working_copy(repo_path, branch): if not os.path.isdir(repo_path): return print("--- Updating '" + repo_path + "' ---") with WorkingDirectory(repo_path): if branch: status = check_output(['git', 'status', '--porcelain']) if status: print("Please, commit your changes.") print(status) exit(1) check_call(['git', 'checkout', branch]) # Prior to Git 2.6, this is the way to do a "git pull # --rebase" that respects rebase.autostash. See # http://stackoverflow.com/a/30209750/125349 check_call(["git", "fetch"]) check_call(["git", "rebase", "FETCH_HEAD"]) def obtain_additional_swift_sources( with_ssh, branch, skip_history, skip_repositories): for dir_name, repo in REPOSITORIES.items(): if dir_name in skip_repositories: print("--- Skipping '" + dir_name + "' ---") continue with WorkingDirectory(SWIFT_SOURCE_ROOT): if not os.path.isdir(os.path.join(dir_name, ".git")): print("--- Cloning '" + dir_name + "' ---") if with_ssh is True: remote = "git@github.com:" + repo + '.git' else: remote = "https://github.com/" + repo + '.git' if skip_history: check_call(['git', 'clone', '--recursive', '--depth', '1', remote, dir_name]) else: check_call(['git', 'clone', '--recursive', remote, dir_name]) if branch: if branch == "stable-next" or branch == "master-next": repo_branch = NEXT_BRANCHES[dir_name] else: repo_branch = branch src_path = SWIFT_SOURCE_ROOT + "/" + dir_name + "/" + \ ".git" check_call(['git', '--git-dir', src_path, '--work-tree', os.path.join(SWIFT_SOURCE_ROOT, dir_name), 'checkout', repo_branch]) def main(): parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=""" repositories. By default, updates your checkouts of Swift, SourceKit, LLDB, and SwiftPM.""") parser.add_argument( "--clone", help="Obtain Sources for Swift and Related Projects", action="store_true") parser.add_argument( "--clone-with-ssh", help="Obtain Sources for Swift and Related Projects via SSH", action="store_true") parser.add_argument( "--skip-history", help="Skip histories when obtaining sources", action="store_true") parser.add_argument( "--skip-repository", metavar="DIRECTORY", default=[], help="Skip the specified repository", action="append") parser.add_argument( "--branch", help="Obtain Sources for specific branch") args = parser.parse_args() clone = args.clone clone_with_ssh = args.clone_with_ssh skip_history = args.skip_history branch = args.branch if clone or clone_with_ssh: obtain_additional_swift_sources( clone_with_ssh, branch, skip_history, args.skip_repository) repo_branch = branch for dir_name, _ in REPOSITORIES.items(): if dir_name in args.skip_repository: print("--- Skipping '" + dir_name + "' ---") continue if branch: if branch == "stable-next" or branch == "master-next": repo_branch = NEXT_BRANCHES[dir_name] update_working_copy(os.path.join(SWIFT_SOURCE_ROOT, dir_name), repo_branch) return 0 if __name__ == "__main__": sys.exit(main())