diff options
Diffstat (limited to 'bin/test-hid-vs-ui.py')
-rwxr-xr-x | bin/test-hid-vs-ui.py | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/bin/test-hid-vs-ui.py b/bin/test-hid-vs-ui.py new file mode 100755 index 000000000..635a121ad --- /dev/null +++ b/bin/test-hid-vs-ui.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python +# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at http://mozilla.org/MPL/2.0/. +# +# Parses all help files (.xhp) to check that hids referencing .ui are up-to-date +# From fdo#67350 + + +import sys +import argparse +import os +import subprocess +import xml.etree.ElementTree as ET +import collections +import re +import smtplib +import email +import email.mime.text +import time +import datetime + +# retrieve all hids related to .ui files +def init_hids(): + global args, local_repo + if local_repo: + repo_dir = os.path.join(core_repo_dir,'helpcontent2') + os.chdir(repo_dir) + return subprocess.check_output(['git','grep','hid="[^"]*/[^"]*">','.']) + else: + repo_dir = '/var/tmp/help.git' + if not os.path.exists(repo_dir):os.makedirs(repo_dir) + os.chdir(repo_dir) + + if not os.path.exists(os.path.join(repo_dir,'config')): + subprocess.call(['git','clone','--bare','git://gerrit.libreoffice.org/help',repo_dir]) + elif not args['git_static']: + subprocess.call(['git','fetch','origin']) + return subprocess.check_output(['git','grep','hid="[^"]*/[^"]*">','master','--']) + +# retrieve .ui files list from the core +def init_core_files(): + global core_repo_dir, local_repo + core_repo_dir = args['core_repo_dir'] + if core_repo_dir is None: + core_repo_dir = os.path.dirname(os.path.abspath(os.path.dirname(sys.argv[0]))) + local_repo = True + + if not os.path.exists(core_repo_dir):os.makedirs(core_repo_dir) + os.chdir(core_repo_dir) + + if not os.path.exists(os.path.join(core_repo_dir,'.git')): + subprocess.call(['git','clone','git://gerrit.libreoffice.org/core',core_repo_dir]) + elif not args['git_static']: + subprocess.call(['git','fetch','origin']) + allfiles = subprocess.check_output(['git','ls-tree','--name-only','--full-name','-r','master']) + return re.findall('.*\.ui',allfiles) + + +if __name__ == "__main__": + + parser = argparse.ArgumentParser('hid for ui consistency parser') + parser.add_argument('-s', '--send-to', action='append', help='email address to send the report to. Use one flag per address.', required=False) + parser.add_argument('-g', '--git-static', action='store_true', help='to avoid contacting remote server to refresh repositories.', required=False) + parser.add_argument('-r', '--core-repo-dir', help='enforce path to core repository when analyzing .ui files.', required=False) + args=vars(parser.parse_args()) + + uifileslist = init_core_files() # play it early to gain the local repo identification + + rows = init_hids().splitlines() + #<tree>:<relative_file>:<text> + # handled as sets to remove duplicates (and we don't need an iterator) + targets = collections.defaultdict(set) + origin = collections.defaultdict(set) + + # fill all matching hids and their parent file + for row in rows: + fname, rawtext = row.split(':',1)[0:] + hid = rawtext.split('hid="')[1].split('"')[0] + if hid.startswith('.uno'): continue + uifileraw, compname = hid.rsplit('/',1) + uifile = uifileraw + ".ui" + # map modules/ etc, which exist only in install + # back to their source location + if uifile.startswith("modules/scalc"): + uifile = "sc/scalc" + uifile[13:] + elif uifile.startswith("modules/swriter"): + uifile = "sw/swriter" + uifile[15:] + elif uifile.startswith("modules/schart"): + uifile = "chart2" + uifile[14:] + elif uifile.startswith("modules/smath"): + uifile = "starmath/smath" + uifile[13:] + elif uifile.startswith("modules/sdraw"): + uifile = "sd/sdraw" + uifile[13:] + elif uifile.startswith("modules/simpress"): + uifile = "sd/simpress" + uifile[16:] + elif uifile.startswith("modules/BasicIDE"): + uifile = "basctl/basicide" + uifile[16:] + elif uifile.startswith("modules/sabpilot"): + uifile = "extensions/sabpilot" + uifile[16:] + elif uifile.startswith("modules/sbibliography"): + uifile = "extensions/sbibliography" + uifile[21:] + elif uifile.startswith("modules/scanner"): + uifile = "extensions/scanner" + uifile[15:] + elif uifile.startswith("modules/spropctrlr"): + uifile = "extensions/spropctrlr" + uifile[18:] + elif uifile.startswith("sfx"): + uifile = "sfx2" + uifile[3:] + elif uifile.startswith("svt"): + uifile = "svtools" + uifile[3:] + elif uifile.startswith("fps"): + uifile = "fpicker" + uifile[3:] + components = uifile.split('/',1); + uifile = components[0] + '/uiconfig/' + components[1] + targets[uifile].add(compname.split(':')[0]) + origin[uifile].add(fname) # help file(s) + + errors = '' + # search in all .ui files referenced in help + # 2 possible errors: file not found in repo, id not found in file + for uikey in dict.keys(targets): + if uikey not in uifileslist: + if len(origin[uikey]) == 1: + errors += '\nFrom ' + origin[uikey].pop() + else: + errors += '\nFrom one of ' + str(origin[uikey]).replace('set(','').replace(')','') + errors += ', we did not find file '+ uikey+'.' + continue + + full_path = os.path.join(core_repo_dir,uikey) + # print full_path + root = ET.parse(full_path).getroot() + ids = [element.attrib['id'].split(':')[0] for element in root.findall('.//object[@id]')] + # print targets[uikey] + missing_ids = [ element for element in targets[uikey] if element not in ids ] + if missing_ids: + if len(origin[uikey]) == 1: + errors += '\nFrom ' + origin[uikey].pop() + else: + errors += '\nFrom one of ' + str(origin[uikey]).replace('set(','').replace(')','') + errors += ', referenced items '+ str(missing_ids) + ' were not found inside '+ uikey+'.' + + if not errors: + errors = '\nall is clean\n' + + if args['send_to']: + msg_from = os.path.basename(sys.argv[0]) + '@libreoffice.org' + if isinstance(args['send_to'], basestring): + msg_to = [args['send_to']] + else: + msg_to = args['send_to'] + print "send to array " + msg_to[0] + + server = smtplib.SMTP('localhost') + body = ''' +Hello, + +Here is the report for wrong hids from help related to .ui files + +''' + body += errors + body += ''' + +Best, + +Your friendly LibreOffice Help-ids Checker + +Note: The bot generating this message can be found and improved here: + https://gerrit.libreoffice.org/gitweb?p=dev-tools.git;a=blob;f=scripts/test-hid-vs-ui.py''' + now = datetime.datetime.now() + msg = email.mime.text.MIMEText(body, 'plain', 'UTF-8') + msg['From'] = msg_from + msg['To'] = msg_to[0] + msg['Cc'] = ', '.join(msg_to[1:]) # Works only if at least 2 items in tuple + msg['Date'] = email.utils.formatdate(time.mktime(now.timetuple())) + msg['Subject'] = 'LibreOffice Gerrit News for python on %s' % (now.date().isoformat()) + msg['Reply-To'] = msg_to[0] + msg['X-Mailer'] = 'LibreOfficeGerritDigestMailer 1.1' + + server.sendmail(msg_from, msg_to, str(msg)) + else: + print errors + +# vim: set shiftwidth=4 softtabstop=4 expandtab: |