def update_watchfile(fn):
    with open('debian/watch', 'r') as f:
        old = f.readlines()

    new = []
    for line in old:
        try:
            (bef, aft) = line.split('#', 1)
        except ValueError:
            bef = line
            aft = None
        newbef = fn(bef)
        if newbef != bef:
            issue = LintianIssue('source', 'debian-watch-uses-insecure-uri',
                                 bef)
            if issue.should_fix():
                if aft is not None:
                    new.append('#'.join([newbef, aft]))
                else:
                    new.append(newbef)
                issue.report_fixed()
            else:
                new.append(line)
        else:
            new.append(line)

    if old != new:
        with open('debian/watch', 'w') as f:
            f.writelines(new)
        return True
    return False
Beispiel #2
0
def update_line(line, target):
    if line.strip() == b'dh_clean -k':
        issue = LintianIssue('source', "dh-clean-k-is-deprecated", '')
        if issue.should_fix():
            issue.report_fixed()
            return b'dh_prep'
    return line
def check_global(origline):
    if origline.startswith(b'export '):
        prefix = b'export '
        line = origline[len(prefix):]
    else:
        prefix = b''
        line = origline
    try:
        (name, value) = line.split(b'=', 1)
    except ValueError:
        # Simple export of a variable, not an assignment
        return origline
    name = name.strip()
    value = value.strip()
    if name == b'DEB_LDFLAGS_MAINT_APPEND' and b'-Wl,--as-needed' in value:
        issue = LintianIssue('source', 'debian-rules-uses-as-needed-linker-flag', 'line X')
        if issue.should_fix():
            issue.report_fixed()
            args = shlex.split(value.decode())
            args.remove('-Wl,--as-needed')
            if not args:
                return None
            return prefix + b'%s = %s' % (name, shlex.join(args).encode())
        return origline
    return origline
def fix_malformed(lineno, override):
    if override.tag not in REMOVED_TAGS:
        return override
    issue = LintianIssue((override.type, override.package),
                         'malformed-override',
                         'Unknown tag %s in line %d' % (override.tag, lineno))
    if issue.should_fix():
        issue.report_fixed()
        return None
    return override
Beispiel #5
0
def drop_explicit_dh_compat(line):
    m = re.match(b'export DH_COMPAT[ \t]*=[ \t]*([0-9]+)', line)
    if m:
        issue = LintianIssue(
            'source',
            'declares-possibly-conflicting-debhelper-compat-versions',
            info='rules=%d compat=%s' % (compat_version, m.group(1)))
        if issue.should_fix():
            issue.report_fixed()
            return []
    return line
def drop_quilt_with(line, target):
    newline = dh_invoke_drop_with(line, b'quilt')
    if line != newline:
        issue = LintianIssue(
            'source', 'dh-quilt-addon-but-quilt-source-format',
            'dh ... --with quilt (line XX)')
        if issue.should_fix():
            issue.report_fixed()
        else:
            newline = line
    return newline
def filter_by_tag(orig, changed, fields, tag):
    if all(field in orig for field in fields):
        return

    issue = LintianIssue('source', tag, info='')

    if (not all(field in orig for field in fields) and not issue.should_fix()):
        for field in fields:
            if field in changed:
                del changed[field]

    if all(field in orig or field in changed for field in fields):
        issue.report_fixed()
 def rep_dbgsym_migration(m):
     rep = m.group(2).strip(b'"').strip(b"'").decode()
     if '$' in rep:
         # too complicated
         return m.group(0)
     rep = PkgRelation.parse_relations(rep)
     if migration_done(rep):
         issue = LintianIssue(
             'source', 'debug-symbol-migration-possibly-complete',
             '%s (line XX)' % (m.group(0).decode().strip()))
         if issue.should_fix():
             issue.report_fixed()
             return b''
     return m.group(0)
def file_strip_whitespace(path,
                          strip_tabs=True,
                          strip_trailing_empty_lines=True,
                          delete_new_empty_line=False):
    newlines = []
    changed = False
    try:
        with open(path, 'rb') as f:
            for lineno, line in enumerate(f, 1):
                newline = strip_whitespace(line, strip_tabs=strip_tabs)
                if newline != line:
                    issue = LintianIssue('source',
                                         'trailing-whitespace',
                                         info='%s (line %d)' % (path, lineno))
                    if issue.should_fix():
                        issue.report_fixed()
                        changed = True
                        if newline == b'\n' and delete_new_empty_line:
                            continue
                newlines.append(newline)
    except FileNotFoundError:
        return
    if strip_trailing_empty_lines:
        while newlines and newlines[-1] == b'\n':
            issue = LintianIssue('source',
                                 'trailing-whitespace',
                                 info='%s (line %d)' %
                                 (path, len(newlines) - 1))
            if issue.should_fix():
                issue.report_fixed()
                changed = True
                newlines.pop(-1)
            else:
                break
    if changed:
        with open(path, 'wb') as f:
            f.writelines(newlines)
