diff options
Diffstat (limited to 'gbp/pkg/pkgpolicy.py')
-rw-r--r-- | gbp/pkg/pkgpolicy.py | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/gbp/pkg/pkgpolicy.py b/gbp/pkg/pkgpolicy.py new file mode 100644 index 00000000..eb2d72ea --- /dev/null +++ b/gbp/pkg/pkgpolicy.py @@ -0,0 +1,167 @@ +# vim: set fileencoding=utf-8 : +# +# (C) 2017 Guido Guenther <agx@sigxcpu.org> +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, please see +# <http://www.gnu.org/licenses/> + + +import os +import re + +from gbp.pkg.archive import Archive + + +class PkgPolicy(object): + """ + Common helpers for packaging policy. + """ + packagename_re = None + packagename_msg = None + upstreamversion_re = None + upstreamversion_msg = None + + @classmethod + def is_valid_packagename(cls, name): + """ + Is this a valid package name? + + >>> PkgPolicy.is_valid_packagename('doesnotmatter') + Traceback (most recent call last): + ... + NotImplementedError: Class needs to provide packagename_re + """ + if cls.packagename_re is None: + raise NotImplementedError("Class needs to provide packagename_re") + return True if cls.packagename_re.match(name) else False + + @classmethod + def is_valid_upstreamversion(cls, version): + """ + Is this a valid upstream version number? + + >>> PkgPolicy.is_valid_upstreamversion('doesnotmatter') + Traceback (most recent call last): + ... + NotImplementedError: Class needs to provide upstreamversion_re + """ + if cls.upstreamversion_re is None: + raise NotImplementedError("Class needs to provide upstreamversion_re") + return True if cls.upstreamversion_re.match(version) else False + + @staticmethod + def guess_upstream_src_version(filename, extra_regex=r''): + """ + Guess the package name and version from the filename of an upstream + archive. + + @param filename: filename (archive or directory) from which to guess + @type filename: C{string} + @param extra_regex: additional regex to apply, needs a 'package' and a + 'version' group + @return: (package name, version) or ('', '') + @rtype: tuple + + >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.gz') + ('foo-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('foo-Bar_0.2.orig.tar.gz') + ('', '') + >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2.tar.gz') + ('git-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2-rc1.tar.gz') + ('git-bar', '0.2-rc1') + >>> PkgPolicy.guess_upstream_src_version('git-bar-0.2:~-rc1.tar.gz') + ('git-bar', '0.2:~-rc1') + >>> PkgPolicy.guess_upstream_src_version('git-Bar-0A2d:rc1.tar.bz2') + ('git-Bar', '0A2d:rc1') + >>> PkgPolicy.guess_upstream_src_version('git-1.tar.bz2') + ('git', '1') + >>> PkgPolicy.guess_upstream_src_version('kvm_87+dfsg.orig.tar.gz') + ('kvm', '87+dfsg') + >>> PkgPolicy.guess_upstream_src_version('foo-Bar-a.b.tar.gz') + ('', '') + >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.xz') + ('foo-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.orig.tar.lzma') + ('foo-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('foo-bar-0.2.zip') + ('foo-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('foo-bar-0.2.tlz') + ('foo-bar', '0.2') + >>> PkgPolicy.guess_upstream_src_version('foo-bar_0.2.tar.gz') + ('foo-bar', '0.2') + """ + version_chars = r'[a-zA-Z\d\.\~\-\:\+]' + basename = Archive.parse_filename(os.path.basename(filename))[0] + + version_filters = map( + lambda x: x % version_chars, + ( # Debian upstream tarball: package_'<version>.orig.tar.gz' + r'^(?P<package>[a-z\d\.\+\-]+)_(?P<version>%s+)\.orig', + # Debian native: 'package_<version>.tar.gz' + r'^(?P<package>[a-z\d\.\+\-]+)_(?P<version>%s+)', + # Upstream 'package-<version>.tar.gz' + # or directory 'package-<version>': + r'^(?P<package>[a-zA-Z\d\.\+\-]+)(-)(?P<version>[0-9]%s*)')) + if extra_regex: + version_filters = extra_regex + version_filters + + for filter in version_filters: + m = re.match(filter, basename) + if m: + return (m.group('package'), m.group('version')) + return ('', '') + + @staticmethod + def has_origs(orig_files, dir): + "Check orig tarball and additional tarballs exists in dir" + for o in orig_files: + if not os.path.exists(os.path.join(dir, o)): + return False + return True + + @classmethod + def has_orig(cls, orig_file, dir): + return cls.has_origs([orig_file], dir) + + @staticmethod + def symlink_origs(orig_files, orig_dir, output_dir, force=False): + """ + symlink orig tarball from orig_dir to output_dir + @return: [] if all links were created, list of + failed links otherwise + """ + orig_dir = os.path.abspath(orig_dir) + output_dir = os.path.abspath(output_dir) + err = [] + + if orig_dir == output_dir: + return [] + + for f in orig_files: + src = os.path.join(orig_dir, f) + dst = os.path.join(output_dir, f) + if not os.access(src, os.F_OK): + err.append(f) + continue + try: + if os.path.exists(dst) and force: + os.unlink(dst) + os.symlink(src, dst) + except OSError: + err.append(f) + return err + + @classmethod + def symlink_orig(cls, orig_file, orig_dir, output_dir, force=False): + return cls.symlink_origs([orig_file], orig_dir, output_dir, force=force) |