From 15e5ef9a82398a4e6e72b6617dbdb6a92603fc79 Mon Sep 17 00:00:00 2001 From: Benjamin Drung Date: Fri, 26 Nov 2010 19:34:31 +0100 Subject: [PATCH] sponsor-patch: Support building with sbuild (LP: #681242). --- debian/changelog | 3 +- doc/sponsor-patch.1 | 33 +++++++++++------ sponsor-patch | 90 ++++++++++++++++++++++++++++++++++++--------- 3 files changed, 97 insertions(+), 29 deletions(-) diff --git a/debian/changelog b/debian/changelog index 6b20677..22581a4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -18,8 +18,9 @@ ubuntu-dev-tools (0.107) UNRELEASED; urgency=low [ Benjamin Drung ] * wrap-and-sort: Remove duplicate items from sorted lists. * syncpackage: Fix error message for failed downloads. + * sponsor-patch: Support building with sbuild (LP: #681242). - -- Stefano Rivera Fri, 26 Nov 2010 18:38:05 +0200 + -- Benjamin Drung Fri, 26 Nov 2010 19:32:48 +0100 ubuntu-dev-tools (0.106) experimental; urgency=low diff --git a/doc/sponsor-patch.1 b/doc/sponsor-patch.1 index 569c0e3..5a59f26 100644 --- a/doc/sponsor-patch.1 +++ b/doc/sponsor-patch.1 @@ -11,9 +11,7 @@ test-build it, and upload. .SH DESCRIPTION \fBsponsor\-patch\fR downloads the patch or Bazaar branch linked to an Ubuntu bug, applies it, generates a review diff, (optionally) test -builds it with -.BR pbuilder (8), -runs +builds it, runs .BR lintian (1) and, after review and confirmation, can upload it. @@ -50,33 +48,39 @@ the patched source and try building it again. The sources and patches will be downloaded into the working directory (which defaults to the current directory). -.BR pbuilder (8) -output will be placed in \fIworkdir\fR/\fIsourcepkg\fB\-buildresult/\fR. +The output of the build tool will be placed in +\fIworkdir\fR/\fIsourcepkg\fB\-buildresult/\fR. .SH OPTIONS .TP .BR \-b ", " \-\-build -Build the package with \fBpbuilder\fR(1). This assumes the common -configuration, where the \fBDIST\fR environment is read by -\fBpbuilderrc\fR(5) to select the correct base image. +Build the package with the specified builder. Note for \fBpbuilder\fR(8) users: +This assumes the common configuration, where the \fBDIST\fR environment is read +by \fBpbuilderrc\fR(5) to select the correct base image. +.TP +.B \-B \fIBUILDER\fR, \fB\-\-builder\fR=\fIBUILDER +Use the specify builder to build the package. +Supported are \fBpbuilder\fR(8) and \fBsbuild\fR(1). +This overrides \fBSPONSOR_PATCH_BUILDER\fR. +The default is \fBpbuilder\fR(8). .TP .BR \-e ", " \-\-edit Launch a sub-shell to allow editing of the patched source before building. .TP -.B \-k\fIKEY\fR, \fB\-\-key\fR=\fIKEY +.B \-k \fIKEY\fR, \fB\-\-key\fR=\fIKEY Specify a key ID for signing the upload. .TP .BR \-s ", " \-\-sponsor Shortcut for sponsored uploads. Equivalent to \fB\-b \-u ubuntu\fR. .TP -.B \-u\fIDEST\fR, \fB\-\-upload\fR=\fIDEST +.B \-u \fIDEST\fR, \fB\-\-upload\fR=\fIDEST Upload to \fIDEST\fR with \fBdput\fR(1) (after confirmation). .TP .BR \-v ", " \-\-verbose Print more information. .TP -.B \-w\fIDIR\fR, \fB\-\-workdir\fR=\fIDIR +.B \-w \fIDIR\fR, \fB\-\-workdir\fR=\fIDIR Use the specified working directory, creating it if necessary, instead of the current directory. This overrides \fBSPONSOR_PATCH_WORKDIR\fR. .TP @@ -85,6 +89,12 @@ Display a help message and exit. .SH ENVIRONMENT +.TP +.B SPONSOR_PATCH_BUILDER +The default builder for \fBsponsor\-patch\fR. +Supported are \fBpbuilder\fR(8) and \fBsbuild\fR(1). +If unset and not provided on the command line, \fBpbuilder\fR(8) is used. + .TP .B SPONSOR_PATCH_WORKDIR The default working directory for \fBsponsor\-patch\fR. If unset and not @@ -112,6 +122,7 @@ Performing a test build of bug \fB1234\fR in your PPA: .BR edit-patch (1), .BR lintian (1), .BR pbuilder (8), +.BR sbuild (1), .BR update\-maintainer (1) .SH AUTHORS diff --git a/sponsor-patch b/sponsor-patch index 679412a..0f6ca7c 100755 --- a/sponsor-patch +++ b/sponsor-patch @@ -148,6 +148,50 @@ class BugTask(object): return self.project == "ubuntu" +class Builder(object): + def __init__(self, name): + self.name = name + cmd = ["dpkg-architecture", "-qDEB_BUILD_ARCH_CPU"] + process = subprocess.Popen(cmd, stdout=subprocess.PIPE) + self.architecture = process.communicate()[0].strip() + + def get_architecture(self): + return self.architecture + + def get_name(self): + return self.name + + +class Pbuilder(Builder): + def __init__(self): + Builder.__init__(self, "pbuilder") + + def build(self, dsc_file, dist, result_directory): + # TODO: Do not rely on a specific pbuilder configuration. + cmd = ["sudo", "-E", "DIST=" + dist, "pbuilder", "--build", + "--distribution", dist, "--architecture", self.architecture, + "--buildresult", result_directory, dsc_file] + Print.command(cmd) + return subprocess.call(cmd) + + +class Sbuild(Builder): + def __init__(self): + Builder.__init__(self, "sbuild") + + def build(self, dsc_file, dist, result_directory): + workdir = os.getcwd() + Print.command(["cd", result_directory]) + os.chdir(result_directory) + cmd = ["sbuild", "--arch-all", "--dist=" + dist, + "--arch=" + self.architecture, dsc_file] + Print.command(cmd) + result = subprocess.call(cmd) + Print.command(["cd", workdir]) + os.chdir(workdir) + return result + + class Patch(object): def __init__(self, patch_file): self.patch_file = patch_file @@ -442,7 +486,7 @@ def apply_patch(task, patch): edit = True return edit -def main(script_name, bug_number, build, edit, keyid, upload, workdir, +def main(script_name, bug_number, build, edit, keyid, upload, workdir, builder, verbose=False): workdir = os.path.expanduser(workdir) if not os.path.isdir(workdir): @@ -634,27 +678,21 @@ def main(script_name, bug_number, build, edit, keyid, upload, workdir, buildresult = os.path.join(workdir, task.package + "-buildresult") if not os.path.isdir(buildresult): os.makedirs(buildresult) - cmd = ["dpkg-architecture", "-qDEB_BUILD_ARCH_CPU"] - process = subprocess.Popen(cmd, stdout=subprocess.PIPE) - architecture = process.communicate()[0].strip() # build package dist = re.sub("-.*$", "", changelog.distributions) - # TODO: Do not rely on a specific pbuilder configuration. - cmd = ["sudo", "-E", "DIST=" + dist, "pbuilder", "--build", - "--distribution", dist, "--buildresult", buildresult, - "--architecture", architecture, new_dsc_file] - Print.command(cmd) - if subprocess.call(cmd) != 0: - Print.error("Failed to build %s from source." % \ - (os.path.basename(new_dsc_file))) + result = builder.build(new_dsc_file, dist, buildresult) + if result != 0: + Print.error("Failed to build %s from source with %s." % \ + (os.path.basename(new_dsc_file), + builder.get_name())) # TODO: Add "retry" and "update" option ask_for_manual_fixing() continue # Check lintian changes_name = task.package + "_" + strip_epoch(new_version) + \ - "_" + architecture + ".changes" + "_" + builder.get_architecture() + ".changes" build_changes = os.path.join(buildresult, changes_name) assert os.path.isfile(build_changes), "%s does not exist." % \ (build_changes) @@ -674,7 +712,7 @@ def main(script_name, bug_number, build, edit, keyid, upload, workdir, if upload: if upload == "ubuntu": build_name = task.package + "_" + strip_epoch(new_version) + \ - "_" + architecture + ".build" + "_" + builder.get_architecture() + ".build" build_log = os.path.join(buildresult, build_name) print "Please check %s %s carefully:\nfile://%s\nfile://%s\n" \ "file://%s" % (task.package, new_version, @@ -725,8 +763,17 @@ if __name__ == "__main__": else: default_workdir = os.getcwd() - parser.add_option("-b", "--build", help="Build the package with pbuilder.", - dest="build", action="store_true", default=False) + if "SPONSOR_PATCH_BUILDER" in os.environ: + default_builder = os.environ["SPONSOR_PATCH_BUILDER"] + else: + default_builder = "pbuilder" + + parser.add_option("-b", "--build", dest="build", + help="Build the package with the specified builder.", + action="store_true", default=False) + parser.add_option("-B", "--builder", dest="builder", + help="Specify the package builder (default pbuilder)", + default=default_builder) parser.add_option("-e", "--edit", help="launch sub-shell to allow editing of the patch", dest="edit", action="store_true", default=False) @@ -759,9 +806,18 @@ if __name__ == "__main__": Print.error("Invalid bug number specified: %s" % (bug_number)) sys.exit(1) + if options.builder == "pbuilder": + builder = Pbuilder() + elif options.builder == "sbuild": + builder = Sbuild() + else: + Print.error("Unsupported builder specified: %s. Only pbuilder and " + "sbuild are supported." % (options.builder)) + sys.exit(1) + if options.sponsoring: options.build = True options.upload = "ubuntu" main(script_name, bug_number, options.build, options.edit, options.keyid, - options.upload, options.workdir, options.verbose) + options.upload, options.workdir, builder, options.verbose)