Blame tools/daca2.py

Packit 2035a7
#!/usr/bin/env python
Packit 2035a7
#
Packit 2035a7
# 1. Create a folder daca2 in your HOME folder
Packit 2035a7
# 2. Put cppcheck-O2 in daca2. It should be built with all optimisations.
Packit 2035a7
# 3. Optional: Put a file called "suppressions.txt" in the daca2 folder.
Packit 2035a7
# 4. Optional: tweak FTPSERVER and FTPPATH in this script below.
Packit 2035a7
# 5. Run the daca2 script:  python daca2.py FOLDER
Packit 2035a7
Packit 2035a7
import argparse
Packit 2035a7
import subprocess
Packit 2035a7
import sys
Packit 2035a7
import shutil
Packit 2035a7
import glob
Packit 2035a7
import os
Packit 2035a7
import datetime
Packit 2035a7
import time
Packit 2035a7
import logging
Packit 2035a7
Packit 2035a7
DEBIAN = ('ftp://ftp.se.debian.org/debian/',
Packit 2035a7
          'ftp://ftp.debian.org/debian/')
Packit 2035a7
Packit 2035a7
Packit 2035a7
def wget(filepath):
Packit 2035a7
    filename = filepath
Packit 2035a7
    if '/' in filepath:
Packit 2035a7
        filename = filename[filename.rfind('/') + 1:]
Packit 2035a7
    for d in DEBIAN:
Packit 2035a7
        subprocess.call(
Packit 2035a7
            ['nice', 'wget', '--tries=10', '--timeout=300', '-O', filename, d + filepath])
Packit 2035a7
        if os.path.isfile(filename):
Packit 2035a7
            return True
Packit 2035a7
        print('Sleep for 10 seconds..')
Packit 2035a7
        time.sleep(10)
Packit 2035a7
    return False
Packit 2035a7
Packit 2035a7
Packit 2035a7
def getpackages(folder):
Packit 2035a7
    if not wget('ls-lR.gz'):
Packit 2035a7
        return []
Packit 2035a7
    subprocess.call(['nice', 'gunzip', 'ls-lR.gz'])
Packit 2035a7
    f = open('ls-lR', 'rt')
Packit 2035a7
    lines = f.readlines()
Packit 2035a7
    f.close()
Packit 2035a7
    subprocess.call(['rm', 'ls-lR'])
Packit 2035a7
Packit 2035a7
    path = None
Packit 2035a7
    archives = []
Packit 2035a7
    filename = None
Packit 2035a7
    for line in lines:
Packit 2035a7
        line = line.strip()
Packit 2035a7
        if len(line) < 4:
Packit 2035a7
            if filename:
Packit 2035a7
                archives.append(path + '/' + filename)
Packit 2035a7
            path = None
Packit 2035a7
            filename = None
Packit 2035a7
        elif line[:13 + len(folder)] == './pool/main/' + folder + '/':
Packit 2035a7
            path = line[2:-1]
Packit 2035a7
        elif path and '.orig.tar.' in line:
Packit 2035a7
            filename = line[1 + line.rfind(' '):]
Packit 2035a7
Packit 2035a7
    for a in archives:
Packit 2035a7
        print(a)
Packit 2035a7
Packit 2035a7
    return archives
Packit 2035a7
Packit 2035a7
Packit 2035a7
def handleRemoveReadonly(func, path, exc):
Packit 2035a7
    import stat
Packit 2035a7
    if not os.access(path, os.W_OK):
Packit 2035a7
        # Is the error an access error ?
Packit 2035a7
        os.chmod(path, stat.S_IWUSR)
Packit 2035a7
        func(path)
Packit 2035a7
Packit 2035a7
Packit 2035a7
def removeAllExceptResults():
Packit 2035a7
    filenames = []
Packit 2035a7
    filenames.extend(glob.glob('[A-Za-z0-9]*'))
Packit 2035a7
    filenames.extend(glob.glob('.[a-z]*'))
Packit 2035a7
Packit 2035a7
    for filename in filenames:
Packit 2035a7
        count = 5
Packit 2035a7
        while count > 0:
Packit 2035a7
            count -= 1
