diff --git a/add-bugzilla-versions/add-versions.py b/add-bugzilla-versions/add-versions.py index 5bd0db3..4c1228f 100644 --- a/add-bugzilla-versions/add-versions.py +++ b/add-bugzilla-versions/add-versions.py @@ -1,129 +1,134 @@ #!/usr/bin/env python3 # Copyright 2015 Jonathan Riddell # Copyright 2017 Adrian Chaves # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from pathlib import Path import re from shutil import rmtree from subprocess import run, DEVNULL, PIPE from tempfile import mkdtemp, mkstemp from bs4 import BeautifulSoup from click import command, echo, option from requests import RequestException, Session ERROR = 'needs a legitimate login and password to continue' URL = 'https://bugs.kde.org' EDIT_VERSION_URL = '{}/editversions.cgi'.format(URL) VERSION_RE = re.compile(r'(?m)^BUGZILLA_APPLICATION_VERSION:STRING=(.*)$') def response_error(response): html = response.text soup = BeautifulSoup(html, 'html.parser') error_message = soup.find('div', {'id': 'error_msg'}) if not error_message: return None return re.sub(r'\s+', ' ', error_message.get_text()).strip() def log_in(session, email, password): data = {'Bugzilla_login': email, 'Bugzilla_password': password} headers = {'Referer': 'https://bugs.kde.org/'} try: response = session.post(URL, data=data, headers=headers) error = response_error(response) if error: echo(error) exit(1) except RequestException: echo('Unexpected login error. Please, contact the maintainers of this ' 'script.') exit(1) def products(): modules_path = Path(__file__).resolve().parent.parent / 'modules.git' with modules_path.open() as modules_file: for line in modules_file: match = re.match('^\S+', line) if match: yield match.group(0) @command() @option('-s', '--srcdir', prompt=True) @option('-e', '--email', prompt=True) @option('-p', '--password', prompt=True, hide_input=True) def main(srcdir, email, password): srcdir = srcdir.rstrip('/') session = Session() log_in(session, email, password) for product in products(): folder = mkdtemp() try: command = ['cmake', '-L', srcdir + '/' + product] execution = run(command, cwd=folder, stdout=PIPE, stderr=DEVNULL) output = execution.stdout.decode() if '-- Cache values' not in output: output_file = mkstemp() with open(output_file, 'w') as file: file.write(output) raise RuntimeError( 'Unexpected CMake output for \'{product}\'.\n' '\n' '\'-- Cache values\' string not found in CMake output for ' '\'{product}\'. Please report this issue to the script ' 'maintainers and attach the CMake output, which has been ' 'saved to \'{output_file}\'.'.format( product=product, output_file=output_file)) match = VERSION_RE.search(output) if not match: echo('{} (skipped)'.format(product)) continue version = match.group(1) + if not version: + raise RuntimeError( + 'BUGZILLA_APPLICATION_VERSION has been found, but its ' + 'value is an empty string. Please, review your CMake set ' + 'command.') params = {'action': 'add', 'product': product} response = session.get(EDIT_VERSION_URL, params=params) soup = BeautifulSoup(response.text, 'html.parser') try: token = soup.find('input', {'name': 'token'})['value'] except: raise RuntimeError('Could not parse token from \'{}\''.format( response.url)) params = {'version': version, 'action': 'new', 'product': product, 'token': token} try: response = session.get(EDIT_VERSION_URL, params=params) response.raise_for_status() except RequestException: echo('{} (error)'.format(product)) continue error = response_error(response) if not error: echo(product) else: echo('{} (error: {})'.format(product, error)) except RuntimeError as error: echo('ERROR: {}'.format(error)) exit(1) finally: rmtree(folder) if __name__ == '__main__': main()