def cb(line, target):
    if line.strip() == b'dh_autotools-dev_updateconfig':
        issue = LintianIssue(
            'source',
            'debhelper-tools-from-autotools-dev-are-deprecated',
            info='dh_autotools-dev_updateconfig')
        if issue.should_fix():
            issue.report_fixed()
            return []
    if line.strip() == b'dh_autotools-dev_restoreconfig':
        issue = LintianIssue(
            'source',
            'debhelper-tools-from-autotools-dev-are-deprecated',
            info='dh_autotools-dev_restoreconfig')
        if issue.should_fix():
            issue.report_fixed()
            return []
    newline = dh_invoke_drop_with(line, b'autotools-dev')
    if newline != line:
        issue = LintianIssue(
            'source',
            'debhelper-tools-from-autotools-dev-are-deprecated',
            info='dh ... --with autotools-dev')
        if issue.should_fix():
            line = newline
            issue.report_fixed()
    newline = dh_invoke_drop_with(line, b'autotools_dev')
    if newline != line:
        issue = LintianIssue(
            'source',
            'debhelper-tools-from-autotools-dev-are-deprecated',
            info='dh ... --with autotools_dev')
        if issue.should_fix():
            line = newline
            issue.report_fixed()
    return line
def drop_unnecessary_args(line, target):
    if not line.startswith(b'dh ') and not line.startswith(b'dh_'):
        return line
    for arg in unnecessary_args:
        newline = dh_invoke_drop_argument(line, arg)
        if newline != line:
            issue = LintianIssue('source',
                                 'debian-rules-uses-unnecessary-dh-argument',
                                 info='dh ... %s' % arg.decode())
            if issue.should_fix():
                removed_args.append(arg)
                line = newline
                issue.report_fixed()
    for arg in unnecessary_with:
        newline = dh_invoke_drop_with(line, arg)
        if newline != line:
            issue = LintianIssue('source',
                                 'debian-rules-uses-unnecessary-dh-argument',
                                 info='dh ... -with=%s' % arg.decode())
            if issue.should_fix():
                removed_args.append(b'--with=%s' % arg)
                line = newline
                issue.report_fixed()
    return line
Beispiel #12
0
def fix_shortname(copyright):
    for paragraph in copyright.all_paragraphs():
        if paragraph.license is None:
            continue
        try:
            new_name = typos[paragraph.license.synopsis]
        except KeyError:
            continue
        issue = LintianIssue('source',
                             'invalid-short-name-in-dep5-copyright',
                             info=paragraph.license.synopsis)
        if issue.should_fix():
            renames[paragraph.license.synopsis] = new_name
            paragraph.license = License(new_name, paragraph.license.text)
            issue.report_fixed()
Beispiel #13
0
def rename_override_tags(lineno, override):
    try:
        new_tag = renames[override.tag]
    except KeyError:
        pass  # no rename
    else:
        issue = LintianIssue((override.type, override.package), 'renamed-tag',
                             '%s => %s' % (override.tag, new_tag))
        if issue.should_fix():
            issue.report_fixed()
            return LintianOverride(package=override.package,
                                   archlist=override.archlist,
                                   type=override.type,
                                   tag=new_tag,
                                   info=override.info)
    return override
Beispiel #14
0
def update_configure_ac(path):
    global resolution
    if not os.path.exists(path):
        return

    with LineEditor(path, 'b') as e:
        for lineno, line in e:
            m = re.fullmatch(
                b'\\s*AC_PATH_PROG\\s*'
                b'\\(\\s*(\\[)?(?P<variable>[A-Z_]+)(\\])?\\s*'
                b',\\s*(\\[)?pkg-config(\\])?\\s*'
                b'(,\\s*(\\[)?(?P<default>.*)(\\])?\\s*)?\\)\n', line)

            if not m:
                continue

            issue = LintianIssue(
                'source', 'autotools-pkg-config-macro-not-cross-compilation-'
                'safe',
                info='%s (line %d)' % (name, lineno))
            if not issue.should_fix():
                continue

            if (m.group('variable') == b'PKG_CONFIG'
                    and not m.group('default')):
                e[lineno] = b'PKG_PROG_PKG_CONFIG\n'
                resolution = ("This patch changes it to use "
                              "PKG_PROG_PKG_CONFIG macro from pkg.m4.")
                # Build-Depend on pkg-config for pkg.m4
                with control:
                    control.source['Build-Depends'] = (ensure_some_version(
                        control.source.get('Build-Depends', ''), 'pkg-config'))
            else:
                e[lineno] = line.replace(b'AC_PATH_PROG', b'AC_PATH_TOOL')
                resolution = ("This patch changes it to use AC_PATH_TOOL.")

            issue.report_fixed()
    for datum in guess_upstream_metadata_items('.',
                                               trust_package=trust_package()):
        if datum.field != 'Homepage':
            continue
        if not meets_minimum_certainty(datum.certainty):
            continue
        if known_bad_guess(datum):
            continue
        return datum


