1617a3babSopenharmony_ci#!/usr/bin/env python3 2617a3babSopenharmony_ci 3617a3babSopenharmony_ci# Copyright 2017 The Glslang Authors. All rights reserved. 4617a3babSopenharmony_ci# 5617a3babSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 6617a3babSopenharmony_ci# you may not use this file except in compliance with the License. 7617a3babSopenharmony_ci# You may obtain a copy of the License at 8617a3babSopenharmony_ci# 9617a3babSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 10617a3babSopenharmony_ci# 11617a3babSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 12617a3babSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 13617a3babSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14617a3babSopenharmony_ci# See the License for the specific language governing permissions and 15617a3babSopenharmony_ci# limitations under the License. 16617a3babSopenharmony_ci 17617a3babSopenharmony_ci"""Get source files for Glslang and its dependencies from public repositories. 18617a3babSopenharmony_ci""" 19617a3babSopenharmony_ci 20617a3babSopenharmony_ciimport argparse 21617a3babSopenharmony_ciimport json 22617a3babSopenharmony_ciimport os 23617a3babSopenharmony_ciimport subprocess 24617a3babSopenharmony_ciimport sys 25617a3babSopenharmony_ci 26617a3babSopenharmony_ciKNOWN_GOOD_FILE = 'known_good.json' 27617a3babSopenharmony_ci 28617a3babSopenharmony_ciSITE_TO_KNOWN_GOOD_FILE = { 'github' : 'known_good.json', 29617a3babSopenharmony_ci 'gitlab' : 'known_good_khr.json' } 30617a3babSopenharmony_ci 31617a3babSopenharmony_ci# Maps a site name to its hostname. 32617a3babSopenharmony_ciSITE_TO_HOST = { 'github' : 'https://github.com/', 33617a3babSopenharmony_ci 'gitlab' : 'git@gitlab.khronos.org:' } 34617a3babSopenharmony_ci 35617a3babSopenharmony_ciVERBOSE = True 36617a3babSopenharmony_ci 37617a3babSopenharmony_ci 38617a3babSopenharmony_cidef command_output(cmd, directory, fail_ok=False): 39617a3babSopenharmony_ci """Runs a command in a directory and returns its standard output stream. 40617a3babSopenharmony_ci 41617a3babSopenharmony_ci Captures the standard error stream. 42617a3babSopenharmony_ci 43617a3babSopenharmony_ci Raises a RuntimeError if the command fails to launch or otherwise fails. 44617a3babSopenharmony_ci """ 45617a3babSopenharmony_ci if VERBOSE: 46617a3babSopenharmony_ci print('In {d}: {cmd}'.format(d=directory, cmd=cmd)) 47617a3babSopenharmony_ci p = subprocess.Popen(cmd, 48617a3babSopenharmony_ci cwd=directory, 49617a3babSopenharmony_ci stdout=subprocess.PIPE) 50617a3babSopenharmony_ci (stdout, _) = p.communicate() 51617a3babSopenharmony_ci if p.returncode != 0 and not fail_ok: 52617a3babSopenharmony_ci raise RuntimeError('Failed to run {} in {}'.format(cmd, directory)) 53617a3babSopenharmony_ci if VERBOSE: 54617a3babSopenharmony_ci print(stdout) 55617a3babSopenharmony_ci return stdout 56617a3babSopenharmony_ci 57617a3babSopenharmony_ci 58617a3babSopenharmony_cidef command_retval(cmd, directory): 59617a3babSopenharmony_ci """Runs a command in a directory and returns its return value. 60617a3babSopenharmony_ci 61617a3babSopenharmony_ci Captures the standard error stream. 62617a3babSopenharmony_ci """ 63617a3babSopenharmony_ci p = subprocess.Popen(cmd, 64617a3babSopenharmony_ci cwd=directory, 65617a3babSopenharmony_ci stdout=subprocess.PIPE) 66617a3babSopenharmony_ci p.communicate() 67617a3babSopenharmony_ci return p.returncode 68617a3babSopenharmony_ci 69617a3babSopenharmony_ci 70617a3babSopenharmony_ciclass GoodCommit(object): 71617a3babSopenharmony_ci """Represents a good commit for a repository.""" 72617a3babSopenharmony_ci 73617a3babSopenharmony_ci def __init__(self, json): 74617a3babSopenharmony_ci """Initializes this good commit object. 75617a3babSopenharmony_ci 76617a3babSopenharmony_ci Args: 77617a3babSopenharmony_ci 'json': A fully populated JSON object describing the commit. 78617a3babSopenharmony_ci """ 79617a3babSopenharmony_ci self._json = json 80617a3babSopenharmony_ci self.name = json['name'] 81617a3babSopenharmony_ci self.site = json['site'] 82617a3babSopenharmony_ci self.subrepo = json['subrepo'] 83617a3babSopenharmony_ci self.subdir = json['subdir'] if ('subdir' in json) else '.' 84617a3babSopenharmony_ci self.commit = json['commit'] 85617a3babSopenharmony_ci 86617a3babSopenharmony_ci def GetUrl(self): 87617a3babSopenharmony_ci """Returns the URL for the repository.""" 88617a3babSopenharmony_ci host = SITE_TO_HOST[self.site] 89617a3babSopenharmony_ci return '{host}{subrepo}'.format( 90617a3babSopenharmony_ci host=host, 91617a3babSopenharmony_ci subrepo=self.subrepo) 92617a3babSopenharmony_ci 93617a3babSopenharmony_ci def AddRemote(self): 94617a3babSopenharmony_ci """Add the remote 'known-good' if it does not exist.""" 95617a3babSopenharmony_ci remotes = command_output(['git', 'remote'], self.subdir).splitlines() 96617a3babSopenharmony_ci if b'known-good' not in remotes: 97617a3babSopenharmony_ci command_output(['git', 'remote', 'add', 'known-good', self.GetUrl()], self.subdir) 98617a3babSopenharmony_ci 99617a3babSopenharmony_ci def HasCommit(self): 100617a3babSopenharmony_ci """Check if the repository contains the known-good commit.""" 101617a3babSopenharmony_ci return 0 == subprocess.call(['git', 'rev-parse', '--verify', '--quiet', 102617a3babSopenharmony_ci self.commit + "^{commit}"], 103617a3babSopenharmony_ci cwd=self.subdir) 104617a3babSopenharmony_ci 105617a3babSopenharmony_ci def Clone(self): 106617a3babSopenharmony_ci os.makedirs(self.subdir, exist_ok=True) 107617a3babSopenharmony_ci command_output(['git', 'clone', self.GetUrl(), '.'], self.subdir) 108617a3babSopenharmony_ci 109617a3babSopenharmony_ci def Fetch(self): 110617a3babSopenharmony_ci command_output(['git', 'fetch', 'known-good'], self.subdir) 111617a3babSopenharmony_ci 112617a3babSopenharmony_ci def Checkout(self): 113617a3babSopenharmony_ci if not os.path.exists(os.path.join(self.subdir,'.git')): 114617a3babSopenharmony_ci self.Clone() 115617a3babSopenharmony_ci self.AddRemote() 116617a3babSopenharmony_ci if not self.HasCommit(): 117617a3babSopenharmony_ci self.Fetch() 118617a3babSopenharmony_ci command_output(['git', 'checkout', self.commit], self.subdir) 119617a3babSopenharmony_ci 120617a3babSopenharmony_ci 121617a3babSopenharmony_cidef GetGoodCommits(site): 122617a3babSopenharmony_ci """Returns the latest list of GoodCommit objects.""" 123617a3babSopenharmony_ci known_good_file = SITE_TO_KNOWN_GOOD_FILE[site] 124617a3babSopenharmony_ci with open(known_good_file) as known_good: 125617a3babSopenharmony_ci return [GoodCommit(c) for c in json.loads(known_good.read())['commits']] 126617a3babSopenharmony_ci 127617a3babSopenharmony_ci 128617a3babSopenharmony_cidef main(): 129617a3babSopenharmony_ci parser = argparse.ArgumentParser(description='Get Glslang source dependencies at a known-good commit') 130617a3babSopenharmony_ci parser.add_argument('--dir', dest='dir', default='.', 131617a3babSopenharmony_ci help="Set target directory for Glslang source root. Default is \'.\'.") 132617a3babSopenharmony_ci parser.add_argument('--site', dest='site', default='github', 133617a3babSopenharmony_ci help="Set git server site. Default is github.") 134617a3babSopenharmony_ci 135617a3babSopenharmony_ci args = parser.parse_args() 136617a3babSopenharmony_ci 137617a3babSopenharmony_ci commits = GetGoodCommits(args.site) 138617a3babSopenharmony_ci 139617a3babSopenharmony_ci os.makedirs(args.dir, exist_ok=True) 140617a3babSopenharmony_ci print('Change directory to {d}'.format(d=args.dir)) 141617a3babSopenharmony_ci os.chdir(args.dir) 142617a3babSopenharmony_ci 143617a3babSopenharmony_ci # Create the subdirectories in sorted order so that parent git repositories 144617a3babSopenharmony_ci # are created first. 145617a3babSopenharmony_ci for c in sorted(commits, key=lambda x: x.subdir): 146617a3babSopenharmony_ci print('Get {n}\n'.format(n=c.name)) 147617a3babSopenharmony_ci c.Checkout() 148617a3babSopenharmony_ci sys.exit(0) 149617a3babSopenharmony_ci 150617a3babSopenharmony_ci 151617a3babSopenharmony_ciif __name__ == '__main__': 152617a3babSopenharmony_ci main() 153