From e556fdae0057bbf6a81b890431c1887f1dff0f25 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Fri, 2 Dec 2011 18:59:46 +0200 Subject: [PATCH 01/16] New Tool: who-can-upload (LP: #876554) --- debian/changelog | 1 + ubuntutools/lp/lpapicache.py | 77 ++++++++++++++++++++++++++-- who-can-upload | 97 ++++++++++++++++++++++++++++++++++++ 3 files changed, 170 insertions(+), 5 deletions(-) create mode 100755 who-can-upload diff --git a/debian/changelog b/debian/changelog index b0db2d1..0bcc159 100644 --- a/debian/changelog +++ b/debian/changelog @@ -18,6 +18,7 @@ ubuntu-dev-tools (0.137) UNRELEASED; urgency=low * mk-sbuild, pbuilder-dist, ubuntu-build: Add armhf. * pull-debian-source, pull-lp-source: Resolve the source package (via DDE), if a binary package was requested (LP: #617349) + * New Tool: who-can-upload (LP: #876554) [ Andreas Moog ] * sponsor-patch: Check permission to unsubscribe sponsors-team (LP: #896884) diff --git a/ubuntutools/lp/lpapicache.py b/ubuntutools/lp/lpapicache.py index f284d09..dedda24 100644 --- a/ubuntutools/lp/lpapicache.py +++ b/ubuntutools/lp/lpapicache.py @@ -278,11 +278,11 @@ class Archive(BaseWrapper): resource_type = 'archive' def __init__(self, *args): - # Don't share between different Archives - if '_binpkgs' not in self.__dict__: - self._binpkgs = dict() - if '_srcpkgs' not in self.__dict__: - self._srcpkgs = dict() + self._binpkgs = {} + self._srcpkgs = {} + self._pkg_uploaders = {} + self._pkgset_uploaders = {} + self._component_uploaders = {} def getSourcePackage(self, name, series=None, pocket=None): ''' @@ -400,6 +400,40 @@ class Archive(BaseWrapper): include_binaries=include_binaries ) + def getUploadersForComponent(self, component_name): + '''Get the list of PersonTeams who can upload packages in the + specified component. + ''' + if component_name not in self._component_uploaders: + self._component_uploaders[component_name] = sorted(set( + PersonTeam(permission.person_link) + for permission in self._lpobject.getUploadersForComponent( + component_name=component_name + ))) + return self._component_uploaders[component_name] + + def getUploadersForPackage(self, source_package_name): + '''Get the list of PersonTeams who can upload source_package_name)''' + if source_package_name not in self._pkg_uploaders: + self._pkg_uploaders[source_package_name] = sorted(set( + PersonTeam(permission.person_link) + for permission in self._lpobject.getUploadersForPackage( + source_package_name=source_package_name + ))) + return self._pkg_uploaders[source_package_name] + + def getUploadersForPackageset(self, packageset, direct_permissions=False): + '''Get the list of PersonTeams who can upload packages in packageset''' + key = (packageset, direct_permissions) + if key not in self._pkgset_uploaders: + self._pkgset_uploaders[key] = sorted(set( + PersonTeam(permission.person_link) + for permission in self._lpobject.getUploadersForPackageset( + packageset=packageset._lpobject, + direct_permissions=direct_permissions, + ))) + return self._pkgset_uploaders[key] + class SourcePackagePublishingHistory(BaseWrapper): ''' @@ -703,3 +737,36 @@ class DistributionSourcePackage(BaseWrapper): Caching class for distribution_source_package objects. ''' resource_type = 'distribution_source_package' + + +class Packageset(BaseWrapper): + ''' + Caching class for packageset objects. + ''' + resource_type = 'packageset' + _lp_packagesets = None + _source_sets = {} + + @classmethod + def setsIncludingSource(cls, sourcepackagename, distroseries=None, + direct_inclusion=False): + '''Get the package sets including sourcepackagename''' + + if cls._lp_packagesets is None: + cls._lp_packagesets = Launchpad.packagesets + + key = (sourcepackagename, distroseries, direct_inclusion) + if key not in cls._source_sets: + params = { + 'sourcepackagename': sourcepackagename, + 'direct_inclusion': direct_inclusion, + } + if distroseries is not None: + params['distroseries'] = distroseries._lpobject + + cls._source_sets[key] = [ + Packageset(packageset) for packageset + in cls._lp_packagesets.setsIncludingSource(**params) + ] + + return cls._source_sets[key] diff --git a/who-can-upload b/who-can-upload new file mode 100755 index 0000000..04ea9f5 --- /dev/null +++ b/who-can-upload @@ -0,0 +1,97 @@ +#!/usr/bin/python +# +# Copyright (C) 2011, Stefano Rivera +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import optparse + +from ubuntutools.lp.lpapicache import (Launchpad, Distribution, PersonTeam, + Packageset, + SeriesNotFoundException) + + +def main(): + parser = optparse.OptionParser('%prog [options] package') + parser.add_option('-r', '--release', default=None, metavar='RELEASE', + help='Use RELEASE, rather than the current development ' + 'release') + parser.add_option('-t', '--list-team-members', + default=False, action='store_true', + help='List all team members of teams with upload rights') + options, args = parser.parse_args() + + if len(args) != 1: + parser.error("One (and only one) package must be specified") + package = args[0] + + # Need to be logged in to see uploaders: + Launchpad.login() + + ubuntu = Distribution('ubuntu') + archive = ubuntu.getArchive() + if options.release is None: + series = ubuntu.getDevelopmentSeries() + else: + try: + series = ubuntu.getSeries(options.release) + except SeriesNotFoundException, e: + parser.error(str(e)) + + spph = archive.getSourcePackage(package) + component = spph.getComponent() + component_uploader = archive.getUploadersForComponent( + component_name=component)[0] + print "Component (%s)" % component + print "============" + ("=" * len(component)) + print_uploaders([component_uploader], options.list_team_members) + + packagesets = sorted(Packageset.setsIncludingSource(distroseries=series, + sourcepackagename=package)) + if packagesets: + print + print "Packagesets" + print "===========" + for packageset in packagesets: + print + print "%s:" % packageset.name + print_uploaders(archive.getUploadersForPackageset( + packageset=packageset), options.list_team_members) + + ppu_uploaders = archive.getUploadersForPackage(source_package_name=package) + if ppu_uploaders: + print + print "Per-Package-Uploaders" + print "=====================" + print + print_uploaders(ppu_uploaders, options.list_team_members) + + print + if PersonTeam.me.canUploadPackage(archive, series, package, component): + print "You can upload this package" + else: + print "You can not upload this package, yourself." + print ("But you can still contribute to it via the sponsorship " + "process: https://wiki.ubuntu.com/SponsorshipProcess") + + +def print_uploaders(uploaders, expand_teams=False, prefix=''): + for uploader in sorted(uploaders, key=lambda p: p.display_name): + print ("%s* %s (%s)%s" + % (prefix, uploader.display_name, uploader.name, + ' [team]' if uploader.is_team else '')) + if expand_teams and uploader.is_team: + print_uploaders(uploader.participants, True, prefix=prefix + ' ') + +if __name__ == '__main__': + main() From 89192f4e69b053f1e60780d0530d0812eb4f3406 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sat, 3 Dec 2011 22:37:55 +0200 Subject: [PATCH 02/16] UI tweaks --- who-can-upload | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/who-can-upload b/who-can-upload index 04ea9f5..a0a9f23 100755 --- a/who-can-upload +++ b/who-can-upload @@ -52,6 +52,8 @@ def main(): component = spph.getComponent() component_uploader = archive.getUploadersForComponent( component_name=component)[0] + print "All upload permissions for %s:" % package + print print "Component (%s)" % component print "============" + ("=" * len(component)) print_uploaders([component_uploader], options.list_team_members) @@ -86,6 +88,11 @@ def main(): def print_uploaders(uploaders, expand_teams=False, prefix=''): + """Given a list of uploaders, pretty-print them all + Each line is prefixed with prefix. + If expand_teams is set, recurse, adding more spaces to prefix on each + recursion. + """ for uploader in sorted(uploaders, key=lambda p: p.display_name): print ("%s* %s (%s)%s" % (prefix, uploader.display_name, uploader.name, @@ -93,5 +100,6 @@ def print_uploaders(uploaders, expand_teams=False, prefix=''): if expand_teams and uploader.is_team: print_uploaders(uploader.participants, True, prefix=prefix + ' ') + if __name__ == '__main__': main() From 3ea5038905ae3a773ffc01a36ae5333017f0c238 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sat, 3 Dec 2011 22:44:13 +0200 Subject: [PATCH 03/16] PEP8 and docstring improments --- ubuntutools/lp/lpapicache.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/ubuntutools/lp/lpapicache.py b/ubuntutools/lp/lpapicache.py index dedda24..5906c48 100644 --- a/ubuntutools/lp/lpapicache.py +++ b/ubuntutools/lp/lpapicache.py @@ -54,6 +54,7 @@ __all__ = [ _POCKETS = ('Release', 'Security', 'Updates', 'Proposed', 'Backports') + class _Launchpad(object): '''Singleton for LP API access.''' @@ -116,7 +117,7 @@ class BaseWrapper(object): A base class from which other wrapper classes are derived. ''' __metaclass__ = MetaWrapper - resource_type = None # it's a base class after all + resource_type = None # it's a base class after all def __new__(cls, data): if (isinstance(data, basestring) and @@ -403,6 +404,7 @@ class Archive(BaseWrapper): def getUploadersForComponent(self, component_name): '''Get the list of PersonTeams who can upload packages in the specified component. + [Note: the permission records, themselves, aren't exposed] ''' if component_name not in self._component_uploaders: self._component_uploaders[component_name] = sorted(set( @@ -413,7 +415,9 @@ class Archive(BaseWrapper): return self._component_uploaders[component_name] def getUploadersForPackage(self, source_package_name): - '''Get the list of PersonTeams who can upload source_package_name)''' + '''Get the list of PersonTeams who can upload source_package_name) + [Note: the permission records, themselves, aren't exposed] + ''' if source_package_name not in self._pkg_uploaders: self._pkg_uploaders[source_package_name] = sorted(set( PersonTeam(permission.person_link) @@ -423,7 +427,9 @@ class Archive(BaseWrapper): return self._pkg_uploaders[source_package_name] def getUploadersForPackageset(self, packageset, direct_permissions=False): - '''Get the list of PersonTeams who can upload packages in packageset''' + '''Get the list of PersonTeams who can upload packages in packageset + [Note: the permission records, themselves, aren't exposed] + ''' key = (packageset, direct_permissions) if key not in self._pkgset_uploaders: self._pkgset_uploaders[key] = sorted(set( @@ -619,6 +625,7 @@ class MetaPersonTeam(MetaWrapper): raise return cls._me + class PersonTeam(BaseWrapper): ''' Wrapper class around a LP person or team object. @@ -721,7 +728,7 @@ class Build(BaseWrapper): def rescore(self, score): if self.can_be_rescored: - self().rescore(score = score) + self().rescore(score=score) return True return False From 710aa8aa5a34bb4bc4f5d17e2e4048a00f653cac Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sat, 3 Dec 2011 23:26:12 +0200 Subject: [PATCH 04/16] Rename tool, and make output less verbose by default --- debian/changelog | 4 +- who-can-upload => upload-permission | 67 ++++++++++++++++++----------- 2 files changed, 43 insertions(+), 28 deletions(-) rename who-can-upload => upload-permission (63%) diff --git a/debian/changelog b/debian/changelog index 0bcc159..d4d8f1d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -18,11 +18,11 @@ ubuntu-dev-tools (0.137) UNRELEASED; urgency=low * mk-sbuild, pbuilder-dist, ubuntu-build: Add armhf. * pull-debian-source, pull-lp-source: Resolve the source package (via DDE), if a binary package was requested (LP: #617349) - * New Tool: who-can-upload (LP: #876554) + * New Tool: upload-permission: Query upload permissions (LP: #876554) [ Andreas Moog ] * sponsor-patch: Check permission to unsubscribe sponsors-team (LP: #896884) - * grep-merges: We already require a UTF-8 enabled terminal, so encode + * grep-merges: We already require a UTF-8 enabled terminal, so encode package and uploader name in UTF-8 (LP: #694388) -- Andreas Moog Wed, 30 Nov 2011 21:04:39 +0100 diff --git a/who-can-upload b/upload-permission similarity index 63% rename from who-can-upload rename to upload-permission index a0a9f23..b48018b 100755 --- a/who-can-upload +++ b/upload-permission @@ -15,6 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import optparse +import sys from ubuntutools.lp.lpapicache import (Launchpad, Distribution, PersonTeam, Packageset, @@ -26,15 +27,22 @@ def main(): parser.add_option('-r', '--release', default=None, metavar='RELEASE', help='Use RELEASE, rather than the current development ' 'release') + parser.add_option('-a', '--list-uploaders', + default=False, action='store_true', + help='List all the people/teams with upload rights') parser.add_option('-t', '--list-team-members', default=False, action='store_true', - help='List all team members of teams with upload rights') + help='List all team members of teams with upload rights ' + '(implies --list-uploaders)') options, args = parser.parse_args() if len(args) != 1: parser.error("One (and only one) package must be specified") package = args[0] + if options.list_team_members: + options.list_uploaders = True + # Need to be logged in to see uploaders: Launchpad.login() @@ -50,41 +58,48 @@ def main(): spph = archive.getSourcePackage(package) component = spph.getComponent() - component_uploader = archive.getUploadersForComponent( - component_name=component)[0] - print "All upload permissions for %s:" % package - print - print "Component (%s)" % component - print "============" + ("=" * len(component)) - print_uploaders([component_uploader], options.list_team_members) - - packagesets = sorted(Packageset.setsIncludingSource(distroseries=series, - sourcepackagename=package)) - if packagesets: + if options.list_uploaders: + component_uploader = archive.getUploadersForComponent( + component_name=component)[0] + print "All upload permissions for %s:" % package print - print "Packagesets" - print "===========" - for packageset in packagesets: + print "Component (%s)" % component + print "============" + ("=" * len(component)) + print_uploaders([component_uploader], options.list_team_members) + + packagesets = sorted(Packageset.setsIncludingSource( + distroseries=series, + sourcepackagename=package)) + if packagesets: print - print "%s:" % packageset.name - print_uploaders(archive.getUploadersForPackageset( - packageset=packageset), options.list_team_members) + print "Packagesets" + print "===========" + for packageset in packagesets: + print + print "%s:" % packageset.name + print_uploaders(archive.getUploadersForPackageset( + packageset=packageset), options.list_team_members) - ppu_uploaders = archive.getUploadersForPackage(source_package_name=package) - if ppu_uploaders: + ppu_uploaders = archive.getUploadersForPackage( + source_package_name=package) + if ppu_uploaders: + print + print "Per-Package-Uploaders" + print "=====================" + print + print_uploaders(ppu_uploaders, options.list_team_members) print - print "Per-Package-Uploaders" - print "=====================" - print - print_uploaders(ppu_uploaders, options.list_team_members) - print if PersonTeam.me.canUploadPackage(archive, series, package, component): - print "You can upload this package" + print "You can upload this package." else: print "You can not upload this package, yourself." print ("But you can still contribute to it via the sponsorship " "process: https://wiki.ubuntu.com/SponsorshipProcess") + if not options.list_uploaders: + print ("To see who has the necessary upload rights, " + "use the --list-uploaders option.") + sys.exit(1) def print_uploaders(uploaders, expand_teams=False, prefix=''): From 6ef82feac4ce3bfee1cd69bcba671b8b0c1d416f Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sat, 3 Dec 2011 23:36:10 +0200 Subject: [PATCH 05/16] Manpage and other accoutrements --- debian/control | 1 + debian/copyright | 2 ++ doc/upload-permission.1 | 60 +++++++++++++++++++++++++++++++++++++++++ setup.py | 1 + 4 files changed, 64 insertions(+) create mode 100644 doc/upload-permission.1 diff --git a/debian/control b/debian/control index e15fd97..19cec22 100644 --- a/debian/control +++ b/debian/control @@ -106,3 +106,4 @@ Description: useful tools for Ubuntu developers command line. - ubuntu-iso - output information of an Ubuntu ISO image. - update-maintainer - script to update maintainer field in ubuntu packages. + - upload-permission - query / list the upload permissions for a package. diff --git a/debian/copyright b/debian/copyright index d3963b3..5933bf2 100644 --- a/debian/copyright +++ b/debian/copyright @@ -151,6 +151,7 @@ Files: doc/pull-debian-debdiff.1 doc/sponsor-patch.1 doc/ubuntu-dev-tools.5 doc/update-maintainer.1 + doc/upload-permission.1 pull-debian-debdiff pull-debian-source requestbackport @@ -166,6 +167,7 @@ Files: doc/pull-debian-debdiff.1 ubuntutools/test/* ubuntutools/update_maintainer.py update-maintainer + upload-permission Copyright: 2009-2011, Benjamin Drung 2010, Evan Broder 2008, Siegfried-Angel Gevatter Pujals diff --git a/doc/upload-permission.1 b/doc/upload-permission.1 new file mode 100644 index 0000000..742b95d --- /dev/null +++ b/doc/upload-permission.1 @@ -0,0 +1,60 @@ +.\" Copyright (C) 2011, Stefano Rivera +.\" +.\" Permission to use, copy, modify, and/or distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +.\" AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +.\" OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +.\" PERFORMANCE OF THIS SOFTWARE. +.TH upload\-permission 1 "November 2011" ubuntu\-dev\-tools + +.SH NAME +upload\-permission \- Query upload rights and (optionally) list the +people and teams with upload rights for a package + +.SH SYNOPSIS +.B upload\-permission \fR[\fIoptions\fR] \fIpackage + +.SH DESCRIPTION +\fBupload\-permission\fR checks if the user has upload permissions for +\fIpackage\fR. +If the \fB\-\-list\-uploaders\fR option is provided, all the people and +teams that do have upload rights for \fIpackage\fR will be listed. + +.SH OPTIONS +.TP +\fB\-r\fR \fIRELEASE\fR, \fB\-\-release\fR=\fIRELEASE\fR +Query permissions in \fIRELEASE\fR. +Default: current development release. +.TP +\fB\-a\fR, \fB\-\-list\-uploaders\fR +List all the people and teams who have upload rights for \fIpackage\fR. +.TP +\fB\-t\fR, \fB\-\-list\-team\-members\fR +List all the members of every team with rights. (Implies +\fB\-\-list\-uploaders\fR) +.TP +\fB\-h\fR, \fB\-\-help\fR +Display a help message and exit + +.SH EXIT STATUS +.TP +.B 0 +You have the necessary upload rights. +.TP +.B 1 +You don't have the necessary upload rights. +.TP +.B 2 +There was an error. + +.SH AUTHORS +\fBupload\-permission\fR and this manpage were written by Stefano Rivera +. +.PP +Both are released under the terms of the ISC License. diff --git a/setup.py b/setup.py index 36dd05a..92d9c96 100755 --- a/setup.py +++ b/setup.py @@ -42,6 +42,7 @@ scripts = ['404main', 'ubuntu-build', 'ubuntu-iso', 'update-maintainer', + 'upload-permission', ] if __name__ == '__main__': From 0d2d356ddb7a18dbe7ddb58606566b11c025b58e Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sat, 3 Dec 2011 23:50:11 +0200 Subject: [PATCH 06/16] Break up main() --- upload-permission | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/upload-permission b/upload-permission index b48018b..2b1437c 100755 --- a/upload-permission +++ b/upload-permission @@ -17,12 +17,15 @@ import optparse import sys +from devscripts.logger import Logger + from ubuntutools.lp.lpapicache import (Launchpad, Distribution, PersonTeam, Packageset, SeriesNotFoundException) -def main(): +def parse_arguments(): + '''Parse arguments and return (options, package)''' parser = optparse.OptionParser('%prog [options] package') parser.add_option('-r', '--release', default=None, metavar='RELEASE', help='Use RELEASE, rather than the current development ' @@ -43,6 +46,12 @@ def main(): if options.list_team_members: options.list_uploaders = True + return (options, package) + + +def main(): + '''Query upload permissions''' + options, package = parse_arguments() # Need to be logged in to see uploaders: Launchpad.login() @@ -54,7 +63,8 @@ def main(): try: series = ubuntu.getSeries(options.release) except SeriesNotFoundException, e: - parser.error(str(e)) + Logger.error(str(e)) + sys.exit(2) spph = archive.getSourcePackage(package) component = spph.getComponent() From 58ee0de242533aa5fe9e7dc263fca12c86cb646e Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sat, 3 Dec 2011 23:51:24 +0200 Subject: [PATCH 07/16] Catch PackageNotFoundException --- upload-permission | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/upload-permission b/upload-permission index 2b1437c..47e6350 100755 --- a/upload-permission +++ b/upload-permission @@ -20,7 +20,7 @@ import sys from devscripts.logger import Logger from ubuntutools.lp.lpapicache import (Launchpad, Distribution, PersonTeam, - Packageset, + Packageset, PackageNotFoundException, SeriesNotFoundException) @@ -66,7 +66,11 @@ def main(): Logger.error(str(e)) sys.exit(2) - spph = archive.getSourcePackage(package) + try: + spph = archive.getSourcePackage(package) + except PackageNotFoundException, e: + Logger.error(str(e)) + sys.exit(2) component = spph.getComponent() if options.list_uploaders: component_uploader = archive.getUploadersForComponent( From d420a25b947ab9554d980d5fec852944b5792a6e Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 4 Dec 2011 00:08:08 +0200 Subject: [PATCH 08/16] Pocket awareness --- upload-permission | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/upload-permission b/upload-permission index 47e6350..0518572 100755 --- a/upload-permission +++ b/upload-permission @@ -22,6 +22,7 @@ from devscripts.logger import Logger from ubuntutools.lp.lpapicache import (Launchpad, Distribution, PersonTeam, Packageset, PackageNotFoundException, SeriesNotFoundException) +from ubuntutools.misc import split_release_pocket def parse_arguments(): @@ -59,9 +60,11 @@ def main(): archive = ubuntu.getArchive() if options.release is None: series = ubuntu.getDevelopmentSeries() + pocket = 'Release' else: try: - series = ubuntu.getSeries(options.release) + release, pocket = split_release_pocket(options.release) + series = ubuntu.getSeries(release) except SeriesNotFoundException, e: Logger.error(str(e)) sys.exit(2) @@ -104,15 +107,21 @@ def main(): print_uploaders(ppu_uploaders, options.list_team_members) print - if PersonTeam.me.canUploadPackage(archive, series, package, component): - print "You can upload this package." + if PersonTeam.me.canUploadPackage(archive, series, package, component, + pocket): + print "You can upload %s." % package else: - print "You can not upload this package, yourself." + print "You can not upload %s, yourself." % package print ("But you can still contribute to it via the sponsorship " "process: https://wiki.ubuntu.com/SponsorshipProcess") if not options.list_uploaders: print ("To see who has the necessary upload rights, " "use the --list-uploaders option.") + if (series.status in ('Current Stable Release', 'Supported', 'Obsolete') + and pocket == 'Release'): + print ("%s is in the '%s' state. " + "You may want to query the %s-proposed pocket." + % (release, series.status, release)) sys.exit(1) From 3a403daf6b0e4001c0cc09a5b5949c95367c3b99 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 4 Dec 2011 00:18:23 +0200 Subject: [PATCH 09/16] Tweak minimal output --- upload-permission | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/upload-permission b/upload-permission index 0518572..e29b3ec 100755 --- a/upload-permission +++ b/upload-permission @@ -109,19 +109,21 @@ def main(): if PersonTeam.me.canUploadPackage(archive, series, package, component, pocket): - print "You can upload %s." % package + print "You can upload %s to %s." % (package, options.release) else: - print "You can not upload %s, yourself." % package - print ("But you can still contribute to it via the sponsorship " - "process: https://wiki.ubuntu.com/SponsorshipProcess") - if not options.list_uploaders: - print ("To see who has the necessary upload rights, " - "use the --list-uploaders option.") + print ("You can not upload %s to %s, yourself." + % (package, options.release)) if (series.status in ('Current Stable Release', 'Supported', 'Obsolete') and pocket == 'Release'): print ("%s is in the '%s' state. " "You may want to query the %s-proposed pocket." % (release, series.status, release)) + else: + print ("But you can still contribute to it via the sponsorship " + "process: https://wiki.ubuntu.com/SponsorshipProcess") + if not options.list_uploaders: + print ("To see who has the necessary upload rights, " + "use the --list-uploaders option.") sys.exit(1) From dcef46eeea2af3cd6f8f59eb8b990ba750551cf2 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 4 Dec 2011 00:20:06 +0200 Subject: [PATCH 10/16] Don't list component upload rights for non-dev series --- upload-permission | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/upload-permission b/upload-permission index e29b3ec..437463b 100755 --- a/upload-permission +++ b/upload-permission @@ -76,13 +76,15 @@ def main(): sys.exit(2) component = spph.getComponent() if options.list_uploaders: - component_uploader = archive.getUploadersForComponent( - component_name=component)[0] - print "All upload permissions for %s:" % package - print - print "Component (%s)" % component - print "============" + ("=" * len(component)) - print_uploaders([component_uploader], options.list_team_members) + if series.status in ('Experimental', 'Active Development', + 'Pre-release Freeze'): + component_uploader = archive.getUploadersForComponent( + component_name=component)[0] + print "All upload permissions for %s:" % package + print + print "Component (%s)" % component + print "============" + ("=" * len(component)) + print_uploaders([component_uploader], options.list_team_members) packagesets = sorted(Packageset.setsIncludingSource( distroseries=series, From 25694bdfdda3e9f6fd9499ebef6ae96c3af03c51 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 4 Dec 2011 00:26:39 +0200 Subject: [PATCH 11/16] Don't list None as a release --- upload-permission | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/upload-permission b/upload-permission index 437463b..4e1c7e8 100755 --- a/upload-permission +++ b/upload-permission @@ -59,15 +59,13 @@ def main(): ubuntu = Distribution('ubuntu') archive = ubuntu.getArchive() if options.release is None: - series = ubuntu.getDevelopmentSeries() - pocket = 'Release' - else: - try: - release, pocket = split_release_pocket(options.release) - series = ubuntu.getSeries(release) - except SeriesNotFoundException, e: - Logger.error(str(e)) - sys.exit(2) + options.release = ubuntu.getDevelopmentSeries().name + try: + release, pocket = split_release_pocket(options.release) + series = ubuntu.getSeries(release) + except SeriesNotFoundException, e: + Logger.error(str(e)) + sys.exit(2) try: spph = archive.getSourcePackage(package) @@ -123,9 +121,9 @@ def main(): else: print ("But you can still contribute to it via the sponsorship " "process: https://wiki.ubuntu.com/SponsorshipProcess") - if not options.list_uploaders: - print ("To see who has the necessary upload rights, " - "use the --list-uploaders option.") + if not options.list_uploaders: + print ("To see who has the necessary upload rights, " + "use the --list-uploaders option.") sys.exit(1) From ff644a2ca1cb746c3b7c1620c0b057098a04b9bc Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 4 Dec 2011 00:26:59 +0200 Subject: [PATCH 12/16] Actually, skip all upload rights when the release is non-dev --- upload-permission | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/upload-permission b/upload-permission index 4e1c7e8..d27e363 100755 --- a/upload-permission +++ b/upload-permission @@ -73,16 +73,16 @@ def main(): Logger.error(str(e)) sys.exit(2) component = spph.getComponent() - if options.list_uploaders: - if series.status in ('Experimental', 'Active Development', - 'Pre-release Freeze'): - component_uploader = archive.getUploadersForComponent( - component_name=component)[0] - print "All upload permissions for %s:" % package - print - print "Component (%s)" % component - print "============" + ("=" * len(component)) - print_uploaders([component_uploader], options.list_team_members) + if (options.list_uploaders and series.status in + ('Experimental', 'Active Development', 'Pre-release Freeze')): + + component_uploader = archive.getUploadersForComponent( + component_name=component)[0] + print "All upload permissions for %s:" % package + print + print "Component (%s)" % component + print "============" + ("=" * len(component)) + print_uploaders([component_uploader], options.list_team_members) packagesets = sorted(Packageset.setsIncludingSource( distroseries=series, From 405a3c3327b6edbf40b180fe50806ab9f47d8760 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 4 Dec 2011 00:31:23 +0200 Subject: [PATCH 13/16] non-release pockets are ok for non-dev releases --- upload-permission | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/upload-permission b/upload-permission index d27e363..2df06bd 100755 --- a/upload-permission +++ b/upload-permission @@ -73,8 +73,8 @@ def main(): Logger.error(str(e)) sys.exit(2) component = spph.getComponent() - if (options.list_uploaders and series.status in - ('Experimental', 'Active Development', 'Pre-release Freeze')): + if (options.list_uploaders and (pocket != 'Release' or series.status in + ('Experimental', 'Active Development', 'Pre-release Freeze'))): component_uploader = archive.getUploadersForComponent( component_name=component)[0] From a22f4eebab9aabd9459a2d5041c1c6c21f73aacc Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 4 Dec 2011 00:35:49 +0200 Subject: [PATCH 14/16] Rename again --- debian/changelog | 2 +- debian/control | 4 +++- debian/copyright | 4 ++-- ...d-permission.1 => ubuntu-upload-permission.1} | 16 ++++++++-------- setup.py | 2 +- upload-permission => ubuntu-upload-permission | 0 6 files changed, 15 insertions(+), 13 deletions(-) rename doc/{upload-permission.1 => ubuntu-upload-permission.1} (78%) rename upload-permission => ubuntu-upload-permission (100%) diff --git a/debian/changelog b/debian/changelog index d4d8f1d..cf07842 100644 --- a/debian/changelog +++ b/debian/changelog @@ -18,7 +18,7 @@ ubuntu-dev-tools (0.137) UNRELEASED; urgency=low * mk-sbuild, pbuilder-dist, ubuntu-build: Add armhf. * pull-debian-source, pull-lp-source: Resolve the source package (via DDE), if a binary package was requested (LP: #617349) - * New Tool: upload-permission: Query upload permissions (LP: #876554) + * New Tool: ubuntu-upload-permission: Query upload permissions (LP: #876554) [ Andreas Moog ] * sponsor-patch: Check permission to unsubscribe sponsors-team (LP: #896884) diff --git a/debian/control b/debian/control index 19cec22..b70af40 100644 --- a/debian/control +++ b/debian/control @@ -106,4 +106,6 @@ Description: useful tools for Ubuntu developers command line. - ubuntu-iso - output information of an Ubuntu ISO image. - update-maintainer - script to update maintainer field in ubuntu packages. - - upload-permission - query / list the upload permissions for a package. + - ubuntu-upload-permission - query / list the upload permissions for a + package. + - update-maintainer - Set the Ubuntu-policy Maintainer in debian/control. diff --git a/debian/copyright b/debian/copyright index 5933bf2..67276b4 100644 --- a/debian/copyright +++ b/debian/copyright @@ -150,14 +150,15 @@ Files: doc/pull-debian-debdiff.1 doc/reverse-depends.1 doc/sponsor-patch.1 doc/ubuntu-dev-tools.5 + doc/ubuntu-upload-permission.1 doc/update-maintainer.1 - doc/upload-permission.1 pull-debian-debdiff pull-debian-source requestbackport reverse-depends sponsor-patch test-data/* + ubuntu-upload-permission ubuntutools/archive.py ubuntutools/builder.py ubuntutools/config.py @@ -167,7 +168,6 @@ Files: doc/pull-debian-debdiff.1 ubuntutools/test/* ubuntutools/update_maintainer.py update-maintainer - upload-permission Copyright: 2009-2011, Benjamin Drung 2010, Evan Broder 2008, Siegfried-Angel Gevatter Pujals diff --git a/doc/upload-permission.1 b/doc/ubuntu-upload-permission.1 similarity index 78% rename from doc/upload-permission.1 rename to doc/ubuntu-upload-permission.1 index 742b95d..4d97b03 100644 --- a/doc/upload-permission.1 +++ b/doc/ubuntu-upload-permission.1 @@ -11,18 +11,18 @@ .\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR .\" OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR .\" PERFORMANCE OF THIS SOFTWARE. -.TH upload\-permission 1 "November 2011" ubuntu\-dev\-tools +.TH ubuntu\-upload\-permission 1 "November 2011" ubuntu\-dev\-tools .SH NAME -upload\-permission \- Query upload rights and (optionally) list the -people and teams with upload rights for a package +ubuntu\-upload\-permission \- Query upload rights and (optionally) list +the people and teams with upload rights for a package .SH SYNOPSIS -.B upload\-permission \fR[\fIoptions\fR] \fIpackage +.B ubuntu\-upload\-permission \fR[\fIoptions\fR] \fIpackage .SH DESCRIPTION -\fBupload\-permission\fR checks if the user has upload permissions for -\fIpackage\fR. +\fBubuntu\-upload\-permission\fR checks if the user has upload +permissions for \fIpackage\fR. If the \fB\-\-list\-uploaders\fR option is provided, all the people and teams that do have upload rights for \fIpackage\fR will be listed. @@ -54,7 +54,7 @@ You don't have the necessary upload rights. There was an error. .SH AUTHORS -\fBupload\-permission\fR and this manpage were written by Stefano Rivera -. +\fBubuntu\-upload\-permission\fR and this manpage were written by +Stefano Rivera . .PP Both are released under the terms of the ISC License. diff --git a/setup.py b/setup.py index 92d9c96..2efa54f 100755 --- a/setup.py +++ b/setup.py @@ -41,8 +41,8 @@ scripts = ['404main', 'syncpackage', 'ubuntu-build', 'ubuntu-iso', + 'ubuntu-upload-permission', 'update-maintainer', - 'upload-permission', ] if __name__ == '__main__': diff --git a/upload-permission b/ubuntu-upload-permission similarity index 100% rename from upload-permission rename to ubuntu-upload-permission From 973e1b51c127e3ac67a2f7db880b930820acb265 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 4 Dec 2011 00:42:09 +0200 Subject: [PATCH 15/16] Missed update-maintainer --- debian/control | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/debian/control b/debian/control index b70af40..0cfbe5b 100644 --- a/debian/control +++ b/debian/control @@ -105,7 +105,6 @@ Description: useful tools for Ubuntu developers - ubuntu-build - give commands to the Launchpad build daemons from the command line. - ubuntu-iso - output information of an Ubuntu ISO image. - - update-maintainer - script to update maintainer field in ubuntu packages. - ubuntu-upload-permission - query / list the upload permissions for a package. - - update-maintainer - Set the Ubuntu-policy Maintainer in debian/control. + - update-maintainer - script to update maintainer field in ubuntu packages. From 2da0560c686e4330c411917c9cd193426a703f0e Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 4 Dec 2011 00:45:26 +0200 Subject: [PATCH 16/16] Mention backportpackage in debian/control --- debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/control b/debian/control index 0cfbe5b..7255fb1 100644 --- a/debian/control +++ b/debian/control @@ -68,6 +68,7 @@ Description: useful tools for Ubuntu developers . - 404main - used to check what components a package's deps are in, for doing a main inclusion report for example. + - backportpackage - helper to test package backports - bitesize - add the 'bitesize' tag to a bug and comment that you are willing to help fix it. - check-mir - check support status of build/binary dependencies