with control as updater:
    if 'Homepage' not in updater.source:
        datum = guess_homepage()
        issue = LintianIssue('source', 'no-homepage-field')
        if datum and issue.should_fix():
            updater.source["Homepage"] = datum.value
            issue.report_fixed()
            report_result('Fill in Homepage field.', certainty=datum.certainty)
    else:
        hostname = urlparse(updater.source['Homepage']).hostname
        if hostname == 'pypi.org':
            issue = LintianIssue('source', 'pypi-homepage',
                                 updater.source['Homepage'])
        elif hostname == 'rubygems.org':
            issue = LintianIssue('source', 'pypi-homepage',
                                 updater.source['Homepage'])
        else:
            issue = None

        if issue:
    if all(field in orig or field in changed for field in fields):
        issue.report_fixed()


if package_is_native():
    # Native package
    sys.exit(0)

current_version = current_package_version()

missing_file_issue = LintianIssue('source',
                                  'upstream-metadata-file-is-missing',
                                  info=())

if (not os.path.exists('debian/upstream/metadata')
        and not missing_file_issue.should_fix()):
    sys.exit(0)

with YamlUpdater('debian/upstream/metadata') as editor:
    if isinstance(editor.code, str):
        sys.exit(0)

    upstream_metadata = {
        k: UpstreamDatum(k, v, 'certain')
        for (k, v) in editor.code.items() if v is not None
    }

    minimum_certainty = os.environ.get('MINIMUM_CERTAINTY')
    net_access = net_access_allowed()

    # Downgrade minimum certainty, since check_upstream_metadata can
Beispiel #17
0
    warn,
)
import os
import sys

if is_debcargo_package():
    sys.exit(0)

description = None

if not os.path.exists('debian/source/format'):
    orig_format = None
    format = '1.0'
    missing_source_format_issue = LintianIssue('source',
                                               'missing-debian-source-format')
    if not missing_source_format_issue.should_fix():
        sys.exit(0)
    missing_source_format_issue.report_fixed()
    description = "Explicitly specify source format."
else:
    with open('debian/source/format', 'r') as f:
        format = orig_format = f.read().strip()

if orig_format not in (None, '1.0'):
    sys.exit(0)

older_source_format_issue = LintianIssue('source',
                                         'older-source-format',
                                         info=(orig_format or '1.0'))

if older_source_format_issue.should_fix():
versions = []

with ChangelogEditor() as updater:
    for block in updater.changelog:
        try:
            dt = email.utils.parsedate_to_datetime(block.date)
        except (TypeError, ValueError):
            warn('Invalid date %r for %s' % (block.date, block.version))
            # parsedate_to_datetime is buggy and raises a TypeError
            # when the date is invalid.
            continue
        if dt is None:
            # Can't interpret the date. Just ignore..
            continue
        newdate = email.utils.format_datetime(dt)
        issue = LintianIssue('source',
                             'debian-changelog-has-wrong-day-of-week',
                             info='%04d-%02d-%02d is a %s' %
                             (dt.year, dt.month, dt.day, dt.strftime('%A')))
        if newdate[:3] != block.date[:3] and issue.should_fix():
            block.date = newdate
            versions.append(block.version)
            issue.report_fixed()

if len(versions) == 1:
    report_result('Fix day-of-week for changelog entry %s.' %
                  ', '.join([str(v) for v in versions]))
else:
    report_result('Fix day-of-week for changelog entries %s.' %
                  ', '.join([str(v) for v in versions]))
binary_sections_set = set()
source_section_set = False
regexes = None

