1# vim: tabstop=4 shiftwidth=4 softtabstop=4 2 3# Copyright (c) 2016 Cisco Systems, Inc. 4# 5# Permission is hereby granted, free of charge, to any person obtaining a copy 6# of this software and associated documentation files (the "Software"), to 7# deal in the Software without restriction, including without limitation the 8# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9# sell copies of the Software, and to permit persons to whom the Software is 10# furnished to do so, subject to the following conditions: 11# 12# The above copyright notice and this permission notice shall be included in 13# all copies or substantial portions of the Software. 14# 15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21# DEALINGS IN THE SOFTWARE. 22 23import glob 24import os 25import shutil 26 27import sh 28 29from gilt import util 30 31 32def clone(name, repository, destination, debug=False): 33 """ 34 Clone the specified repository into a temporary directory and return None. 35 36 :param name: A string containing the name of the repository being cloned. 37 :param repository: A string containing the repository to clone. 38 :param destination: A string containing the directory to clone the 39 repository into. 40 :param debug: An optional bool to toggle debug output. 41 :return: None 42 """ 43 msg = ' - cloning {} to {}'.format(name, destination) 44 util.print_info(msg) 45 cmd = sh.git.bake('clone', repository, destination) 46 util.run_command(cmd, debug=debug) 47 48 49def extract(repository, destination, version, debug=False): 50 """ 51 Extract the specified repository/version into the given directory and 52 return None. 53 54 :param repository: A string containing the path to the repository to be 55 extracted. 56 :param destination: A string containing the directory to clone the 57 repository into. Relative to the directory ``gilt`` is running 58 in. Must end with a '/'. 59 :param version: A string containing the branch/tag/sha to be exported. 60 :param debug: An optional bool to toggle debug output. 61 :return: None 62 """ 63 with util.saved_cwd(): 64 if os.path.isdir(destination): 65 shutil.rmtree(destination) 66 67 os.chdir(repository) 68 _get_version(version, debug) 69 cmd = sh.git.bake( 70 'checkout-index', force=True, all=True, prefix=destination) 71 util.run_command(cmd, debug=debug) 72 msg = ' - extracting ({}) {} to {}'.format(version, repository, 73 destination) 74 util.print_info(msg) 75 76 77def overlay(repository, files, version, debug=False): 78 """ 79 Overlay files from the specified repository/version into the given 80 directory and return None. 81 82 :param repository: A string containing the path to the repository to be 83 extracted. 84 :param files: A list of `FileConfig` objects. 85 :param version: A string containing the branch/tag/sha to be exported. 86 :param debug: An optional bool to toggle debug output. 87 :return: None 88 """ 89 with util.saved_cwd(): 90 os.chdir(repository) 91 _get_version(version, debug) 92 93 for fc in files: 94 if '*' in fc.src: 95 for filename in glob.glob(fc.src): 96 util.copy(filename, fc.dst) 97 msg = ' - copied ({}) {} to {}'.format( 98 version, filename, fc.dst) 99 util.print_info(msg) 100 else: 101 if os.path.isdir(fc.dst) and os.path.isdir(fc.src): 102 shutil.rmtree(fc.dst) 103 util.copy(fc.src, fc.dst) 104 msg = ' - copied ({}) {} to {}'.format( 105 version, fc.src, fc.dst) 106 util.print_info(msg) 107 108 109def _get_version(version, debug=False): 110 """ 111 Handle switching to the specified version and return None. 112 113 1. Fetch the origin. 114 2. Checkout the specified version. 115 3. Clean the repository before we begin. 116 4. Pull the origin when a branch; _not_ a commit id. 117 118 :param version: A string containing the branch/tag/sha to be exported. 119 :param debug: An optional bool to toggle debug output. 120 :return: None 121 """ 122 if not any( 123 (_has_branch(version, debug), _has_tag(version, debug), _has_commit( 124 version, debug))): 125 cmd = sh.git.bake('fetch') 126 util.run_command(cmd, debug=debug) 127 cmd = sh.git.bake('checkout', version) 128 util.run_command(cmd, debug=debug) 129 cmd = sh.git.bake('clean', '-d', '-x', '-f') 130 util.run_command(cmd, debug=debug) 131 if _has_branch(version, debug): 132 cmd = sh.git.bake('pull', rebase=True, ff_only=True) 133 util.run_command(cmd, debug=debug) 134 135 136def _has_commit(version, debug=False): 137 """ 138 Determine a version is a local git commit sha or not. 139 140 :param version: A string containing the branch/tag/sha to be determined. 141 :param debug: An optional bool to toggle debug output. 142 :return: bool 143 """ 144 if _has_tag(version, debug) or _has_branch(version, debug): 145 return False 146 cmd = sh.git.bake('cat-file', '-e', version) 147 try: 148 util.run_command(cmd, debug=debug) 149 return True 150 except sh.ErrorReturnCode: 151 return False 152 153 154def _has_tag(version, debug=False): 155 """ 156 Determine a version is a local git tag name or not. 157 158 :param version: A string containing the branch/tag/sha to be determined. 159 :param debug: An optional bool to toggle debug output. 160 :return: bool 161 """ 162 cmd = sh.git.bake('show-ref', '--verify', '--quiet', 163 "refs/tags/{}".format(version)) 164 try: 165 util.run_command(cmd, debug=debug) 166 return True 167 except sh.ErrorReturnCode: 168 return False 169 170 171def _has_branch(version, debug=False): 172 """ 173 Determine a version is a local git branch name or not. 174 175 :param version: A string containing the branch/tag/sha to be determined. 176 :param debug: An optional bool to toggle debug output. 177 :return: bool 178 """ 179 cmd = sh.git.bake('show-ref', '--verify', '--quiet', 180 "refs/heads/{}".format(version)) 181 try: 182 util.run_command(cmd, debug=debug) 183 return True 184 except sh.ErrorReturnCode: 185 return False 186