diff options
-rw-r--r-- | gbp/deb.py | 63 | ||||
-rwxr-xr-x | git-import-orig | 80 |
2 files changed, 113 insertions, 30 deletions
@@ -18,6 +18,28 @@ from errors import GbpError # the valid characters. debian_version_chars = 'a-zA-Z\d.~+-' +# Valid package names according to Debian Policy Manual 5.6.1: +# "Package names (both source and binary, see Package, Section 5.6.7) +# must consist only of lower case letters (a-z), digits (0-9), plus (+) +# and minus (-) signs, and periods (.). They must be at least two +# characters long and must start with an alphanumeric character." +packagename_re = re.compile("^[a-z0-9][a-z0-9\.\+\-]+$") +packagename_msg = """Package names must be at least two characters long, start with an +alphanumeric and can only containg lower case letters (a-z), digits +(0-9), plus signs (+), minus signs (-), and periods (.)""" + +# Valid upstream versions according to Debian Policy Manual 5.6.12: +# "The upstream_version may contain only alphanumerics[32] and the +# characters . + - : ~ (full stop, plus, hyphen, colon, tilde) and +# should start with a digit. If there is no debian_revision then hyphens +# are not allowed; if there is no epoch then colons are not allowed." +# Since we don't know about any epochs and debian revisions yet, the +# last two conditions are not checked. +upstreamversion_re = re.compile("^[0-9][a-z0-9\.\+\-\:\~]*$") +upstreamversion_msg = """Upstream version numbers must start with a digit and can only containg lower case +letters (a-z), digits (0-9), full stops (.), plus signs (+), minus signs +(-), colons (:) and tildes (~)""" + # compression types, extra options and extensions compressor_opts = { 'gzip' : [ '-n', 'gz' ], 'bzip2' : [ '', 'bz2' ], @@ -190,6 +212,13 @@ def is_native(cp): "Is this a debian native package" return [ True, False ]['-' in cp['Version']] +def is_valid_packagename(name): + "Is this a valid Debian package name?" + return packagename_re.match(name) + +def is_valid_upstreamversion(version): + "Is this a valid upstream version number?" + return upstreamversion_re.match(version) def get_compression(orig_file): "Given an orig file return the compression used" @@ -314,44 +343,48 @@ def get_arch(): return arch -def guess_upstream_version(archive, version_regex=r''): +def guess_upstream_version(archive, extra_regex=r''): """ - guess the version from the filename of an upstgream archive + guess the package name and version from the filename of an upstgream + archive. Returns a tuple with package name and version, or None. @archive: filename to guess to version for - @version_regex: additional version regex to apply, needs a 'version' group + @extra_regex: additional regex to apply, needs a 'package' and a + 'version' group >>> guess_upstream_version('foo-bar_0.2.orig.tar.gz') - '0.2' + ('foo-bar', '0.2') >>> guess_upstream_version('foo-Bar_0.2.orig.tar.gz') >>> guess_upstream_version('git-bar-0.2.tar.gz') - '0.2' + ('git-bar', '0.2') >>> guess_upstream_version('git-bar-0.2-rc1.tar.gz') - '0.2-rc1' + ('git-bar', '0.2-rc1') >>> guess_upstream_version('git-bar-0.2:~-rc1.tar.gz') - '0.2:~-rc1' + ('git-bar', '0.2:~-rc1') >>> guess_upstream_version('git-Bar-0A2d:rc1.tar.bz2') - '0A2d:rc1' + ('git-Bar', '0A2d:rc1') >>> guess_upstream_version('git-1.tar.bz2') - '1' + ('git', '1') >>> guess_upstream_version('kvm_87+dfsg.orig.tar.gz') - '87+dfsg' + ('kvm', '87+dfsg') >>> guess_upstream_version('foo-Bar_0.2.orig.tar.gz') >>> guess_upstream_version('foo-Bar-a.b.tar.gz') + """ version_chars = r'[a-zA-Z\d\.\~\-\:\+]' extensions = r'\.tar\.(gz|bz2)' version_filters = map ( lambda x: x % (version_chars, extensions), ( # Debian package_<version>.orig.tar.gz: - r'^[a-z\d\.\+\-]+_(?P<version>%s+)\.orig%s', + r'^(?P<package>[a-z\d\.\+\-]+)_(?P<version>%s+)\.orig%s', # Upstream package-<version>.tar.gz: - r'^[a-zA-Z\d\.\+\-]+-(?P<version>[0-9]%s*)%s')) - if version_regex: - version_filters = version_regex + version_filters + r'^(?P<package>[a-zA-Z\d\.\+\-]+)-(?P<version>[0-9]%s*)%s')) + if extra_regex: + version_filters = extra_regex + version_filters + for filter in version_filters: m = re.match(filter, os.path.basename(archive)) if m: - return m.group('version') + return (m.group('package'), m.group('version')) def compare_versions(version1, version2): diff --git a/git-import-orig b/git-import-orig index 1455656..031198d 100755 --- a/git-import-orig +++ b/git-import-orig @@ -30,11 +30,22 @@ import tempfile import gbp.command_wrappers as gbpc from gbp.deb import (parse_changelog, unpack_orig, repack_orig, NoChangelogError, has_epoch, tar_toplevel, - guess_upstream_version, do_uscan) + guess_upstream_version, do_uscan, + parse_changelog_repo, is_valid_packagename, + packagename_msg, is_valid_upstreamversion, + upstreamversion_msg) from gbp.git import (FastImport, GitRepositoryError, GitRepository, build_tag) from gbp.config import GbpOptionParser, GbpOptionGroup from gbp.errors import (GbpError, GbpNothingImported) +# Try to import readline, since that will cause raw_input to get fancy +# line editing and history capabilities. However, if readline is not +# available, raw_input will still work. +try: + import readline +except ImportError: + pass + def cleanup_tmp_tree(tree): """remove a tree of temporary files""" try: @@ -130,6 +141,42 @@ def turn_off_fastimport(options, msg): options.fast_import = False +def ask_package_name(default): + """ + Ask the user for the source package name. + @default The default package name to suggest to the user. + """ + while True: + sourcepackage = raw_input("What will be the source package name? [%s] " % default) + if not sourcepackage: # No input, use the default. + sourcepackage = default + # Valid package name, return it. + if is_valid_packagename(sourcepackage): + return sourcepackage + + # Not a valid package name. Print an extra + # newline before the error to make the output a + # bit clearer. + print "\nNot a valid package name: '%s'.\n%s" % (sourcepackage, packagename_msg) + +def ask_package_version(default): + """ + Ask the user for the upstream package version. + @default The default package version to suggest to the user. + """ + while True: + version = raw_input("What is the upstream version? [%s] " % default) + if not version: # No input, use the default. + version = default + # Valid version, return it. + if is_valid_upstreamversion(version): + return version + + # Not a valid upstream version. Print an extra + # newline before the error to make the output a + # bit clearer. + print "\nNot a valid upstream version: '%s'.\n%s" % (version, upstreamversion_msg) + def main(argv): ret = 0 tmpdir = '' @@ -256,17 +303,22 @@ on howto create it otherwise use --upstream-branch to specify it. """ % options.upstream_branch raise GbpError + # Guess defaults for the package name and version from the + # original tarball. + (guessed_package, guessed_version) = guess_upstream_version(archive) or ('', '') + + # Try to find the source package name + try: + cp = parse_changelog('debian/changelog') + sourcepackage = cp['Source'] + except NoChangelogError: + sourcepackage = ask_package_name(guessed_package) + + # Try to find the version. if options.version: version = options.version else: - version = guess_upstream_version(archive) - - if version: - print "Upstream version is %s" % version - else: - print >>sys.stderr, "Cannot determine upstream version from %s - use -u <version>" % archive - parser.print_help() - raise GbpError + version = ask_package_version(guessed_version) (clean, out) = repo.is_clean() if not clean and not is_empty: @@ -299,12 +351,7 @@ on howto create it otherwise use --upstream-branch to specify it. os.path.basename(archive).replace(".tar", ".gbp.tar") ) repack_orig(archive, tmpdir, os.path.basename(orig_dir)) - try: - cp = parse_changelog('debian/changelog') - pristine_orig = symlink_orig(archive, cp['Source'], version) - except NoChangelogError: - print "Warning: Can't symlink orig tarball due to missing debian/changelog" - pristine_orig = archive + pristine_orig = symlink_orig(archive, sourcepackage, version) try: upstream_branch = [ options.upstream_branch, 'master' ][is_empty] @@ -313,6 +360,9 @@ on howto create it otherwise use --upstream-branch to specify it. print "Importing '%s' to branch '%s'%s..." % (archive, upstream_branch, filter_msg) + print "Source package is %s" % sourcepackage + print "Upstream version is %s" % version + if options.fast_import: fast_import_upstream_tree(repo, pristine_orig, version, options) commit = options.upstream_branch |