with control as updater:
    if updater.source.get('Section'):
        sys.exit(0)
    binary_sections = set()
    for binary in updater.binaries:
        if not binary.get('Section'):
            if regexes is None:
                regexes = get_name_section_mappings()
            section = find_expected_section(regexes, binary['Package'])
            issue = LintianIssue(binary, 'recommended-field', 'Section')
            if section and issue.should_fix():
                binary['Section'] = section
                binary_sections_set.add(binary['Package'])
                issue.report_fixed()
        if binary.get('Section'):
            binary_sections.add(binary['Section'])
    issue = LintianIssue(updater.source, 'recommended-field', 'Section')
    if len(binary_sections) == 1 and issue.should_fix():
        updater.source['Section'] = binary_sections.pop()
        for binary in updater.binaries:
            try:
                del binary['Section']
            except KeyError:
                pass
        issue.report_fixed()
        source_section_set = True
import os
import sys
from lintian_brush.fixer import LintianIssue, report_result

OLD_PATH = 'debian/tests/control.autodep8'
NEW_PATH = 'debian/tests/control'

if not os.path.exists(OLD_PATH):
    sys.exit(0)

issue = LintianIssue('source',
                     'debian-tests-control-autodep8-is-obsolete',
                     info=OLD_PATH)

if not issue.should_fix():
    sys.exit(0)

if not os.path.exists(NEW_PATH):
    os.rename(OLD_PATH, 'debian/tests/control')
    issue.report_fixed()
    report_result("Rename obsolete path %s to %s." % (OLD_PATH, NEW_PATH))
else:
    merge_issue = LintianIssue('source',
                               'debian-tests-control-and-control-autodep8',
                               info='%s %s' % (OLD_PATH, NEW_PATH))
    if not merge_issue.should_fix():
        sys.exit(0)
    merge_issue.report_fixed()
    issue.report_fixed()
    with open(NEW_PATH, 'ab') as outf:
Beispiel #21
0
             else:
                 needed_keys.add(sig.fpr)
         sigs_valid.append(is_valid)
         used_mangles.append(mangle)
         break
     else:
         used_mangles.append(None)
 if not all(sigs_valid[:NUM_KEYS_TO_CHECK]):
     sys.exit(0)
 found_common_mangles = set(used_mangles[:5])
 active_common_mangles = set([x for x in found_common_mangles if x])
 if pgpsigurlmangle is None and active_common_mangles:
     issue = LintianIssue('source',
                          'debian-watch-does-not-check-gpg-signature',
                          ())
     if issue.should_fix():
         # If only a single mangle is used for all releases
         # that have signatures, set that.
         if len(active_common_mangles) == 1:
             new_mangle = active_common_mangles.pop()
             entry.set_option('pgpsigurlmangle', new_mangle)
         # If all releases are signed, mandate it.
         if len(found_common_mangles) == 1:
             entry.set_option('pgpmode', 'mangle')
             description = "Check upstream PGP signatures."
         else:
             # Otherwise, fall back to auto.
             entry.set_option('pgpmode', 'auto')
             description = "Opportunistically check upstream PGP signatures."
         issue.report_fixed()
 if not has_keys and needed_keys:
Beispiel #22
0
#!/usr/bin/python3

import os
import subprocess
import sys

from hashlib import sha1

from lintian_brush.fixer import LintianIssue, report_result

issue = LintianIssue('source', 'newer-debconf-templates', info=())

if not issue.should_fix():
    sys.exit(0)

if not os.path.isdir('debian/po'):
    sys.exit(0)


def read_hashes():
    ret = {}
    for entry in os.scandir('debian/po'):
        with open(entry.path, 'rb') as f:
            ret[entry.path] = sha1(f.read()).hexdigest()
    return ret


def debconf_updatepo():
    try:
        subprocess.check_call(['debconf-updatepo'])
    except FileNotFoundError:
    'jh_makepkg',
    'jh_manifest',
    'jh_repack',
    'jh_setupenvironment',
])

known_targets = []
for dh_command in known_dh_commands:
    known_targets.extend([
        'override_' + dh_command, 'execute_before_' + dh_command,
        'execute_after_' + dh_command
    ])

renamed: List[Tuple[str, str]] = []

with RulesEditor() as editor:
    for rule in editor.makefile.iter_all_rules():
        if rule.target.decode() in known_targets:
            continue
        for known_target in known_targets:
            issue = LintianIssue('source', 'typo-in-debhelper-override-target',
                                 '%s -> %s (line X)')
            if distance(known_target,
                        rule.target.decode()) == 1 and issue.should_fix():
                renamed.append((rule.target.decode(), known_target))
                rule.rename_target(rule.target, known_target.encode())
                issue.report_fixed()

report_result('Fix typo in debian/rules rules: %s' %
              ', '.join('%s => %s' % (old, new) for old, new in renamed))