Bump actions/checkout from 4.1.3 to 4.1.4
[glslang.git] / update_glslang_sources.py
blob2e02c96eeb772668c72abc3c5a80a7653b590a18
1 #!/usr/bin/env python3
3 # Copyright 2017 The Glslang Authors. All rights reserved.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 """Get source files for Glslang and its dependencies from public repositories.
18 """
20 import argparse
21 import json
22 import os
23 import subprocess
24 import sys
26 KNOWN_GOOD_FILE = 'known_good.json'
28 SITE_TO_KNOWN_GOOD_FILE = { 'github' : 'known_good.json',
29 'gitlab' : 'known_good_khr.json' }
31 # Maps a site name to its hostname.
32 SITE_TO_HOST = { 'github' : 'https://github.com/',
33 'gitlab' : 'git@gitlab.khronos.org:' }
35 VERBOSE = True
38 def command_output(cmd, directory, fail_ok=False):
39 """Runs a command in a directory and returns its standard output stream.
41 Captures the standard error stream.
43 Raises a RuntimeError if the command fails to launch or otherwise fails.
44 """
45 if VERBOSE:
46 print('In {d}: {cmd}'.format(d=directory, cmd=cmd))
47 p = subprocess.Popen(cmd,
48 cwd=directory,
49 stdout=subprocess.PIPE)
50 (stdout, _) = p.communicate()
51 if p.returncode != 0 and not fail_ok:
52 raise RuntimeError('Failed to run {} in {}'.format(cmd, directory))
53 if VERBOSE:
54 print(stdout)
55 return stdout
58 def command_retval(cmd, directory):
59 """Runs a command in a directory and returns its return value.
61 Captures the standard error stream.
62 """
63 p = subprocess.Popen(cmd,
64 cwd=directory,
65 stdout=subprocess.PIPE)
66 p.communicate()
67 return p.returncode
70 class GoodCommit(object):
71 """Represents a good commit for a repository."""
73 def __init__(self, json):
74 """Initializes this good commit object.
76 Args:
77 'json': A fully populated JSON object describing the commit.
78 """
79 self._json = json
80 self.name = json['name']
81 self.site = json['site']
82 self.subrepo = json['subrepo']
83 self.subdir = json['subdir'] if ('subdir' in json) else '.'
84 self.commit = json['commit']
86 def GetUrl(self):
87 """Returns the URL for the repository."""
88 host = SITE_TO_HOST[self.site]
89 return '{host}{subrepo}'.format(
90 host=host,
91 subrepo=self.subrepo)
93 def AddRemote(self):
94 """Add the remote 'known-good' if it does not exist."""
95 remotes = command_output(['git', 'remote'], self.subdir).splitlines()
96 if b'known-good' not in remotes:
97 command_output(['git', 'remote', 'add', 'known-good', self.GetUrl()], self.subdir)
99 def HasCommit(self):
100 """Check if the repository contains the known-good commit."""
101 return 0 == subprocess.call(['git', 'rev-parse', '--verify', '--quiet',
102 self.commit + "^{commit}"],
103 cwd=self.subdir)
105 def Clone(self):
106 os.makedirs(self.subdir, exist_ok=True)
107 command_output(['git', 'clone', self.GetUrl(), '.'], self.subdir)
109 def Fetch(self):
110 command_output(['git', 'fetch', 'known-good'], self.subdir)
112 def Checkout(self):
113 if not os.path.exists(os.path.join(self.subdir,'.git')):
114 self.Clone()
115 self.AddRemote()
116 if not self.HasCommit():
117 self.Fetch()
118 command_output(['git', 'checkout', self.commit], self.subdir)
121 def GetGoodCommits(site):
122 """Returns the latest list of GoodCommit objects."""
123 known_good_file = SITE_TO_KNOWN_GOOD_FILE[site]
124 with open(known_good_file) as known_good:
125 return [GoodCommit(c) for c in json.loads(known_good.read())['commits']]
128 def main():
129 parser = argparse.ArgumentParser(description='Get Glslang source dependencies at a known-good commit')
130 parser.add_argument('--dir', dest='dir', default='.',
131 help="Set target directory for Glslang source root. Default is \'.\'.")
132 parser.add_argument('--site', dest='site', default='github',
133 help="Set git server site. Default is github.")
135 args = parser.parse_args()
137 commits = GetGoodCommits(args.site)
139 os.makedirs(args.dir, exist_ok=True)
140 print('Change directory to {d}'.format(d=args.dir))
141 os.chdir(args.dir)
143 # Create the subdirectories in sorted order so that parent git repositories
144 # are created first.
145 for c in sorted(commits, key=lambda x: x.subdir):
146 print('Get {n}\n'.format(n=c.name))
147 c.Checkout()
148 sys.exit(0)
151 if __name__ == '__main__':
152 main()