Packit 2035a7
Packit 2035a7
            try:
Packit 2035a7
                if os.path.isdir(filename):
Packit 2035a7
                    shutil.rmtree(filename, onerror=handleRemoveReadonly)
Packit 2035a7
                elif filename != RESULTS_FILENAME:
Packit 2035a7
                    os.remove(filename)
Packit 2035a7
                break
Packit 2035a7
            except WindowsError as err:
Packit 2035a7
                time.sleep(30)
Packit 2035a7
                if count == 0:
Packit 2035a7
                    logging.error('Failed to cleanup {}: {}'.format(filename, err))
Packit 2035a7
            except OSError as err:
Packit 2035a7
                time.sleep(30)
Packit 2035a7
                if count == 0:
Packit 2035a7
                    logging.error('Failed to cleanup {}: {}'.format(filename, err))
Packit 2035a7
Packit 2035a7
Packit 2035a7
def removeLargeFiles(path):
Packit 2035a7
    for g in glob.glob(path + '*'):
Packit 2035a7
        if g in {'.', '..'}:
Packit 2035a7
            continue
Packit 2035a7
        if os.path.islink(g):
Packit 2035a7
            continue
Packit 2035a7
        if os.path.isdir(g):
Packit 2035a7
            # Remove test code
Packit 2035a7
            if g.endswith('/testsuite') or g.endswith('/clang/INPUTS'):
Packit 2035a7
                shutil.rmtree(g, onerror=handleRemoveReadonly)
Packit 2035a7
            # Remove docs and examples ... that might be garbage
Packit 2035a7
            elif g.endswith('/doc') or g.endswith('/examples'):
Packit 2035a7
                shutil.rmtree(g, onerror=handleRemoveReadonly)
Packit 2035a7
            else:
Packit 2035a7
                removeLargeFiles(g + '/')
Packit 2035a7
        elif os.path.isfile(g) and g[-4:] != '.txt':
Packit 2035a7
            statinfo = os.stat(g)
Packit 2035a7
            if statinfo.st_size > 1000000:
Packit 2035a7
                try:
Packit 2035a7
                    os.remove(g)
Packit 2035a7
                except OSError as err:
Packit 2035a7
                    logging.error('Failed to remove {}: {}'.format(g, err))
Packit 2035a7
Packit 2035a7
Packit 2035a7
def strfCurrTime(fmt):
Packit 2035a7
    return datetime.time.strftime(datetime.datetime.now().time(), fmt)
Packit 2035a7
Packit 2035a7
Packit 2035a7
def scanarchive(filepath, jobs, cpulimit):
Packit 2035a7
    # remove all files/folders except RESULTS_FILENAME
Packit 2035a7
    removeAllExceptResults()
Packit 2035a7
Packit 2035a7
    logging.info(DEBIAN[0] + filepath)
Packit 2035a7
Packit 2035a7
    if not wget(filepath):
Packit 2035a7
        if not wget(filepath):
Packit 2035a7
            logging.error('wget failed at {}'.format(filepath))
Packit 2035a7
            return
Packit 2035a7
Packit 2035a7
    filename = filepath[filepath.rfind('/') + 1:]
Packit 2035a7
    if filename[-3:] == '.gz':
Packit 2035a7
        subprocess.call(['tar', 'xzvf', filename])
Packit 2035a7
    elif filename[-3:] == '.xz':
Packit 2035a7
        subprocess.call(['tar', 'xJvf', filename])
Packit 2035a7
    elif filename[-4:] == '.bz2':
Packit 2035a7
        subprocess.call(['tar', 'xjvf', filename])
Packit 2035a7
Packit 2035a7
    removeLargeFiles('')
Packit 2035a7
Packit 2035a7
    print(strfCurrTime('[%H:%M] cppcheck ') + filename)
Packit 2035a7
Packit 2035a7
    if cpulimit:
Packit 2035a7
        cmd = 'cpulimit --limit=' + cpulimit
Packit 2035a7
    else:
Packit 2035a7
        cmd = 'nice --adjustment=1000'
Packit 2035a7
    cmd = cmd + ' ../cppcheck-O2 -D__GCC__ --enable=style --inconclusive --error-exitcode=0 ' +\
