aboutsummaryrefslogtreecommitdiff
blob: fb70faee76e48ed201b6455767992749bb05adc0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env python
# Copyright: 2011 Brian Harring <ferringb@gmail.com>
# Copyright: 2007 Charlie Shepherd <masterdriverz@gmail.com>
# License: BSD/GPL-2

from os.path import basename
import sys

from snakeoil.lists import iflatten_instance
from snakeoil.osutils import listdir_files, pjoin

try:
    from pkgcore.util import commandline
    from pkgcore.restrictions import packages
    from pkgcore.restrictions.boolean import OrRestriction
    from pkgcore.repository.multiplex import tree as multiplex_tree
    from pkgcore.fetch import fetchable as fetchable_kls
    from pkgcore.chksum.errors import ParseChksumError
    from pkgcore.util.repo_utils import get_virtual_repos
except ImportError:
    print >> sys.stderr, 'Cannot import pkgcore!'
    print >> sys.stderr, 'Verify it is properly installed and/or ' \
        'PYTHONPATH is set correctly.'
    if '--debug' not in sys.argv:
        print >> sys.stderr, 'Add --debug to the commandline for a traceback.'
    else:
        raise
    sys.exit(1)


class OptionParser(commandline.OptionParser):
    def __init__(self, **kwargs):
        commandline.OptionParser.__init__(self, description=__doc__, **kwargs)
        self.add_option("--exclude", "-e", action='append', dest='excludes')
        self.add_option("--exclude-file", "-E", action='callback', dest='excludes',
            callback=commandline.read_file_callback, type="string",
            help='path to the exclusion file')
        self.add_option("--ignore-failures", "-i", action="store_true",
            default=False, help="ignore checksum parsing errors")

    def check_values(self, values, args):
        values, args = commandline.OptionParser.check_values(
            self, values, args)

        if args:
            self.error("This script takes no arguments")
        domain = values.config.get_default('domain')
        values.vdb = domain.vdb
        values.repo = multiplex_tree(*get_virtual_repos(domain.repos, False))
        values.distdir = domain.fetcher.distdir
        restrict = commandline.convert_to_restrict(values.excludes, default=None)
        if restrict != [None]:
            values.restrict = OrRestriction(negate=True, *restrict)
        else:
            values.restrict = packages.AlwaysTrue

        return values, ()

def main(options, out, err):
    if options.debug:
        out.write('starting scanning distdir %s...' % options.distdir)
    files = set(basename(file) for file in listdir_files(options.distdir))

    if options.debug:
        out.write('scanning repo...')

    pfiles = set()
    for pkg in options.repo.itermatch(options.restrict, sorter=sorted):
        try:
            pfiles.update(fetchable.filename for fetchable in
                        iflatten_instance(pkg.fetchables, fetchable_kls))
        except ParseChksumError as e:
            err.write("got corruption error '%s', with package %s " %
                (e, pkg.cpvstr))
            if options.ignore_failures:
                err.write("skipping...")
                err.write()
            else:
                err.write("aborting...")
                return 1
        except Exception as e:
            err.write("got error '%s', parsing package %s in repo '%s'" %
                (e, pkg.cpvstr, pkg.repo))
            raise

    d = options.distdir
    for file in (files - pfiles):
        out.write(pjoin(d, file))

if __name__ == '__main__':
    commandline.main({None: (OptionParser, main)})