123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- #!/usr/bin/env python3
- # Copyright 2017 The Glslang Authors. All rights reserved.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- """Get source files for Glslang and its dependencies from public repositories.
- """
- import argparse
- import json
- import os
- import subprocess
- import sys
- KNOWN_GOOD_FILE = 'known_good.json'
- SITE_TO_KNOWN_GOOD_FILE = { 'github' : 'known_good.json',
- 'gitlab' : 'known_good_khr.json' }
- # Maps a site name to its hostname.
- SITE_TO_HOST = { 'github' : 'https://github.com/',
- 'gitlab' : 'git@gitlab.khronos.org:' }
- VERBOSE = True
- def command_output(cmd, directory, fail_ok=False):
- """Runs a command in a directory and returns its standard output stream.
- Captures the standard error stream.
- Raises a RuntimeError if the command fails to launch or otherwise fails.
- """
- if VERBOSE:
- print('In {d}: {cmd}'.format(d=directory, cmd=cmd))
- p = subprocess.Popen(cmd,
- cwd=directory,
- stdout=subprocess.PIPE)
- (stdout, _) = p.communicate()
- if p.returncode != 0 and not fail_ok:
- raise RuntimeError('Failed to run {} in {}'.format(cmd, directory))
- if VERBOSE:
- print(stdout)
- return stdout
- def command_retval(cmd, directory):
- """Runs a command in a directory and returns its return value.
- Captures the standard error stream.
- """
- p = subprocess.Popen(cmd,
- cwd=directory,
- stdout=subprocess.PIPE)
- p.communicate()
- return p.returncode
- class GoodCommit(object):
- """Represents a good commit for a repository."""
- def __init__(self, json):
- """Initializes this good commit object.
- Args:
- 'json': A fully populated JSON object describing the commit.
- """
- self._json = json
- self.name = json['name']
- self.site = json['site']
- self.subrepo = json['subrepo']
- self.subdir = json['subdir'] if ('subdir' in json) else '.'
- self.commit = json['commit']
- def GetUrl(self):
- """Returns the URL for the repository."""
- host = SITE_TO_HOST[self.site]
- return '{host}{subrepo}'.format(
- host=host,
- subrepo=self.subrepo)
- def AddRemote(self):
- """Add the remote 'known-good' if it does not exist."""
- remotes = command_output(['git', 'remote'], self.subdir).splitlines()
- if b'known-good' not in remotes:
- command_output(['git', 'remote', 'add', 'known-good', self.GetUrl()], self.subdir)
- def HasCommit(self):
- """Check if the repository contains the known-good commit."""
- return 0 == subprocess.call(['git', 'rev-parse', '--verify', '--quiet',
- self.commit + "^{commit}"],
- cwd=self.subdir)
- def Clone(self):
- os.makedirs(self.subdir, exist_ok=True)
- command_output(['git', 'clone', self.GetUrl(), '.'], self.subdir)
- def Fetch(self):
- command_output(['git', 'fetch', 'known-good'], self.subdir)
- def Checkout(self):
- if not os.path.exists(os.path.join(self.subdir,'.git')):
- self.Clone()
- self.AddRemote()
- if not self.HasCommit():
- self.Fetch()
- command_output(['git', 'checkout', self.commit], self.subdir)
- def GetGoodCommits(site):
- """Returns the latest list of GoodCommit objects."""
- known_good_file = SITE_TO_KNOWN_GOOD_FILE[site]
- with open(known_good_file) as known_good:
- return [GoodCommit(c) for c in json.loads(known_good.read())['commits']]
- def main():
- parser = argparse.ArgumentParser(description='Get Glslang source dependencies at a known-good commit')
- parser.add_argument('--dir', dest='dir', default='.',
- help="Set target directory for Glslang source root. Default is \'.\'.")
- parser.add_argument('--site', dest='site', default='github',
- help="Set git server site. Default is github.")
- args = parser.parse_args()
- commits = GetGoodCommits(args.site)
- os.makedirs(args.dir, exist_ok=True)
- print('Change directory to {d}'.format(d=args.dir))
- os.chdir(args.dir)
- # Create the subdirectories in sorted order so that parent git repositories
- # are created first.
- for c in sorted(commits, key=lambda x: x.subdir):
- print('Get {n}\n'.format(n=c.name))
- c.Checkout()
- sys.exit(0)
- if __name__ == '__main__':
- main()
|