Packit 2035a7
        '--exception-handling=stderr ' + jobs + ' --template=daca2 .'
Packit 2035a7
    cmds = cmd.split()
Packit 2035a7
Packit 2035a7
    p = subprocess.Popen(cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Packit 2035a7
    comm = p.communicate()
Packit 2035a7
Packit 2035a7
    if p.returncode == 0:
Packit 2035a7
        logging.info(comm[1] + strfCurrTime('[%H:%M]'))
Packit 2035a7
    elif 'cppcheck: error: could not find or open any of the paths given.' not in comm[0]:
Packit 2035a7
        logging.error(comm[1] + strfCurrTime('[%H:%M]'))
Packit 2035a7
        logging.error('Exit code is not zero! Crash?\n')
Packit 2035a7
Packit 2035a7
Packit 2035a7
parser = argparse.ArgumentParser(description='Checks debian source code')
Packit 2035a7
parser.add_argument('folder', metavar='FOLDER')
Packit 2035a7
parser.add_argument('--rev')
Packit 2035a7
parser.add_argument('--workdir', default='~/daca2')
Packit 2035a7
parser.add_argument('-j', '--jobs', default='-j1')
Packit 2035a7
parser.add_argument('--skip', default=[], action='append')
Packit 2035a7
parser.add_argument('--cpulimit')
Packit 2035a7
Packit 2035a7
args = parser.parse_args()
Packit 2035a7
Packit 2035a7
workdir = os.path.expanduser(args.workdir)
Packit 2035a7
if not os.path.isdir(workdir):
Packit 2035a7
    logging.critical('workdir \'' + workdir + '\' is not a folder')
Packit 2035a7
    sys.exit(1)
Packit 2035a7
Packit 2035a7
workdir = os.path.join(workdir, args.folder)
Packit 2035a7
if not os.path.isdir(workdir):
Packit 2035a7
    os.makedirs(workdir)
Packit 2035a7
Packit 2035a7
RESULTS_FILENAME = 'results.txt'
Packit 2035a7
RESULTS_FILE = os.path.join(workdir, RESULTS_FILENAME)
Packit 2035a7
Packit 2035a7
logging.basicConfig(
Packit 2035a7
    filename=RESULTS_FILE,
Packit 2035a7
    level=logging.INFO,
Packit 2035a7
    format='%(message)s')
Packit 2035a7
Packit 2035a7
print(workdir)
Packit 2035a7
Packit 2035a7
archives = getpackages(args.folder)
Packit 2035a7
if len(archives) == 0:
Packit 2035a7
    logging.critical('failed to load packages')
Packit 2035a7
    sys.exit(1)
Packit 2035a7
Packit 2035a7
if not os.path.isdir(workdir):
Packit 2035a7
    os.makedirs(workdir)
Packit 2035a7
os.chdir(workdir)
Packit 2035a7
Packit 2035a7
try:
Packit 2035a7
    logging.info('STARTDATE ' + str(datetime.date.today()))
Packit 2035a7
    logging.info('STARTTIME ' + strfCurrTime('%H:%M:%S'))
Packit 2035a7
    if args.rev:
Packit 2035a7
        logging.info('GIT-REVISION ' + args.rev + '\n')
Packit 2035a7
    logging.info('')
Packit 2035a7
Packit 2035a7
    for archive in archives:
Packit 2035a7
        if len(args.skip) > 0:
Packit 2035a7
            a = archive[:archive.rfind('/')]
Packit 2035a7
            a = a[a.rfind('/') + 1:]
Packit 2035a7
            if a in args.skip:
Packit 2035a7
                continue
Packit 2035a7
        scanarchive(archive, args.jobs, args.cpulimit)
Packit 2035a7
Packit 2035a7
    logging.info('DATE {}'.format(datetime.date.today()))
Packit 2035a7
    logging.info('TIME {}'.format(strfCurrTime('%H:%M:%S')))
Packit 2035a7
Packit 2035a7
except EOFError:
Packit 2035a7
    pass
Packit 2035a7
Packit 2035a7
# remove all files/folders except RESULTS_FILENAME
Packit 2035a7
removeAllExceptResults()