def find_new_urls(vcs_type, vcs_url, package, maintainer_email,
                  net_access=False):
    if net_access and (
            vcs_url.startswith('https://') or vcs_url.startswith('http://')):
        headers = {'User-Agent': USER_AGENT}
        try:
            response = urlopen(
                Request(vcs_url, headers=headers),
                timeout=DEFAULT_URLLIB_TIMEOUT)
        except (urllib.error.HTTPError, urllib.error.URLError):
            pass
        except socket.timeout:
            pass
        else:
            redirected_url = response.geturl()
            if not is_on_obsolete_host(redirected_url):
                vcs_url = redirected_url
                vcs_browser = determine_browser_url(vcs_type, vcs_url)
                print("Update Vcs-* headers from URL redirect.")
                return (vcs_type, vcs_url, vcs_browser)

    # If possible, we use vcswatch to find the VCS repository URL
    if net_access:
        loop = asyncio.get_event_loop()
        try:
            (vcs_type, vcs_url, vcs_browser) = loop.run_until_complete(
                retrieve_vcswatch_urls(package))
        except VcsWatchError as e:
            warn('vcswatch URL unusable: %s' % e.args[0])
        except KeyError:
            pass
        else:
            if not is_on_obsolete_host(vcs_url):
                print("Update Vcs-* headers from vcswatch.")
                if is_on_obsolete_host(vcs_browser):
                    vcs_browser = (
                        determine_browser_url(vcs_type, vcs_url) or
                        vcs_browser)
                return (vcs_type, vcs_url, vcs_browser)
            warn('vcswatch URL %s is still on old infrastructure.' % vcs_url)

    # Otherwise, attempt to guess based on maintainer email.
    guessed_url = guess_repository_url(package, maintainer_email)
    if guessed_url is not None:
        vcs_type = "Git"
        vcs_url = guessed_url
    else:
        vcs_url = salsa_url_from_alioth_url(vcs_type, vcs_url)
        if vcs_url is None:
            raise NewRepositoryURLUnknown(vcs_type, vcs_url)
        vcs_type = "Git"
    # Verify that there is actually a repository there
    if net_access:
        if verify_salsa_repository(vcs_url) is False:
            raise NewRepositoryURLUnknown(vcs_type, vcs_url)

    print("Update Vcs-* headers to use salsa repository.")

    vcs_browser = determine_salsa_browser_url(vcs_url)
    return (vcs_type, vcs_url, vcs_browser)
Example #2
0
def replace_full_license(para):
    license = para.license
    license_matched = find_common_license_from_fulltext(license.text)
    if license_matched is None:
        if os.path.exists(os.path.join(COMMON_LICENSES_DIR, license.synopsis)):
            warn('A common license shortname (%s) is used, but license '
                 'text not recognized.' % license.synopsis)
        return
    # The full license text was found. Replace it with a blurb.
    canonical_id = canonical_license_id(license.synopsis)
    for shortname, blurb in _BLURB.items():
        if canonical_id == canonical_license_id(shortname):
            break
    else:
        if license.synopsis in SPDX_RENAMES:
            renames[license.synopsis] = SPDX_RENAMES[license.synopsis]
            return
        else:
            warn('Found full license text for %s, but unknown synopsis %s (%s)'
                 % (license_matched, license.synopsis, canonical_id))
        return
    if license_matched == 'Apache-2.0':
        fixed_lintian_tag('source',
                          'copyright-file-contains-full-apache-2-license',
                          info=())
    if license_matched.startswith('GFDL-'):
        fixed_lintian_tag('source',
                          'copyright-file-contains-full-gfdl-license',
                          info=())
    if license_matched.startswith('GPL-'):
        fixed_lintian_tag('source',
                          'copyright-file-contains-full-gpl-license',
                          info=())
    para.license = License(license.synopsis, blurb)
    return license_matched
Example #3
0
async def valid_bug(package, bug):
    if not net_access_allowed():
        return None
    global debbugs
    if debbugs is None:
        from lintian_brush.debbugs import DebBugs
        _debbugs = DebBugs()
        try:
            await _debbugs.connect()
        except ImportError:
            # No asynpcg?
            return None
        except socket.gaierror as e:
            warn('Unable to connect to debbugs: %s' % e)
            return None
        debbugs = _debbugs
    return await debbugs.check_bug(package, bug)
Example #4
0
def canonical_license_id(license_id):
    # From the standard:
    #  For licenses that have multiple versions in use, the short name is
    #  formed from the general short name of the license family, followed by a
    #  dash and the version number. If the version number is omitted, the
    #  lowest version number is implied. When the license grant permits using
    #  the terms of any later version of that license, add a plus sign to the
    #  end of the short name. For example, the short name GPL refers to the GPL
    #  version 1 and is equivalent to GPL-1, although the latter is clearer and
    #  therefore preferred. If the package may be distributed under the GPL
    #  version 1 or any later version, use a short name of GPL-1+.
    #
    #  For SPDX compatibility, versions with trailing dot-zeroes are considered
    #  to be equivalent to versions without (e.g., “2.0.0” is considered equal
    #  to “2.0” and “2”).
    m = re.fullmatch(r'([A-Za-z0-9]+)(\-[0-9\.]+)?(\+)?', license_id)
    if not m:
        warn('Unable to get canonical name for %r' % license_id)
        return license_id
    version = (m.group(2) or '-1')[1:]
    while version.endswith('.0'):
        version = version[:-2]
    return '%s-%s%s' % (m.group(1), version, m.group(3) or '')
