#!/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, ) 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', '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', } 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', '--depth', '1', remote, dir_name]) else: check_call(['git', 'clone', remote, dir_name]) if 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', 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) for dir_name, _ in REPOSITORIES.items(): if dir_name in args.skip_repository: print("--- Skipping '" + dir_name + "' ---") continue update_working_copy(os.path.join(SWIFT_SOURCE_ROOT, dir_name), branch) return 0 if __name__ == "__main__": sys.exit(main())