mirror of
https://git.launchpad.net/ubuntu-dev-tools
synced 2025-03-13 08:01:09 +00:00
Merge branch 'megamerge_request' of git+ssh://git.launchpad.net/~ddstreet/ubuntu-dev-tools/+git/ubuntu-dev-tools
MR: https://code.launchpad.net/~ddstreet/ubuntu-dev-tools/+git/ubuntu-dev-tools/+merge/375292 Signed-off-by: Mattia Rizzolo <mattia@debian.org>
This commit is contained in:
commit
87f226258a
@ -36,11 +36,13 @@ from ubuntutools.builder import get_builder
|
||||
from ubuntutools.lp.lpapicache import (Launchpad, Distribution,
|
||||
SeriesNotFoundException,
|
||||
PackageNotFoundException)
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.misc import (system_distribution, vendor_to_distroinfo,
|
||||
codename_to_distribution)
|
||||
from ubuntutools.question import YesNoQuestion
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
def error(msg):
|
||||
Logger.error(msg)
|
||||
@ -48,7 +50,7 @@ def error(msg):
|
||||
|
||||
|
||||
def check_call(cmd, *args, **kwargs):
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
ret = subprocess.call(cmd, *args, **kwargs)
|
||||
if ret != 0:
|
||||
error('%s returned %d.' % (cmd[0], ret))
|
||||
@ -302,7 +304,7 @@ def orig_needed(upload, workdir, pkg):
|
||||
not headers['content-location'].startswith('https://launchpadlibrarian.net')):
|
||||
return True
|
||||
except HttpLib2Error as e:
|
||||
Logger.info(e)
|
||||
Logger.debug(e)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
4
bitesize
4
bitesize
@ -28,7 +28,9 @@ from launchpadlib.launchpad import Launchpad
|
||||
from launchpadlib.errors import HTTPError
|
||||
|
||||
from ubuntutools.config import UDTConfig
|
||||
from ubuntutools.logger import Logger
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
def error_out(msg):
|
||||
|
5
debian/changelog
vendored
5
debian/changelog
vendored
@ -12,6 +12,11 @@ ubuntu-dev-tools (0.175) UNRELEASED; urgency=medium
|
||||
[ Dan Streetman ]
|
||||
* tests/pylint.conf: use jobs=0 to speed up tests.
|
||||
* submittodebian: use a context manager while opening a file.
|
||||
* d/control: add dependency on python3-lazr.restfulclient.
|
||||
* Big refactor/rewrite of the whole archive.py module, together with a
|
||||
restracturing of all the pull-pkg-* commands.
|
||||
* Unify the logging using the standard python logging module, and remove the
|
||||
local ubuntutools.logger module.
|
||||
|
||||
-- Mattia Rizzolo <mattia@debian.org> Mon, 28 Oct 2019 14:32:20 +0100
|
||||
|
||||
|
9
debian/control
vendored
9
debian/control
vendored
@ -104,7 +104,13 @@ Description: useful tools for Ubuntu developers
|
||||
a Debian package and its immediate parent to generate a debdiff.
|
||||
- pull-debian-source - downloads the latest source package available in
|
||||
Debian of a package.
|
||||
- pull-lp-source - downloads latest source package from Launchpad.
|
||||
- pull-lp-source - downloads source package from Launchpad.
|
||||
- pull-lp-debs - downloads debs package(s) from Launchpad.
|
||||
- pull-lp-ddebs - downloads dbgsym/ddebs package(s) from Launchpad.
|
||||
- pull-lp-udebs - downloads udebs package(s) from Launchpad.
|
||||
- pull-debian-* - same as pull-lp-* but for Debian packages.
|
||||
- pull-uca-* - same as pull-lp-* but for Ubuntu Cloud Archive packages.
|
||||
- pull-pkg - common script that provides above pull-* functionality.
|
||||
- pull-revu-source - downloads the latest source package from REVU
|
||||
- requestbackport - file a backporting request.
|
||||
- requestsync - files a sync request with Debian changelog and rationale.
|
||||
@ -132,6 +138,7 @@ Depends:
|
||||
python3-distro-info,
|
||||
python3-httplib2,
|
||||
python3-launchpadlib,
|
||||
python3-lazr.restfulclient,
|
||||
sensible-utils,
|
||||
${misc:Depends},
|
||||
${python3:Depends},
|
||||
|
1
doc/pull-debian-ddebs.1
Symbolic link
1
doc/pull-debian-ddebs.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
1
doc/pull-debian-debs.1
Symbolic link
1
doc/pull-debian-debs.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
@ -1,89 +0,0 @@
|
||||
.\" Copyright (C) 2010-2011, Stefano Rivera <stefanor@ubuntu.com>
|
||||
.\"
|
||||
.\" 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 PULL\-DEBIAN\-SOURCE "1" "22 January 2011" "ubuntu\-dev\-tools"
|
||||
|
||||
.SH NAME
|
||||
pull\-debian\-source \- download and extract a source package from Debian
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B pull\-debian\-source \fR[\fIoptions\fR] <\fIsource package\fR>
|
||||
[\fIrelease\fR|\fIversion\fR]
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBpull\-debian\-source\fR downloads and extracts the specified
|
||||
\fIversion\fR of \fIsource package\fR, or the latest version in the
|
||||
specified Debian \fIrelease\fR.
|
||||
.P
|
||||
\fBpull\-debian\-source\fR will try the preferred mirror, default
|
||||
mirror, security mirror, and fall back to \fBLaunchpad\fR or
|
||||
\fBsnapshot.debian.org\fR, in search of the requested version.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.I source package
|
||||
The source package to download from Debian.
|
||||
.TP
|
||||
.I release
|
||||
The release to download the source package from. Defaults to
|
||||
\fBunstable\fR.
|
||||
.TP
|
||||
.I version
|
||||
The specific version of the package to download.
|
||||
.TP
|
||||
.BR \-d ", " \-\-download\-only
|
||||
Do not extract the source package.
|
||||
.TP
|
||||
.B \-m \fIDEBIAN_MIRROR\fR, \fB\-\-mirror\fR=\fIDEBIAN_MIRROR\fR
|
||||
Use the specified mirror.
|
||||
Should be in the form \fBhttp://ftp.debian.org/debian\fR.
|
||||
If the package isn't found on this mirror, \fBpull\-debian\-source\fR
|
||||
will fall back to the default mirror.
|
||||
.TP
|
||||
.B \-s \fIDEBSEC_MIRROR\fR, \fB\-\-security\-mirror\fR=\fIDEBSEC_MIRROR\fR
|
||||
Use the specified mirror.
|
||||
Should be in the form \fBhttp://security.debian.org\fR.
|
||||
If the package isn't found on this mirror, \fBpull\-debian\-source\fR
|
||||
will fall back to the default mirror.
|
||||
.TP
|
||||
.B \-\-no\-conf
|
||||
Do not read any configuration files, or configuration from environment
|
||||
variables.
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Display the usage instructions and exit.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
All of the \fBCONFIGURATION VARIABLES\fR below are also supported as
|
||||
environment variables.
|
||||
Variables in the environment take precedence to those in configuration
|
||||
files.
|
||||
|
||||
.SH CONFIGURATION VARIABLES
|
||||
The following variables can be set in the environment or in
|
||||
.BR ubuntu\-dev\-tools (5)
|
||||
configuration files.
|
||||
In each case, the script\-specific variable takes precedence over the
|
||||
package\-wide variable.
|
||||
.TP
|
||||
.BR PULL_DEBIAN_SOURCE_DEBIAN_MIRROR ", " UBUNTUTOOLS_DEBIAN_MIRROR
|
||||
The default value for \fB\-\-mirror\fR.
|
||||
.TP
|
||||
.BR PULL_DEBIAN_SOURCE_DEBSEC_MIRROR ", " UBUNTUTOOLS_DEBSEC_MIRROR
|
||||
The default value for \fB\-\-security\-mirror\fR.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR dget (1),
|
||||
.BR pull\-debian\-debdiff (1),
|
||||
.BR pull\-lp\-source (1),
|
||||
.BR ubuntu\-dev\-tools (5)
|
1
doc/pull-debian-source.1
Symbolic link
1
doc/pull-debian-source.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
1
doc/pull-debian-udebs.1
Symbolic link
1
doc/pull-debian-udebs.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
1
doc/pull-lp-ddebs.1
Symbolic link
1
doc/pull-lp-ddebs.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
1
doc/pull-lp-debs.1
Symbolic link
1
doc/pull-lp-debs.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
@ -1,79 +0,0 @@
|
||||
.TH PULL\-LP\-SOURCE "1" "4 August 2008" "ubuntu-dev-tools"
|
||||
|
||||
.SH NAME
|
||||
pull\-lp\-source \- download a source package from Launchpad
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B pull\-lp\-source \fR[\fIoptions\fR]\fB \fBsource package\fR
|
||||
[\fIrelease\fR|\fIversion\fR]
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBpull\-lp\-source\fR downloads and extracts the specified
|
||||
\fIversion\fR of <\fBsource package\fR> from Launchpad, or the latest
|
||||
version of the specified \fIrelease\fR.
|
||||
To request a version from a particular pocket say
|
||||
\fIrelease\fB\-\fIpocket\fR (with a magic \fB\-release\fR for only the
|
||||
release pocket).
|
||||
If no \fIversion\fR or \fIrelease\fR is specified, the latest version in
|
||||
the development release will be downloaded.
|
||||
|
||||
.SH OPTIONS
|
||||
Listed below are the command line options for pull\-lp\-source:
|
||||
.TP
|
||||
.B source package
|
||||
This is the source package that you would like to be downloaded from Launchpad.
|
||||
.TP
|
||||
.B version
|
||||
This is the version of the source package to be downloaded.
|
||||
.TP
|
||||
.B release
|
||||
This is the release that you would like the source package to be downloaded from.
|
||||
This value defaults to the current development release.
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Display a help message and exit.
|
||||
.TP
|
||||
.BR \-d ", " \-\-download\-only
|
||||
Do not extract the source package.
|
||||
.TP
|
||||
.B \-m \fIUBUNTU_MIRROR\fR, \fB\-\-mirror\fR=\fIUBUNTU_MIRROR\fR
|
||||
Use the specified Ubuntu mirror.
|
||||
Should be in the form \fBhttp://archive.ubuntu.com/ubuntu\fR.
|
||||
If the package isn't found on this mirror, \fBpull\-lp\-source\fR will
|
||||
fall back to Launchpad, as its name implies.
|
||||
.TP
|
||||
.B \-\-no\-conf
|
||||
Do not read any configuration files, or configuration from environment
|
||||
variables.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
All of the \fBCONFIGURATION VARIABLES\fR below are also supported as
|
||||
environment variables.
|
||||
Variables in the environment take precedence to those in configuration
|
||||
files.
|
||||
.TP
|
||||
.B
|
||||
DIST
|
||||
Specifies the default target.
|
||||
|
||||
.SH CONFIGURATION VARIABLES
|
||||
The following variables can be set in the environment or in
|
||||
.BR ubuntu\-dev\-tools (5)
|
||||
configuration files.
|
||||
In each case, the script\-specific variable takes precedence over the
|
||||
package\-wide variable.
|
||||
.TP
|
||||
.BR PULL_LP_SOURCE_UBUNTU_MIRROR ", " UBUNTUTOOLS_UBUNTU_MIRROR
|
||||
The default value for \fB\-\-mirror\fR.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR dget (1),
|
||||
.BR pull\-debian\-source (1),
|
||||
.BR pull\-debian\-debdiff (1),
|
||||
.BR ubuntu\-dev\-tools (5)
|
||||
|
||||
.SH AUTHOR
|
||||
.PP
|
||||
\fBpull\-lp\-source\fR and this manual page were written by Iain Lane
|
||||
<iain@orangesquash.org.uk>.
|
||||
Both are released under the GNU General Public License, version 3 or later.
|
1
doc/pull-lp-source.1
Symbolic link
1
doc/pull-lp-source.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
1
doc/pull-lp-udebs.1
Symbolic link
1
doc/pull-lp-udebs.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
146
doc/pull-pkg.1
Normal file
146
doc/pull-pkg.1
Normal file
@ -0,0 +1,146 @@
|
||||
.TH PULL\-PKG "1" "28 August 2017" "ubuntu-dev-tools"
|
||||
|
||||
.SH NAME
|
||||
pull\-pkg \- download a package for Debian, Ubuntu, UCA, or a PPA
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B pull\-pkg \fR[\fIoptions\fR]\fR <\fIpackage name\fR>
|
||||
[\fIrelease\fR|\fIversion\fR]
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBpull\-pkg\fR downloads the specified \fIversion\fR of
|
||||
<\fIpackage name\fR>, or the latest version from the
|
||||
specified \fIrelease\fR. To request a version from
|
||||
a particular pocket say \fIrelease\fB\-\fIpocket\fR (with a magic
|
||||
\fB\-release\fR for only the release pocket).
|
||||
If no \fIversion\fR or \fIrelease\fR is specified, the latest version in
|
||||
the development release will be downloaded.
|
||||
|
||||
There are convenience scripts that set pull type and distribution
|
||||
appropriately: these are
|
||||
\fBpull\-lp\-source\fR, \fBpull\-lp\-debs\fR, \fBpull\-lp\-ddebs\fR,
|
||||
and \fBpull\-lp\-udebs\fR, which all pull Ubuntu packages;
|
||||
\fBpull\-debian\-source\fR, \fBpull\-debian\-debs\fR, \fBpull\-debian\-ddebs\fR,
|
||||
and \fBpull\-debian\-udebs\fR, which all pull Debian packages;
|
||||
\fBpull\-uca\-source\fR, \fBpull\-uca\-debs\fR, \fBpull\-uca\-ddebs\fR,
|
||||
and \fBpull\-uca\-udebs\fR, which all pull Ubuntu Cloud Archive packages;
|
||||
and \fBpull\-ppa\-source\fR, \fBpull\-ppa\-debs\fR, \fBpull\-ppa\-ddebs\fR,
|
||||
and \fBpull\-ppa\-udebs\fR, which all pull from a specified Personal Package
|
||||
Archive on Launchpad. Each script pulls the file type in its name, i.e.
|
||||
\fIsource\fR, \fIdebs\fR, \fIddebs\fR, or \fIudebs\fR.
|
||||
|
||||
.SH OPTIONS
|
||||
Listed below are the command line options for pull\-pkg:
|
||||
.TP
|
||||
.I package name
|
||||
This is name of the package to downloaded.
|
||||
You can use either the source package name, or binary package name.
|
||||
.TP
|
||||
.I version
|
||||
This is the version of the package to downloaded.
|
||||
.TP
|
||||
.I release
|
||||
This is the release to downloaded from.
|
||||
For debian, you can use either the release name like \fBjessie\fR
|
||||
or \fBsid\fR, or you can use the special release names \fBunstable\fR,
|
||||
\fBstable\fR, or \fBtesting\fR.
|
||||
For ubuntu, you can use either the release name like \fBxenial\fR
|
||||
or the release-pocket like \fBxenial-proposed\fR.
|
||||
For ubuntu cloud archive (uca) you can use either the uca release
|
||||
name like \fBmitaka\fR or the ubuntu and uca release names like
|
||||
\fBtrusty-mitaka\fR. Defaults to the current development release.
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Display a help message and exit.
|
||||
.TP
|
||||
.BR \-v ", " \-\-verbose
|
||||
Be verbose about what is being done.
|
||||
.TP
|
||||
.BR \-d ", " \-\-download\-only
|
||||
Do not extract the source package (applies only to source packages).
|
||||
.TP
|
||||
.B \-m \fIMIRROR\fR, \fB\-\-mirror\fR=\fIMIRROR\fR
|
||||
Use the specified mirror server.
|
||||
Should be in the form \fBhttp://archive.ubuntu.com/ubuntu\fR or
|
||||
\fBhttp://deb.debian.org/debian\fR. If not specified or if the
|
||||
package is not found on the specified mirror, this will fall
|
||||
back to the default mirror(s) and/or mirror(s) from environment
|
||||
variables, and then will fall back to Launchpad or Debian Snapshot.
|
||||
This can be specified multiple times to try multiple mirrors.
|
||||
.TP
|
||||
.B \-\-no\-conf
|
||||
Do not use mirrors from the default configuration, or from
|
||||
any environment variables.
|
||||
.TP
|
||||
.B \-a \fIARCH\fR, \fB\-\-arch\fR=\fIARCH\fR
|
||||
Get binary packages from the \fIARCH\fR architecture.
|
||||
Defaults to the local architecture, if it can be deteected.
|
||||
.TP
|
||||
.B \-p \fIPULL\fR, \fB\-\-pull\fR=\fIPULL\fR
|
||||
What to pull: \fBsource\fR, \fBdebs\fR, \fBddebs\fR, \fBudebs\fR,
|
||||
or \fBlist\fR. The \fBlist\fR action only lists all a package's
|
||||
source and binary files, but does not actually download any.
|
||||
Defaults to \fBsource\fR.
|
||||
.TP
|
||||
.B \-D \fIDISTRO\fR, \fB\-\-distro\fR=\fIDISTRO\fR
|
||||
Pull from: \fBdebian\fR, \fBuca\fR, \fBubuntu\fR, or a \fBppa\fR.
|
||||
\fBlp\fR can be used instead of \fBubuntu\fR.
|
||||
Any string containing \fBcloud\fR can be used instead of \fBuca\fR.
|
||||
If pulling from a ppa, you must specify the PPA. Deafults to \fBubuntu\fR.
|
||||
.TP
|
||||
.B \-\-ppa\fR=ppa:\fIUSER/NAME\fR
|
||||
Applies only when \fBdistro\fR is \fIppa\fR. Can be provided either as
|
||||
a value to the \fB\-\-ppa\fR option parameter, or as a plain option
|
||||
(like \fIrelease\fR or \fIversion\fR). When specified as a plain option,
|
||||
the form must be \fBppa:USER/NAME\fR; when specified as a value to the
|
||||
\fB\-\-ppa\fR option parameter, the leading \fBppa:\fR is optional.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
All of the \fBCONFIGURATION VARIABLES\fR below are also supported as
|
||||
environment variables.
|
||||
Variables in the environment take precedence to those in configuration
|
||||
files.
|
||||
|
||||
.SH CONFIGURATION VARIABLES
|
||||
The following variables can be set in the environment or in
|
||||
.BR ubuntu\-dev\-tools (5)
|
||||
configuration files.
|
||||
In each case, the script\-specific variable takes precedence over the
|
||||
package\-wide variable.
|
||||
.TP
|
||||
.BR UBUNTUTOOLS_UBUNTU_MIRROR
|
||||
The default mirror.
|
||||
.TP
|
||||
.BR PULL_PKG_UBUNTU_MIRROR
|
||||
The default mirror when using the \fBpull\-pkg\fR script.
|
||||
.TP
|
||||
.BR PULL_[LP|DEBIAN|PPA|UCA]_[SOURCE|DEBS|DDEBS|UDEBS]_MIRROR
|
||||
The default mirror when using the associated script.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR dget (1),
|
||||
.BR pull\-lp\-source (1),
|
||||
.BR pull\-lp\-debs (1),
|
||||
.BR pull\-lp\-ddebs (1),
|
||||
.BR pull\-lp\-udebs (1),
|
||||
.BR pull\-debian\-source (1),
|
||||
.BR pull\-debian\-debs (1),
|
||||
.BR pull\-debian\-ddebs (1),
|
||||
.BR pull\-debian\-udebs (1),
|
||||
.BR pull\-ppa\-source (1),
|
||||
.BR pull\-ppa\-debs (1),
|
||||
.BR pull\-ppa\-ddebs (1),
|
||||
.BR pull\-ppa\-udebs (1),
|
||||
.BR pull\-uca\-source (1),
|
||||
.BR pull\-uca\-debs (1),
|
||||
.BR pull\-uca\-ddebs (1),
|
||||
.BR pull\-uca\-udebs (1),
|
||||
.BR pull\-debian\-debdiff (1),
|
||||
.BR ubuntu\-dev\-tools (5)
|
||||
|
||||
.SH AUTHOR
|
||||
.PP
|
||||
\fBpull\-pkg\fR was written by Dan Streetman <ddstreet@canonical.com>,
|
||||
based on the original \fBpull\-lp\-source\fR; it and this manual page
|
||||
were written by Iain Lane <iain@orangesquash.org.uk>.
|
||||
All are released under the GNU General Public License, version 3 or later.
|
1
doc/pull-ppa-ddebs.1
Symbolic link
1
doc/pull-ppa-ddebs.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
1
doc/pull-ppa-debs.1
Symbolic link
1
doc/pull-ppa-debs.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
1
doc/pull-ppa-source.1
Symbolic link
1
doc/pull-ppa-source.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
1
doc/pull-ppa-udebs.1
Symbolic link
1
doc/pull-ppa-udebs.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
1
doc/pull-uca-ddebs.1
Symbolic link
1
doc/pull-uca-ddebs.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
1
doc/pull-uca-debs.1
Symbolic link
1
doc/pull-uca-debs.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
1
doc/pull-uca-source.1
Symbolic link
1
doc/pull-uca-source.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
1
doc/pull-uca-udebs.1
Symbolic link
1
doc/pull-uca-udebs.1
Symbolic link
@ -0,0 +1 @@
|
||||
pull-pkg.1
|
11
grep-merges
11
grep-merges
@ -27,6 +27,9 @@ from httplib2 import Http, HttpLib2Error
|
||||
|
||||
import ubuntutools.misc
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
def main():
|
||||
parser = optparse.OptionParser(
|
||||
@ -52,11 +55,11 @@ def main():
|
||||
try:
|
||||
headers, page = Http().request(url)
|
||||
except HttpLib2Error as e:
|
||||
print(str(e), file=sys.stderr)
|
||||
Logger.exception(e)
|
||||
sys.exit(1)
|
||||
if headers.status != 200:
|
||||
print("%s: %s %s" % (url, headers.status, headers.reason),
|
||||
file=sys.stderr)
|
||||
Logger.error("%s: %s %s" % (url, headers.status,
|
||||
headers.reason))
|
||||
sys.exit(1)
|
||||
|
||||
for merge in json.loads(page):
|
||||
@ -71,7 +74,7 @@ def main():
|
||||
pretty_uploader = '{} {}'.format(author, uploader)
|
||||
if (match is None or match in package or match in author
|
||||
or match in uploader or match in teams):
|
||||
print('%s\t%s' % (package, pretty_uploader))
|
||||
Logger.info('%s\t%s' % (package, pretty_uploader))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
25
hugdaylist
25
hugdaylist
@ -36,6 +36,9 @@ from launchpadlib.launchpad import Launchpad
|
||||
|
||||
from ubuntutools.lp.libsupport import translate_web_api
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
def check_args():
|
||||
howmany = -1
|
||||
@ -57,8 +60,7 @@ def check_args():
|
||||
|
||||
# Check that we have an URL.
|
||||
if not args:
|
||||
print("An URL pointing to a Launchpad bug list is required.",
|
||||
file=sys.stderr)
|
||||
Logger.error("An URL pointing to a Launchpad bug list is required.")
|
||||
opt_parser.print_help()
|
||||
sys.exit(1)
|
||||
else:
|
||||
@ -87,15 +89,14 @@ def main():
|
||||
if len(url.split("?", 1)) == 2:
|
||||
# search options not supported, because there is no mapping web ui
|
||||
# options <-> API options
|
||||
print("Options in url are not supported, url: %s" % url,
|
||||
file=sys.stderr)
|
||||
Logger.error("Options in url are not supported, url: %s" % url)
|
||||
sys.exit(1)
|
||||
|
||||
launchpad = None
|
||||
try:
|
||||
launchpad = Launchpad.login_with("ubuntu-dev-tools", 'production')
|
||||
except IOError as error:
|
||||
print(error)
|
||||
Logger.exception(error)
|
||||
sys.exit(1)
|
||||
|
||||
api_url = translate_web_api(url, launchpad)
|
||||
@ -104,8 +105,8 @@ def main():
|
||||
except Exception as error:
|
||||
response = getattr(error, "response", {})
|
||||
if response.get("status", None) == "404":
|
||||
print(("The URL at '%s' does not appear to be a valid url to a "
|
||||
"product") % url, file=sys.stderr)
|
||||
Logger.error("The URL at '%s' does not appear to be a "
|
||||
"valid url to a product" % url)
|
||||
sys.exit(1)
|
||||
else:
|
||||
raise
|
||||
@ -113,12 +114,12 @@ def main():
|
||||
bug_list = [b for b in product.searchTasks() if filter_unsolved(b)]
|
||||
|
||||
if not bug_list:
|
||||
print("Bug list of %s is empty." % url)
|
||||
Logger.info("Bug list of %s is empty." % url)
|
||||
sys.exit(0)
|
||||
if howmany == -1:
|
||||
howmany = len(bug_list)
|
||||
|
||||
print("""
|
||||
Logger.info("""
|
||||
## ||<rowbgcolor="#CCFFCC"> This task is done || somebody || ||
|
||||
## ||<rowbgcolor="#FFFFCC"> This task is assigned || somebody || <status> ||
|
||||
## ||<rowbgcolor="#FFEBBB"> This task isn't || ... || ||
|
||||
@ -128,13 +129,13 @@ def main():
|
||||
|
||||
for i in list(bug_list)[:howmany]:
|
||||
bug = i.bug
|
||||
print('||<rowbgcolor="#FFEBBB"> [%s %s] || %s || ||'
|
||||
% (bug.web_link, bug.id, bug.title))
|
||||
Logger.info('||<rowbgcolor="#FFEBBB"> [%s %s] || %s || ||' %
|
||||
(bug.web_link, bug.id, bug.title))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print("Aborted.", file=sys.stderr)
|
||||
Logger.error("Aborted.")
|
||||
sys.exit(1)
|
||||
|
@ -30,7 +30,9 @@ import webbrowser
|
||||
from launchpadlib.launchpad import Launchpad
|
||||
|
||||
from ubuntutools.config import UDTConfig
|
||||
from ubuntutools.logger import Logger
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
try:
|
||||
import debianbts
|
||||
@ -134,7 +136,7 @@ def main():
|
||||
d_watch = u_bug.addWatch(remote_bug=bug_num, bug_tracker=lp_debbugs)
|
||||
d_task.bug_watch = d_watch
|
||||
d_task.lp_save()
|
||||
Logger.normal("Opened %s", u_bug.web_link)
|
||||
Logger.info("Opened %s", u_bug.web_link)
|
||||
if not options.browserless:
|
||||
webbrowser.open(u_bug.web_link)
|
||||
|
||||
|
@ -22,9 +22,12 @@ import sys
|
||||
|
||||
from debian.changelog import Changelog
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
def usage(exit_code=1):
|
||||
print('''Usage: merge-changelog <left changelog> <right changelog>
|
||||
Logger.info('''Usage: merge-changelog <left changelog> <right changelog>
|
||||
|
||||
merge-changelog takes two changelogs that once shared a common source,
|
||||
merges them back together, and prints the merged result to stdout. This
|
||||
@ -61,7 +64,7 @@ def merge_changelog(left_changelog, right_changelog):
|
||||
|
||||
assert block.version == version
|
||||
|
||||
print(str(block).strip(), end='\n\n')
|
||||
Logger.info(str(block).strip() + '\n\n')
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -39,9 +39,11 @@ from distro_info import DebianDistroInfo, UbuntuDistroInfo, DistroDataOutdated
|
||||
import ubuntutools.misc
|
||||
import ubuntutools.version
|
||||
from ubuntutools.config import UDTConfig
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.question import YesNoQuestion
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
class PbuilderDist(object):
|
||||
def __init__(self, builder):
|
||||
@ -103,9 +105,10 @@ class PbuilderDist(object):
|
||||
'~/pbuilder/'))
|
||||
|
||||
if 'SUDO_USER' in os.environ:
|
||||
Logger.warn('Running under sudo. '
|
||||
'This is probably not what you want. '
|
||||
'pbuilder-dist will use sudo itself, when necessary.')
|
||||
Logger.warning('Running under sudo. '
|
||||
'This is probably not what you want. '
|
||||
'pbuilder-dist will use sudo itself, '
|
||||
'when necessary.')
|
||||
if os.stat(os.environ['HOME']).st_uid != os.getuid():
|
||||
Logger.error("You don't own $HOME")
|
||||
sys.exit(1)
|
||||
@ -280,7 +283,7 @@ class PbuilderDist(object):
|
||||
codename = debian_info.codename(self.target_distro,
|
||||
default=self.target_distro)
|
||||
except DistroDataOutdated as error:
|
||||
Logger.warn(error)
|
||||
Logger.warning(error)
|
||||
if codename in (debian_info.devel(), 'experimental'):
|
||||
self.enable_security = False
|
||||
self.enable_updates = False
|
||||
@ -307,7 +310,7 @@ class PbuilderDist(object):
|
||||
try:
|
||||
dev_release = self.target_distro == UbuntuDistroInfo().devel()
|
||||
except DistroDataOutdated as error:
|
||||
Logger.warn(error)
|
||||
Logger.warning(error)
|
||||
dev_release = True
|
||||
|
||||
if dev_release:
|
||||
@ -396,7 +399,7 @@ def show_help(exit_code=0):
|
||||
|
||||
Print a help message for pbuilder-dist, and exit with the given code.
|
||||
"""
|
||||
print('See man pbuilder-dist for more information.')
|
||||
Logger.info('See man pbuilder-dist for more information.')
|
||||
|
||||
sys.exit(exit_code)
|
||||
|
||||
@ -498,7 +501,7 @@ def main():
|
||||
if '--debug-echo' not in args:
|
||||
sys.exit(subprocess.call(app.get_command(args)))
|
||||
else:
|
||||
print(app.get_command([arg for arg in args if arg != '--debug-echo']))
|
||||
Logger.info(app.get_command([arg for arg in args if arg != '--debug-echo']))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
11
pull-debian-ddebs
Executable file
11
pull-debian-ddebs
Executable file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-debian-ddebs -- pull ddeb package files for debian
|
||||
# Basic usage: pull-debian-ddebs <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='debian', pull='ddebs')
|
@ -24,9 +24,11 @@ import debian.changelog
|
||||
|
||||
from ubuntutools.archive import DebianSourcePackage, DownloadError
|
||||
from ubuntutools.config import UDTConfig
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.version import Version
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
def previous_version(package, version, distance):
|
||||
"Given an (extracted) package, determine the version distance versions ago"
|
||||
@ -79,7 +81,7 @@ def main():
|
||||
opts.debsec_mirror = config.get_value('DEBSEC_MIRROR')
|
||||
mirrors = [opts.debsec_mirror, opts.debian_mirror]
|
||||
|
||||
Logger.normal('Downloading %s %s', package, version)
|
||||
Logger.info('Downloading %s %s', package, version)
|
||||
|
||||
newpkg = DebianSourcePackage(package, version, mirrors=mirrors)
|
||||
try:
|
||||
@ -96,7 +98,7 @@ def main():
|
||||
if not oldversion:
|
||||
Logger.error('No previous version could be found')
|
||||
sys.exit(1)
|
||||
Logger.normal('Downloading %s %s', package, oldversion)
|
||||
Logger.info('Downloading %s %s', package, oldversion)
|
||||
|
||||
oldpkg = DebianSourcePackage(package, oldversion, mirrors=mirrors)
|
||||
try:
|
||||
@ -104,11 +106,11 @@ def main():
|
||||
except DownloadError as e:
|
||||
Logger.error('Failed to download: %s', str(e))
|
||||
sys.exit(1)
|
||||
print('file://' + oldpkg.debdiff(newpkg, diffstat=True))
|
||||
Logger.info('file://' + oldpkg.debdiff(newpkg, diffstat=True))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
Logger.normal('User abort.')
|
||||
Logger.info('User abort.')
|
||||
|
11
pull-debian-debs
Executable file
11
pull-debian-debs
Executable file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-debian-debs -- pull deb package files for debian
|
||||
# Basic usage: pull-debian-debs <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='debian', pull='debs')
|
@ -1,148 +1,11 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-debian-source -- pull a source package from Launchpad
|
||||
# Copyright (C) 2011, Stefano Rivera <stefanor@ubuntu.com>
|
||||
# Inspired by a tool of the same name by Nathan Handler.
|
||||
# pull-debian-source -- pull source package files for debian
|
||||
# Basic usage: pull-debian-source <package name> [version|release]
|
||||
#
|
||||
# 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 json
|
||||
import optparse
|
||||
import sys
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
from distro_info import DebianDistroInfo, DistroDataOutdated
|
||||
|
||||
from ubuntutools.archive import DebianSourcePackage, DownloadError, rmadison
|
||||
from ubuntutools.config import UDTConfig
|
||||
from ubuntutools.logger import Logger
|
||||
|
||||
|
||||
def is_suite(version):
|
||||
"""If version could be considered to be a Debian suite, return the
|
||||
canonical suite name. Otherwise None
|
||||
"""
|
||||
debian_info = DebianDistroInfo()
|
||||
debian_releases = debian_info.all + ['experimental']
|
||||
|
||||
if '-' in version:
|
||||
release, pocket = version.split('-', 1)
|
||||
release = debian_info.codename(release, default=release)
|
||||
if release in debian_releases:
|
||||
if pocket in ('proposed-updates', 'p-u'):
|
||||
return (release + '-proposed-updates')
|
||||
elif pocket == 'security':
|
||||
return (release + '-security')
|
||||
else:
|
||||
release = debian_info.codename(version, default=version)
|
||||
if release in debian_releases:
|
||||
return release
|
||||
return None
|
||||
|
||||
|
||||
def source_package_for(binary, release):
|
||||
"""Query DDE to find the source package for a particular binary"""
|
||||
try:
|
||||
release = DebianDistroInfo().codename(release, default=release)
|
||||
except DistroDataOutdated as e:
|
||||
Logger.warn(e)
|
||||
url = ('http://dde.debian.net/dde/q/udd/dist/d:debian/r:%s/p:%s/?t=json'
|
||||
% (release, binary))
|
||||
data = None
|
||||
try:
|
||||
data = json.load(urllib.request.urlopen(url))['r']
|
||||
except urllib.error.URLError as e:
|
||||
Logger.error('Unable to retrieve package information from DDE: '
|
||||
'%s (%s)', url, str(e))
|
||||
except ValueError as e:
|
||||
Logger.error('Unable to parse JSON response from DDE: '
|
||||
'%s (%s)', url, str(e))
|
||||
if not data:
|
||||
return None
|
||||
return data[0]['source']
|
||||
|
||||
|
||||
def main():
|
||||
usage = 'Usage: %prog <package> [release|version]'
|
||||
parser = optparse.OptionParser(usage)
|
||||
parser.add_option('-d', '--download-only',
|
||||
dest='download_only', default=False, action='store_true',
|
||||
help='Do not extract the source package')
|
||||
parser.add_option('-m', '--mirror', metavar='DEBIAN_MIRROR',
|
||||
dest='debian_mirror',
|
||||
help='Preferred Debian mirror (default: %s)'
|
||||
% UDTConfig.defaults['DEBIAN_MIRROR'])
|
||||
parser.add_option('-s', '--security-mirror', metavar='DEBSEC_MIRROR',
|
||||
dest='debsec_mirror',
|
||||
help='Preferred Debian Security mirror (default: %s)'
|
||||
% UDTConfig.defaults['DEBSEC_MIRROR'])
|
||||
parser.add_option('--no-conf',
|
||||
dest='no_conf', default=False, action='store_true',
|
||||
help="Don't read config files or environment variables")
|
||||
parser.add_option('--no-verify-signature',
|
||||
dest='verify_signature', default=True,
|
||||
action='store_false',
|
||||
help="Allow signature verification failure")
|
||||
(options, args) = parser.parse_args()
|
||||
if not args:
|
||||
parser.error('Must specify package name')
|
||||
elif len(args) > 2:
|
||||
parser.error('Too many arguments. '
|
||||
'Must only specify package and (optionally) release.')
|
||||
|
||||
config = UDTConfig(options.no_conf)
|
||||
if options.debian_mirror is None:
|
||||
options.debian_mirror = config.get_value('DEBIAN_MIRROR')
|
||||
if options.debsec_mirror is None:
|
||||
options.debsec_mirror = config.get_value('DEBSEC_MIRROR')
|
||||
|
||||
package = args[0].lower()
|
||||
|
||||
version = args[1] if len(args) > 1 else 'unstable'
|
||||
component = None
|
||||
|
||||
suite = is_suite(version)
|
||||
if suite is not None:
|
||||
line = list(rmadison('debian', package, suite, 'source'))
|
||||
if not line:
|
||||
source_package = source_package_for(package, suite)
|
||||
if source_package is not None and package != source_package:
|
||||
package = source_package
|
||||
line = list(rmadison('debian', package, suite, 'source'))
|
||||
if not line:
|
||||
Logger.error('Unable to find %s in Debian suite "%s".', package,
|
||||
suite)
|
||||
sys.exit(1)
|
||||
line = line[-1]
|
||||
version = line['version']
|
||||
component = line['component']
|
||||
|
||||
Logger.normal('Downloading %s version %s', package, version)
|
||||
srcpkg = DebianSourcePackage(package, version, component=component,
|
||||
mirrors=[options.debian_mirror,
|
||||
options.debsec_mirror])
|
||||
try:
|
||||
srcpkg.pull(verify_signature=options.verify_signature)
|
||||
except DownloadError as e:
|
||||
Logger.error('Failed to download: %s', str(e))
|
||||
sys.exit(1)
|
||||
if not options.download_only:
|
||||
srcpkg.unpack()
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
Logger.normal('User abort.')
|
||||
PullPkg.main(distro='debian', pull='source')
|
||||
|
11
pull-debian-udebs
Executable file
11
pull-debian-udebs
Executable file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-debian-udebs -- pull udeb package files for debian
|
||||
# Basic usage: pull-debian-udebs <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='debian', pull='udebs')
|
11
pull-lp-ddebs
Executable file
11
pull-lp-ddebs
Executable file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-lp-ddebs -- pull ddeb package files for ubuntu
|
||||
# Basic usage: pull-lp-ddebs <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='ubuntu', pull='ddebs')
|
11
pull-lp-debs
Executable file
11
pull-lp-debs
Executable file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-lp-debs -- pull deb package files for ubuntu
|
||||
# Basic usage: pull-lp-debs <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='ubuntu', pull='debs')
|
149
pull-lp-source
149
pull-lp-source
@ -1,150 +1,11 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-lp-source -- pull a source package from Launchpad
|
||||
# Basic usage: pull-lp-source <source package> [<release>]
|
||||
# pull-lp-source -- pull source package files for ubuntu
|
||||
# Basic usage: pull-lp-source <package name> [version|release]
|
||||
#
|
||||
# Copyright (C) 2008, Iain Lane <iain@orangesquash.org.uk>,
|
||||
# 2010-2011, Stefano Rivera <stefanor@ubuntu.com>
|
||||
#
|
||||
# ##################################################################
|
||||
#
|
||||
# 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 3
|
||||
# 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.
|
||||
#
|
||||
# See file /usr/share/common-licenses/GPL for more details.
|
||||
#
|
||||
# ##################################################################
|
||||
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from optparse import OptionParser
|
||||
|
||||
from distro_info import UbuntuDistroInfo, DistroDataOutdated
|
||||
|
||||
from ubuntutools.archive import UbuntuSourcePackage, DownloadError
|
||||
from ubuntutools.config import UDTConfig
|
||||
from ubuntutools.lp.lpapicache import Distribution, Launchpad
|
||||
from ubuntutools.lp.udtexceptions import (SeriesNotFoundException,
|
||||
PackageNotFoundException,
|
||||
PocketDoesNotExistError)
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.misc import split_release_pocket
|
||||
|
||||
|
||||
def source_package_for(binary, release):
|
||||
"""Query DDE to find the source package for a particular binary
|
||||
Should really do this with LP, but it's not possible LP: #597041
|
||||
"""
|
||||
url = ('http://dde.debian.net/dde/q/udd/dist/d:ubuntu/r:%s/p:%s/?t=json'
|
||||
% (release, binary))
|
||||
data = None
|
||||
try:
|
||||
data = json.load(urllib.request.urlopen(url))['r']
|
||||
except urllib.error.URLError as e:
|
||||
Logger.error('Unable to retrieve package information from DDE: '
|
||||
'%s (%s)', url, str(e))
|
||||
except ValueError as e:
|
||||
Logger.error('Unable to parse JSON response from DDE: '
|
||||
'%s (%s)', url, str(e))
|
||||
if not data:
|
||||
return None
|
||||
return data[0]['source']
|
||||
|
||||
|
||||
def main():
|
||||
usage = "Usage: %prog <package> [release|version]"
|
||||
opt_parser = OptionParser(usage)
|
||||
opt_parser.add_option('-d', '--download-only',
|
||||
dest='download_only', default=False,
|
||||
action='store_true',
|
||||
help="Do not extract the source package")
|
||||
opt_parser.add_option('-m', '--mirror', metavar='UBUNTU_MIRROR',
|
||||
dest='ubuntu_mirror',
|
||||
help='Preferred Ubuntu mirror (default: Launchpad)')
|
||||
opt_parser.add_option('--no-conf',
|
||||
dest='no_conf', default=False, action='store_true',
|
||||
help="Don't read config files or environment "
|
||||
"variables")
|
||||
(options, args) = opt_parser.parse_args()
|
||||
if not args:
|
||||
opt_parser.error("Must specify package name")
|
||||
|
||||
config = UDTConfig(options.no_conf)
|
||||
if options.ubuntu_mirror is None:
|
||||
options.ubuntu_mirror = config.get_value('UBUNTU_MIRROR')
|
||||
|
||||
# Login anonymously to LP
|
||||
Launchpad.login_anonymously()
|
||||
|
||||
package = str(args[0]).lower()
|
||||
|
||||
ubuntu_info = UbuntuDistroInfo()
|
||||
if len(args) > 1: # Custom distribution specified.
|
||||
version = str(args[1])
|
||||
else:
|
||||
try:
|
||||
version = os.getenv('DIST') or ubuntu_info.devel()
|
||||
except DistroDataOutdated as e:
|
||||
Logger.warn("%s\nOr specify a distribution.", e)
|
||||
sys.exit(1)
|
||||
component = None
|
||||
|
||||
# Release, not package version number:
|
||||
release = None
|
||||
pocket = None
|
||||
try:
|
||||
(release, pocket) = split_release_pocket(version, default=None)
|
||||
except PocketDoesNotExistError:
|
||||
pass
|
||||
if release in ubuntu_info.all:
|
||||
archive = Distribution('ubuntu').getArchive()
|
||||
try:
|
||||
spph = archive.getSourcePackage(package, release, pocket)
|
||||
except SeriesNotFoundException as e:
|
||||
Logger.error(str(e))
|
||||
sys.exit(1)
|
||||
except PackageNotFoundException as e:
|
||||
source_package = source_package_for(package, release)
|
||||
if source_package is not None and source_package != package:
|
||||
try:
|
||||
spph = archive.getSourcePackage(source_package, release,
|
||||
pocket)
|
||||
package = source_package
|
||||
except PackageNotFoundException:
|
||||
Logger.error(str(e))
|
||||
sys.exit(1)
|
||||
else:
|
||||
Logger.error(str(e))
|
||||
sys.exit(1)
|
||||
|
||||
version = spph.getVersion()
|
||||
component = spph.getComponent()
|
||||
|
||||
Logger.normal('Downloading %s version %s', package, version)
|
||||
srcpkg = UbuntuSourcePackage(package, version, component=component,
|
||||
mirrors=[options.ubuntu_mirror])
|
||||
try:
|
||||
srcpkg.pull()
|
||||
except DownloadError as e:
|
||||
Logger.error('Failed to download: %s', str(e))
|
||||
sys.exit(1)
|
||||
if not options.download_only:
|
||||
srcpkg.unpack()
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
Logger.normal('User abort.')
|
||||
PullPkg.main(distro='ubuntu', pull='source')
|
||||
|
11
pull-lp-udebs
Executable file
11
pull-lp-udebs
Executable file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-lp-udebs -- pull udeb package files for ubuntu
|
||||
# Basic usage: pull-lp-udebs <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='ubuntu', pull='udebs')
|
29
pull-pkg
Executable file
29
pull-pkg
Executable file
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-pkg -- pull package files for debian/ubuntu/uca/ppa
|
||||
# Basic usage: pull-pkg -D distro -p type <package name> [version|release]
|
||||
#
|
||||
# Copyright (C) 2008, Iain Lane <iain@orangesquash.org.uk>,
|
||||
# 2010-2011, Stefano Rivera <stefanor@ubuntu.com>
|
||||
# 2017-2018, Dan Streetman <ddstreet@canonical.com>
|
||||
#
|
||||
# ##################################################################
|
||||
#
|
||||
# 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 3
|
||||
# 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.
|
||||
#
|
||||
# See file /usr/share/common-licenses/GPL for more details.
|
||||
#
|
||||
# ##################################################################
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main()
|
12
pull-ppa-ddebs
Executable file
12
pull-ppa-ddebs
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-ppa-ddebs -- pull ddeb package files for a Launchpad Personal Package Archive
|
||||
# Basic usage: pull-ppa-ddebs <package name> <ppa:USER/NAME> [version|release]
|
||||
# pull-ppa-ddebs --ppa USER/NAME <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='ppa', pull='ddebs')
|
12
pull-ppa-debs
Executable file
12
pull-ppa-debs
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-ppa-debs -- pull deb package files for a Launchpad Personal Package Archive
|
||||
# Basic usage: pull-ppa-debs <package name> <ppa:USER/NAME> [version|release]
|
||||
# pull-ppa-debs --ppa USER/NAME <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='ppa', pull='debs')
|
12
pull-ppa-source
Executable file
12
pull-ppa-source
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-ppa-source -- pull source package files for a Launchpad Personal Package Archive
|
||||
# Basic usage: pull-ppa-source <package name> <ppa:USER/NAME> [version|release]
|
||||
# pull-ppa-source --ppa USER/NAME <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='ppa', pull='source')
|
12
pull-ppa-udebs
Executable file
12
pull-ppa-udebs
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-ppa-udebs -- pull udeb package files for a Launchpad Personal Package Archive
|
||||
# Basic usage: pull-ppa-udebs <package name> <ppa:USER/NAME> [version|release]
|
||||
# pull-ppa-udebs --ppa USER/NAME <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='ppa', pull='udebs')
|
11
pull-uca-ddebs
Executable file
11
pull-uca-ddebs
Executable file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-uca-ddebs -- pull ddeb package files for ubuntu cloud archive
|
||||
# Basic usage: pull-uca-ddebs <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='uca', pull='ddebs')
|
11
pull-uca-debs
Executable file
11
pull-uca-debs
Executable file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-uca-debs -- pull deb package files for ubuntu cloud archive
|
||||
# Basic usage: pull-uca-debs <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='uca', pull='debs')
|
156
pull-uca-source
156
pull-uca-source
@ -1,157 +1,11 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-uca-source -- pull a source package from Ubuntu Cloud Archive
|
||||
# Basic usage: pull-uca-source <source package> <openstack release> [version]
|
||||
# pull-uca-source -- pull source package files for ubuntu cloud archive
|
||||
# Basic usage: pull-uca-source <package name> [version|release]
|
||||
#
|
||||
# Copyright (C) 2008, Iain Lane <iain@orangesquash.org.uk>,
|
||||
# 2010-2011, Stefano Rivera <stefanor@ubuntu.com>
|
||||
# 2016, Corey Bryant <corey.bryant@ubuntu.com>
|
||||
# 2016, Dan Streetman <dan.streetman@canonical.com>
|
||||
#
|
||||
# ##################################################################
|
||||
#
|
||||
# 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 3
|
||||
# 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.
|
||||
#
|
||||
# See file /usr/share/common-licenses/GPL for more details.
|
||||
#
|
||||
# ##################################################################
|
||||
|
||||
|
||||
import re
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
|
||||
from ubuntutools.archive import UbuntuCloudArchiveSourcePackage, DownloadError
|
||||
from ubuntutools.config import UDTConfig
|
||||
from ubuntutools.lp.lpapicache import Launchpad
|
||||
from ubuntutools.lp.udtexceptions import PocketDoesNotExistError
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.misc import split_release_pocket
|
||||
|
||||
from lazr.restfulclient.errors import NotFound
|
||||
|
||||
from launchpadlib.launchpad import Launchpad as LP
|
||||
|
||||
|
||||
def showOpenstackReleases(uca):
|
||||
releases = []
|
||||
for p in uca.ppas:
|
||||
if re.match(r"\w*-staging", p.name):
|
||||
releases.append(re.sub("-staging", "", p.name))
|
||||
Logger.error("Openstack releases are:\n\t%s", ", ".join(releases))
|
||||
|
||||
|
||||
def getSPPH(lp, archive, package, version=None, series=None, pocket=None, try_binary=True):
|
||||
params = {'exact_match': True, 'order_by_date': True}
|
||||
if pocket:
|
||||
params['pocket'] = pocket
|
||||
if series:
|
||||
params['distro_series'] = series()
|
||||
elif version:
|
||||
params['version'] = version
|
||||
Logger.normal("checking %s version %s pocket %s", package, version, pocket)
|
||||
spphs = archive.getPublishedSources(source_name=package, **params)
|
||||
if spphs:
|
||||
return spphs[0]
|
||||
if not try_binary:
|
||||
return None
|
||||
|
||||
# Didn't find any, maybe the package is a binary package name
|
||||
if series:
|
||||
del params['distro_series']
|
||||
archs = lp.load(series().architectures_collection_link).entries
|
||||
params['distro_arch_series'] = archs[0]['self_link']
|
||||
bpphs = archive.getPublishedBinaries(binary_name=package, **params)
|
||||
if bpphs:
|
||||
bpph_build = lp.load(bpphs[0].build_link)
|
||||
source_package = bpph_build.source_package_name
|
||||
return getSPPH(lp, archive, source_package, version, series, pocket,
|
||||
try_binary=False)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
usage = "Usage: %prog <package> <openstack release> [version]"
|
||||
opt_parser = OptionParser(usage)
|
||||
opt_parser.add_option('-d', '--download-only',
|
||||
dest='download_only', default=False,
|
||||
action='store_true',
|
||||
help="Do not extract the source package")
|
||||
opt_parser.add_option('-m', '--mirror', metavar='OPENSTACK_MIRROR',
|
||||
dest='openstack_mirror',
|
||||
help='Preferred Openstack mirror (default: Launchpad)')
|
||||
opt_parser.add_option('--no-conf',
|
||||
dest='no_conf', default=False, action='store_true',
|
||||
help="Don't read config files or environment "
|
||||
"variables")
|
||||
(options, args) = opt_parser.parse_args()
|
||||
if len(args) < 2:
|
||||
opt_parser.error("Must specify package name and openstack release")
|
||||
|
||||
config = UDTConfig(options.no_conf)
|
||||
if options.openstack_mirror is None:
|
||||
options.openstack_mirror = config.get_value('OPENSTACK_MIRROR')
|
||||
mirrors = []
|
||||
if options.openstack_mirror:
|
||||
mirrors.append(options.openstack_mirror)
|
||||
|
||||
# Login anonymously to LP
|
||||
Launchpad.login_anonymously()
|
||||
lp = LP.login_anonymously("pull-uca-source", "production")
|
||||
uca = lp.people("ubuntu-cloud-archive")
|
||||
|
||||
package = str(args[0]).lower()
|
||||
release = str(args[1]).lower()
|
||||
version = None
|
||||
if len(args) > 2:
|
||||
version = str(args[2])
|
||||
|
||||
pocket = None
|
||||
try:
|
||||
(release, pocket) = split_release_pocket(release, default=None)
|
||||
except PocketDoesNotExistError:
|
||||
pass
|
||||
|
||||
try:
|
||||
archive = uca.getPPAByName(name="%s-staging" % release)
|
||||
except NotFound:
|
||||
Logger.error('Archive does not exist for Openstack release: %s',
|
||||
release)
|
||||
showOpenstackReleases(uca)
|
||||
sys.exit(1)
|
||||
|
||||
spph = getSPPH(lp, archive, package, version, pocket=pocket)
|
||||
if not spph:
|
||||
Logger.error("Package %s in %s not found.", package, release)
|
||||
sys.exit(1)
|
||||
|
||||
package = spph.source_package_name
|
||||
version = spph.source_package_version
|
||||
component = spph.component_name
|
||||
Logger.normal('Downloading %s version %s component %s', package, version, component)
|
||||
srcpkg = UbuntuCloudArchiveSourcePackage(release, package, version, component=component,
|
||||
mirrors=mirrors)
|
||||
|
||||
try:
|
||||
srcpkg.pull()
|
||||
except DownloadError as e:
|
||||
Logger.error('Failed to download: %s', str(e))
|
||||
sys.exit(1)
|
||||
if not options.download_only:
|
||||
srcpkg.unpack()
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
Logger.normal('User abort.')
|
||||
PullPkg.main(distro='uca', pull='source')
|
||||
|
11
pull-uca-udebs
Executable file
11
pull-uca-udebs
Executable file
@ -0,0 +1,11 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# pull-uca-udebs -- pull udeb package files for ubuntu cloud archive
|
||||
# Basic usage: pull-uca-udebs <package name> [version|release]
|
||||
#
|
||||
# See pull-pkg
|
||||
|
||||
from ubuntutools.pullpkg import PullPkg
|
||||
|
||||
if __name__ == '__main__':
|
||||
PullPkg.main(distro='uca', pull='udebs')
|
@ -25,11 +25,13 @@ from distro_info import UbuntuDistroInfo
|
||||
from ubuntutools.config import UDTConfig
|
||||
from ubuntutools.lp.lpapicache import Launchpad, Distribution
|
||||
from ubuntutools.lp.udtexceptions import PackageNotFoundException
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.question import (YesNoQuestion, EditBugReport,
|
||||
confirmation_prompt)
|
||||
from ubuntutools.rdepends import query_rdepends, RDependsException
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
class DestinationException(Exception):
|
||||
pass
|
||||
@ -106,16 +108,11 @@ def check_existing(package, destinations):
|
||||
if not bugs:
|
||||
return
|
||||
|
||||
Logger.normal("There are existing bug reports that look similar to your "
|
||||
"request. Please check before continuing:")
|
||||
Logger.info("There are existing bug reports that look similar to your "
|
||||
"request. Please check before continuing:")
|
||||
|
||||
by_id = {}
|
||||
for bug_task in bugs:
|
||||
bug = bug_task.bug
|
||||
by_id[bug.id] = bug
|
||||
|
||||
for id_, bug in sorted(by_id.items()):
|
||||
Logger.normal(" * LP: #%-7i: %s %s", bug.id, bug.title, bug.web_link)
|
||||
for bug in sorted(set(bug_task.bug for bug_task in bugs)):
|
||||
Logger.info(" * LP: #%-7i: %s %s", bug.id, bug.title, bug.web_link)
|
||||
|
||||
confirmation_prompt()
|
||||
|
||||
@ -190,8 +187,8 @@ def locate_package(package, distribution):
|
||||
except KeyError:
|
||||
continue
|
||||
package = apt_pkg.candidate.source_name
|
||||
Logger.normal("Binary package specified, considering its source "
|
||||
"package instead: %s", package)
|
||||
Logger.info("Binary package specified, considering its source "
|
||||
"package instead: %s", package)
|
||||
|
||||
|
||||
def request_backport(package_spph, source, destinations):
|
||||
@ -204,8 +201,8 @@ def request_backport(package_spph, source, destinations):
|
||||
Logger.error("%s (%s) has no published binaries in %s. ",
|
||||
package_spph.getPackageName(), package_spph.getVersion(),
|
||||
source)
|
||||
Logger.normal("Is it stuck in bin-NEW? It can't be backported until "
|
||||
"the binaries have been accepted.")
|
||||
Logger.info("Is it stuck in bin-NEW? It can't be backported until "
|
||||
"the binaries have been accepted.")
|
||||
sys.exit(1)
|
||||
|
||||
testing = []
|
||||
@ -256,8 +253,8 @@ def request_backport(package_spph, source, destinations):
|
||||
editor.edit()
|
||||
subject, body = editor.get_report()
|
||||
|
||||
Logger.normal('The final report is:\nSummary: %s\nDescription:\n%s\n',
|
||||
subject, body)
|
||||
Logger.info('The final report is:\nSummary: %s\nDescription:\n%s\n',
|
||||
subject, body)
|
||||
if YesNoQuestion().ask("Request this backport", "yes") == "no":
|
||||
sys.exit(1)
|
||||
|
||||
@ -268,7 +265,7 @@ def request_backport(package_spph, source, destinations):
|
||||
for target in targets[1:]:
|
||||
bug.addTask(target=target)
|
||||
|
||||
Logger.normal("Backport request filed as %s", bug.web_link)
|
||||
Logger.info("Backport request filed as %s", bug.web_link)
|
||||
|
||||
|
||||
def main():
|
||||
|
76
requestsync
76
requestsync
@ -38,6 +38,9 @@ from ubuntutools.misc import require_utf8
|
||||
from ubuntutools.question import confirmation_prompt, EditBugReport
|
||||
from ubuntutools.version import Version
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
#
|
||||
# entry point
|
||||
#
|
||||
@ -97,7 +100,7 @@ def main():
|
||||
config = UDTConfig(options.no_conf)
|
||||
|
||||
if options.deprecated_lp_flag:
|
||||
print("The --lp flag is now default, ignored.")
|
||||
Logger.info("The --lp flag is now default, ignored.")
|
||||
if options.email:
|
||||
options.lpapi = False
|
||||
else:
|
||||
@ -115,8 +118,8 @@ def main():
|
||||
elif options.lpinstance == 'staging':
|
||||
bug_mail_domain = 'bugs.staging.launchpad.net'
|
||||
else:
|
||||
print('Error: Unknown launchpad instance: %s' % options.lpinstance,
|
||||
file=sys.stderr)
|
||||
Logger.error('Error: Unknown launchpad instance: %s'
|
||||
% options.lpinstance)
|
||||
sys.exit(1)
|
||||
|
||||
mailserver_host = config.get_value('SMTP_SERVER',
|
||||
@ -130,8 +133,8 @@ def main():
|
||||
firstmx = mxlist[0]
|
||||
mailserver_host = firstmx[1]
|
||||
except ImportError:
|
||||
print('Please install python3-dns to support Launchpad mail '
|
||||
'server lookup.', file=sys.stderr)
|
||||
Logger.error('Please install python-dns to support '
|
||||
'Launchpad mail server lookup.')
|
||||
sys.exit(1)
|
||||
|
||||
mailserver_port = config.get_value('SMTP_PORT', default=25,
|
||||
@ -167,9 +170,8 @@ def main():
|
||||
get_ubuntu_delta_changelog,
|
||||
mail_bug, need_sponsorship)
|
||||
if not any(x in os.environ for x in ('UBUMAIL', 'DEBEMAIL', 'EMAIL')):
|
||||
print('E: The environment variable UBUMAIL, DEBEMAIL or EMAIL '
|
||||
'needs to be set to let this script mail the sync request.',
|
||||
file=sys.stderr)
|
||||
Logger.error('The environment variable UBUMAIL, DEBEMAIL or EMAIL needs '
|
||||
'to be set to let this script mail the sync request.')
|
||||
sys.exit(1)
|
||||
|
||||
newsource = options.newpkg
|
||||
@ -187,15 +189,14 @@ def main():
|
||||
else:
|
||||
ubu_info = UbuntuDistroInfo()
|
||||
release = ubu_info.devel()
|
||||
print('W: Target release missing - assuming %s' % release,
|
||||
file=sys.stderr)
|
||||
Logger.warning('Target release missing - assuming %s' % release)
|
||||
elif len(args) == 2:
|
||||
release = args[1]
|
||||
elif len(args) == 3:
|
||||
release = args[1]
|
||||
force_base_version = Version(args[2])
|
||||
else:
|
||||
print('E: Too many arguments.', file=sys.stderr)
|
||||
Logger.error('Too many arguments.')
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
@ -210,13 +211,12 @@ def main():
|
||||
ubuntu_version = Version('~')
|
||||
ubuntu_component = None # Set after getting the Debian info
|
||||
if not newsource:
|
||||
print(("'%s' doesn't exist in 'Ubuntu %s'.\n"
|
||||
"Do you want to sync a new package?")
|
||||
% (srcpkg, release))
|
||||
Logger.info("'%s' doesn't exist in 'Ubuntu %s'." % (srcpkg, release))
|
||||
Logger.info("Do you want to sync a new package?")
|
||||
confirmation_prompt()
|
||||
newsource = True
|
||||
except udtexceptions.SeriesNotFoundException as error:
|
||||
print("E: %s" % error, file=sys.stderr)
|
||||
Logger.error(error)
|
||||
sys.exit(1)
|
||||
|
||||
# Get the requested Debian source package
|
||||
@ -225,10 +225,10 @@ def main():
|
||||
debian_version = Version(debian_srcpkg.getVersion())
|
||||
debian_component = debian_srcpkg.getComponent()
|
||||
except udtexceptions.PackageNotFoundException as error:
|
||||
print("E: %s" % error, file=sys.stderr)
|
||||
Logger.error(error)
|
||||
sys.exit(1)
|
||||
except udtexceptions.SeriesNotFoundException as error:
|
||||
print("E: %s" % error, file=sys.stderr)
|
||||
Logger.error(error)
|
||||
sys.exit(1)
|
||||
|
||||
if ubuntu_component is None:
|
||||
@ -246,17 +246,17 @@ def main():
|
||||
debian_version = Version(debian_srcpkg.getVersion())
|
||||
debian_component = debian_srcpkg.getComponent()
|
||||
except udtexceptions.PackageNotFoundException as error:
|
||||
print("E: %s" % error, file=sys.stderr)
|
||||
Logger.error(error)
|
||||
sys.exit(1)
|
||||
|
||||
if ubuntu_version == debian_version:
|
||||
print('E: The versions in Debian and Ubuntu are the same already '
|
||||
'(%s). Aborting.' % ubuntu_version, file=sys.stderr)
|
||||
Logger.error('The versions in Debian and Ubuntu are the '
|
||||
'same already (%s). Aborting.' % ubuntu_version)
|
||||
sys.exit(1)
|
||||
if ubuntu_version > debian_version:
|
||||
print(('E: The version in Ubuntu (%s) is newer than the version in '
|
||||
'Debian (%s). Aborting.')
|
||||
% (ubuntu_version, debian_version), file=sys.stderr)
|
||||
Logger.error('The version in Ubuntu (%s) is newer than '
|
||||
'the version in Debian (%s). Aborting.'
|
||||
% (ubuntu_version, debian_version))
|
||||
sys.exit(1)
|
||||
|
||||
# -s flag not specified - check if we do need sponsorship
|
||||
@ -264,8 +264,8 @@ def main():
|
||||
sponsorship = need_sponsorship(srcpkg, ubuntu_component, release)
|
||||
|
||||
if not sponsorship and not ffe:
|
||||
print('Consider using syncpackage(1) for syncs that do not require '
|
||||
'feature freeze exceptions.', file=sys.stderr)
|
||||
Logger.error('Consider using syncpackage(1) for syncs that '
|
||||
'do not require feature freeze exceptions.')
|
||||
|
||||
# Check for existing package reports
|
||||
if not newsource:
|
||||
@ -283,9 +283,9 @@ def main():
|
||||
if 'ubuntu' in str(ubuntu_version):
|
||||
need_interaction = True
|
||||
|
||||
print('Changes have been made to the package in Ubuntu.\n'
|
||||
'Please edit the report and give an explanation.\n'
|
||||
'Not saving the report file will abort the request.')
|
||||
Logger.info('Changes have been made to the package in Ubuntu.')
|
||||
Logger.info('Please edit the report and give an explanation.')
|
||||
Logger.info('Not saving the report file will abort the request.')
|
||||
report += ('Explanation of the Ubuntu delta and why it can be '
|
||||
'dropped:\n%s\n>>> ENTER_EXPLANATION_HERE <<<\n\n'
|
||||
% get_ubuntu_delta_changelog(ubuntu_srcpkg))
|
||||
@ -293,9 +293,9 @@ def main():
|
||||
if ffe:
|
||||
need_interaction = True
|
||||
|
||||
print('To approve FeatureFreeze exception, you need to state\n'
|
||||
'the reason why you feel it is necessary.\n'
|
||||
'Not saving the report file will abort the request.')
|
||||
Logger.info('To approve FeatureFreeze exception, you need to state')
|
||||
Logger.info('the reason why you feel it is necessary.')
|
||||
Logger.info('Not saving the report file will abort the request.')
|
||||
report += ('Explanation of FeatureFreeze exception:\n'
|
||||
'>>> ENTER_EXPLANATION_HERE <<<\n\n')
|
||||
|
||||
@ -312,10 +312,10 @@ def main():
|
||||
changelog = debian_srcpkg.getChangelog(since_version=base_version)
|
||||
if not changelog:
|
||||
if not options.missing_changelog_ok:
|
||||
print("E: Did not retrieve any changelog entries. "
|
||||
"Do you need to specify '-C'? "
|
||||
"Was the package recently uploaded? (check "
|
||||
"http://packages.debian.org/changelogs/)", file=sys.stderr)
|
||||
Logger.error("Did not retrieve any changelog entries. "
|
||||
"Do you need to specify '-C'? "
|
||||
"Was the package recently uploaded? (check "
|
||||
"http://packages.debian.org/changelogs/)")
|
||||
sys.exit(1)
|
||||
else:
|
||||
need_interaction = True
|
||||
@ -327,8 +327,8 @@ def main():
|
||||
title, report = editor.get_report()
|
||||
|
||||
if 'XXX FIXME' in report:
|
||||
print("E: changelog boilerplate found in report, please manually add "
|
||||
"changelog when using '-C'", file=sys.stderr)
|
||||
Logger.error("changelog boilerplate found in report, "
|
||||
"please manually add changelog when using '-C'")
|
||||
sys.exit(1)
|
||||
|
||||
# bug status and bug subscriber
|
||||
@ -359,5 +359,5 @@ if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print("\nUser abort.")
|
||||
Logger.error("User abort.")
|
||||
sys.exit(2)
|
||||
|
@ -19,11 +19,13 @@ import sys
|
||||
|
||||
from distro_info import DistroDataOutdated
|
||||
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.misc import (system_distribution, vendor_to_distroinfo,
|
||||
codename_to_distribution)
|
||||
from ubuntutools.rdepends import query_rdepends, RDependsException
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
DEFAULT_MAX_DEPTH = 10 # We want avoid any infinite loop...
|
||||
|
||||
|
||||
@ -32,7 +34,7 @@ def main():
|
||||
try:
|
||||
default_release = system_distro_info.devel()
|
||||
except DistroDataOutdated as e:
|
||||
Logger.warn(e)
|
||||
Logger.warning(e)
|
||||
default_release = 'unstable'
|
||||
|
||||
description = ("List reverse-dependencies of package. "
|
||||
@ -85,7 +87,7 @@ def main():
|
||||
options.release = distro_info.codename(options.release,
|
||||
default=options.release)
|
||||
except DistroDataOutdated:
|
||||
# We already printed a warning
|
||||
# We already logged a warning
|
||||
pass
|
||||
|
||||
if options.build_depends:
|
||||
@ -143,14 +145,14 @@ def main():
|
||||
|
||||
def display_verbose(package, values):
|
||||
if not values:
|
||||
print("No reverse dependencies found")
|
||||
Logger.info("No reverse dependencies found")
|
||||
return
|
||||
|
||||
def print_field(field):
|
||||
print(field)
|
||||
print('=' * len(field))
|
||||
def log_field(field):
|
||||
Logger.info(field)
|
||||
Logger.info('=' * len(field))
|
||||
|
||||
def print_package(values, package, arch, dependency, offset=0):
|
||||
def log_package(values, package, arch, dependency, offset=0):
|
||||
line = ' ' * offset + '* %s' % package
|
||||
if all_archs and set(arch) != all_archs:
|
||||
line += ' [%s]' % ' '.join(sorted(arch))
|
||||
@ -158,17 +160,17 @@ def display_verbose(package, values):
|
||||
if len(line) < 30:
|
||||
line += ' ' * (30 - len(line))
|
||||
line += ' (for %s)' % dependency
|
||||
print(line)
|
||||
Logger.info(line)
|
||||
data = values.get(package)
|
||||
if data:
|
||||
offset = offset + 1
|
||||
for rdeps in data.values():
|
||||
for rdep in rdeps:
|
||||
print_package(values,
|
||||
rdep['Package'],
|
||||
rdep.get('Architectures', all_archs),
|
||||
rdep.get('Dependency'),
|
||||
offset)
|
||||
log_package(values,
|
||||
rdep['Package'],
|
||||
rdep.get('Architectures', all_archs),
|
||||
rdep.get('Dependency'),
|
||||
offset)
|
||||
|
||||
all_archs = set()
|
||||
# This isn't accurate, but we make up for it by displaying what we found
|
||||
@ -179,19 +181,19 @@ def display_verbose(package, values):
|
||||
all_archs.update(rdep['Architectures'])
|
||||
|
||||
for field, rdeps in values[package].items():
|
||||
print_field(field)
|
||||
Logger.info(field)
|
||||
rdeps.sort(key=lambda x: x['Package'])
|
||||
for rdep in rdeps:
|
||||
print_package(values,
|
||||
rdep['Package'],
|
||||
rdep.get('Architectures', all_archs),
|
||||
rdep.get('Dependency'))
|
||||
print()
|
||||
log_package(values,
|
||||
rdep['Package'],
|
||||
rdep.get('Architectures', all_archs),
|
||||
rdep.get('Dependency'))
|
||||
Logger.info("")
|
||||
|
||||
if all_archs:
|
||||
print("Packages without architectures listed are "
|
||||
"reverse-dependencies in: %s"
|
||||
% ', '.join(sorted(list(all_archs))))
|
||||
Logger.info("Packages without architectures listed are "
|
||||
"reverse-dependencies in: %s"
|
||||
% ', '.join(sorted(list(all_archs))))
|
||||
|
||||
|
||||
def display_consise(values):
|
||||
@ -201,7 +203,7 @@ def display_consise(values):
|
||||
for rdep in rdeps:
|
||||
result.add(rdep['Package'])
|
||||
|
||||
print('\n'.join(sorted(list(result))))
|
||||
Logger.info('\n'.join(sorted(list(result))))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -24,7 +24,9 @@ import urllib.request
|
||||
|
||||
from ubuntutools.lp.lpapicache import (Distribution, Launchpad,
|
||||
PackageNotFoundException)
|
||||
from ubuntutools.logger import Logger
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
DATA_URL = 'http://qa.ubuntuwire.org/ubuntu-seeded-packages/seeded.json.gz'
|
||||
|
||||
@ -88,28 +90,28 @@ def output_binaries(index, binaries):
|
||||
'''Print binaries found in index'''
|
||||
for binary in binaries:
|
||||
if binary in index:
|
||||
print("%s is seeded in:" % binary)
|
||||
print(present_on(index[binary]))
|
||||
Logger.info("%s is seeded in:" % binary)
|
||||
Logger.info(present_on(index[binary]))
|
||||
else:
|
||||
print("%s is not seeded (and may not exist)." % binary)
|
||||
Logger.info("%s is not seeded (and may not exist)." % binary)
|
||||
|
||||
|
||||
def output_by_source(index, by_source):
|
||||
'''Print binaries found in index. Grouped by source'''
|
||||
'''Logger.Info(binaries found in index. Grouped by source'''
|
||||
for source, binaries in by_source.items():
|
||||
seen = False
|
||||
if not binaries:
|
||||
print("Status unknown: No binary packages built by the latest "
|
||||
"%s.\nTry again using -b and the expected binary packages."
|
||||
% source)
|
||||
Logger.info("Status unknown: No binary packages built by the latest "
|
||||
"%s.\nTry again using -b and the expected binary packages."
|
||||
% source)
|
||||
continue
|
||||
for binary in binaries:
|
||||
if binary in index:
|
||||
seen = True
|
||||
print("%s (from %s) is seeded in:" % (binary, source))
|
||||
print(present_on(index[binary]))
|
||||
Logger.info("%s (from %s) is seeded in:" % (binary, source))
|
||||
Logger.info(present_on(index[binary]))
|
||||
if not seen:
|
||||
print("%s's binaries are not seeded." % source)
|
||||
Logger.info("%s's binaries are not seeded." % source)
|
||||
|
||||
|
||||
def main():
|
||||
|
14
setup.py
14
setup.py
@ -27,11 +27,25 @@ scripts = [
|
||||
'mk-sbuild',
|
||||
'pbuilder-dist',
|
||||
'pbuilder-dist-simple',
|
||||
'pull-pkg',
|
||||
'pull-debian-debdiff',
|
||||
'pull-debian-source',
|
||||
'pull-debian-debs',
|
||||
'pull-debian-ddebs',
|
||||
'pull-debian-udebs',
|
||||
'pull-lp-source',
|
||||
'pull-lp-debs',
|
||||
'pull-lp-ddebs',
|
||||
'pull-lp-udebs',
|
||||
'pull-ppa-source',
|
||||
'pull-ppa-debs',
|
||||
'pull-ppa-ddebs',
|
||||
'pull-ppa-udebs',
|
||||
'pull-revu-source',
|
||||
'pull-uca-source',
|
||||
'pull-uca-debs',
|
||||
'pull-uca-ddebs',
|
||||
'pull-uca-udebs',
|
||||
'requestbackport',
|
||||
'requestsync',
|
||||
'reverse-build-depends',
|
||||
|
@ -19,12 +19,15 @@ import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import logging
|
||||
|
||||
from ubuntutools.builder import get_builder
|
||||
from ubuntutools.config import UDTConfig
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.sponsor_patch.sponsor_patch import sponsor_patch, check_dependencies
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
def parse(script_name):
|
||||
"""Parse the command line parameters."""
|
||||
@ -64,7 +67,8 @@ def parse(script_name):
|
||||
"temporary directory, deleted afterwards).")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
Logger.set_verbosity(options.verbose)
|
||||
if options.verbose:
|
||||
Logger.setLevel(logging.DEBUG)
|
||||
check_dependencies()
|
||||
|
||||
if len(args) == 0:
|
||||
@ -123,7 +127,7 @@ def main():
|
||||
options.keyid, options.lpinstance, options.update,
|
||||
options.upload, workdir)
|
||||
except KeyboardInterrupt:
|
||||
print("\nUser abort.")
|
||||
Logger.error("User abort.")
|
||||
sys.exit(2)
|
||||
finally:
|
||||
if options.workdir is None:
|
||||
|
@ -27,7 +27,9 @@ import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
from subprocess import call, check_call, Popen, PIPE
|
||||
|
||||
from subprocess import call, check_call, run, Popen, PIPE, DEVNULL
|
||||
|
||||
from tempfile import mkdtemp
|
||||
|
||||
from debian.changelog import Changelog
|
||||
@ -37,6 +39,9 @@ from ubuntutools.config import ubu_email
|
||||
from ubuntutools.question import YesNoQuestion, EditFile
|
||||
from ubuntutools.update_maintainer import update_maintainer, restore_maintainer
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
def get_most_recent_debian_version(changelog):
|
||||
for block in changelog:
|
||||
@ -85,10 +90,9 @@ def gen_debdiff(tmpdir, changelog):
|
||||
|
||||
debdiff = os.path.join(tmpdir, '%s_%s.debdiff' % (pkg, newver))
|
||||
|
||||
devnull = open('/dev/null', 'w')
|
||||
diff_cmd = ['bzr', 'diff', '-r', 'tag:' + str(oldver)]
|
||||
if call(diff_cmd, stdout=devnull, stderr=devnull) == 1:
|
||||
print("Extracting bzr diff between %s and %s" % (oldver, newver))
|
||||
if call(diff_cmd, stdout=DEVNULL, stderr=DEVNULL) == 1:
|
||||
Logger.info("Extracting bzr diff between %s and %s" % (oldver, newver))
|
||||
else:
|
||||
if oldver.epoch is not None:
|
||||
oldver = str(oldver)[str(oldver).index(":") + 1:]
|
||||
@ -101,17 +105,13 @@ def gen_debdiff(tmpdir, changelog):
|
||||
check_file(olddsc)
|
||||
check_file(newdsc)
|
||||
|
||||
print("Generating debdiff between %s and %s" % (oldver, newver))
|
||||
Logger.info("Generating debdiff between %s and %s" % (oldver, newver))
|
||||
diff_cmd = ['debdiff', olddsc, newdsc]
|
||||
|
||||
diff = Popen(diff_cmd, stdout=PIPE)
|
||||
debdiff_f = open(debdiff, 'w')
|
||||
filterdiff = Popen(['filterdiff', '-x', '*changelog*'],
|
||||
stdin=diff.stdout, stdout=debdiff_f)
|
||||
diff.stdout.close()
|
||||
filterdiff.wait()
|
||||
debdiff_f.close()
|
||||
devnull.close()
|
||||
with Popen(diff_cmd, stdout=PIPE, encoding='utf-8') as diff:
|
||||
with open(debdiff, 'w', encoding='utf-8') as debdiff_f:
|
||||
run(['filterdiff', '-x', '*changelog*'],
|
||||
stdin=diff.stdout, stdout=debdiff_f, encoding='utf-8')
|
||||
|
||||
return debdiff
|
||||
|
||||
@ -122,7 +122,7 @@ def check_file(fname, critical=True):
|
||||
else:
|
||||
if not critical:
|
||||
return False
|
||||
print("Couldn't find «%s».\n" % fname)
|
||||
Logger.info("Couldn't find «%s».\n" % fname)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@ -130,7 +130,7 @@ def submit_bugreport(body, debdiff, deb_version, changelog):
|
||||
try:
|
||||
devel = UbuntuDistroInfo().devel()
|
||||
except DistroDataOutdated as e:
|
||||
print(str(e))
|
||||
Logger.info(str(e))
|
||||
devel = ''
|
||||
|
||||
if os.path.dirname(sys.argv[0]).startswith('/usr/bin'):
|
||||
@ -200,7 +200,7 @@ no-cc
|
||||
with open(fn, 'w') as f:
|
||||
f.write(reportbugrc)
|
||||
|
||||
print("""\
|
||||
Logger.info("""\
|
||||
You have not configured reportbug. Assuming this is the first time you have
|
||||
used it. Writing a ~/.reportbugrc that will use Debian's mail server, and CC
|
||||
the bug to you at <%s>
|
||||
@ -224,8 +224,8 @@ def main():
|
||||
parser.parse_args()
|
||||
|
||||
if not os.path.exists('/usr/bin/reportbug'):
|
||||
print("This utility requires the «reportbug» package, which isn't "
|
||||
"currently installed.")
|
||||
Logger.error("This utility requires the «reportbug» package, which isn't "
|
||||
"currently installed.")
|
||||
sys.exit(1)
|
||||
|
||||
check_reportbug_config()
|
||||
|
86
syncpackage
86
syncpackage
@ -21,6 +21,7 @@
|
||||
# ##################################################################
|
||||
|
||||
import fnmatch
|
||||
import logging
|
||||
import optparse
|
||||
import os
|
||||
import shutil
|
||||
@ -37,7 +38,6 @@ from ubuntutools.config import UDTConfig, ubu_email
|
||||
from ubuntutools.lp import udtexceptions
|
||||
from ubuntutools.lp.lpapicache import (Distribution, Launchpad, PersonTeam,
|
||||
SourcePackagePublishingHistory)
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.misc import split_release_pocket
|
||||
from ubuntutools.question import YesNoQuestion
|
||||
from ubuntutools.requestsync.mail import (
|
||||
@ -45,6 +45,9 @@ from ubuntutools.requestsync.mail import (
|
||||
from ubuntutools.requestsync.lp import get_debian_srcpkg, get_ubuntu_srcpkg
|
||||
from ubuntutools.version import Version
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
def remove_signature(dscname):
|
||||
'''Removes the signature from a .dsc file if the .dsc file is signed.'''
|
||||
@ -116,7 +119,7 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror,
|
||||
ubuntu_ver = Version('~')
|
||||
ubu_pkg = None
|
||||
need_orig = True
|
||||
Logger.normal('%s does not exist in Ubuntu.', name)
|
||||
Logger.info('%s does not exist in Ubuntu.', name)
|
||||
|
||||
Logger.debug('Source %s: current version %s, new version %s',
|
||||
src_pkg.source, ubuntu_ver, new_ver)
|
||||
@ -128,9 +131,9 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror,
|
||||
Logger.error('--force is required to discard Ubuntu changes.')
|
||||
sys.exit(1)
|
||||
|
||||
Logger.warn('Overwriting modified Ubuntu version %s, '
|
||||
'setting current version to %s',
|
||||
ubuntu_ver.full_version, cur_ver.full_version)
|
||||
Logger.warning('Overwriting modified Ubuntu version %s, '
|
||||
'setting current version to %s',
|
||||
ubuntu_ver.full_version, cur_ver.full_version)
|
||||
if simulate:
|
||||
return
|
||||
|
||||
@ -144,7 +147,7 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror,
|
||||
needs_fakesync = not (need_orig or ubu_pkg.verify_orig())
|
||||
|
||||
if needs_fakesync and fakesync:
|
||||
Logger.warn('Performing a fakesync')
|
||||
Logger.warning('Performing a fakesync')
|
||||
elif not needs_fakesync and fakesync:
|
||||
Logger.error('Fakesync not required, aborting.')
|
||||
sys.exit(1)
|
||||
@ -163,7 +166,7 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror,
|
||||
|
||||
# change into package directory
|
||||
directory = src_pkg.source + '-' + new_ver.upstream_version
|
||||
Logger.command(('cd', directory))
|
||||
Logger.debug('cd' + directory)
|
||||
os.chdir(directory)
|
||||
|
||||
# read Debian distribution from debian/changelog if not specified
|
||||
@ -183,9 +186,9 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror,
|
||||
cmd.append("-sa")
|
||||
else:
|
||||
cmd.append("-sd")
|
||||
if not Logger.verbose:
|
||||
if not Logger.isEnabledFor(logging.DEBUG):
|
||||
cmd += ["-q"]
|
||||
Logger.command(cmd + ['>', '../' + changes_filename])
|
||||
Logger.debug(' '.join(cmd) + '> ../' + changes_filename)
|
||||
changes = subprocess.check_output(cmd, encoding='utf-8')
|
||||
|
||||
# Add additional bug numbers
|
||||
@ -193,7 +196,7 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror,
|
||||
changes = add_fixed_bugs(changes, bugs)
|
||||
|
||||
# remove extracted (temporary) files
|
||||
Logger.command(('cd', '..'))
|
||||
Logger.debug('cd ..')
|
||||
os.chdir('..')
|
||||
shutil.rmtree(directory, True)
|
||||
|
||||
@ -208,7 +211,7 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror,
|
||||
cmd = ["debsign", changes_filename]
|
||||
if keyid is not None:
|
||||
cmd.insert(1, "-k" + keyid)
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
subprocess.check_call(cmd)
|
||||
else:
|
||||
# Create fakesync changelog entry
|
||||
@ -223,14 +226,14 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror,
|
||||
cmd = ['dch', '-v', new_ver.full_version, '--force-distribution',
|
||||
'-D', release, message]
|
||||
env = {'DEBFULLNAME': name, 'DEBEMAIL': email}
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
subprocess.check_call(cmd, env=env)
|
||||
|
||||
# update the Maintainer field
|
||||
cmd = ["update-maintainer"]
|
||||
if not Logger.verbose:
|
||||
if not Logger.isEnabledFor(logging.DEBUG):
|
||||
cmd.append("-q")
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
# Build source package
|
||||
@ -240,7 +243,7 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror,
|
||||
cmd += ['-sa']
|
||||
if keyid:
|
||||
cmd += ["-k" + keyid]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
returncode = subprocess.call(cmd)
|
||||
if returncode != 0:
|
||||
Logger.error('Source-only build with debuild failed. '
|
||||
@ -339,9 +342,9 @@ def copy(src_pkg, release, bugs, sponsoree=None, simulate=False, force=False):
|
||||
ubuntu_spph.getComponent(),
|
||||
mirrors=[])
|
||||
|
||||
Logger.normal('Source %s -> %s/%s: current version %s, new version %s',
|
||||
src_pkg.source, ubuntu_series, ubuntu_pocket,
|
||||
ubuntu_pkg.version, src_pkg.version)
|
||||
Logger.info('Source %s -> %s/%s: current version %s, new version %s',
|
||||
src_pkg.source, ubuntu_series, ubuntu_pocket,
|
||||
ubuntu_pkg.version, src_pkg.version)
|
||||
|
||||
ubuntu_version = Version(ubuntu_pkg.version.full_version)
|
||||
base_version = ubuntu_version.get_related_debian_version()
|
||||
@ -358,21 +361,21 @@ def copy(src_pkg, release, bugs, sponsoree=None, simulate=False, force=False):
|
||||
sys.exit(1)
|
||||
except udtexceptions.PackageNotFoundException:
|
||||
base_version = Version('~')
|
||||
Logger.normal('Source %s -> %s/%s: not in Ubuntu, new version %s',
|
||||
src_pkg.source, ubuntu_series, ubuntu_pocket,
|
||||
src_pkg.version)
|
||||
Logger.info('Source %s -> %s/%s: not in Ubuntu, new version %s',
|
||||
src_pkg.source, ubuntu_series, ubuntu_pocket,
|
||||
src_pkg.version)
|
||||
|
||||
changes = debian_spph.getChangelog(since_version=base_version)
|
||||
if changes:
|
||||
changes = changes.strip()
|
||||
Logger.normal("New changes:\n%s", changes)
|
||||
Logger.info("New changes:\n%s", changes)
|
||||
|
||||
if simulate:
|
||||
return
|
||||
|
||||
if sponsoree:
|
||||
Logger.normal("Sponsoring this sync for %s (%s)",
|
||||
sponsoree.display_name, sponsoree.name)
|
||||
Logger.info("Sponsoring this sync for %s (%s)",
|
||||
sponsoree.display_name, sponsoree.name)
|
||||
answer = YesNoQuestion().ask("Sync this package", "no")
|
||||
if answer != "yes":
|
||||
return
|
||||
@ -392,14 +395,14 @@ def copy(src_pkg, release, bugs, sponsoree=None, simulate=False, force=False):
|
||||
Logger.error(error.content)
|
||||
sys.exit(1)
|
||||
|
||||
Logger.normal('Request succeeded; you should get an e-mail once it is '
|
||||
'processed.')
|
||||
Logger.info('Request succeeded; you should get an e-mail once it is '
|
||||
'processed.')
|
||||
bugs = sorted(set(bugs))
|
||||
if bugs:
|
||||
Logger.normal("Launchpad bugs to be closed: %s",
|
||||
', '.join(str(bug) for bug in bugs))
|
||||
Logger.normal('Please wait for the sync to be successful before '
|
||||
'closing bugs.')
|
||||
Logger.info("Launchpad bugs to be closed: %s",
|
||||
', '.join(str(bug) for bug in bugs))
|
||||
Logger.info('Please wait for the sync to be successful before '
|
||||
'closing bugs.')
|
||||
answer = YesNoQuestion().ask("Close bugs", "yes")
|
||||
if answer == "yes":
|
||||
close_bugs(bugs, src_pkg.source, src_pkg.version.full_version,
|
||||
@ -468,7 +471,7 @@ def close_bugs(bugs, package, version, changes, sponsoree):
|
||||
if target == ubuntu or (target.name == package and
|
||||
getattr(target, 'distribution', None) == ubuntu):
|
||||
if task.status != 'Fix Released':
|
||||
Logger.normal("Closed bug %s", task.web_link)
|
||||
Logger.info("Closed bug %s", task.web_link)
|
||||
task.status = 'Fix Released'
|
||||
task.lp_save()
|
||||
bug.newMessage(content=message)
|
||||
@ -597,7 +600,8 @@ def main():
|
||||
'''Handle parameters and get the ball rolling'''
|
||||
(options, package) = parse()
|
||||
|
||||
Logger.verbose = options.verbose
|
||||
if options.verbose:
|
||||
Logger.setLevel('DEBUG')
|
||||
config = UDTConfig(options.no_conf)
|
||||
if options.debian_mirror is None:
|
||||
options.debian_mirror = config.get_value('DEBIAN_MIRROR')
|
||||
@ -626,10 +630,10 @@ def main():
|
||||
options.release = "%s-proposed" % ubuntu.current_series.name
|
||||
|
||||
if not options.fakesync and not options.lp:
|
||||
Logger.warn("The use of --no-lp is not recommended for uploads "
|
||||
"targeted at Ubuntu. "
|
||||
"The archive-admins discourage its use, except for "
|
||||
"fakesyncs.")
|
||||
Logger.warning("The use of --no-lp is not recommended for uploads "
|
||||
"targeted at Ubuntu. "
|
||||
"The archive-admins discourage its use, except for "
|
||||
"fakesyncs.")
|
||||
|
||||
sponsoree = None
|
||||
if options.sponsoree:
|
||||
@ -687,17 +691,17 @@ def main():
|
||||
if blacklist_fail:
|
||||
Logger.error("Source package %s is blacklisted.", src_pkg.source)
|
||||
elif blacklisted == 'ALWAYS':
|
||||
Logger.normal("Source package %s is blacklisted.", src_pkg.source)
|
||||
Logger.info(u"Source package %s is blacklisted.", src_pkg.source)
|
||||
if messages:
|
||||
for message in messages:
|
||||
for line in textwrap.wrap(message):
|
||||
Logger.normal(line)
|
||||
Logger.info(line)
|
||||
|
||||
if comments:
|
||||
Logger.normal("Blacklist Comments:")
|
||||
Logger.info("Blacklist Comments:")
|
||||
for comment in comments:
|
||||
for line in textwrap.wrap(comment):
|
||||
Logger.normal(" " + line)
|
||||
Logger.info(" " + line)
|
||||
|
||||
if blacklist_fail:
|
||||
sys.exit(1)
|
||||
@ -717,4 +721,4 @@ if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
Logger.normal('User abort.')
|
||||
Logger.info('User abort.')
|
||||
|
68
ubuntu-build
68
ubuntu-build
@ -32,6 +32,9 @@ from ubuntutools.lp.udtexceptions import (SeriesNotFoundException,
|
||||
from ubuntutools.lp.lpapicache import Distribution, PersonTeam
|
||||
from ubuntutools.misc import split_release_pocket
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
def main():
|
||||
# Usage.
|
||||
@ -108,15 +111,15 @@ def main():
|
||||
|
||||
# Check our operation.
|
||||
if op not in ("rescore", "retry", "status"):
|
||||
print("Invalid operation: %s." % op, file=sys.stderr)
|
||||
Logger.error("Invalid operation: %s." % op)
|
||||
sys.exit(1)
|
||||
|
||||
# If the user has specified an architecture to build, we only wish to
|
||||
# rebuild it and nothing else.
|
||||
if options.architecture:
|
||||
if options.architecture[0] not in valid_archs:
|
||||
print("Invalid architecture specified: %s."
|
||||
% options.architecture[0], file=sys.stderr)
|
||||
Logger.error("Invalid architecture specified: %s."
|
||||
% options.architecture[0])
|
||||
sys.exit(1)
|
||||
else:
|
||||
one_arch = True
|
||||
@ -127,7 +130,7 @@ def main():
|
||||
try:
|
||||
(release, pocket) = split_release_pocket(release)
|
||||
except PocketDoesNotExistError as error:
|
||||
print('E: %s' % error)
|
||||
Logger.error(error)
|
||||
sys.exit(1)
|
||||
|
||||
# Get the ubuntu archive
|
||||
@ -141,7 +144,7 @@ def main():
|
||||
sources = ubuntu_archive.getSourcePackage(package, release, pocket)
|
||||
distroseries = Distribution('ubuntu').getSeries(release)
|
||||
except (SeriesNotFoundException, PackageNotFoundException) as error:
|
||||
print(error)
|
||||
Logger.error(error)
|
||||
sys.exit(1)
|
||||
# Get list of builds for that package.
|
||||
builds = sources.getBuilds()
|
||||
@ -163,16 +166,16 @@ def main():
|
||||
pocket=pocket)
|
||||
|
||||
if op in ('rescore', 'retry') and not necessary_privs:
|
||||
print(("You cannot perform the %s operation on a %s package as "
|
||||
"you do not have the permissions to do this action.")
|
||||
% (op, component), file=sys.stderr)
|
||||
Logger.error("You cannot perform the %s operation on a %s "
|
||||
"package as you do not have the permissions "
|
||||
"to do this action." % (op, component))
|
||||
sys.exit(1)
|
||||
|
||||
# Output details.
|
||||
print("The source version for '%s' in %s (%s) is at %s."
|
||||
% (package, release.capitalize(), component, version))
|
||||
Logger.info("The source version for '%s' in %s (%s) is at %s." %
|
||||
(package, release.capitalize(), component, version))
|
||||
|
||||
print("Current build status for this package:")
|
||||
Logger.info("Current build status for this package:")
|
||||
|
||||
# Output list of arches for package and their status.
|
||||
done = False
|
||||
@ -182,29 +185,28 @@ def main():
|
||||
continue
|
||||
|
||||
done = True
|
||||
print("%s: %s." % (build.arch_tag, build.buildstate))
|
||||
Logger.info("%s: %s." % (build.arch_tag, build.buildstate))
|
||||
if op == 'rescore':
|
||||
if build.can_be_rescored:
|
||||
# FIXME: make priority an option
|
||||
priority = 5000
|
||||
print('Rescoring build %s to %d...'
|
||||
% (build.arch_tag, priority))
|
||||
Logger.info('Rescoring build %s to %d...' % (build.arch_tag, priority))
|
||||
build.rescore(score=priority)
|
||||
else:
|
||||
print('Cannot rescore build on %s.' % build.arch_tag)
|
||||
Logger.info('Cannot rescore build on %s.' % build.arch_tag)
|
||||
if op == 'retry':
|
||||
if build.can_be_retried:
|
||||
print('Retrying build on %s...' % build.arch_tag)
|
||||
Logger.info('Retrying build on %s...' % build.arch_tag)
|
||||
build.retry()
|
||||
else:
|
||||
print('Cannot retry build on %s.' % build.arch_tag)
|
||||
Logger.info('Cannot retry build on %s.' % build.arch_tag)
|
||||
|
||||
# We are done
|
||||
if done:
|
||||
sys.exit(0)
|
||||
|
||||
print(("No builds for '%s' found in the %s release - it may have been "
|
||||
"built in a former release.") % (package, release.capitalize()))
|
||||
Logger.info("No builds for '%s' found in the %s release" % (package, release.capitalize()))
|
||||
Logger.info("It may have been built in a former release.")
|
||||
sys.exit(0)
|
||||
|
||||
# Batch mode
|
||||
@ -225,14 +227,14 @@ def main():
|
||||
try:
|
||||
(release, pocket) = split_release_pocket(release)
|
||||
except PocketDoesNotExistError as error:
|
||||
print('E: %s' % error)
|
||||
Logger.error(error)
|
||||
sys.exit(1)
|
||||
|
||||
ubuntu_archive = Distribution('ubuntu').getArchive()
|
||||
try:
|
||||
distroseries = Distribution('ubuntu').getSeries(release)
|
||||
except SeriesNotFoundException as error:
|
||||
print(error)
|
||||
Logger.error(error)
|
||||
sys.exit(1)
|
||||
me = PersonTeam.me
|
||||
|
||||
@ -241,14 +243,14 @@ def main():
|
||||
and me.isLpTeamMember('launchpad-buildd-admins'))
|
||||
or False)
|
||||
if options.priority and not can_rescore:
|
||||
print("You don't have the permissions to rescore builds. "
|
||||
"Ignoring your rescore request.", file=sys.stderr)
|
||||
Logger.error("You don't have the permissions to rescore "
|
||||
"builds. Ignoring your rescore request.")
|
||||
|
||||
for pkg in args:
|
||||
try:
|
||||
pkg = ubuntu_archive.getSourcePackage(pkg, release, pocket)
|
||||
except PackageNotFoundException as error:
|
||||
print(error)
|
||||
Logger.error(error)
|
||||
continue
|
||||
|
||||
# Check permissions (part 2): check upload permissions for the source
|
||||
@ -258,20 +260,20 @@ def main():
|
||||
pkg.getPackageName(),
|
||||
pkg.getComponent())
|
||||
if options.retry and not can_retry:
|
||||
print(("You don't have the permissions to retry the build of "
|
||||
"'%s'. Ignoring your request.")
|
||||
% pkg.getPackageName(), file=sys.stderr)
|
||||
Logger.error("You don't have the permissions to retry the "
|
||||
"build of '%s'. Ignoring your request."
|
||||
% pkg.getPackageName())
|
||||
|
||||
print("The source version for '%s' in '%s' (%s) is: %s"
|
||||
% (pkg.getPackageName(), release, pocket, pkg.getVersion()))
|
||||
Logger.info("The source version for '%s' in '%s' (%s) is: %s" %
|
||||
(pkg.getPackageName(), release, pocket, pkg.getVersion()))
|
||||
|
||||
print(pkg.getBuildStates(archs))
|
||||
Logger.info(pkg.getBuildStates(archs))
|
||||
if can_retry:
|
||||
print(pkg.retryBuilds(archs))
|
||||
Logger.info(pkg.retryBuilds(archs))
|
||||
if options.priority and can_rescore:
|
||||
print(pkg.rescoreBuilds(archs, options.priority))
|
||||
Logger.info(pkg.rescoreBuilds(archs, options.priority))
|
||||
|
||||
print()
|
||||
Logger.info('')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
18
ubuntu-iso
18
ubuntu-iso
@ -24,18 +24,21 @@ import optparse
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
def extract(iso, path):
|
||||
command = ['isoinfo', '-R', '-i', iso, '-x', path]
|
||||
pipe = subprocess.Popen(command, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, encoding='utf-8')
|
||||
stdout, stderr = pipe.communicate()
|
||||
pipe = subprocess.run(command, encoding='utf-8',
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
|
||||
if pipe.returncode != 0:
|
||||
sys.stderr.write(stderr)
|
||||
sys.stderr.write(pipe.stderr)
|
||||
sys.exit(pipe.returncode)
|
||||
|
||||
return stdout
|
||||
return pipe.stdout
|
||||
|
||||
|
||||
def main():
|
||||
@ -54,12 +57,11 @@ def main():
|
||||
version = extract(iso, '/.disk/info')
|
||||
|
||||
if len(version) == 0:
|
||||
print('%s does not appear to be an Ubuntu ISO' % iso,
|
||||
file=sys.stderr)
|
||||
Logger.error('%s does not appear to be an Ubuntu ISO' % iso)
|
||||
err = True
|
||||
continue
|
||||
|
||||
print(prefix + version)
|
||||
Logger.info(prefix + version)
|
||||
|
||||
if err:
|
||||
sys.exit(1)
|
||||
|
@ -20,9 +20,11 @@ import sys
|
||||
from ubuntutools.lp.lpapicache import (Launchpad, Distribution, PersonTeam,
|
||||
Packageset, PackageNotFoundException,
|
||||
SeriesNotFoundException)
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.misc import split_release_pocket
|
||||
|
||||
from ubuntutools import getLogger
|
||||
Logger = getLogger(__name__)
|
||||
|
||||
|
||||
def parse_arguments():
|
||||
'''Parse arguments and return (options, package)'''
|
||||
@ -77,52 +79,50 @@ def main():
|
||||
|
||||
component_uploader = archive.getUploadersForComponent(
|
||||
component_name=component)[0]
|
||||
print("All upload permissions for %s:" % package)
|
||||
print()
|
||||
print("Component (%s)" % component)
|
||||
print("============" + ("=" * len(component)))
|
||||
Logger.info("All upload permissions for %s:" % package)
|
||||
Logger.info("")
|
||||
Logger.info("Component (%s)" % component)
|
||||
Logger.info("============" + ("=" * len(component)))
|
||||
print_uploaders([component_uploader], options.list_team_members)
|
||||
|
||||
packagesets = sorted(Packageset.setsIncludingSource(
|
||||
distroseries=series,
|
||||
sourcepackagename=package))
|
||||
if packagesets:
|
||||
print()
|
||||
print("Packagesets")
|
||||
print("===========")
|
||||
Logger.info("")
|
||||
Logger.info("Packagesets")
|
||||
Logger.info("===========")
|
||||
for packageset in packagesets:
|
||||
print()
|
||||
print("%s:" % packageset.name)
|
||||
Logger.info("")
|
||||
Logger.info("%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()
|
||||
Logger.info("")
|
||||
Logger.info("Per-Package-Uploaders")
|
||||
Logger.info("=====================")
|
||||
Logger.info("")
|
||||
print_uploaders(ppu_uploaders, options.list_team_members)
|
||||
print()
|
||||
Logger.info("")
|
||||
|
||||
if PersonTeam.me.canUploadPackage(archive, series, package, component,
|
||||
pocket):
|
||||
print("You can upload %s to %s." % (package, options.release))
|
||||
Logger.info("You can upload %s to %s." % (package, options.release))
|
||||
else:
|
||||
print("You can not upload %s to %s, yourself."
|
||||
% (package, options.release))
|
||||
Logger.info("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))
|
||||
Logger.info("%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")
|
||||
Logger.info("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.")
|
||||
Logger.info("To see who has the necessary upload rights, "
|
||||
"use the --list-uploaders option.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@ -133,9 +133,9 @@ def print_uploaders(uploaders, expand_teams=False, prefix=''):
|
||||
recursion.
|
||||
"""
|
||||
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 '')))
|
||||
Logger.info("%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 + ' ')
|
||||
|
||||
|
@ -2,3 +2,20 @@
|
||||
#
|
||||
# Ubuntu Development Tools
|
||||
# https://launchpad.net/ubuntu-dev-tools
|
||||
|
||||
import logging
|
||||
|
||||
|
||||
def _loggingBasicConfig(**kwargs):
|
||||
'''Set log level to INFO and define log format to use.'''
|
||||
if 'level' not in kwargs:
|
||||
kwargs['level'] = logging.INFO
|
||||
if 'format' not in kwargs:
|
||||
kwargs['format'] = '%(message)s'
|
||||
logging.basicConfig(**kwargs)
|
||||
|
||||
|
||||
def getLogger(name=None):
|
||||
'''Get standard Python logging.Logger with some ubuntutools defaults.'''
|
||||
_loggingBasicConfig()
|
||||
return logging.getLogger(name)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,8 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from ubuntutools.logger import Logger
|
||||
import logging
|
||||
Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _build_preparation(result_directory):
|
||||
@ -34,8 +35,7 @@ class Builder(object):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
cmd = ["dpkg-architecture", "-qDEB_BUILD_ARCH_CPU"]
|
||||
self.architecture = subprocess.check_output(
|
||||
cmd, encoding='utf-8').strip()
|
||||
self.architecture = subprocess.check_output(cmd, encoding='utf-8').strip()
|
||||
|
||||
def _build_failure(self, returncode, dsc_file):
|
||||
if returncode != 0:
|
||||
@ -72,7 +72,7 @@ class Pbuilder(Builder):
|
||||
self.name, "--build",
|
||||
"--architecture", self.architecture, "--distribution", dist,
|
||||
"--buildresult", result_directory, dsc_file]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
returncode = subprocess.call(cmd)
|
||||
return self._build_failure(returncode, dsc_file)
|
||||
|
||||
@ -80,7 +80,7 @@ class Pbuilder(Builder):
|
||||
cmd = ["sudo", "-E", "ARCH=" + self.architecture, "DIST=" + dist,
|
||||
self.name, "--update",
|
||||
"--architecture", self.architecture, "--distribution", dist]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
returncode = subprocess.call(cmd)
|
||||
return self._update_failure(returncode, dist)
|
||||
|
||||
@ -93,13 +93,13 @@ class Pbuilderdist(Builder):
|
||||
_build_preparation(result_directory)
|
||||
cmd = [self.name, dist, self.architecture,
|
||||
"build", dsc_file, "--buildresult", result_directory]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
returncode = subprocess.call(cmd)
|
||||
return self._build_failure(returncode, dsc_file)
|
||||
|
||||
def update(self, dist):
|
||||
cmd = [self.name, dist, self.architecture, "update"]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
returncode = subprocess.call(cmd)
|
||||
return self._update_failure(returncode, dist)
|
||||
|
||||
@ -111,22 +111,21 @@ class Sbuild(Builder):
|
||||
def build(self, dsc_file, dist, result_directory):
|
||||
_build_preparation(result_directory)
|
||||
workdir = os.getcwd()
|
||||
Logger.command(["cd", result_directory])
|
||||
Logger.debug("cd " + result_directory)
|
||||
os.chdir(result_directory)
|
||||
cmd = ["sbuild", "--arch-all", "--dist=" + dist,
|
||||
"--arch=" + self.architecture, dsc_file]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
returncode = subprocess.call(cmd)
|
||||
Logger.command(["cd", workdir])
|
||||
Logger.debug("cd " + workdir)
|
||||
os.chdir(workdir)
|
||||
return self._build_failure(returncode, dsc_file)
|
||||
|
||||
def update(self, dist):
|
||||
cmd = ["schroot", "--list"]
|
||||
Logger.command(cmd)
|
||||
process = subprocess.Popen(
|
||||
cmd, stdout=subprocess.PIPE, encoding='utf-8')
|
||||
chroots, _ = process.communicate()[0].strip().split()
|
||||
Logger.debug(' '.join(cmd))
|
||||
process = subprocess.run(cmd, stdout=subprocess.PIPE, encoding='utf-8')
|
||||
chroots, _ = process.stdout.strip().split()
|
||||
if process.returncode != 0:
|
||||
return process.returncode
|
||||
|
||||
@ -146,7 +145,7 @@ class Sbuild(Builder):
|
||||
["sbuild-clean", "-a", "-c"]]
|
||||
for cmd in commands:
|
||||
# pylint: disable=W0631
|
||||
Logger.command(cmd + [chroot])
|
||||
Logger.debug(' '.join(cmd) + " " + chroot)
|
||||
ret = subprocess.call(cmd + [chroot])
|
||||
# pylint: enable=W0631
|
||||
if ret != 0:
|
||||
|
@ -23,7 +23,8 @@ import socket
|
||||
import sys
|
||||
import locale
|
||||
|
||||
from ubuntutools.logger import Logger
|
||||
import logging
|
||||
Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UDTConfig(object):
|
||||
@ -37,10 +38,12 @@ class UDTConfig(object):
|
||||
'BUILDER': 'pbuilder',
|
||||
'DEBIAN_MIRROR': 'http://deb.debian.org/debian',
|
||||
'DEBSEC_MIRROR': 'http://security.debian.org',
|
||||
'DEBIAN_DDEBS_MIRROR': 'http://debug.mirrors.debian.org/debian-debug',
|
||||
'LPINSTANCE': 'production',
|
||||
'MIRROR_FALLBACK': True,
|
||||
'UBUNTU_MIRROR': 'http://archive.ubuntu.com/ubuntu',
|
||||
'UBUNTU_PORTS_MIRROR': 'http://ports.ubuntu.com',
|
||||
'UBUNTU_DDEBS_MIRROR': 'http://ddebs.ubuntu.com',
|
||||
'UPDATE_BUILDER': False,
|
||||
'WORKDIR': None,
|
||||
'KEYID': None,
|
||||
@ -69,8 +72,8 @@ class UDTConfig(object):
|
||||
for line in f:
|
||||
parsed = shlex.split(line, comments=True)
|
||||
if len(parsed) > 1:
|
||||
Logger.warn('Cannot parse variable assignment in %s: %s',
|
||||
getattr(f, 'name', '<config>'), line)
|
||||
Logger.warning('Cannot parse variable assignment in %s: %s',
|
||||
getattr(f, 'name', '<config>'), line)
|
||||
if len(parsed) >= 1 and '=' in parsed[0]:
|
||||
key, value = parsed[0].split('=', 1)
|
||||
config[key] = value
|
||||
@ -109,10 +112,8 @@ class UDTConfig(object):
|
||||
replacements = self.prefix + '_' + key
|
||||
if key in self.defaults:
|
||||
replacements += 'or UBUNTUTOOLS_' + key
|
||||
Logger.warn(
|
||||
'Using deprecated configuration variable %s. '
|
||||
'You should use %s.',
|
||||
k, replacements)
|
||||
Logger.warning('Using deprecated configuration variable %s. '
|
||||
'You should use %s.', k, replacements)
|
||||
return value
|
||||
return default
|
||||
|
||||
|
@ -1,76 +0,0 @@
|
||||
#
|
||||
# logger.py - A simple logging helper class
|
||||
#
|
||||
# Copyright (C) 2010, Benjamin Drung <bdrung@debian.org>
|
||||
#
|
||||
# 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 os
|
||||
import sys
|
||||
|
||||
|
||||
def escape_arg(arg):
|
||||
"""Shell-escpae arg, if necessary.
|
||||
Fairly simplistic, doesn't escape anything except whitespace.
|
||||
"""
|
||||
if ' ' not in arg:
|
||||
return arg
|
||||
return '"%s"' % arg.replace('\\', r'\\').replace('"', r'\"')
|
||||
|
||||
|
||||
class Logger(object):
|
||||
script_name = os.path.basename(sys.argv[0])
|
||||
verbose = False
|
||||
|
||||
stdout = sys.stdout
|
||||
stderr = sys.stderr
|
||||
|
||||
@classmethod
|
||||
def _print(cls, format_, message, args=None, stderr=False):
|
||||
if args:
|
||||
message = message % args
|
||||
stream = cls.stderr if stderr else cls.stdout
|
||||
stream.write((format_ + "\n") % (cls.script_name, message))
|
||||
|
||||
@classmethod
|
||||
def command(cls, cmd):
|
||||
if cls.verbose:
|
||||
cls._print("%s: I: %s", " ".join(escape_arg(arg) for arg in cmd))
|
||||
|
||||
@classmethod
|
||||
def debug(cls, message, *args):
|
||||
if cls.verbose:
|
||||
cls._print("%s: D: %s", message, args, stderr=True)
|
||||
|
||||
@classmethod
|
||||
def error(cls, message, *args):
|
||||
cls._print("%s: Error: %s", message, args, stderr=True)
|
||||
|
||||
@classmethod
|
||||
def warn(cls, message, *args):
|
||||
cls._print("%s: Warning: %s", message, args, stderr=True)
|
||||
|
||||
@classmethod
|
||||
def info(cls, message, *args):
|
||||
if cls.verbose:
|
||||
cls._print("%s: I: %s", message, args)
|
||||
|
||||
@classmethod
|
||||
def normal(cls, message, *args):
|
||||
cls._print("%s: %s", message, args)
|
||||
|
||||
@classmethod
|
||||
def set_verbosity(cls, verbose):
|
||||
cls.verbose = verbose
|
@ -3,4 +3,4 @@
|
||||
#
|
||||
|
||||
service = 'production'
|
||||
api_version = '1.0'
|
||||
api_version = 'devel'
|
||||
|
@ -26,7 +26,7 @@
|
||||
# httplib2.debuglevel = 1
|
||||
|
||||
import collections
|
||||
import sys
|
||||
import re
|
||||
|
||||
from debian.changelog import Changelog
|
||||
from httplib2 import Http, HttpLib2Error
|
||||
@ -36,6 +36,9 @@ from lazr.restfulclient.resource import Entry
|
||||
|
||||
from ubuntutools.version import Version
|
||||
from ubuntutools.lp import (service, api_version)
|
||||
from ubuntutools.misc import (host_architecture,
|
||||
DEFAULT_POCKETS, POCKETS,
|
||||
DEFAULT_STATUSES, STATUSES)
|
||||
from ubuntutools.lp.udtexceptions import (AlreadyLoggedInError,
|
||||
ArchiveNotFoundException,
|
||||
ArchSeriesNotFoundException,
|
||||
@ -43,6 +46,9 @@ from ubuntutools.lp.udtexceptions import (AlreadyLoggedInError,
|
||||
PocketDoesNotExistError,
|
||||
SeriesNotFoundException)
|
||||
|
||||
import logging
|
||||
Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
__all__ = [
|
||||
'Archive',
|
||||
@ -51,13 +57,12 @@ __all__ = [
|
||||
'Distribution',
|
||||
'DistributionSourcePackage',
|
||||
'DistroSeries',
|
||||
'DistroArchSeries',
|
||||
'Launchpad',
|
||||
'PersonTeam',
|
||||
'SourcePackagePublishingHistory',
|
||||
]
|
||||
|
||||
_POCKETS = ('Release', 'Security', 'Updates', 'Proposed', 'Backports')
|
||||
|
||||
|
||||
class _Launchpad(object):
|
||||
'''Singleton for LP API access.'''
|
||||
@ -69,7 +74,7 @@ class _Launchpad(object):
|
||||
self.__lp = LP.login_with('ubuntu-dev-tools', service,
|
||||
version=api_version)
|
||||
except IOError as error:
|
||||
print('E: %s' % error, file=sys.stderr)
|
||||
Logger.error(str(error))
|
||||
raise
|
||||
else:
|
||||
raise AlreadyLoggedInError('Already logged in to Launchpad.')
|
||||
@ -150,6 +155,7 @@ class BaseWrapper(object, metaclass=MetaWrapper):
|
||||
cached._lpobject = data
|
||||
# and add it to our cache
|
||||
cls._cache[data.self_link] = cached
|
||||
Logger.debug("%s: %s" % (cls.__name__, data.self_link))
|
||||
# add additional class specific caching (if available)
|
||||
cache = getattr(cls, 'cache', None)
|
||||
if isinstance(cache, collections.Callable):
|
||||
@ -188,15 +194,23 @@ class Distribution(BaseWrapper):
|
||||
resource_type = 'distribution'
|
||||
|
||||
def __init__(self, *args):
|
||||
# Don't share _series and _archives between different Distributions
|
||||
if '_series' not in self.__dict__:
|
||||
self._series = dict()
|
||||
if '_archives' not in self.__dict__:
|
||||
self._archives = dict()
|
||||
self._archives = dict()
|
||||
self._series_by_name = dict()
|
||||
self._series = dict()
|
||||
self._dev_series = None
|
||||
self._have_all_series = False
|
||||
|
||||
def cache(self):
|
||||
self._cache[self.name] = self
|
||||
|
||||
def _cache_series(self, series):
|
||||
'''
|
||||
Add the DistroSeries to the cache if needed.
|
||||
'''
|
||||
if series.version not in self._series:
|
||||
self._series_by_name[series.name] = series
|
||||
self._series[series.version] = series
|
||||
|
||||
@classmethod
|
||||
def fetch(cls, dist):
|
||||
'''
|
||||
@ -243,28 +257,49 @@ class Distribution(BaseWrapper):
|
||||
(e.g. 'karmic') or version (e.g. '9.10').
|
||||
If the series is not found: raise SeriesNotFoundException
|
||||
'''
|
||||
if name_or_version not in self._series:
|
||||
try:
|
||||
series = DistroSeries(self().getSeries(name_or_version=name_or_version))
|
||||
# Cache with name and version
|
||||
self._series[series.name] = series
|
||||
self._series[series.version] = series
|
||||
except HTTPError:
|
||||
message = "Release '%s' is unknown in '%s'." % \
|
||||
(name_or_version, self.display_name)
|
||||
raise SeriesNotFoundException(message)
|
||||
return self._series[name_or_version]
|
||||
if name_or_version in self._series:
|
||||
return self._series[name_or_version]
|
||||
if name_or_version in self._series_by_name:
|
||||
return self._series_by_name[name_or_version]
|
||||
|
||||
try:
|
||||
series = DistroSeries(self().getSeries(name_or_version=name_or_version))
|
||||
except HTTPError:
|
||||
message = "Release '%s' is unknown in '%s'." % \
|
||||
(name_or_version, self.display_name)
|
||||
raise SeriesNotFoundException(message)
|
||||
|
||||
self._cache_series(series)
|
||||
return series
|
||||
|
||||
def getDevelopmentSeries(self):
|
||||
'''
|
||||
Returns a DistroSeries object of the current development series.
|
||||
'''
|
||||
dev = DistroSeries(self.current_series_link)
|
||||
# Cache it in _series if not already done
|
||||
if dev.name not in self._series:
|
||||
self._series[dev.name] = dev
|
||||
self._series[dev.version] = dev
|
||||
return dev
|
||||
if not self._dev_series:
|
||||
series = DistroSeries(self.current_series_link)
|
||||
self._cache_series(series)
|
||||
self._dev_series = series
|
||||
return self._dev_series
|
||||
|
||||
def getAllSeries(self, active=True):
|
||||
'''
|
||||
Returns a list of all DistroSeries objects.
|
||||
'''
|
||||
if not self._have_all_series:
|
||||
for s in Launchpad.load(self.series_collection_link).entries:
|
||||
series = DistroSeries(s['self_link'])
|
||||
self._cache_series(series)
|
||||
self._have_all_series = True
|
||||
|
||||
allseries = filter(lambda s: s.active, self._series.values())
|
||||
allseries = sorted(allseries,
|
||||
key=lambda s: float(s.version),
|
||||
reverse=True)
|
||||
Logger.debug("Found series: %s" % ", ".join(map(lambda s: "%s (%s)" %
|
||||
(s.name, s.version),
|
||||
allseries)))
|
||||
return collections.OrderedDict((s.name, s) for s in allseries)
|
||||
|
||||
|
||||
class DistroArchSeries(BaseWrapper):
|
||||
@ -273,6 +308,12 @@ class DistroArchSeries(BaseWrapper):
|
||||
'''
|
||||
resource_type = 'distro_arch_series'
|
||||
|
||||
def getSeries(self):
|
||||
'''
|
||||
Get DistroSeries for this.
|
||||
'''
|
||||
return DistroSeries(self._lpobject.distroseries_link)
|
||||
|
||||
|
||||
class DistroSeries(BaseWrapper):
|
||||
'''
|
||||
@ -284,12 +325,16 @@ class DistroSeries(BaseWrapper):
|
||||
if "_architectures" not in self.__dict__:
|
||||
self._architectures = dict()
|
||||
|
||||
def getArchSeries(self, archtag):
|
||||
def getArchSeries(self, archtag=None):
|
||||
'''
|
||||
Returns a DistroArchSeries object for an architecture passed by name
|
||||
(e.g. 'amd64').
|
||||
If arch is not specified, get the DistroArchSeries for the system arch.
|
||||
The special archtag 'all' will get the system arch.
|
||||
If the architecture is not found: raise ArchSeriesNotFoundException.
|
||||
'''
|
||||
if not archtag or archtag == 'all':
|
||||
archtag = host_architecture()
|
||||
if archtag not in self._architectures:
|
||||
try:
|
||||
architecture = DistroArchSeries(
|
||||
@ -315,16 +360,35 @@ class Archive(BaseWrapper):
|
||||
self._pkgset_uploaders = {}
|
||||
self._component_uploaders = {}
|
||||
|
||||
def getSourcePackage(self, name, series=None, pocket=None):
|
||||
def getSourcePackage(self, name, series=None, pocket=None, version=None,
|
||||
status=None, wrapper=None, search_all_series=False):
|
||||
'''
|
||||
Returns a SourcePackagePublishingHistory object for the most
|
||||
recent source package in the distribution 'dist', series and
|
||||
pocket.
|
||||
|
||||
series defaults to the current development series if not specified.
|
||||
series must be either a series name string, or DistroSeries object.
|
||||
|
||||
pocket may be a list, if so, the highest version will be returned.
|
||||
It defaults to all pockets except backports.
|
||||
version may be specified to get only the exact version requested.
|
||||
|
||||
pocket may be a string or a list. If no version is provided, it
|
||||
defaults to all pockets except 'Backports'; if searching for a
|
||||
specific version, it defaults to all pockets. Pocket strings must
|
||||
be capitalized.
|
||||
|
||||
status may be a string or a list. If no version is provided, it
|
||||
defaults to only 'Pending' and 'Published'; if searching for a
|
||||
specific version, it defaults to all statuses. Status strings must
|
||||
be capitalized.
|
||||
|
||||
wrapper is the class to return an instance of; defaults to
|
||||
SourcePackagePublishingHistory.
|
||||
|
||||
search_all_series is used if series is None. If False, this will
|
||||
search only the latest devel series, and if True all series
|
||||
will be searched, in reverse order, starting with the latest
|
||||
devel series. Defaults to False.
|
||||
|
||||
If the requested source package doesn't exist a
|
||||
PackageNotFoundException is raised.
|
||||
@ -332,113 +396,236 @@ class Archive(BaseWrapper):
|
||||
return self._getPublishedItem(name, series, pocket, cache=self._srcpkgs,
|
||||
function='getPublishedSources',
|
||||
name_key='source_name',
|
||||
wrapper=SourcePackagePublishingHistory)
|
||||
wrapper=wrapper or SourcePackagePublishingHistory,
|
||||
version=version,
|
||||
status=status,
|
||||
search_all_series=search_all_series,
|
||||
binary=False)
|
||||
|
||||
def getBinaryPackage(self, name, archtag=None, series=None, pocket=None):
|
||||
def getBinaryPackage(self, name, archtag=None, series=None, pocket=None,
|
||||
version=None, status=None, wrapper=None,
|
||||
search_all_series=False):
|
||||
'''
|
||||
Returns a BinaryPackagePublishingHistory object for the most
|
||||
recent source package in the distribution 'dist', architecture
|
||||
'archtag', series and pocket.
|
||||
|
||||
series defaults to the current development series if not specified.
|
||||
series must be either a series name string, or DistroArchSeries object.
|
||||
series may be omitted if version is specified.
|
||||
|
||||
pocket may be a list, if so, the highest version will be returned.
|
||||
It defaults to all pockets except backports.
|
||||
version may be specified to get only the exact version requested.
|
||||
|
||||
pocket may be a string or a list. If no version is provided, it
|
||||
defaults to all pockets except 'Backports'; if searching for a
|
||||
specific version, it defaults to all pockets. Pocket strings must
|
||||
be capitalized.
|
||||
|
||||
status may be a string or a list. If no version is provided, it
|
||||
defaults to only 'Pending' and 'Published'; if searching for a
|
||||
specific version, it defaults to all statuses. Status strings must
|
||||
be capitalized.
|
||||
|
||||
wrapper is the class to return an instance of; defaults to
|
||||
BinaryPackagePublishingHistory.
|
||||
|
||||
search_all_series is used if series is None. If False, this will
|
||||
search only the latest devel series, and if True all series
|
||||
will be searched, in reverse order, starting with the latest
|
||||
devel series. Defaults to False.
|
||||
|
||||
If the requested binary package doesn't exist a
|
||||
PackageNotFoundException is raised.
|
||||
'''
|
||||
if archtag is None:
|
||||
archtag = []
|
||||
return self._getPublishedItem(name, series, pocket, archtag=archtag,
|
||||
cache=self._binpkgs,
|
||||
function='getPublishedBinaries',
|
||||
name_key='binary_name',
|
||||
wrapper=BinaryPackagePublishingHistory)
|
||||
wrapper=wrapper or BinaryPackagePublishingHistory,
|
||||
version=version,
|
||||
status=status,
|
||||
search_all_series=search_all_series,
|
||||
binary=True)
|
||||
|
||||
def _getPublishedItem(self, name, series, pocket, cache,
|
||||
function, name_key, wrapper, archtag=None):
|
||||
'''Common code between getSourcePackage and getBinaryPackage
|
||||
function, name_key, wrapper, archtag=None,
|
||||
version=None, status=None, search_all_series=False,
|
||||
binary=False):
|
||||
'''
|
||||
if pocket is None:
|
||||
pockets = frozenset(('Proposed', 'Updates', 'Security', 'Release'))
|
||||
elif isinstance(pocket, str):
|
||||
pockets = frozenset((pocket,))
|
||||
else:
|
||||
pockets = frozenset(pocket)
|
||||
Common code between getSourcePackage and getBinaryPackage.
|
||||
|
||||
for pocket in pockets:
|
||||
if pocket not in _POCKETS:
|
||||
raise PocketDoesNotExistError("Pocket '%s' does not exist." %
|
||||
pocket)
|
||||
Don't use this directly.
|
||||
'''
|
||||
if not pocket:
|
||||
if version and not series:
|
||||
# check ALL pockets if specific version in any series
|
||||
pockets = POCKETS
|
||||
else:
|
||||
# otherwise, check all pockets EXCEPT 'Backports'
|
||||
pockets = DEFAULT_POCKETS
|
||||
elif isinstance(pocket, str):
|
||||
pockets = (pocket,)
|
||||
else:
|
||||
pockets = tuple(pocket)
|
||||
|
||||
for p in pockets:
|
||||
if p not in POCKETS:
|
||||
raise PocketDoesNotExistError("Pocket '%s' does not exist." % p)
|
||||
|
||||
if not status:
|
||||
if version:
|
||||
# check ALL statuses if specific version
|
||||
statuses = STATUSES
|
||||
else:
|
||||
# otherwise, only check 'Pending' and 'Published'
|
||||
statuses = DEFAULT_STATUSES
|
||||
elif isinstance(status, str):
|
||||
statuses = (status,)
|
||||
else:
|
||||
statuses = tuple(status)
|
||||
|
||||
for s in statuses:
|
||||
if s not in STATUSES:
|
||||
raise ValueError("Status '%s' is not valid." % s)
|
||||
|
||||
dist = Distribution(self.distribution_link)
|
||||
# Check if series is already a DistroSeries object or not
|
||||
if not isinstance(series, DistroSeries):
|
||||
if series:
|
||||
|
||||
# please don't pass DistroArchSeries as archtag!
|
||||
# but, the code was like that before so keep
|
||||
# backwards compatibility.
|
||||
if isinstance(archtag, DistroArchSeries):
|
||||
series = archtag
|
||||
archtag = None
|
||||
|
||||
series_to_check = [series]
|
||||
if not version and not series:
|
||||
# if neither version or series are specified, use either the
|
||||
# devel series or search all series
|
||||
if search_all_series:
|
||||
series_to_check = dist.getAllSeries().values()
|
||||
else:
|
||||
series_to_check = [dist.getDevelopmentSeries()]
|
||||
|
||||
# check each series - if only version was provided, series will be None
|
||||
for series in series_to_check:
|
||||
arch_series = None
|
||||
|
||||
if isinstance(series, DistroArchSeries):
|
||||
arch_series = series
|
||||
series = series.getSeries()
|
||||
elif isinstance(series, DistroSeries):
|
||||
pass
|
||||
elif series:
|
||||
series = dist.getSeries(series)
|
||||
else:
|
||||
series = dist.getDevelopmentSeries()
|
||||
|
||||
# getPublishedSources requires a distro_series, while
|
||||
# getPublishedBinaries requires a distro_arch_series.
|
||||
# If archtag is not None, I'll assume it's getPublishedBinaries.
|
||||
if archtag is not None and archtag != []:
|
||||
if not isinstance(archtag, DistroArchSeries):
|
||||
arch_series = series.getArchSeries(archtag=archtag)
|
||||
else:
|
||||
arch_series = archtag
|
||||
if binary:
|
||||
if arch_series is None and series:
|
||||
arch_series = series.getArchSeries(archtag=archtag)
|
||||
if archtag is None and arch_series:
|
||||
archtag = arch_series.architecture_tag
|
||||
if archtag is None:
|
||||
archtag = host_architecture()
|
||||
|
||||
if archtag is not None and archtag != []:
|
||||
index = (name, series.name, archtag, pockets)
|
||||
else:
|
||||
index = (name, series.name, pockets)
|
||||
index = (name, getattr(series, 'name', None), archtag, pockets, statuses, version)
|
||||
|
||||
if index in cache:
|
||||
return cache[index]
|
||||
|
||||
if index not in cache:
|
||||
params = {
|
||||
name_key: name,
|
||||
'status': 'Published',
|
||||
'exact_match': True,
|
||||
}
|
||||
if archtag is not None and archtag != []:
|
||||
|
||||
if arch_series:
|
||||
params['distro_arch_series'] = arch_series()
|
||||
else:
|
||||
elif series:
|
||||
params['distro_series'] = series()
|
||||
|
||||
if len(pockets) == 1:
|
||||
params['pocket'] = list(pockets)[0]
|
||||
params['pocket'] = pockets[0]
|
||||
|
||||
if len(statuses) == 1:
|
||||
params['status'] = statuses[0]
|
||||
|
||||
if version:
|
||||
params['version'] = version
|
||||
|
||||
Logger.debug('Calling %s(%s)' % (function,
|
||||
', '.join(['%s=%s' % (k, v)
|
||||
for (k, v) in params.items()])))
|
||||
records = getattr(self, function)(**params)
|
||||
|
||||
latest = None
|
||||
err_msg = ("does not exist in the %s %s archive" %
|
||||
(dist.display_name, self.name))
|
||||
|
||||
for record in records:
|
||||
if record.pocket not in pockets:
|
||||
continue
|
||||
if latest is None or (Version(latest.source_package_version)
|
||||
< Version(record.source_package_version)):
|
||||
latest = record
|
||||
|
||||
if latest is None:
|
||||
if name_key == 'binary_name':
|
||||
package_type = "binary package"
|
||||
elif name_key == 'source_name':
|
||||
package_type = "source package"
|
||||
if binary:
|
||||
rversion = getattr(record, 'binary_package_version', None)
|
||||
else:
|
||||
package_type = "package"
|
||||
msg = ("The %s '%s' does not exist in the %s %s archive" %
|
||||
(package_type, name, dist.display_name, self.name))
|
||||
if archtag is not None and archtag != []:
|
||||
msg += " for architecture %s" % archtag
|
||||
pockets = [series.name if pocket == 'Release'
|
||||
else '%s-%s' % (series.name, pocket.lower())
|
||||
for pocket in pockets]
|
||||
if len(pockets) > 1:
|
||||
pockets[-2:] = [' or '.join(pockets[-2:])]
|
||||
msg += " in " + ', '.join(pockets)
|
||||
raise PackageNotFoundException(msg)
|
||||
rversion = getattr(record, 'source_package_version', None)
|
||||
skipmsg = ('Skipping version %s: ' % rversion)
|
||||
|
||||
cache[index] = wrapper(latest)
|
||||
return cache[index]
|
||||
if record.pocket not in pockets:
|
||||
err_msg = 'pocket %s not in (%s)' % (record.pocket, ','.join(pockets))
|
||||
Logger.debug(skipmsg + err_msg)
|
||||
continue
|
||||
if record.status not in statuses:
|
||||
err_msg = 'status %s not in (%s)' % (record.status, ','.join(statuses))
|
||||
Logger.debug(skipmsg + err_msg)
|
||||
continue
|
||||
r = wrapper(record)
|
||||
if binary and archtag and archtag != r.arch:
|
||||
err_msg = 'arch %s does not match requested arch %s' % (r.arch, archtag)
|
||||
Logger.debug(skipmsg + err_msg)
|
||||
continue
|
||||
# results are ordered so first is latest
|
||||
cache[index] = r
|
||||
return r
|
||||
|
||||
version_with_epoch = None
|
||||
if version and version == Version(version).strip_epoch() and len(records) == 0:
|
||||
# a specific version was asked for, but we found none;
|
||||
# check if one exists with an epoch to give a hint in error msg
|
||||
for epoch in range(1, 9):
|
||||
v = Version(version)
|
||||
v.epoch = epoch
|
||||
params['version'] = v.full_version
|
||||
if len(getattr(self, function)(**params)) > 0:
|
||||
version_with_epoch = v.full_version
|
||||
Logger.debug('Found version with epoch %s' % version_with_epoch)
|
||||
break
|
||||
|
||||
if name_key == 'binary_name':
|
||||
package_type = "binary package"
|
||||
elif name_key == 'source_name':
|
||||
package_type = "source package"
|
||||
else:
|
||||
package_type = "package"
|
||||
msg = "The %s '%s' " % (package_type, name)
|
||||
if version:
|
||||
msg += "version %s " % version
|
||||
msg += err_msg
|
||||
if binary and archtag:
|
||||
msg += " for architecture %s" % archtag
|
||||
if len(series_to_check) > 1:
|
||||
msg += " in any release"
|
||||
if len(pockets) == 1:
|
||||
msg += " for pocket %s" % pockets[0]
|
||||
elif len(pockets) != len(POCKETS):
|
||||
msg += " for pockets " + ', '.join(pockets)
|
||||
elif series:
|
||||
msg += " in %s" % series.name
|
||||
if len(pockets) == 1:
|
||||
msg += "-%s" % pockets[0]
|
||||
elif len(pockets) != len(POCKETS):
|
||||
msg += " for pockets " + ', '.join(pockets)
|
||||
if len(statuses) == 1:
|
||||
msg += " with status %s" % statuses[0]
|
||||
elif len(statuses) != len(STATUSES):
|
||||
msg += " with status in " + ', '.join(statuses)
|
||||
if version_with_epoch:
|
||||
msg += " (did you forget the epoch? try %s)" % version_with_epoch
|
||||
raise PackageNotFoundException(msg)
|
||||
|
||||
def copyPackage(self, source_name, version, from_archive, to_pocket,
|
||||
to_series=None, sponsored=None, include_binaries=False):
|
||||
@ -509,13 +696,24 @@ class SourcePackagePublishingHistory(BaseWrapper):
|
||||
resource_type = 'source_package_publishing_history'
|
||||
|
||||
def __init__(self, *args):
|
||||
self._archive = None
|
||||
self._changelog = None
|
||||
self._binaries = None
|
||||
self._binaries = {}
|
||||
self._have_all_binaries = False
|
||||
self._distro_series = None
|
||||
# Don't share _builds between different
|
||||
# SourcePackagePublishingHistory objects
|
||||
if '_builds' not in self.__dict__:
|
||||
self._builds = dict()
|
||||
|
||||
def getDistroSeries(self):
|
||||
'''
|
||||
Return the DistroSeries.
|
||||
'''
|
||||
if not self._distro_series:
|
||||
self._distro_series = DistroSeries(self._lpobject.distro_series_link)
|
||||
return self._distro_series
|
||||
|
||||
def getPackageName(self):
|
||||
'''
|
||||
Returns the source package name.
|
||||
@ -534,16 +732,33 @@ class SourcePackagePublishingHistory(BaseWrapper):
|
||||
'''
|
||||
return self._lpobject.component_name
|
||||
|
||||
def getSeriesName(self):
|
||||
'''
|
||||
Returns the series
|
||||
|
||||
Named getSeriesName() to avoid confusion with
|
||||
getDistroSeries()
|
||||
'''
|
||||
return self.getDistroSeries().name
|
||||
|
||||
def getSeriesAndPocket(self):
|
||||
'''
|
||||
Returns a human-readable release-pocket
|
||||
'''
|
||||
series = DistroSeries(self._lpobject.distro_series_link)
|
||||
release = series.name
|
||||
if self._lpobject.pocket != 'Release':
|
||||
release += '-' + self._lpobject.pocket.lower()
|
||||
release = self.getSeriesName()
|
||||
if self.pocket != 'Release':
|
||||
release += '-' + self.pocket.lower()
|
||||
return release
|
||||
|
||||
def getArchive(self):
|
||||
'''
|
||||
Get this SPPH's archive.
|
||||
'''
|
||||
if not self._archive:
|
||||
self._archive = Archive(self._lpobject.archive_link)
|
||||
|
||||
return self._archive
|
||||
|
||||
def getChangelog(self, since_version=None):
|
||||
'''
|
||||
Return the changelog, optionally since a particular version
|
||||
@ -553,17 +768,17 @@ class SourcePackagePublishingHistory(BaseWrapper):
|
||||
if self._changelog is None:
|
||||
url = self._lpobject.changelogUrl()
|
||||
if url is None:
|
||||
print('E: No changelog available for %s %s' %
|
||||
(self.getPackageName(), self.getVersion()), file=sys.stderr)
|
||||
Logger.error('No changelog available for %s %s' %
|
||||
(self.getPackageName(), self.getVersion()))
|
||||
return None
|
||||
|
||||
try:
|
||||
response, changelog = Http().request(url)
|
||||
except HttpLib2Error as e:
|
||||
print(str(e), file=sys.stderr)
|
||||
Logger.error(str(e))
|
||||
return None
|
||||
if response.status != 200:
|
||||
print('%s: %s %s' % (url, response.status, response.reason), file=sys.stderr)
|
||||
Logger.error('%s: %s %s' % (url, response.status, response.reason))
|
||||
return None
|
||||
self._changelog = changelog
|
||||
|
||||
@ -580,15 +795,97 @@ class SourcePackagePublishingHistory(BaseWrapper):
|
||||
new_entries.append(str(block))
|
||||
return ''.join(new_entries)
|
||||
|
||||
def getBinaries(self):
|
||||
def getBinaries(self, arch, name=None, ext=None):
|
||||
'''
|
||||
Returns the resulting BinaryPackagePublishingHistorys
|
||||
Returns the resulting BinaryPackagePublishingHistorys.
|
||||
Must specify arch, or use 'all' to get all archs.
|
||||
|
||||
If name is specified, only returns BPPH matching that (regex) name.
|
||||
|
||||
If ext is specified, only returns BPPH matching that (regex) ext.
|
||||
'''
|
||||
if self._binaries is None:
|
||||
self._binaries = [BinaryPackagePublishingHistory(bpph)
|
||||
for bpph in
|
||||
self._lpobject.getPublishedBinaries()]
|
||||
return self._binaries
|
||||
if not arch:
|
||||
raise RuntimeError("Must specify arch")
|
||||
|
||||
# debs with arch 'all' have to be categorized as a specific arch
|
||||
# so use requested arch if not 'all', or system arch
|
||||
fallback_arch = arch
|
||||
if fallback_arch == 'all':
|
||||
fallback_arch = host_architecture()
|
||||
|
||||
if self._have_all_binaries:
|
||||
# Great!
|
||||
pass
|
||||
elif self.status in ["Pending", "Published"]:
|
||||
# Published, great! Directly query the list of binaries
|
||||
binaries = map(BinaryPackagePublishingHistory,
|
||||
self._lpobject.getPublishedBinaries())
|
||||
for b in binaries:
|
||||
a = b.arch
|
||||
if a == 'all':
|
||||
a = fallback_arch
|
||||
if a not in self._binaries:
|
||||
self._binaries[a] = {}
|
||||
self._binaries[a][b.binary_package_name] = b
|
||||
self._have_all_binaries = True
|
||||
else:
|
||||
# we have to go the long way :(
|
||||
Logger.info("Please wait, this may take some time...")
|
||||
archive = self.getArchive()
|
||||
urls = self.binaryFileUrls()
|
||||
for url in urls:
|
||||
# strip out the URL leading text.
|
||||
filename = url.rsplit('/', 1)[1]
|
||||
# strip the file suffix
|
||||
(pkgname, _, e) = filename.rpartition('.')
|
||||
# split into name, version, arch
|
||||
(n, v, a) = pkgname.rsplit('_', 2)
|
||||
if a == 'all':
|
||||
a = fallback_arch
|
||||
# Only check the arch requested - saves time
|
||||
if arch != 'all' and arch != a:
|
||||
continue
|
||||
# Only check the name requested - saves time
|
||||
if name and not re.match(name, n):
|
||||
continue
|
||||
# Only check the ext requested - saves time
|
||||
if ext and not re.match(ext, e):
|
||||
continue
|
||||
# If we already have this BPPH, keep going
|
||||
if a in self._binaries and n in self._binaries[a]:
|
||||
continue
|
||||
# we ignore the version, as it may be missing epoch
|
||||
# also we can't use series, as some package versions
|
||||
# span multiple series! (e.g. for different archs)
|
||||
params = {'name': n,
|
||||
'archtag': a,
|
||||
'version': self.getVersion()}
|
||||
try:
|
||||
bpph = archive.getBinaryPackage(**params)
|
||||
except PackageNotFoundException:
|
||||
Logger.debug("Could not find pkg in archive: %s" % filename)
|
||||
continue
|
||||
if a not in self._binaries:
|
||||
self._binaries[a] = {}
|
||||
self._binaries[a][n] = bpph
|
||||
if not name and not ext and arch == 'all':
|
||||
# We must have got them all
|
||||
self._have_all_binaries = True
|
||||
|
||||
bpphs = []
|
||||
if arch == 'all':
|
||||
for a in self._binaries.values():
|
||||
bpphs += a.values()
|
||||
elif arch in self._binaries:
|
||||
bpphs = self._binaries[arch].copy().values()
|
||||
|
||||
if name:
|
||||
bpphs = [b for b in bpphs if re.match(name, b.binary_package_name)]
|
||||
|
||||
if ext:
|
||||
bpphs = [b for b in bpphs if re.match(ext, b.getFileExt())]
|
||||
|
||||
return bpphs
|
||||
|
||||
def _fetch_builds(self):
|
||||
'''Populate self._builds with the build records.'''
|
||||
@ -648,6 +945,23 @@ class BinaryPackagePublishingHistory(BaseWrapper):
|
||||
'''
|
||||
resource_type = 'binary_package_publishing_history'
|
||||
|
||||
def __init__(self, *args):
|
||||
self._arch = None
|
||||
self._ext = None
|
||||
|
||||
@property
|
||||
def arch(self):
|
||||
if not self._arch:
|
||||
das = DistroArchSeries(self._lpobject.distro_arch_series_link)
|
||||
self._arch = das.architecture_tag
|
||||
return self._arch
|
||||
|
||||
def getSourcePackageName(self):
|
||||
'''
|
||||
Returns the source package name.
|
||||
'''
|
||||
return self.getBuild().source_package_name
|
||||
|
||||
def getPackageName(self):
|
||||
'''
|
||||
Returns the binary package name.
|
||||
@ -672,11 +986,84 @@ class BinaryPackagePublishingHistory(BaseWrapper):
|
||||
Only available in the devel API, not 1.0
|
||||
'''
|
||||
try:
|
||||
return self._lpobject.binaryFileUrls()
|
||||
urls = self._lpobject.binaryFileUrls()
|
||||
if not urls:
|
||||
Logger.warning('BPPH %s_%s has no binaryFileUrls' %
|
||||
(self.getPackageName(), self.getVersion()))
|
||||
return urls
|
||||
except AttributeError:
|
||||
raise AttributeError("binaryFileUrls can only be found in lpapi "
|
||||
"devel, not 1.0. Login using devel to have it.")
|
||||
|
||||
def getBuild(self):
|
||||
'''
|
||||
Returns the original build of the binary package.
|
||||
'''
|
||||
return Build(self._lpobject.build_link)
|
||||
|
||||
def getUrl(self):
|
||||
'''
|
||||
Returns the original build URL of the binary package.
|
||||
'''
|
||||
return "{build}/+files/{filename}".format(build=self.getBuild().getUrl(),
|
||||
filename=self.getFileName())
|
||||
|
||||
def getFileVersion(self):
|
||||
'''
|
||||
Returns the file version, which is the package version without the epoch
|
||||
'''
|
||||
return Version(self.getVersion()).strip_epoch()
|
||||
|
||||
def getFileArch(self):
|
||||
'''
|
||||
Returns the file arch, which is 'all' if not arch-specific
|
||||
'''
|
||||
if bool(self._lpobject.architecture_specific):
|
||||
return self.arch
|
||||
else:
|
||||
return 'all'
|
||||
|
||||
def getFileExt(self):
|
||||
'''
|
||||
Returns the file extension; "deb", "ddeb", or "udeb".
|
||||
'''
|
||||
if not self._ext:
|
||||
self._ext = self._getFileExt()
|
||||
|
||||
return self._ext
|
||||
|
||||
def _getFileExt(self):
|
||||
try:
|
||||
# this is the best way, from the actual URL filename
|
||||
return self.binaryFileUrls()[0].rpartition('.')[2]
|
||||
except (AttributeError, IndexError):
|
||||
Logger.debug('Could not get file ext from url, trying to guess...')
|
||||
|
||||
# is_debug should be reliable way of detecting ddeb...?
|
||||
try:
|
||||
if self.is_debug:
|
||||
return "ddeb"
|
||||
except AttributeError:
|
||||
# is_debug only available with api version 'devel'
|
||||
if self.getPackageName().endswith("-dbgsym"):
|
||||
return "ddeb"
|
||||
|
||||
# is this reliable?
|
||||
if self.getPackageName().endswith("-di") or self.getPackageName().endswith("-udeb"):
|
||||
return "udeb"
|
||||
|
||||
# everything else - assume regular deb
|
||||
return "deb"
|
||||
|
||||
def getFileName(self):
|
||||
'''
|
||||
Returns the filename for this binary package.
|
||||
'''
|
||||
return "{name}_{version}_{arch}.{ext}".format(name=self.getPackageName(),
|
||||
version=self.getFileVersion(),
|
||||
arch=self.getFileArch(),
|
||||
ext=self.getFileExt())
|
||||
|
||||
|
||||
class MetaPersonTeam(MetaWrapper):
|
||||
@property
|
||||
@ -705,6 +1092,7 @@ class PersonTeam(BaseWrapper, metaclass=MetaPersonTeam):
|
||||
|
||||
def __init__(self, *args):
|
||||
# Don't share _upload between different PersonTeams
|
||||
self._ppas = None
|
||||
if '_upload' not in self.__dict__:
|
||||
self._upload = dict()
|
||||
|
||||
@ -754,7 +1142,7 @@ class PersonTeam(BaseWrapper, metaclass=MetaPersonTeam):
|
||||
if package is None and component is None:
|
||||
raise ValueError('Either a source package name or a component has '
|
||||
'to be specified.')
|
||||
if pocket not in _POCKETS:
|
||||
if pocket not in POCKETS:
|
||||
raise PocketDoesNotExistError("Pocket '%s' does not exist." %
|
||||
pocket)
|
||||
|
||||
@ -782,6 +1170,16 @@ class PersonTeam(BaseWrapper, metaclass=MetaPersonTeam):
|
||||
|
||||
return canUpload
|
||||
|
||||
def getPPAs(self):
|
||||
if self._ppas is None:
|
||||
ppas = [Archive(ppa['self_link']) for ppa in
|
||||
Launchpad.load(self._lpobject.ppas_collection_link).entries]
|
||||
self._ppas = {ppa.name: ppa for ppa in ppas}
|
||||
return self._ppas
|
||||
|
||||
def getPPAByName(self, name):
|
||||
return Archive(self._lpobject.getPPAByName(name=name))
|
||||
|
||||
|
||||
class Build(BaseWrapper):
|
||||
'''
|
||||
@ -792,6 +1190,18 @@ class Build(BaseWrapper):
|
||||
def __str__(self):
|
||||
return u'%s: %s' % (self.arch_tag, self.buildstate)
|
||||
|
||||
def getSourcePackagePublishingHistory(self):
|
||||
link = self._lpobject.current_source_publication_link
|
||||
if link:
|
||||
if re.search('redacted', link):
|
||||
# Too old - the link has been 'redacted'
|
||||
return None
|
||||
return SourcePackagePublishingHistory(link)
|
||||
return None
|
||||
|
||||
def getUrl(self):
|
||||
return self()
|
||||
|
||||
def rescore(self, score):
|
||||
if self.can_be_rescored:
|
||||
self().rescore(score=score)
|
||||
|
@ -26,3 +26,8 @@ class AlreadyLoggedInError(Exception):
|
||||
class ArchSeriesNotFoundException(BaseException):
|
||||
"""Thrown when a distroarchseries is not found."""
|
||||
pass
|
||||
|
||||
|
||||
class InvalidDistroValueError(ValueError):
|
||||
""" Thrown when distro value is invalid """
|
||||
pass
|
||||
|
@ -32,6 +32,12 @@ import distro_info
|
||||
|
||||
from ubuntutools.lp.udtexceptions import PocketDoesNotExistError
|
||||
|
||||
DEFAULT_POCKETS = ('Release', 'Security', 'Updates', 'Proposed')
|
||||
POCKETS = DEFAULT_POCKETS + ('Backports',)
|
||||
|
||||
DEFAULT_STATUSES = ('Pending', 'Published')
|
||||
STATUSES = DEFAULT_STATUSES + ('Superseded', 'Deleted', 'Obsolete')
|
||||
|
||||
_system_distribution_chain = []
|
||||
|
||||
|
||||
@ -141,7 +147,7 @@ def split_release_pocket(release, default='Release'):
|
||||
(release, pocket) = release.rsplit('-', 1)
|
||||
pocket = pocket.capitalize()
|
||||
|
||||
if pocket not in ('Release', 'Security', 'Updates', 'Proposed', 'Backports'):
|
||||
if pocket not in POCKETS:
|
||||
raise PocketDoesNotExistError("Pocket '%s' does not exist." % pocket)
|
||||
|
||||
return (release, pocket)
|
||||
|
420
ubuntutools/pullpkg.py
Normal file
420
ubuntutools/pullpkg.py
Normal file
@ -0,0 +1,420 @@
|
||||
# pullpkg.py -- pull package files for debian/ubuntu/uca
|
||||
# modified from ../pull-lp-source and converted to module
|
||||
#
|
||||
# Copyright (C) 2008, Iain Lane <iain@orangesquash.org.uk>,
|
||||
# 2010-2011, Stefano Rivera <stefanor@ubuntu.com>
|
||||
# 2017, Dan Streetman <dan.streetman@canonical.com>
|
||||
#
|
||||
# ##################################################################
|
||||
#
|
||||
# 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 3
|
||||
# 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.
|
||||
#
|
||||
# See file /usr/share/common-licenses/GPL for more details.
|
||||
#
|
||||
# ##################################################################
|
||||
|
||||
|
||||
import re
|
||||
import sys
|
||||
import errno
|
||||
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from distro_info import DebianDistroInfo
|
||||
|
||||
from ubuntutools.archive import (UbuntuSourcePackage, DebianSourcePackage,
|
||||
UbuntuCloudArchiveSourcePackage,
|
||||
PersonalPackageArchiveSourcePackage)
|
||||
from ubuntutools.config import UDTConfig
|
||||
from ubuntutools.lp.lpapicache import (Distribution, Launchpad)
|
||||
from ubuntutools.lp.udtexceptions import (SeriesNotFoundException,
|
||||
PackageNotFoundException,
|
||||
PocketDoesNotExistError,
|
||||
InvalidDistroValueError)
|
||||
from ubuntutools.misc import (split_release_pocket, host_architecture, STATUSES)
|
||||
|
||||
from ubuntutools import _loggingBasicConfig
|
||||
|
||||
import logging
|
||||
Logger = logging.getLogger(__name__)
|
||||
|
||||
PULL_SOURCE = 'source'
|
||||
PULL_DEBS = 'debs'
|
||||
PULL_DDEBS = 'ddebs'
|
||||
PULL_UDEBS = 'udebs'
|
||||
PULL_LIST = 'list'
|
||||
|
||||
VALID_PULLS = [PULL_SOURCE, PULL_DEBS, PULL_DDEBS, PULL_UDEBS, PULL_LIST]
|
||||
VALID_BINARY_PULLS = [PULL_DEBS, PULL_DDEBS, PULL_UDEBS]
|
||||
|
||||
DISTRO_DEBIAN = 'debian'
|
||||
DISTRO_UBUNTU = 'ubuntu'
|
||||
DISTRO_UCA = 'uca'
|
||||
DISTRO_PPA = 'ppa'
|
||||
|
||||
DISTRO_PKG_CLASS = {
|
||||
DISTRO_DEBIAN: DebianSourcePackage,
|
||||
DISTRO_UBUNTU: UbuntuSourcePackage,
|
||||
DISTRO_UCA: UbuntuCloudArchiveSourcePackage,
|
||||
DISTRO_PPA: PersonalPackageArchiveSourcePackage,
|
||||
}
|
||||
VALID_DISTROS = DISTRO_PKG_CLASS.keys()
|
||||
|
||||
|
||||
class InvalidPullValueError(ValueError):
|
||||
""" Thrown when --pull value is invalid """
|
||||
pass
|
||||
|
||||
|
||||
class PullPkg(object):
|
||||
"""Class used to pull file(s) associated with a specific package"""
|
||||
@classmethod
|
||||
def main(cls, *args, **kwargs):
|
||||
"""For use by stand-alone cmdline scripts.
|
||||
|
||||
This will handle catching certain exceptions or kbd interrupts,
|
||||
setting up the root logger level to INFO, and printing out
|
||||
(via Logger) a caught error message, instead of allowing the
|
||||
exception to flow up to the script. This does not catch
|
||||
unexpected exceptions, such as internal errors.
|
||||
|
||||
On (expected) error, this will call sys.exit(error);
|
||||
unexpected errors will flow up to the caller.
|
||||
On success, this simply returns.
|
||||
"""
|
||||
_loggingBasicConfig()
|
||||
|
||||
try:
|
||||
cls(*args, **kwargs).pull()
|
||||
return
|
||||
except KeyboardInterrupt:
|
||||
Logger.info('User abort.')
|
||||
except (PackageNotFoundException, SeriesNotFoundException,
|
||||
PocketDoesNotExistError, InvalidDistroValueError) as e:
|
||||
Logger.error(str(e))
|
||||
sys.exit(errno.ENOENT)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._default_pull = kwargs.get('pull')
|
||||
self._default_distro = kwargs.get('distro')
|
||||
self._default_arch = kwargs.get('arch', host_architecture())
|
||||
|
||||
def parse_args(self, args):
|
||||
args = args[:]
|
||||
|
||||
help_default_pull = "What to pull: " + ", ".join(VALID_PULLS)
|
||||
if self._default_pull:
|
||||
help_default_pull += (" (default: %s)" % self._default_pull)
|
||||
help_default_distro = "Pull from: " + ", ".join(VALID_DISTROS)
|
||||
if self._default_distro:
|
||||
help_default_distro += (" (default: %s)" % self._default_distro)
|
||||
help_default_arch = ("Get binary packages for arch")
|
||||
help_default_arch += ("(default: %s)" % self._default_arch)
|
||||
|
||||
# use add_help=False because we do parse_known_args() below, and if
|
||||
# that sees --help then it exits immediately
|
||||
parser = ArgumentParser(add_help=False)
|
||||
parser.add_argument('-v', '--verbose', action='count', default=0,
|
||||
help="Increase verbosity/debug")
|
||||
parser.add_argument('-d', '--download-only', action='store_true',
|
||||
help="Do not extract the source package")
|
||||
parser.add_argument('-m', '--mirror', action='append',
|
||||
help='Preferred mirror(s)')
|
||||
parser.add_argument('--no-conf', action='store_true',
|
||||
help="Don't read config files or environment variables")
|
||||
parser.add_argument('--no-verify-signature', action='store_true',
|
||||
help="Don't fail if dsc signature can't be verified")
|
||||
parser.add_argument('-s', '--status', action='append', default=[],
|
||||
help="Search for packages with specific status(es)")
|
||||
parser.add_argument('-a', '--arch', default=self._default_arch,
|
||||
help=help_default_arch)
|
||||
parser.add_argument('-p', '--pull', default=self._default_pull,
|
||||
help=help_default_pull)
|
||||
parser.add_argument('-D', '--distro', default=self._default_distro,
|
||||
help=help_default_distro)
|
||||
|
||||
# add distro-specific params
|
||||
try:
|
||||
distro = self.parse_distro(parser.parse_known_args(args)[0].distro)
|
||||
except InvalidDistroValueError:
|
||||
# don't fail at this point, finish setting up parser help/usage
|
||||
distro = None
|
||||
|
||||
if distro == DISTRO_UBUNTU:
|
||||
parser.add_argument('--security', action='store_true',
|
||||
help='Check the Ubuntu Security Team PPA')
|
||||
if distro == DISTRO_PPA:
|
||||
parser.add_argument('--ppa', help='PPA to pull from')
|
||||
if parser.parse_known_args(args)[0].ppa is None:
|
||||
# check for any param starting with "ppa:"
|
||||
# if found, move it to a --ppa param
|
||||
for param in args:
|
||||
if param.startswith('ppa:'):
|
||||
args.remove(param)
|
||||
args.insert(0, param)
|
||||
args.insert(0, '--ppa')
|
||||
break
|
||||
|
||||
# add the positional params
|
||||
parser.add_argument('package', help="Package name to pull")
|
||||
parser.add_argument('release', nargs='?', help="Release to pull from")
|
||||
parser.add_argument('version', nargs='?', help="Package version to pull")
|
||||
|
||||
epilog = ("Note on --status: if a version is provided, all status types "
|
||||
"will be searched; if no version is provided, by default only "
|
||||
"'Pending' and 'Published' status will be searched.")
|
||||
|
||||
# since parser has no --help handler, create a new parser that does
|
||||
newparser = ArgumentParser(parents=[parser], epilog=epilog)
|
||||
|
||||
return self.parse_options(vars(newparser.parse_args(args)))
|
||||
|
||||
def parse_pull(self, pull):
|
||||
if not pull:
|
||||
raise InvalidPullValueError("Must specify --pull")
|
||||
|
||||
# allow 'dbgsym' as alias for 'ddebs'
|
||||
if pull == 'dbgsym':
|
||||
Logger.debug("Pulling '%s' for '%s'", PULL_DDEBS, pull)
|
||||
pull = PULL_DDEBS
|
||||
# assume anything starting with 'bin' means 'debs'
|
||||
if str(pull).startswith('bin'):
|
||||
Logger.debug("Pulling '%s' for '%s'", PULL_DEBS, pull)
|
||||
pull = PULL_DEBS
|
||||
# verify pull action is valid
|
||||
if pull not in VALID_PULLS:
|
||||
raise InvalidPullValueError("Invalid pull action '%s'" % pull)
|
||||
|
||||
return pull
|
||||
|
||||
def parse_distro(self, distro):
|
||||
if not distro:
|
||||
raise InvalidDistroValueError("Must specify --distro")
|
||||
|
||||
distro = distro.lower()
|
||||
|
||||
# allow 'lp' for 'ubuntu'
|
||||
if distro == 'lp':
|
||||
Logger.debug("Using distro '%s' for '%s'", DISTRO_UBUNTU, distro)
|
||||
distro = DISTRO_UBUNTU
|
||||
# assume anything with 'cloud' is UCA
|
||||
if re.match(r'.*cloud.*', distro):
|
||||
Logger.debug("Using distro '%s' for '%s'", DISTRO_UCA, distro)
|
||||
distro = DISTRO_UCA
|
||||
# verify distro is valid
|
||||
if distro not in VALID_DISTROS:
|
||||
raise InvalidDistroValueError("Invalid distro '%s'" % distro)
|
||||
|
||||
return distro
|
||||
|
||||
def parse_release(self, distro, release):
|
||||
if distro == DISTRO_UCA:
|
||||
# UCA is special; it is specified UBUNTURELEASE-UCARELEASE or just
|
||||
# UCARELEASE. The user could also specify UCARELEASE-POCKET. But UCA
|
||||
# archives always correspond to only one UBUNTURELEASE, and UCA archives
|
||||
# have only the Release pocket, so only UCARELEASE matters to us.
|
||||
for r in release.split('-'):
|
||||
if UbuntuCloudArchiveSourcePackage.isValidRelease(r):
|
||||
Logger.debug("Using UCA release '%s'", r)
|
||||
return (r, None)
|
||||
raise SeriesNotFoundException('UCA release {} not found.'.format(release))
|
||||
|
||||
# Check if release[-pocket] is specified
|
||||
(release, pocket) = split_release_pocket(release, default=None)
|
||||
Logger.debug("Parsed release '%s' pocket '%s'", release, pocket)
|
||||
|
||||
if distro == DISTRO_DEBIAN:
|
||||
# This converts from the aliases like 'unstable'
|
||||
debian_info = DebianDistroInfo()
|
||||
codename = debian_info.codename(release)
|
||||
if codename:
|
||||
Logger.info("Using release '%s' for '%s'", codename, release)
|
||||
release = codename
|
||||
|
||||
if distro == DISTRO_PPA:
|
||||
# PPAs are part of Ubuntu distribution
|
||||
d = Distribution(DISTRO_UBUNTU)
|
||||
else:
|
||||
d = Distribution(distro)
|
||||
|
||||
# let SeriesNotFoundException flow up
|
||||
d.getSeries(release)
|
||||
|
||||
Logger.debug("Using distro '%s' release '%s' pocket '%s'",
|
||||
distro, release, pocket)
|
||||
return (release, pocket)
|
||||
|
||||
def parse_release_and_version(self, distro, release, version, try_swap=True):
|
||||
# Verify specified release is valid, and params in correct order
|
||||
pocket = None
|
||||
try:
|
||||
(release, pocket) = self.parse_release(distro, release)
|
||||
except (SeriesNotFoundException, PocketDoesNotExistError):
|
||||
if try_swap:
|
||||
Logger.debug("Param '%s' not valid series, must be version", release)
|
||||
release, version = version, release
|
||||
if release:
|
||||
return self.parse_release_and_version(distro, release, version, False)
|
||||
else:
|
||||
Logger.error("Can't find series for '%s' or '%s'", release, version)
|
||||
raise
|
||||
return (release, version, pocket)
|
||||
|
||||
def parse_options(self, options):
|
||||
# if any of these fail, there is a problem with the parser
|
||||
# they should all be provided, though the optional ones may be None
|
||||
|
||||
# type bool
|
||||
assert 'verbose' in options
|
||||
assert 'download_only' in options
|
||||
assert 'no_conf' in options
|
||||
assert 'no_verify_signature' in options
|
||||
assert 'status' in options
|
||||
# type string
|
||||
assert 'pull' in options
|
||||
assert 'distro' in options
|
||||
assert 'arch' in options
|
||||
assert 'package' in options
|
||||
# type string, optional
|
||||
assert 'release' in options
|
||||
assert 'version' in options
|
||||
# type list of strings, optional
|
||||
assert 'mirror' in options
|
||||
|
||||
options['pull'] = self.parse_pull(options['pull'])
|
||||
options['distro'] = self.parse_distro(options['distro'])
|
||||
|
||||
# ensure these are always included so we can just check for None/False later
|
||||
options['ppa'] = options.get('ppa', None)
|
||||
options['security'] = options.get('security', False)
|
||||
|
||||
return options
|
||||
|
||||
def _get_params(self, options):
|
||||
distro = options['distro']
|
||||
pull = options['pull']
|
||||
|
||||
params = {}
|
||||
params['package'] = options['package']
|
||||
|
||||
if options['release']:
|
||||
(r, v, p) = self.parse_release_and_version(distro, options['release'],
|
||||
options['version'])
|
||||
params['series'] = r
|
||||
params['version'] = v
|
||||
params['pocket'] = p
|
||||
|
||||
if (params['package'].endswith('.dsc') and not params['series'] and not params['version']):
|
||||
params['dscfile'] = params['package']
|
||||
params.pop('package')
|
||||
|
||||
if options['security']:
|
||||
if options['ppa']:
|
||||
Logger.warning('Both --security and --ppa specified, ignoring --ppa')
|
||||
Logger.debug('Checking Ubuntu Security PPA')
|
||||
# --security is just a shortcut for --ppa ppa:ubuntu-security-proposed/ppa
|
||||
options['ppa'] = 'ubuntu-security-proposed/ppa'
|
||||
|
||||
if options['ppa']:
|
||||
if options['ppa'].startswith('ppa:'):
|
||||
params['ppa'] = options['ppa'][4:]
|
||||
else:
|
||||
params['ppa'] = options['ppa']
|
||||
elif distro == DISTRO_PPA:
|
||||
raise ValueError('Must specify PPA to pull from')
|
||||
|
||||
mirrors = []
|
||||
if options['mirror']:
|
||||
mirrors.append(options['mirror'])
|
||||
if pull == PULL_DDEBS:
|
||||
config = UDTConfig(options['no_conf'])
|
||||
ddebs_mirror = config.get_value(distro.upper() + '_DDEBS_MIRROR')
|
||||
if ddebs_mirror:
|
||||
mirrors.append(ddebs_mirror)
|
||||
if mirrors:
|
||||
Logger.debug("using mirrors %s", ", ".join(mirrors))
|
||||
params['mirrors'] = mirrors
|
||||
|
||||
params['verify_signature'] = not options['no_verify_signature']
|
||||
|
||||
params['status'] = STATUSES if 'all' in options['status'] else options['status']
|
||||
|
||||
return params
|
||||
|
||||
def pull(self, args=sys.argv[1:]):
|
||||
"""Pull (download) specified package file(s)"""
|
||||
options = self.parse_args(args)
|
||||
|
||||
if options['verbose']:
|
||||
Logger.setLevel(logging.DEBUG)
|
||||
if options['verbose'] > 1:
|
||||
logging.getLogger(__package__).setLevel(logging.DEBUG)
|
||||
|
||||
Logger.debug("pullpkg options: %s", options)
|
||||
|
||||
# Login anonymously to LP
|
||||
Launchpad.login_anonymously()
|
||||
|
||||
pull = options['pull']
|
||||
distro = options['distro']
|
||||
|
||||
params = self._get_params(options)
|
||||
package = params['package']
|
||||
|
||||
# call implementation, and allow exceptions to flow up to caller
|
||||
srcpkg = DISTRO_PKG_CLASS[distro](**params)
|
||||
spph = srcpkg.lp_spph
|
||||
|
||||
Logger.info('Found %s', spph.display_name)
|
||||
|
||||
if pull == PULL_LIST:
|
||||
Logger.info("Source files:")
|
||||
for f in srcpkg.dsc['Files']:
|
||||
Logger.info(" %s", f['name'])
|
||||
Logger.info("Binary files:")
|
||||
for f in spph.getBinaries(options['arch']):
|
||||
Logger.info(" %s", f.getFileName())
|
||||
elif pull == PULL_SOURCE:
|
||||
# allow DownloadError to flow up to caller
|
||||
srcpkg.pull()
|
||||
if options['download_only']:
|
||||
Logger.debug("--download-only specified, not extracting")
|
||||
else:
|
||||
srcpkg.unpack()
|
||||
elif pull in VALID_BINARY_PULLS:
|
||||
name = None
|
||||
if package != spph.getPackageName():
|
||||
Logger.info("Pulling only binary package '%s'", package)
|
||||
Logger.info("Use package name '%s' to pull all binary packages",
|
||||
spph.getPackageName())
|
||||
name = package
|
||||
|
||||
# e.g. 'debs' -> 'deb'
|
||||
ext = pull.rstrip('s')
|
||||
|
||||
if distro == DISTRO_DEBIAN:
|
||||
# Debian ddebs don't use .ddeb extension, unfortunately :(
|
||||
if pull in [PULL_DEBS, PULL_DDEBS]:
|
||||
name = name or '.*'
|
||||
ext = 'deb'
|
||||
if pull == PULL_DEBS:
|
||||
name += r'(?<!-dbgsym)$'
|
||||
if pull == PULL_DDEBS:
|
||||
name += r'-dbgsym$'
|
||||
|
||||
# allow DownloadError to flow up to caller
|
||||
total = srcpkg.pull_binaries(name=name, ext=ext, arch=options['arch'])
|
||||
if total < 1:
|
||||
Logger.error("No %s found for %s %s", pull,
|
||||
package, spph.getVersion())
|
||||
else:
|
||||
Logger.error("Internal error: invalid pull value after parse_pull()")
|
||||
raise InvalidPullValueError("Invalid pull value '%s'" % pull)
|
@ -29,9 +29,11 @@ from httplib2 import Http, HttpLib2Error
|
||||
from ubuntutools.lp import udtexceptions
|
||||
from ubuntutools.lp.lpapicache import (Launchpad, Distribution, PersonTeam,
|
||||
DistributionSourcePackage)
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.question import confirmation_prompt
|
||||
|
||||
import logging
|
||||
Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_debian_srcpkg(name, release):
|
||||
debian = Distribution('debian')
|
||||
@ -40,7 +42,7 @@ def get_debian_srcpkg(name, release):
|
||||
try:
|
||||
release = DebianDistroInfo().codename(release, None, release)
|
||||
except DistroDataOutdated as e:
|
||||
Logger.warn(e)
|
||||
Logger.warning(e)
|
||||
|
||||
return debian_archive.getSourcePackage(name, release)
|
||||
|
||||
|
@ -31,11 +31,12 @@ import tempfile
|
||||
from debian.changelog import Changelog
|
||||
from distro_info import DebianDistroInfo, DistroDataOutdated
|
||||
|
||||
from ubuntutools.archive import rmadison, FakeSPPH
|
||||
from ubuntutools.archive import DebianSourcePackage, UbuntuSourcePackage
|
||||
from ubuntutools.lp.udtexceptions import PackageNotFoundException
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.question import confirmation_prompt, YesNoQuestion
|
||||
from ubuntutools.version import Version
|
||||
|
||||
import logging
|
||||
Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
__all__ = [
|
||||
@ -48,32 +49,21 @@ __all__ = [
|
||||
]
|
||||
|
||||
|
||||
def _get_srcpkg(distro, name, release):
|
||||
if distro == 'debian':
|
||||
# Canonicalise release:
|
||||
debian_info = DebianDistroInfo()
|
||||
try:
|
||||
codename = debian_info.codename(release, default=release)
|
||||
except DistroDataOutdated as e:
|
||||
Logger.warn(e)
|
||||
|
||||
lines = list(rmadison(distro, name, suite=codename, arch='source'))
|
||||
if not lines:
|
||||
lines = list(rmadison(distro, name, suite=release, arch='source'))
|
||||
if not lines:
|
||||
raise PackageNotFoundException("'%s' doesn't appear to exist in %s '%s'" %
|
||||
(name, distro.capitalize(), release))
|
||||
pkg = max(lines, key=lambda x: Version(x['version']))
|
||||
|
||||
return FakeSPPH(pkg['source'], pkg['version'], pkg['component'], distro)
|
||||
|
||||
|
||||
def get_debian_srcpkg(name, release):
|
||||
return _get_srcpkg('debian', name, release)
|
||||
# Canonicalise release:
|
||||
debian_info = DebianDistroInfo()
|
||||
try:
|
||||
codename = debian_info.codename(release, default=release)
|
||||
return DebianSourcePackage(package=name, series=codename).lp_spph
|
||||
except DistroDataOutdated as e:
|
||||
Logger.warning(e)
|
||||
except PackageNotFoundException:
|
||||
pass
|
||||
return DebianSourcePackage(package=name, series=release).lp_spph
|
||||
|
||||
|
||||
def get_ubuntu_srcpkg(name, release):
|
||||
return _get_srcpkg('ubuntu', name, release)
|
||||
return UbuntuSourcePackage(package=name, series=release).lp_spph
|
||||
|
||||
|
||||
def need_sponsorship(name, component, release):
|
||||
@ -185,14 +175,14 @@ Content-Type: text/plain; charset=UTF-8
|
||||
with backup:
|
||||
backup.write(mail)
|
||||
|
||||
Logger.normal('The e-mail has been saved in %s and will be deleted '
|
||||
'after succesful transmission', backup.name)
|
||||
Logger.info('The e-mail has been saved in %s and will be deleted '
|
||||
'after succesful transmission', backup.name)
|
||||
|
||||
# connect to the server
|
||||
while True:
|
||||
try:
|
||||
Logger.normal('Connecting to %s:%s ...', mailserver_host,
|
||||
mailserver_port)
|
||||
Logger.info('Connecting to %s:%s ...', mailserver_host,
|
||||
mailserver_port)
|
||||
s = smtplib.SMTP(mailserver_host, mailserver_port)
|
||||
break
|
||||
except smtplib.SMTPConnectError as s:
|
||||
@ -238,7 +228,7 @@ Content-Type: text/plain; charset=UTF-8
|
||||
s.sendmail(myemailaddr, to, mail.encode('utf-8'))
|
||||
s.quit()
|
||||
os.remove(backup.name)
|
||||
Logger.normal('Sync request mailed.')
|
||||
Logger.info('Sync request mailed.')
|
||||
break
|
||||
except smtplib.SMTPRecipientsRefused as smtperror:
|
||||
smtp_code, smtp_message = smtperror.recipients[to]
|
||||
|
@ -23,9 +23,11 @@ from urllib.request import urlretrieve
|
||||
import distro_info
|
||||
import httplib2
|
||||
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.version import Version
|
||||
|
||||
import logging
|
||||
Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def is_sync(bug):
|
||||
"""Checks if a Launchpad bug is a sync request.
|
||||
@ -66,7 +68,7 @@ class BugTask(object):
|
||||
dsc_file = ""
|
||||
for url in source_files:
|
||||
filename = unquote(os.path.basename(url))
|
||||
Logger.info("Downloading %s..." % (filename))
|
||||
Logger.debug("Downloading %s..." % (filename))
|
||||
# HttpLib2 isn't suitable for large files (it reads into memory),
|
||||
# but we want its https certificate validation on the .dsc
|
||||
if url.endswith(".dsc"):
|
||||
|
@ -19,10 +19,12 @@ import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.sponsor_patch.question import ask_for_manual_fixing
|
||||
from functools import reduce
|
||||
|
||||
import logging
|
||||
Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Patch(object):
|
||||
"""This object represents a patch that can be downloaded from Launchpad."""
|
||||
@ -32,8 +34,8 @@ class Patch(object):
|
||||
self._patch_file = re.sub(" |/", "_", patch.title)
|
||||
if not reduce(lambda r, x: r or self._patch.title.endswith(x),
|
||||
(".debdiff", ".diff", ".patch"), False):
|
||||
Logger.info("Patch %s does not have a proper file extension." %
|
||||
(self._patch.title))
|
||||
Logger.debug("Patch %s does not have a proper file extension." %
|
||||
(self._patch.title))
|
||||
self._patch_file += ".patch"
|
||||
self._full_path = os.path.realpath(self._patch_file)
|
||||
self._changed_files = None
|
||||
@ -45,7 +47,7 @@ class Patch(object):
|
||||
if self.is_debdiff():
|
||||
cmd = ["patch", "--merge", "--force", "-p",
|
||||
str(self.get_strip_level()), "-i", self._full_path]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
if subprocess.call(cmd) != 0:
|
||||
Logger.error("Failed to apply debdiff %s to %s %s.",
|
||||
self._patch_file, task.package, task.get_version())
|
||||
@ -54,7 +56,7 @@ class Patch(object):
|
||||
edit = True
|
||||
else:
|
||||
cmd = ["add-patch", self._full_path]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
if subprocess.call(cmd) != 0:
|
||||
Logger.error("Failed to apply diff %s to %s %s.",
|
||||
self._patch_file, task.package, task.get_version())
|
||||
@ -65,7 +67,7 @@ class Patch(object):
|
||||
|
||||
def download(self):
|
||||
"""Downloads the patch from Launchpad."""
|
||||
Logger.info("Downloading %s." % (self._patch_file))
|
||||
Logger.debug("Downloading %s." % (self._patch_file))
|
||||
patch_f = open(self._patch_file, "w")
|
||||
patch_f.write(self._patch.data.open().read())
|
||||
patch_f.close()
|
||||
|
@ -23,13 +23,15 @@ import sys
|
||||
import debian.changelog
|
||||
import debian.deb822
|
||||
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.question import Question, YesNoQuestion
|
||||
|
||||
from ubuntutools.sponsor_patch.question import (ask_for_ignoring_or_fixing,
|
||||
ask_for_manual_fixing,
|
||||
user_abort)
|
||||
|
||||
import logging
|
||||
Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_series(launchpad):
|
||||
"""Returns a tuple with the development and list of supported series."""
|
||||
@ -84,7 +86,7 @@ class SourcePackage(object):
|
||||
if task.importance == "Undecided":
|
||||
task.importance = "Wishlist"
|
||||
task.lp_save()
|
||||
Logger.info("Set bug #%i status to Confirmed.", bug.id)
|
||||
Logger.debug("Set bug #%i status to Confirmed.", bug.id)
|
||||
|
||||
msg = "Sync request ACK'd."
|
||||
if self._build_log:
|
||||
@ -92,26 +94,26 @@ class SourcePackage(object):
|
||||
(self._package, self._version,
|
||||
self._builder.get_architecture())
|
||||
bug.newMessage(content=msg, subject="sponsor-patch")
|
||||
Logger.info("Acknowledged sync request bug #%i.", bug.id)
|
||||
Logger.debug("Acknowledged sync request bug #%i.", bug.id)
|
||||
|
||||
bug.subscribe(person=launchpad.people['ubuntu-archive'])
|
||||
Logger.info("Subscribed ubuntu-archive to bug #%i.", bug.id)
|
||||
Logger.debug("Subscribed ubuntu-archive to bug #%i.", bug.id)
|
||||
|
||||
bug.subscribe(person=launchpad.me)
|
||||
Logger.info("Subscribed me to bug #%i.", bug.id)
|
||||
Logger.debug("Subscribed me to bug #%i.", bug.id)
|
||||
|
||||
sponsorsteam = launchpad.people['ubuntu-sponsors']
|
||||
for sub in bug.subscriptions:
|
||||
if sub.person == sponsorsteam and sub.canBeUnsubscribedByUser():
|
||||
bug.unsubscribe(person=launchpad.people['ubuntu-sponsors'])
|
||||
Logger.info("Unsubscribed ubuntu-sponsors from bug #%i.",
|
||||
bug.id)
|
||||
Logger.debug("Unsubscribed ubuntu-sponsors from bug #%i.",
|
||||
bug.id)
|
||||
elif sub.person == sponsorsteam:
|
||||
Logger.info("Couldn't unsubscribe ubuntu-sponsors from "
|
||||
"bug #%i.", bug.id)
|
||||
Logger.debug("Couldn't unsubscribe ubuntu-sponsors from "
|
||||
"bug #%i.", bug.id)
|
||||
|
||||
Logger.normal("Successfully acknowledged sync request bug #%i.",
|
||||
bug.id)
|
||||
Logger.info("Successfully acknowledged sync request bug #%i.",
|
||||
bug.id)
|
||||
else:
|
||||
Logger.error("Sync requests can only be acknowledged when the "
|
||||
"upload target is Ubuntu.")
|
||||
@ -139,7 +141,7 @@ class SourcePackage(object):
|
||||
elif answer == "no":
|
||||
user_abort()
|
||||
cmd = ["dput", "--force", upload, self._changes_file]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
if subprocess.call(cmd) != 0:
|
||||
Logger.error("Upload of %s to %s failed." %
|
||||
(os.path.basename(self._changes_file), upload))
|
||||
@ -148,17 +150,17 @@ class SourcePackage(object):
|
||||
# Push the branch if the package is uploaded to the Ubuntu archive.
|
||||
if upload == "ubuntu" and self._branch:
|
||||
cmd = ['debcommit']
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
if subprocess.call(cmd) != 0:
|
||||
Logger.error('Bzr commit failed.')
|
||||
sys.exit(1)
|
||||
cmd = ['bzr', 'mark-uploaded']
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
if subprocess.call(cmd) != 0:
|
||||
Logger.error('Bzr tagging failed.')
|
||||
sys.exit(1)
|
||||
cmd = ['bzr', 'push', ':parent']
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
if subprocess.call(cmd) != 0:
|
||||
Logger.error('Bzr push failed.')
|
||||
sys.exit(1)
|
||||
@ -239,7 +241,7 @@ class SourcePackage(object):
|
||||
env = os.environ
|
||||
if upload == 'ubuntu':
|
||||
env['DEB_VENDOR'] = 'Ubuntu'
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
if subprocess.call(cmd, env=env) != 0:
|
||||
Logger.error("Failed to build source tarball.")
|
||||
# TODO: Add a "retry" option
|
||||
@ -322,9 +324,9 @@ class SourcePackage(object):
|
||||
assert os.path.isfile(self._dsc_file), "%s does not exist." % \
|
||||
(self._dsc_file)
|
||||
cmd = ["debdiff", dsc_file, self._dsc_file]
|
||||
if not Logger.verbose:
|
||||
if not Logger.isEnabledFor(logging.DEBUG):
|
||||
cmd.insert(1, "-q")
|
||||
Logger.command(cmd + [">", self._debdiff_filename])
|
||||
Logger.debug(' '.join(cmd) + " > " + self._debdiff_filename)
|
||||
debdiff = subprocess.check_output(cmd, encoding='utf-8')
|
||||
|
||||
# write debdiff file
|
||||
@ -417,7 +419,7 @@ class SourcePackage(object):
|
||||
lintian_filename = os.path.join(self._workdir,
|
||||
self._package + "_" +
|
||||
strip_epoch(self._version) + ".lintian")
|
||||
Logger.command(cmd + [">", lintian_filename])
|
||||
Logger.debug(' '.join(cmd) + " > " + lintian_filename)
|
||||
report = subprocess.check_output(cmd, encoding='utf-8')
|
||||
|
||||
# write lintian report file
|
||||
@ -434,7 +436,7 @@ class SourcePackage(object):
|
||||
cmd = ["syncpackage", self._package, "-b", str(bug_number), "-f",
|
||||
"-s", requester, "-V", str(self._version),
|
||||
"-d", series]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
if subprocess.call(cmd) != 0:
|
||||
Logger.error("Syncing of %s %s failed.", self._package,
|
||||
str(self._version))
|
||||
|
@ -25,7 +25,6 @@ from distro_info import UbuntuDistroInfo
|
||||
|
||||
from launchpadlib.launchpad import Launchpad
|
||||
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.update_maintainer import (update_maintainer,
|
||||
MaintainerUpdateException)
|
||||
from ubuntutools.question import input_number
|
||||
@ -35,6 +34,9 @@ from ubuntutools.sponsor_patch.patch import Patch
|
||||
from ubuntutools.sponsor_patch.question import ask_for_manual_fixing
|
||||
from ubuntutools.sponsor_patch.source_package import SourcePackage
|
||||
|
||||
import logging
|
||||
Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def is_command_available(command, check_sbin=False):
|
||||
"Is command in $PATH?"
|
||||
@ -59,8 +61,8 @@ def check_dependencies():
|
||||
missing.append('pbuilder/cowbuilder/sbuild')
|
||||
|
||||
if missing:
|
||||
Logger.warn("sponsor-patch requires %s to be installed for full "
|
||||
"functionality", ', '.join(missing))
|
||||
Logger.warning("sponsor-patch requires %s to be installed for full "
|
||||
"functionality", ', '.join(missing))
|
||||
|
||||
|
||||
def get_source_package_name(bug_task):
|
||||
@ -82,7 +84,7 @@ def get_user_shell():
|
||||
def edit_source():
|
||||
# Spawn shell to allow modifications
|
||||
cmd = [get_user_shell()]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
print("""An interactive shell was launched in
|
||||
file://%s
|
||||
Edit your files. When you are done, exit the shell. If you wish to abort the
|
||||
@ -112,7 +114,7 @@ def ask_for_patch_or_branch(bug, attached_patches, linked_branches):
|
||||
patches += "es"
|
||||
msg = "https://launchpad.net/bugs/%i has %s linked and %s attached:" % \
|
||||
(bug.id, branches, patches)
|
||||
Logger.normal(msg)
|
||||
Logger.info(msg)
|
||||
i = 0
|
||||
for linked_branch in linked_branches:
|
||||
i += 1
|
||||
@ -160,7 +162,7 @@ def download_branch(branch):
|
||||
if os.path.isdir(dir_name):
|
||||
shutil.rmtree(dir_name)
|
||||
cmd = ["bzr", "branch", branch]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
if subprocess.call(cmd) != 0:
|
||||
Logger.error("Failed to download branch %s." % (branch))
|
||||
sys.exit(1)
|
||||
@ -170,7 +172,7 @@ def download_branch(branch):
|
||||
def merge_branch(branch):
|
||||
edit = False
|
||||
cmd = ["bzr", "merge", branch]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
if subprocess.call(cmd) != 0:
|
||||
Logger.error("Failed to merge branch %s." % (branch))
|
||||
ask_for_manual_fixing()
|
||||
@ -182,7 +184,7 @@ def extract_source(dsc_file, verbose=False):
|
||||
cmd = ["dpkg-source", "--no-preparation", "-x", dsc_file]
|
||||
if not verbose:
|
||||
cmd.insert(1, "-q")
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
if subprocess.call(cmd) != 0:
|
||||
Logger.error("Extraction of %s failed." % (os.path.basename(dsc_file)))
|
||||
sys.exit(1)
|
||||
@ -219,21 +221,21 @@ def get_open_ubuntu_bug_task(launchpad, bug, branch=None):
|
||||
task = tasks[0]
|
||||
elif len(ubuntu_tasks) > 1:
|
||||
task_list = [t.get_short_info() for t in ubuntu_tasks]
|
||||
Logger.info("%i Ubuntu tasks exist for bug #%i.\n%s", len(ubuntu_tasks),
|
||||
bug_id, "\n".join(task_list))
|
||||
Logger.debug("%i Ubuntu tasks exist for bug #%i.\n%s", len(ubuntu_tasks),
|
||||
bug_id, "\n".join(task_list))
|
||||
open_ubuntu_tasks = [x for x in ubuntu_tasks if not x.is_complete()]
|
||||
if len(open_ubuntu_tasks) == 1:
|
||||
task = open_ubuntu_tasks[0]
|
||||
else:
|
||||
Logger.normal("https://launchpad.net/bugs/%i has %i Ubuntu tasks:" %
|
||||
(bug_id, len(ubuntu_tasks)))
|
||||
Logger.info("https://launchpad.net/bugs/%i has %i Ubuntu tasks:" %
|
||||
(bug_id, len(ubuntu_tasks)))
|
||||
for i in range(len(ubuntu_tasks)):
|
||||
print("%i) %s" % (i + 1,
|
||||
ubuntu_tasks[i].get_package_and_series()))
|
||||
selected = input_number("To which Ubuntu task does the patch belong",
|
||||
1, len(ubuntu_tasks))
|
||||
task = ubuntu_tasks[selected - 1]
|
||||
Logger.info("Selected Ubuntu task: %s" % (task.get_short_info()))
|
||||
Logger.debug("Selected Ubuntu task: %s" % (task.get_short_info()))
|
||||
return task
|
||||
|
||||
|
||||
@ -248,15 +250,15 @@ def _create_and_change_into(workdir):
|
||||
(workdir, error.errno, error.strerror))
|
||||
sys.exit(1)
|
||||
if workdir != os.getcwd():
|
||||
Logger.command(["cd", workdir])
|
||||
Logger.debug("cd " + workdir)
|
||||
os.chdir(workdir)
|
||||
|
||||
|
||||
def _update_maintainer_field():
|
||||
"""Update the Maintainer field in debian/control."""
|
||||
Logger.command(["update-maintainer"])
|
||||
Logger.debug("update-maintainer")
|
||||
try:
|
||||
update_maintainer("debian", Logger.verbose)
|
||||
update_maintainer("debian", Logger.isEnabledFor(logging.DEBUG))
|
||||
except MaintainerUpdateException as e:
|
||||
Logger.error("update-maintainer failed: %s", str(e))
|
||||
sys.exit(1)
|
||||
@ -265,9 +267,9 @@ def _update_maintainer_field():
|
||||
def _update_timestamp():
|
||||
"""Run dch to update the timestamp of debian/changelog."""
|
||||
cmd = ["dch", "--maintmaint", "--release", ""]
|
||||
Logger.command(cmd)
|
||||
Logger.debug(' '.join(cmd))
|
||||
if subprocess.call(cmd) != 0:
|
||||
Logger.info("Failed to update timestamp in debian/changelog.")
|
||||
Logger.debug("Failed to update timestamp in debian/changelog.")
|
||||
|
||||
|
||||
def _download_and_change_into(task, dsc_file, patch, branch):
|
||||
@ -277,23 +279,23 @@ def _download_and_change_into(task, dsc_file, patch, branch):
|
||||
branch_dir = download_branch(task.get_branch_link())
|
||||
|
||||
# change directory
|
||||
Logger.command(["cd", branch_dir])
|
||||
Logger.debug("cd " + branch_dir)
|
||||
os.chdir(branch_dir)
|
||||
else:
|
||||
if patch:
|
||||
patch.download()
|
||||
|
||||
Logger.info("Ubuntu package: %s" % (task.package))
|
||||
Logger.debug("Ubuntu package: %s" % (task.package))
|
||||
if task.is_merge():
|
||||
Logger.info("The task is a merge request.")
|
||||
Logger.debug("The task is a merge request.")
|
||||
if task.is_sync():
|
||||
Logger.info("The task is a sync request.")
|
||||
Logger.debug("The task is a sync request.")
|
||||
|
||||
extract_source(dsc_file, Logger.verbose)
|
||||
extract_source(dsc_file, Logger.isEnabledFor(logging.DEBUG))
|
||||
|
||||
# change directory
|
||||
directory = task.package + '-' + task.get_version().upstream_version
|
||||
Logger.command(["cd", directory])
|
||||
Logger.debug("cd " + directory)
|
||||
os.chdir(directory)
|
||||
|
||||
|
||||
|
@ -20,10 +20,9 @@ import os.path
|
||||
import shutil
|
||||
import tempfile
|
||||
from io import BytesIO
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.error import HTTPError
|
||||
from urllib.request import OpenerDirector, urlopen
|
||||
|
||||
import debian.deb822
|
||||
import httplib2
|
||||
|
||||
import ubuntutools.archive
|
||||
@ -85,7 +84,6 @@ class LocalSourcePackageTestCase(unittest.TestCase):
|
||||
self.workdir = tempfile.mkdtemp(prefix='udt-test')
|
||||
|
||||
self._stubout('ubuntutools.archive.Distribution')
|
||||
self._stubout('ubuntutools.archive.rmadison')
|
||||
|
||||
self.mock_http = self._stubout('httplib2.Http.request')
|
||||
self.mock_http.side_effect = self.request_proxy
|
||||
@ -93,10 +91,6 @@ class LocalSourcePackageTestCase(unittest.TestCase):
|
||||
self.url_opener = mock.MagicMock(spec=OpenerDirector)
|
||||
self.url_opener.open.side_effect = self.urlopen_proxy
|
||||
|
||||
# Silence the tests a little:
|
||||
self._stubout('ubuntutools.logger.Logger.stdout')
|
||||
self._stubout('ubuntutools.logger.Logger.stderr')
|
||||
|
||||
def _stubout(self, stub):
|
||||
patcher = mock.patch(stub)
|
||||
self.addCleanup(patcher.stop)
|
||||
@ -146,11 +140,13 @@ class LocalSourcePackageTestCase(unittest.TestCase):
|
||||
return self.request_404(url)
|
||||
|
||||
def test_local_copy(self):
|
||||
pkg = self.SourcePackage('example', '1.0-1', 'main',
|
||||
pkg = self.SourcePackage(package='example',
|
||||
version='1.0-1',
|
||||
component='main',
|
||||
dscfile='test-data/example_1.0-1.dsc',
|
||||
workdir=self.workdir)
|
||||
pkg.quiet = True
|
||||
pkg.pull(verify_signature=False)
|
||||
workdir=self.workdir,
|
||||
verify_signature=False)
|
||||
pkg.pull()
|
||||
pkg.unpack()
|
||||
|
||||
def test_workdir_srcpkg_noinfo(self):
|
||||
@ -160,9 +156,9 @@ class LocalSourcePackageTestCase(unittest.TestCase):
|
||||
|
||||
pkg = self.SourcePackage(dscfile=os.path.join(self.workdir,
|
||||
'example_1.0-1.dsc'),
|
||||
workdir=self.workdir)
|
||||
pkg.quiet = True
|
||||
pkg.pull(verify_signature=False)
|
||||
workdir=self.workdir,
|
||||
verify_signature=False)
|
||||
pkg.pull()
|
||||
pkg.unpack()
|
||||
|
||||
def test_workdir_srcpkg_info(self):
|
||||
@ -170,12 +166,13 @@ class LocalSourcePackageTestCase(unittest.TestCase):
|
||||
shutil.copy2('test-data/example_1.0.orig.tar.gz', self.workdir)
|
||||
shutil.copy2('test-data/example_1.0-1.debian.tar.xz', self.workdir)
|
||||
|
||||
pkg = self.SourcePackage('example', '1.0-1', 'main',
|
||||
pkg = self.SourcePackage(package='example', version='1.0-1',
|
||||
component='main',
|
||||
dscfile=os.path.join(self.workdir,
|
||||
'example_1.0-1.dsc'),
|
||||
workdir=self.workdir)
|
||||
pkg.quiet = True
|
||||
pkg.pull(verify_signature=False)
|
||||
workdir=self.workdir,
|
||||
verify_signature=False)
|
||||
pkg.pull()
|
||||
pkg.unpack()
|
||||
|
||||
def test_verification(self):
|
||||
@ -186,103 +183,18 @@ class LocalSourcePackageTestCase(unittest.TestCase):
|
||||
'r+b') as f:
|
||||
f.write(b'CORRUPTION')
|
||||
|
||||
pkg = self.SourcePackage('example', '1.0-1', 'main',
|
||||
pkg = self.SourcePackage(package='example',
|
||||
version='1.0-1',
|
||||
component='main',
|
||||
dscfile='test-data/example_1.0-1.dsc',
|
||||
workdir=self.workdir)
|
||||
pkg.quiet = True
|
||||
pkg.pull(verify_signature=False)
|
||||
|
||||
def test_pull(self):
|
||||
pkg = self.SourcePackage('example', '1.0-1', 'main',
|
||||
workdir=self.workdir)
|
||||
|
||||
pkg.url_opener = self.url_opener
|
||||
pkg.quiet = True
|
||||
pkg.pull(verify_signature=False)
|
||||
|
||||
def test_mirrors(self):
|
||||
mirror = 'http://mirror'
|
||||
sequence = [self.urlopen_null, self.urlopen_404, self.urlopen_proxy,
|
||||
self.urlopen_proxy]
|
||||
|
||||
def _callable_iter(*args, **kwargs):
|
||||
return sequence.pop(0)(*args, **kwargs)
|
||||
url_opener = mock.MagicMock(spec=OpenerDirector)
|
||||
url_opener.open.side_effect = _callable_iter
|
||||
|
||||
pkg = self.SourcePackage('example', '1.0-1', 'main',
|
||||
workdir=self.workdir, mirrors=[mirror])
|
||||
pkg.url_opener = url_opener
|
||||
pkg.quiet = True
|
||||
pkg.pull(verify_signature=False)
|
||||
workdir=self.workdir,
|
||||
verify_signature=False)
|
||||
pkg.pull()
|
||||
|
||||
def test_dsc_missing(self):
|
||||
self.mock_http.side_effect = self.request_404
|
||||
pkg = self.SourcePackage('example', '1.0-1', 'main',
|
||||
pkg = self.SourcePackage(package='example',
|
||||
version='1.0-1',
|
||||
component='main',
|
||||
workdir=self.workdir)
|
||||
pkg.quiet = True
|
||||
self.assertRaises(ubuntutools.archive.DownloadError, pkg.pull)
|
||||
|
||||
|
||||
class DebianLocalSourcePackageTestCase(LocalSourcePackageTestCase):
|
||||
SourcePackage = ubuntutools.archive.DebianSourcePackage
|
||||
|
||||
def test_mirrors(self):
|
||||
debian_mirror = 'http://mirror/debian'
|
||||
debsec_mirror = 'http://mirror/debsec'
|
||||
|
||||
sequence = [self.urlopen_null,
|
||||
self.urlopen_404,
|
||||
self.urlopen_404,
|
||||
self.urlopen_404,
|
||||
self.urlopen_404,
|
||||
lambda x: BytesIO(
|
||||
b'{"fileinfo": {"hashabc": [{"name": "example_1.0.orig.tar.gz"}]}}'),
|
||||
self.urlopen_file('example_1.0.orig.tar.gz'),
|
||||
self.urlopen_proxy]
|
||||
|
||||
def _callable_iter(*args, **kwargs):
|
||||
return sequence.pop(0)(*args, **kwargs)
|
||||
url_opener = mock.MagicMock(spec=OpenerDirector)
|
||||
url_opener.open.side_effect = _callable_iter
|
||||
|
||||
pkg = self.SourcePackage('example', '1.0-1', 'main',
|
||||
workdir=self.workdir, mirrors=[debian_mirror,
|
||||
debsec_mirror])
|
||||
pkg.quiet = True
|
||||
pkg.url_opener = url_opener
|
||||
pkg.pull(verify_signature=False)
|
||||
pkg.unpack()
|
||||
|
||||
def test_dsc_missing(self):
|
||||
mirror = 'http://mirror'
|
||||
self.mock_http.side_effect = self.request_404_then_proxy
|
||||
|
||||
patcher = mock.patch.object(debian.deb822.GpgInfo, 'from_sequence')
|
||||
self.addCleanup(patcher.stop)
|
||||
mock_gpg_info = patcher.start()
|
||||
mock_gpg_info.return_value = debian.deb822.GpgInfo.from_output(
|
||||
'[GNUPG:] GOODSIG DEADBEEF Joe Developer '
|
||||
'<joe@example.net>')
|
||||
|
||||
pkg = self.SourcePackage('example', '1.0-1', 'main',
|
||||
workdir=self.workdir, mirrors=[mirror])
|
||||
pkg.url_opener = self.url_opener
|
||||
pkg.pull(verify_signature=False)
|
||||
|
||||
def test_dsc_badsig(self):
|
||||
mirror = 'http://mirror'
|
||||
self.mock_http.side_effect = self.request_404_then_proxy
|
||||
|
||||
patcher = mock.patch.object(debian.deb822.GpgInfo, 'from_sequence')
|
||||
self.addCleanup(patcher.stop)
|
||||
mock_gpg_info = patcher.start()
|
||||
mock_gpg_info.return_value = debian.deb822.GpgInfo.from_output(
|
||||
'[GNUPG:] ERRSIG DEADBEEF')
|
||||
|
||||
pkg = self.SourcePackage('example', '1.0-1', 'main',
|
||||
workdir=self.workdir, mirrors=[mirror])
|
||||
try:
|
||||
self.assertRaises(ubuntutools.archive.DownloadError, pkg.pull)
|
||||
except URLError:
|
||||
raise unittest.SkipTest('Test needs addr resolution to work')
|
||||
|
@ -18,11 +18,10 @@
|
||||
import locale
|
||||
import mock
|
||||
import os
|
||||
import sys
|
||||
# import sys
|
||||
from io import StringIO
|
||||
|
||||
from ubuntutools.config import UDTConfig, ubu_email
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.test import unittest
|
||||
|
||||
|
||||
@ -51,16 +50,16 @@ class ConfigTestCase(unittest.TestCase):
|
||||
self.addCleanup(patcher.stop)
|
||||
patcher.start()
|
||||
|
||||
Logger.stdout = StringIO()
|
||||
Logger.stderr = StringIO()
|
||||
# Logger.stdout = StringIO()
|
||||
# Logger.stderr = StringIO()
|
||||
|
||||
self.clean_environment()
|
||||
|
||||
def tearDown(self):
|
||||
self.assertEqual(Logger.stdout.getvalue(), '')
|
||||
self.assertEqual(Logger.stderr.getvalue(), '')
|
||||
Logger.stdout = sys.stdout
|
||||
Logger.stderr = sys.stderr
|
||||
# self.assertEqual(Logger.stdout.getvalue(), '')
|
||||
# self.assertEqual(Logger.stderr.getvalue(), '')
|
||||
# Logger.stdout = sys.stdout
|
||||
# Logger.stderr = sys.stderr
|
||||
|
||||
self.clean_environment()
|
||||
|
||||
@ -98,11 +97,11 @@ REPEAT=yes
|
||||
'INHERIT': 'user',
|
||||
'REPEAT': 'yes',
|
||||
})
|
||||
errs = Logger.stderr.getvalue().strip()
|
||||
Logger.stderr = StringIO()
|
||||
self.assertEqual(len(errs.splitlines()), 1)
|
||||
self.assertRegex(errs,
|
||||
r'Warning: Cannot parse.*\bCOMMAND_EXECUTION=a')
|
||||
# errs = Logger.stderr.getvalue().strip()
|
||||
# Logger.stderr = StringIO()
|
||||
# self.assertEqual(len(errs.splitlines()), 1)
|
||||
# self.assertRegex(errs,
|
||||
# r'Warning: Cannot parse.*\bCOMMAND_EXECUTION=a')
|
||||
|
||||
def get_value(self, *args, **kwargs):
|
||||
config = UDTConfig(prefix='TEST')
|
||||
@ -138,11 +137,11 @@ REPEAT=yes
|
||||
self._config_files['user'] = 'COMPATFOOBAR=bar'
|
||||
self.assertEqual(self.get_value('QUX', compat_keys=['COMPATFOOBAR']),
|
||||
'bar')
|
||||
errs = Logger.stderr.getvalue().strip()
|
||||
Logger.stderr = StringIO()
|
||||
self.assertEqual(len(errs.splitlines()), 1)
|
||||
self.assertRegex(errs,
|
||||
r'deprecated.*\bCOMPATFOOBAR\b.*\bTEST_QUX\b')
|
||||
# errs = Logger.stderr.getvalue().strip()
|
||||
# Logger.stderr = StringIO()
|
||||
# self.assertEqual(len(errs.splitlines()), 1)
|
||||
# self.assertRegex(errs,
|
||||
# r'deprecated.*\bCOMPATFOOBAR\b.*\bTEST_QUX\b')
|
||||
|
||||
def test_boolean(self):
|
||||
self._config_files['user'] = "TEST_BOOLEAN=yes"
|
||||
|
@ -1,54 +0,0 @@
|
||||
# test_logger.py - Test ubuntutools.logger.Logger.
|
||||
#
|
||||
# Copyright (C) 2012, Stefano Rivera <stefanor@debian.org>
|
||||
#
|
||||
# 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.
|
||||
|
||||
from io import StringIO
|
||||
import sys
|
||||
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.test import unittest
|
||||
|
||||
|
||||
class LoggerTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
Logger.stdout = StringIO()
|
||||
Logger.stderr = StringIO()
|
||||
self._script_name = Logger.script_name
|
||||
Logger.script_name = 'test'
|
||||
self._verbose = Logger.verbose
|
||||
|
||||
def tearDown(self):
|
||||
Logger.stdout = sys.stdout
|
||||
Logger.stderr = sys.stderr
|
||||
Logger.script_name = self._script_name
|
||||
Logger.verbose = self._verbose
|
||||
|
||||
def testCommand(self):
|
||||
Logger.command(('ls', 'a b'))
|
||||
self.assertEqual(Logger.stdout.getvalue(), '')
|
||||
Logger.set_verbosity(True)
|
||||
Logger.command(('ls', 'a b'))
|
||||
self.assertEqual(Logger.stdout.getvalue(), 'test: I: ls "a b"\n')
|
||||
self.assertEqual(Logger.stderr.getvalue(), '')
|
||||
|
||||
def testNoArgs(self):
|
||||
Logger.normal('hello %s')
|
||||
self.assertEqual(Logger.stdout.getvalue(), 'test: hello %s\n')
|
||||
self.assertEqual(Logger.stderr.getvalue(), '')
|
||||
|
||||
def testArgs(self):
|
||||
Logger.normal('hello %s', 'world')
|
||||
self.assertEqual(Logger.stdout.getvalue(), 'test: hello world\n')
|
||||
self.assertEqual(Logger.stderr.getvalue(), '')
|
@ -18,10 +18,9 @@
|
||||
|
||||
import mock
|
||||
import os
|
||||
import sys
|
||||
# import sys
|
||||
from io import StringIO
|
||||
|
||||
from ubuntutools.logger import Logger
|
||||
from ubuntutools.test import unittest
|
||||
from ubuntutools.update_maintainer import update_maintainer
|
||||
|
||||
@ -236,18 +235,18 @@ class UpdateMaintainerTestCase(unittest.TestCase):
|
||||
self.addCleanup(patcher.stop)
|
||||
patcher.start()
|
||||
self._files["rules"] = StringIO(_SIMPLE_RULES)
|
||||
Logger.stdout = StringIO()
|
||||
Logger.stderr = StringIO()
|
||||
# Logger.stdout = StringIO()
|
||||
# Logger.stderr = StringIO()
|
||||
|
||||
def tearDown(self):
|
||||
self.assertEqual(Logger.stdout.getvalue(), '')
|
||||
self.assertEqual(Logger.stderr.getvalue(), '')
|
||||
# self.assertEqual(Logger.stdout.getvalue(), '')
|
||||
# self.assertEqual(Logger.stderr.getvalue(), '')
|
||||
self._files["changelog"] = None
|
||||
self._files["control"] = None
|
||||
self._files["control.in"] = None
|
||||
self._files["rules"] = None
|
||||
Logger.stdout = sys.stdout
|
||||
Logger.stderr = sys.stderr
|
||||
# Logger.stdout = sys.stdout
|
||||
# Logger.stderr = sys.stderr
|
||||
|
||||
# pylint: enable=C0103
|
||||
def test_debian_package(self):
|
||||
@ -266,11 +265,11 @@ class UpdateMaintainerTestCase(unittest.TestCase):
|
||||
self._files["control"] = StringIO(_AXIS2C_CONTROL)
|
||||
update_maintainer(self._directory)
|
||||
self.assertEqual(self._files["control"].getvalue(), _AXIS2C_UPDATED)
|
||||
warnings = Logger.stderr.getvalue().strip()
|
||||
Logger.stderr = StringIO()
|
||||
self.assertEqual(len(warnings.splitlines()), 1)
|
||||
self.assertRegex(warnings, "Warning: Overwriting original maintainer: "
|
||||
"Soren Hansen <soren@ubuntu.com>")
|
||||
# warnings = Logger.stderr.getvalue().strip()
|
||||
# Logger.stderr = StringIO()
|
||||
# self.assertEqual(len(warnings.splitlines()), 1)
|
||||
# self.assertRegex(warnings, "Warning: Overwriting original maintainer: "
|
||||
# "Soren Hansen <soren@ubuntu.com>")
|
||||
|
||||
def test_update_maintainer(self):
|
||||
"""Test: Update Maintainer field."""
|
||||
|
@ -20,7 +20,9 @@ import os
|
||||
import re
|
||||
|
||||
import debian.changelog
|
||||
from ubuntutools.logger import Logger
|
||||
|
||||
import logging
|
||||
Logger = logging.getLogger(__name__)
|
||||
|
||||
# Prior May 2009 these Maintainers were used:
|
||||
_PREVIOUS_UBUNTU_MAINTAINER = (
|
||||
@ -176,8 +178,8 @@ def update_maintainer(debian_directory, verbose=False):
|
||||
return
|
||||
|
||||
if control.get_original_maintainer() is not None:
|
||||
Logger.warn("Overwriting original maintainer: %s",
|
||||
control.get_original_maintainer())
|
||||
Logger.warning("Overwriting original maintainer: %s",
|
||||
control.get_original_maintainer())
|
||||
|
||||
if verbose:
|
||||
print("The original maintainer is: %s" % original_maintainer)
|
||||
|
Loading…
x
Reference in New Issue
Block a user