From ec44795f8ab3719c0d720a79efcc476d2499f259 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sat, 16 Jan 2016 17:00:46 +0200 Subject: Moved all wrap related things to their own submodule. --- meson/interpreter.py | 2 +- meson/modules/__init__.py | 0 meson/wrap.py | 204 -------------------------------------------- meson/wrap/wrap.py | 212 ++++++++++++++++++++++++++++++++++++++++++++++ meson/wrap/wraptool.py | 200 +++++++++++++++++++++++++++++++++++++++++++ wraptool | 20 +++++ wraptool.py | 206 -------------------------------------------- 7 files changed, 433 insertions(+), 411 deletions(-) delete mode 100644 meson/modules/__init__.py delete mode 100644 meson/wrap.py create mode 100644 meson/wrap/wrap.py create mode 100755 meson/wrap/wraptool.py create mode 100755 wraptool delete mode 100755 wraptool.py diff --git a/meson/interpreter.py b/meson/interpreter.py index 1a28f3f..1a32998 100644 --- a/meson/interpreter.py +++ b/meson/interpreter.py @@ -19,7 +19,7 @@ from . import dependencies from . import mlog from . import build from . import optinterpreter -from . import wrap +from .wrap import wrap from . import mesonlib import os, sys, platform, subprocess, shutil, uuid, re diff --git a/meson/modules/__init__.py b/meson/modules/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/meson/wrap.py b/meson/wrap.py deleted file mode 100644 index ac9c9ce..0000000 --- a/meson/wrap.py +++ /dev/null @@ -1,204 +0,0 @@ -# Copyright 2015 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. - -from . import mlog -import urllib.request, os, hashlib, shutil -import subprocess -import sys - -try: - import ssl - has_ssl = True - API_ROOT = 'https://wrapdb.mesonbuild.com/v1/' -except ImportError: - has_ssl = False - API_ROOT = 'http://wrapdb.mesonbuild.com/v1/' - -def open_wrapdburl(urlstring): - global ssl_warning_printed - if has_ssl: - try: - return urllib.request.urlopen(urlstring)#, context=build_ssl_context()) - except urllib.error.URLError: - if not ssl_warning_printed: - print('SSL connection failed. Falling back to unencrypted connections.') - ssl_warning_printed = True - if not ssl_warning_printed: - print('Warning: SSL not available, traffic not authenticated.', - file=sys.stderr) - ssl_warning_printed = True - # Trying to open SSL connection to wrapdb fails because the - # certificate is not known. - if urlstring.startswith('https'): - urlstring = 'http' + urlstring[5:] - return urllib.request.urlopen(urlstring) - - -class PackageDefinition: - def __init__(self, fname): - self.values = {} - ifile = open(fname) - first = ifile.readline().strip() - - if first == '[wrap-file]': - self.type = 'file' - elif first == '[wrap-git]': - self.type = 'git' - else: - raise RuntimeError('Invalid format of package file') - for line in ifile: - line = line.strip() - if line == '': - continue - (k, v) = line.split('=', 1) - k = k.strip() - v = v.strip() - self.values[k] = v - - def get(self, key): - return self.values[key] - - def has_patch(self): - return 'patch_url' in self.values - -class Resolver: - def __init__(self, subdir_root): - self.subdir_root = subdir_root - self.cachedir = os.path.join(self.subdir_root, 'packagecache') - - def resolve(self, packagename): - fname = os.path.join(self.subdir_root, packagename + '.wrap') - dirname = os.path.join(self.subdir_root, packagename) - if not os.path.isfile(fname): - if os.path.isdir(dirname): - # No wrap file but dir exists -> user put it there manually. - return packagename - return None - p = PackageDefinition(fname) - if p.type == 'file': - if not os.path.isdir(self.cachedir): - os.mkdir(self.cachedir) - self.download(p, packagename) - self.extract_package(p) - elif p.type == 'git': - self.get_git(p) - else: - raise RuntimeError('Unreachable code.') - return p.get('directory') - - def get_git(self, p): - checkoutdir = os.path.join(self.subdir_root, p.get('directory')) - revno = p.get('revision') - is_there = os.path.isdir(checkoutdir) - if is_there: - if revno.lower() == 'head': - subprocess.check_call(['git', 'pull'], cwd=checkoutdir) - else: - if subprocess.call(['git', 'checkout', revno], cwd=checkoutdir) != 0: - subprocess.check_call(['git', 'fetch'], cwd=checkoutdir) - subprocess.check_call(['git', 'checkout', revno], - cwd=checkoutdir) - else: - subprocess.check_call(['git', 'clone', p.get('url'), - p.get('directory')], cwd=self.subdir_root) - if revno.lower() != 'head': - subprocess.check_call(['git', 'checkout', revno], - cwd=checkoutdir) - - - def get_data(self, url): - blocksize = 10*1024 - if url.startswith('https://wrapdb.mesonbuild.com'): - resp = open_wrapdburl(url) - else: - resp = urllib.request.urlopen(url) - dlsize = int(resp.info()['Content-Length']) - print('Download size:', dlsize) - print('Downloading: ', end='') - sys.stdout.flush() - printed_dots = 0 - blocks = [] - downloaded = 0 - while True: - block = resp.read(blocksize) - if block == b'': - break - downloaded += len(block) - blocks.append(block) - ratio = int(downloaded/dlsize * 10) - while printed_dots < ratio: - print('.', end='') - sys.stdout.flush() - printed_dots += 1 - print('') - resp.close() - return b''.join(blocks) - - def get_hash(self, data): - h = hashlib.sha256() - h.update(data) - hashvalue = h.hexdigest() - return hashvalue - - def download(self, p, packagename): - ofname = os.path.join(self.cachedir, p.get('source_filename')) - if os.path.exists(ofname): - mlog.log('Using', mlog.bold(packagename), 'from cache.') - return - srcurl = p.get('source_url') - mlog.log('Dowloading', mlog.bold(packagename), 'from', mlog.bold(srcurl)) - srcdata = self.get_data(srcurl) - dhash = self.get_hash(srcdata) - expected = p.get('source_hash') - if dhash != expected: - raise RuntimeError('Incorrect hash for source %s:\n %s expected\n %s actual.' % (packagename, expected, dhash)) - open(ofname, 'wb').write(srcdata) - if p.has_patch(): - purl = p.get('patch_url') - mlog.log('Downloading patch from', mlog.bold(purl)) - pdata = self.get_data(purl) - phash = self.get_hash(pdata) - expected = p.get('patch_hash') - if phash != expected: - raise RuntimeError('Incorrect hash for patch %s:\n %s expected\n %s actual' % (packagename, expected, phash)) - open(os.path.join(self.cachedir, p.get('patch_filename')), 'wb').write(pdata) - else: - mlog.log('Package does not require patch.') - - def extract_package(self, package): - if sys.version_info < (3, 5): - try: - import lzma - del lzma - try: - shutil.register_unpack_format('xztar', ['.tar.xz', '.txz'], shutil._unpack_tarfile, [], "xz'ed tar-file") - except shutil.RegistryError: - pass - except ImportError: - pass - target_dir = os.path.join(self.subdir_root, package.get('directory')) - if os.path.isdir(target_dir): - return - extract_dir = self.subdir_root - # Some upstreams ship packages that do not have a leading directory. - # Create one for them. - try: - package.get('lead_directory_missing') - os.mkdir(target_dir) - extract_dir = target_dir - except KeyError: - pass - shutil.unpack_archive(os.path.join(self.cachedir, package.get('source_filename')), extract_dir) - if package.has_patch(): - shutil.unpack_archive(os.path.join(self.cachedir, package.get('patch_filename')), self.subdir_root) diff --git a/meson/wrap/wrap.py b/meson/wrap/wrap.py new file mode 100644 index 0000000..2818fa0 --- /dev/null +++ b/meson/wrap/wrap.py @@ -0,0 +1,212 @@ +# Copyright 2015 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. + +from .. import mlog +import urllib.request, os, hashlib, shutil +import subprocess +import sys + +try: + import ssl + has_ssl = True + API_ROOT = 'https://wrapdb.mesonbuild.com/v1/' +except ImportError: + has_ssl = False + API_ROOT = 'http://wrapdb.mesonbuild.com/v1/' + +def build_ssl_context(): + ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + ctx.options |= ssl.OP_NO_SSLv2 + ctx.options |= ssl.OP_NO_SSLv3 + ctx.verify_mode = ssl.CERT_REQUIRED + ctx.load_default_certs() + return ctx + +def open_wrapdburl(urlstring): + global ssl_warning_printed + if has_ssl: + try: + return urllib.request.urlopen(urlstring)#, context=build_ssl_context()) + except urllib.error.URLError: + if not ssl_warning_printed: + print('SSL connection failed. Falling back to unencrypted connections.') + ssl_warning_printed = True + if not ssl_warning_printed: + print('Warning: SSL not available, traffic not authenticated.', + file=sys.stderr) + ssl_warning_printed = True + # Trying to open SSL connection to wrapdb fails because the + # certificate is not known. + if urlstring.startswith('https'): + urlstring = 'http' + urlstring[5:] + return urllib.request.urlopen(urlstring) + + +class PackageDefinition: + def __init__(self, fname): + self.values = {} + ifile = open(fname) + first = ifile.readline().strip() + + if first == '[wrap-file]': + self.type = 'file' + elif first == '[wrap-git]': + self.type = 'git' + else: + raise RuntimeError('Invalid format of package file') + for line in ifile: + line = line.strip() + if line == '': + continue + (k, v) = line.split('=', 1) + k = k.strip() + v = v.strip() + self.values[k] = v + + def get(self, key): + return self.values[key] + + def has_patch(self): + return 'patch_url' in self.values + +class Resolver: + def __init__(self, subdir_root): + self.subdir_root = subdir_root + self.cachedir = os.path.join(self.subdir_root, 'packagecache') + + def resolve(self, packagename): + fname = os.path.join(self.subdir_root, packagename + '.wrap') + dirname = os.path.join(self.subdir_root, packagename) + if not os.path.isfile(fname): + if os.path.isdir(dirname): + # No wrap file but dir exists -> user put it there manually. + return packagename + return None + p = PackageDefinition(fname) + if p.type == 'file': + if not os.path.isdir(self.cachedir): + os.mkdir(self.cachedir) + self.download(p, packagename) + self.extract_package(p) + elif p.type == 'git': + self.get_git(p) + else: + raise RuntimeError('Unreachable code.') + return p.get('directory') + + def get_git(self, p): + checkoutdir = os.path.join(self.subdir_root, p.get('directory')) + revno = p.get('revision') + is_there = os.path.isdir(checkoutdir) + if is_there: + if revno.lower() == 'head': + subprocess.check_call(['git', 'pull'], cwd=checkoutdir) + else: + if subprocess.call(['git', 'checkout', revno], cwd=checkoutdir) != 0: + subprocess.check_call(['git', 'fetch'], cwd=checkoutdir) + subprocess.check_call(['git', 'checkout', revno], + cwd=checkoutdir) + else: + subprocess.check_call(['git', 'clone', p.get('url'), + p.get('directory')], cwd=self.subdir_root) + if revno.lower() != 'head': + subprocess.check_call(['git', 'checkout', revno], + cwd=checkoutdir) + + + def get_data(self, url): + blocksize = 10*1024 + if url.startswith('https://wrapdb.mesonbuild.com'): + resp = open_wrapdburl(url) + else: + resp = urllib.request.urlopen(url) + dlsize = int(resp.info()['Content-Length']) + print('Download size:', dlsize) + print('Downloading: ', end='') + sys.stdout.flush() + printed_dots = 0 + blocks = [] + downloaded = 0 + while True: + block = resp.read(blocksize) + if block == b'': + break + downloaded += len(block) + blocks.append(block) + ratio = int(downloaded/dlsize * 10) + while printed_dots < ratio: + print('.', end='') + sys.stdout.flush() + printed_dots += 1 + print('') + resp.close() + return b''.join(blocks) + + def get_hash(self, data): + h = hashlib.sha256() + h.update(data) + hashvalue = h.hexdigest() + return hashvalue + + def download(self, p, packagename): + ofname = os.path.join(self.cachedir, p.get('source_filename')) + if os.path.exists(ofname): + mlog.log('Using', mlog.bold(packagename), 'from cache.') + return + srcurl = p.get('source_url') + mlog.log('Dowloading', mlog.bold(packagename), 'from', mlog.bold(srcurl)) + srcdata = self.get_data(srcurl) + dhash = self.get_hash(srcdata) + expected = p.get('source_hash') + if dhash != expected: + raise RuntimeError('Incorrect hash for source %s:\n %s expected\n %s actual.' % (packagename, expected, dhash)) + open(ofname, 'wb').write(srcdata) + if p.has_patch(): + purl = p.get('patch_url') + mlog.log('Downloading patch from', mlog.bold(purl)) + pdata = self.get_data(purl) + phash = self.get_hash(pdata) + expected = p.get('patch_hash') + if phash != expected: + raise RuntimeError('Incorrect hash for patch %s:\n %s expected\n %s actual' % (packagename, expected, phash)) + open(os.path.join(self.cachedir, p.get('patch_filename')), 'wb').write(pdata) + else: + mlog.log('Package does not require patch.') + + def extract_package(self, package): + if sys.version_info < (3, 5): + try: + import lzma + del lzma + try: + shutil.register_unpack_format('xztar', ['.tar.xz', '.txz'], shutil._unpack_tarfile, [], "xz'ed tar-file") + except shutil.RegistryError: + pass + except ImportError: + pass + target_dir = os.path.join(self.subdir_root, package.get('directory')) + if os.path.isdir(target_dir): + return + extract_dir = self.subdir_root + # Some upstreams ship packages that do not have a leading directory. + # Create one for them. + try: + package.get('lead_directory_missing') + os.mkdir(target_dir) + extract_dir = target_dir + except KeyError: + pass + shutil.unpack_archive(os.path.join(self.cachedir, package.get('source_filename')), extract_dir) + if package.has_patch(): + shutil.unpack_archive(os.path.join(self.cachedir, package.get('patch_filename')), self.subdir_root) diff --git a/meson/wrap/wraptool.py b/meson/wrap/wraptool.py new file mode 100755 index 0000000..d2f0a28 --- /dev/null +++ b/meson/wrap/wraptool.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python3 + +# Copyright 2015-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. + +import json +import sys, os +import configparser +import shutil + +from glob import glob + +from .wrap import API_ROOT, open_wrapdburl + +help_templ = '''This program allows you to manage your Wrap dependencies +using the online wrap database http://wrapdb.mesonbuild.com. + +Run this command in your top level source directory. + +Usage: + +%s [options] + +Commands: + + list - show all available projects + search - search the db by name + install - install the specified project + update - update the project to its newest available release + info - show available versions of a project + status - show installed and available versions of your projects + +''' + + +def print_help(): + print(help_templ % sys.argv[0]) + +def get_result(urlstring): + u = open_wrapdburl(urlstring) + data = u.read().decode('utf-8') + jd = json.loads(data) + if jd['output'] != 'ok': + print('Got bad output from server.') + print(data) + sys.exit(1) + return jd + +def get_projectlist(): + jd = get_result(API_ROOT + 'projects') + projects = jd['projects'] + return projects + +def list_projects(): + projects = get_projectlist() + for p in projects: + print(p) + +def search(name): + jd = get_result(API_ROOT + 'query/byname/' + name) + for p in jd['projects']: + print(p) + +def get_latest_version(name): + jd = get_result(API_ROOT + 'query/get_latest/' + name) + branch = jd['branch'] + revision = jd['revision'] + return (branch, revision) + +def install(name): + if not os.path.isdir('subprojects'): + print('Subprojects dir not found. Run this script in your source root directory.') + sys.exit(1) + if os.path.isdir(os.path.join('subprojects', name)): + print('Subproject directory for this project already exists.') + sys.exit(1) + wrapfile = os.path.join('subprojects', name + '.wrap') + if os.path.exists(wrapfile): + print('Wrap file already exists.') + sys.exit(1) + (branch, revision) = get_latest_version(name) + u = open_wrapdburl(API_ROOT + 'projects/%s/%s/%s/get_wrap' % (name, branch, revision)) + data = u.read() + open(wrapfile, 'wb').write(data) + print('Installed', name, 'branch', branch, 'revision', revision) + +def get_current_version(wrapfile): + cp = configparser.ConfigParser() + cp.read(wrapfile) + cp = cp['wrap-file'] + patch_url = cp['patch_url'] + arr = patch_url.split('/') + branch = arr[-3] + revision = int(arr[-2]) + return (branch, revision, cp['directory'], cp['source_filename'], cp['patch_filename']) + +def update(name): + if not os.path.isdir('subprojects'): + print('Subprojects dir not found. Run this command in your source root directory.') + sys.exit(1) + wrapfile = os.path.join('subprojects', name + '.wrap') + if not os.path.exists(wrapfile): + print('Project', name, 'is not in use.') + sys.exit(1) + (branch, revision, subdir, src_file, patch_file) = get_current_version(wrapfile) + (new_branch, new_revision) = get_latest_version(name) + if new_branch == branch and new_revision == revision: + print('Project', name, 'is already up to date.') + sys.exit(0) + u = open_wrapdburl(API_ROOT + 'projects/%s/%s/%d/get_wrap' % (name, new_branch, new_revision)) + data = u.read() + shutil.rmtree(os.path.join('subprojects', subdir), ignore_errors=True) + try: + os.unlink(os.path.join('subprojects/packagecache', src_file)) + except FileNotFoundError: + pass + try: + os.unlink(os.path.join('subprojects/packagecache', patch_file)) + except FileNotFoundError: + pass + open(wrapfile, 'wb').write(data) + print('Updated', name, 'to branch', new_branch, 'revision', new_revision) + +def info(name): + jd = get_result(API_ROOT + 'projects/' + name) + versions = jd['versions'] + if len(versions) == 0: + print('No available versions of', name) + sys.exit(0) + print('Available versions of %s:' % name) + for v in versions: + print(' ', v['branch'], v['revision']) + +def status(): + print('Subproject status') + for w in glob('subprojects/*.wrap'): + name = os.path.split(w)[1][:-5] + try: + (latest_branch, latest_revision) = get_latest_version(name) + except Exception: + print('', name, 'not available in wrapdb.') + continue + try: + (current_branch, current_revision, _, _, _) = get_current_version(w) + except Exception: + print('Wrap file not from wrapdb.') + continue + if current_branch == latest_branch and current_revision == latest_revision: + print('', name, 'up to date. Branch %s, revision %d.' % (current_branch, current_revision)) + else: + print('', name, 'not up to date. Have %s %d, but %s %d is available.' % (current_branch, current_revision, latest_branch, latest_revision)) + +def run(args): + if len(sys.argv) < 1 or sys.argv[0] == '-h' or sys.argv[1] == '--help': + print_help() + return 0 + command = args[0] + args = args[1:] + if command == 'list': + list_projects() + elif command == 'search': + if len(args) != 1: + print('Search requires exactly one argument.') + return 1 + search(args[0]) + elif command == 'install': + if len(args) != 1: + print('Install requires exactly one argument.') + return 1 + install(args[0]) + elif command == 'update': + if len(args) != 1: + print('update requires exactly one argument.') + return 1 + update(args[0]) + elif command == 'info': + if len(args) != 1: + print('info requires exactly one argument.') + return 1 + info(args[0]) + elif command == 'status': + status() + else: + print('Unknown command', command) + return 1 + return 0 + +if __name__ == '__main__': + sys.exit(run(sys.argv[1:])) diff --git a/wraptool b/wraptool new file mode 100755 index 0000000..46a2c26 --- /dev/null +++ b/wraptool @@ -0,0 +1,20 @@ +#!/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. + +from meson.wrap import wraptool +import sys + +sys.exit(wraptool.run(sys.argv[1:])) \ No newline at end of file diff --git a/wraptool.py b/wraptool.py deleted file mode 100755 index 46860aa..0000000 --- a/wraptool.py +++ /dev/null @@ -1,206 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2015 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. - -import json -import sys, os -import configparser -import shutil - - -ssl_warning_printed = False - -from glob import glob - -help_templ = '''This program allows you to manage your Wrap dependencies -using the online wrap database http://wrapdb.mesonbuild.com. - -Run this command in your top level source directory. - -Usage: - -%s [options] - -Commands: - - list - show all available projects - search - search the db by name - install - install the specified project - update - update the project to its newest available release - info - show available versions of a project - status - show installed and available versions of your projects - -''' - - -def print_help(): - print(help_templ % sys.argv[0]) - -def build_ssl_context(): - ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) - ctx.options |= ssl.OP_NO_SSLv2 - ctx.options |= ssl.OP_NO_SSLv3 - ctx.verify_mode = ssl.CERT_REQUIRED - ctx.load_default_certs() - return ctx - -def get_result(urlstring): - u = open_wrapdburl(urlstring) - data = u.read().decode('utf-8') - jd = json.loads(data) - if jd['output'] != 'ok': - print('Got bad output from server.') - print(data) - sys.exit(1) - return jd - -def get_projectlist(): - jd = get_result(API_ROOT + 'projects') - projects = jd['projects'] - return projects - -def list_projects(): - projects = get_projectlist() - for p in projects: - print(p) - -def search(name): - jd = get_result(API_ROOT + 'query/byname/' + name) - for p in jd['projects']: - print(p) - -def get_latest_version(name): - jd = get_result(API_ROOT + 'query/get_latest/' + name) - branch = jd['branch'] - revision = jd['revision'] - return (branch, revision) - -def install(name): - if not os.path.isdir('subprojects'): - print('Subprojects dir not found. Run this script in your source root directory.') - sys.exit(1) - if os.path.isdir(os.path.join('subprojects', name)): - print('Subproject directory for this project already exists.') - sys.exit(1) - wrapfile = os.path.join('subprojects', name + '.wrap') - if os.path.exists(wrapfile): - print('Wrap file already exists.') - sys.exit(1) - (branch, revision) = get_latest_version(name) - u = open_wrapdburl(API_ROOT + 'projects/%s/%s/%s/get_wrap' % (name, branch, revision)) - data = u.read() - open(wrapfile, 'wb').write(data) - print('Installed', name, 'branch', branch, 'revision', revision) - -def get_current_version(wrapfile): - cp = configparser.ConfigParser() - cp.read(wrapfile) - cp = cp['wrap-file'] - patch_url = cp['patch_url'] - arr = patch_url.split('/') - branch = arr[-3] - revision = int(arr[-2]) - return (branch, revision, cp['directory'], cp['source_filename'], cp['patch_filename']) - -def update(name): - if not os.path.isdir('subprojects'): - print('Subprojects dir not found. Run this command in your source root directory.') - sys.exit(1) - wrapfile = os.path.join('subprojects', name + '.wrap') - if not os.path.exists(wrapfile): - print('Project', name, 'is not in use.') - sys.exit(1) - (branch, revision, subdir, src_file, patch_file) = get_current_version(wrapfile) - (new_branch, new_revision) = get_latest_version(name) - if new_branch == branch and new_revision == revision: - print('Project', name, 'is already up to date.') - sys.exit(0) - u = open_wrapdburl(API_ROOT + 'projects/%s/%s/%d/get_wrap' % (name, new_branch, new_revision)) - data = u.read() - shutil.rmtree(os.path.join('subprojects', subdir), ignore_errors=True) - try: - os.unlink(os.path.join('subprojects/packagecache', src_file)) - except FileNotFoundError: - pass - try: - os.unlink(os.path.join('subprojects/packagecache', patch_file)) - except FileNotFoundError: - pass - open(wrapfile, 'wb').write(data) - print('Updated', name, 'to branch', new_branch, 'revision', new_revision) - -def info(name): - jd = get_result(API_ROOT + 'projects/' + name) - versions = jd['versions'] - if len(versions) == 0: - print('No available versions of', name) - sys.exit(0) - print('Available versions of %s:' % name) - for v in versions: - print(' ', v['branch'], v['revision']) - -def status(): - print('Subproject status') - for w in glob('subprojects/*.wrap'): - name = os.path.split(w)[1][:-5] - try: - (latest_branch, latest_revision) = get_latest_version(name) - except Exception: - print('', name, 'not available in wrapdb.') - continue - try: - (current_branch, current_revision, _, _, _) = get_current_version(w) - except Exception: - print('Wrap file not from wrapdb.') - continue - if current_branch == latest_branch and current_revision == latest_revision: - print('', name, 'up to date. Branch %s, revision %d.' % (current_branch, current_revision)) - else: - print('', name, 'not up to date. Have %s %d, but %s %d is available.' % (current_branch, current_revision, latest_branch, latest_revision)) - -if __name__ == '__main__': - if len(sys.argv) < 2 or sys.argv[1] == '-h' or sys.argv[1] == '--help': - print_help() - sys.exit(0) - command = sys.argv[1] - args = sys.argv[2:] - if command == 'list': - list_projects() - elif command == 'search': - if len(args) != 1: - print('Search requires exactly one argument.') - sys.exit(1) - search(args[0]) - elif command == 'install': - if len(args) != 1: - print('Install requires exactly one argument.') - sys.exit(1) - install(args[0]) - elif command == 'update': - if len(args) != 1: - print('update requires exactly one argument.') - sys.exit(1) - update(args[0]) - elif command == 'info': - if len(args) != 1: - print('info requires exactly one argument.') - sys.exit(1) - info(args[0]) - elif command == 'status': - status() - else: - print('Unknown command', command) - sys.exit(1) - -- cgit v1.1