Example #5
0
 if pgpsigurlmangle and has_keys:
     continue
 try:
     pgpmode = entry.get_option('pgpmode')
 except KeyError:
     pgpmode = 'default'
 else:
     if diligence() == 0:
         continue
 if pgpmode in ('gittag', 'previous', 'next', 'self'):
     sys.exit(2)
 try:
     releases = list(
         sorted(entry.discover(source_package_name()), reverse=True))
 except HTTPError as e:
     warn('HTTP error accessing discovery URL %s: %s.' %
          (e.geturl(), e))
     sys.exit(0)
 for r in releases[:RELEASES_TO_INSPECT]:
     if r.pgpsigurl:
         pgpsigurls = [(pgpsigurlmangle, r.pgpsigurl)]
     else:
         pgpsigurls = [(mangle, apply_url_mangle(mangle, r.url))
                       for mangle in COMMON_MANGLES]
     for mangle, pgpsigurl in pgpsigurls:
         # Try and download signatures from some predictable locations.
         try:
             resp = urlopen(pgpsigurl)
         except HTTPError:
             continue
         sig = resp.read()
         actual = urlopen(r.url).read()
    'Files', 'License', 'Copyright', 'Comment', 'Upstream-Name', 'Format',
    'Upstream-Contact', 'Source', 'Upstream', 'Contact', 'Name'
}

typo_fixed = set()
case_fixed = set()

try:
    with Deb822Editor('debian/copyright') as updater:
        for paragraph in updater.paragraphs:
            for field in paragraph:
                if field in valid_field_names:
                    continue
                if (field.startswith('X-') and field[2:] in valid_field_names):
                    if field[2:] in paragraph:
                        warn('Both %s and %s exist.' % (field, field[2:]))
                        continue
                    value = paragraph[field]
                    del paragraph[field]
                    paragraph[field[2:]] = value
                    typo_fixed.add((field, field[2:]))
                    fixed_lintian_tag('source',
                                      'field-name-typo-in-dep5-copyright',
                                      '%s (line XX)' % field)
                    continue

                for option in valid_field_names:
                    if distance(field, option) == 1:
                        value = paragraph[field]
                        del paragraph[field]
                        paragraph[option] = value
#!/usr/bin/python3

import email.utils
from debmutate.changelog import ChangelogEditor

from lintian_brush.fixer import report_result, LintianIssue, warn

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()
    except FileNotFoundError:
        return False
    return False


if autoreconf_disabled():
    try:
        with open('configure', 'rb') as f:
            for line in f:
                if b'runstatedir' in line:
                    break
            else:
                new_debhelper_compat_version = min(
                    new_debhelper_compat_version, 10)
                warn('Not upgrading beyond debhelper %d, since the package '
                     'disables autoreconf but its configure does not provide '
                     '--runstatedir.' % new_debhelper_compat_version)
    except (IsADirectoryError, FileNotFoundError):
        pass

if os.path.exists('debian/compat'):
    # Package currently stores compat version in debian/compat..

    current_debhelper_compat_version = read_debhelper_compat_file(
        'debian/compat')
    if current_debhelper_compat_version < new_debhelper_compat_version:
        with open('debian/compat', 'w') as cf:
            cf.write('%s\n' % new_debhelper_compat_version)
    else:
        # Nothing to do
        sys.exit(2)
Example #9
0
if older_source_format_issue.should_fix():
    if package_is_native():
        format = '3.0 (native)'
        description = "Upgrade to newer source format %s." % format
    else:
        from lintian_brush.patches import (
            tree_non_patches_changes,
            find_patches_directory,
        )
        from breezy import errors
        from breezy.workingtree import WorkingTree
        patches_directory = find_patches_directory('.')
        if patches_directory not in ('debian/patches', None):
            # Non-standard patches directory.
            warn('Tree has non-standard patches directory %s.' %
                 (patches_directory))
        else:
            try:
                tree, path = WorkingTree.open_containing('.')
            except errors.NotBranchError as e:
                if not meets_minimum_certainty('possible'):
                    warn('unable to open vcs to check for delta: %s' % e)
                    sys.exit(0)
                format = "3.0 (quilt)"
                description = "Upgrade to newer source format %s." % format
            else:
                delta = list(tree_non_patches_changes(tree, patches_directory))
                if delta:
                    warn('Tree has non-quilt changes against upstream.')
                    if opinionated():
                        format = "3.0 (quilt)"