aboutsummaryrefslogtreecommitdiffstats
path: root/meson/ghwt.py
diff options
context:
space:
mode:
Diffstat (limited to 'meson/ghwt.py')
-rwxr-xr-xmeson/ghwt.py132
1 files changed, 132 insertions, 0 deletions
diff --git a/meson/ghwt.py b/meson/ghwt.py
new file mode 100755
index 000000000..6f9373b2c
--- /dev/null
+++ b/meson/ghwt.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python3
+
+# Copyright 2016 The Meson development team
+
+# 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.
+
+# ghwt - GitHub WrapTool
+#
+# An emergency wraptool(1) replacement downloader that downloads
+# directly from GitHub in case wrapdb.mesonbuild.com is down.
+
+import urllib.request, json, sys, os, shutil, subprocess
+import configparser, hashlib
+
+req_timeout = 600.0
+private_repos = {'meson', 'wrapweb', 'meson-ci'}
+spdir = 'subprojects'
+
+def gh_get(url):
+ r = urllib.request.urlopen(url, timeout=req_timeout)
+ jd = json.loads(r.read().decode('utf-8'))
+ return jd
+
+def list_projects():
+ jd = gh_get('https://api.github.com/orgs/mesonbuild/repos')
+ entries = [entry['name'] for entry in jd]
+ entries = [e for e in entries if e not in private_repos]
+ entries.sort()
+ for i in entries:
+ print(i)
+ return 0
+
+def unpack(sproj, branch):
+ tmpdir = os.path.join(spdir, sproj + '_ghwt')
+ shutil.rmtree(tmpdir, ignore_errors=True)
+ subprocess.check_call(['git', 'clone', '-b', branch, f'https://github.com/mesonbuild/{sproj}.git', tmpdir])
+ usfile = os.path.join(tmpdir, 'upstream.wrap')
+ assert(os.path.isfile(usfile))
+ config = configparser.ConfigParser(interpolation=None)
+ config.read(usfile)
+ outdir = os.path.join(spdir, sproj)
+ if 'directory' in config['wrap-file']:
+ outdir = os.path.join(spdir, config['wrap-file']['directory'])
+ if os.path.isdir(outdir):
+ print(f'Subproject is already there. To update, nuke the {outdir} dir and reinstall.')
+ shutil.rmtree(tmpdir)
+ return 1
+ us_url = config['wrap-file']['source_url']
+ us = urllib.request.urlopen(us_url, timeout=req_timeout).read()
+ h = hashlib.sha256()
+ h.update(us)
+ dig = h.hexdigest()
+ should = config['wrap-file']['source_hash']
+ if dig != should:
+ print('Incorrect hash on download.')
+ print(' expected:', should)
+ print(' obtained:', dig)
+ return 1
+ ofilename = os.path.join(spdir, config['wrap-file']['source_filename'])
+ with open(ofilename, 'wb') as ofile:
+ ofile.write(us)
+ if 'lead_directory_missing' in config['wrap-file']:
+ os.mkdir(outdir)
+ shutil.unpack_archive(ofilename, outdir)
+ else:
+ shutil.unpack_archive(ofilename, spdir)
+ assert(os.path.isdir(outdir))
+ shutil.move(os.path.join(tmpdir, '.git'), outdir)
+ subprocess.check_call(['git', 'reset', '--hard'], cwd=outdir)
+ shutil.rmtree(tmpdir)
+ shutil.rmtree(os.path.join(outdir, '.git'))
+ os.unlink(ofilename)
+
+def install(sproj, requested_branch=None):
+ if not os.path.isdir(spdir):
+ print('Run this in your source root and make sure there is a subprojects directory in it.')
+ return 1
+ blist = gh_get(f'https://api.github.com/repos/mesonbuild/{sproj}/branches')
+ blist = [b['name'] for b in blist]
+ blist = [b for b in blist if b != 'master']
+ blist.sort()
+ branch = blist[-1]
+ if requested_branch is not None:
+ if requested_branch in blist:
+ branch = requested_branch
+ else:
+ print('Could not find user-requested branch', requested_branch)
+ print('Available branches for', sproj, ':')
+ print(blist)
+ return 1
+ print('Using branch', branch)
+ return unpack(sproj, branch)
+
+def print_help():
+ print('Usage:')
+ print(sys.argv[0], 'list')
+ print(sys.argv[0], 'install', 'package_name', '[branch_name]')
+
+def run(args):
+ if not args or args[0] == '-h' or args[0] == '--help':
+ print_help()
+ return 1
+ command = args[0]
+ args = args[1:]
+ if command == 'list':
+ list_projects()
+ return 0
+ elif command == 'install':
+ if len(args) == 1:
+ return install(args[0])
+ elif len(args) == 2:
+ return install(args[0], args[1])
+ else:
+ print_help()
+ return 1
+ else:
+ print('Unknown command')
+ return 1
+
+if __name__ == '__main__':
+ print('This is an emergency wrap downloader. Use only when wrapdb is down.')
+ sys.exit(run(sys.argv[1:]))