def update(self, dist): cmd = ["schroot", "--list"] Logger.command(cmd) process = subprocess.Popen(cmd, stdout=subprocess.PIPE) chroots, _ = process.communicate()[0].strip().split() if process.returncode != 0: return process.returncode params = {"dist": dist, "arch": self.architecture} for chroot in ("%(dist)s-%(arch)s-sbuild-source", "%(dist)s-sbuild-source", "%(dist)s-%(arch)s-source", "%(dist)s-source"): chroot = chroot % params if chroot in chroots: break else: return 1 commands = [["sbuild-update"], ["sbuild-distupgrade"], ["sbuild-clean", "-a", "-c"]] for cmd in commands: # pylint: disable=W0631 Logger.command(cmd + [chroot]) ret = subprocess.call(cmd + [chroot]) # pylint: enable=W0631 if ret != 0: return self._update_failure(ret, dist) return 0
def build_source(self, keyid, upload, previous_version): """Tries to build the source package. Returns true if the source package was built successfully. Returns false if the user wants to change something. """ if self._branch: cmd = ['bzr', 'builddeb', '--builder=debuild', '-S', '--', '--no-lintian', '-nc'] else: cmd = ['debuild', '--no-lintian', '-nc', '-S'] cmd.append("-v" + previous_version.full_version) if previous_version.upstream_version == \ self._changelog.upstream_version and upload == "ubuntu": # FIXME: Add proper check that catches cases like changed # compression (.tar.gz -> tar.bz2) and multiple orig source tarballs cmd.append("-sd") else: cmd.append("-sa") if keyid is not None: cmd += ["-k" + keyid] env = os.environ if upload == 'ubuntu': env['DEB_VENDOR'] = 'Ubuntu' Logger.command(cmd) if subprocess.call(cmd, env=env) != 0: Logger.error("Failed to build source tarball.") # TODO: Add a "retry" option ask_for_manual_fixing() return False return True
def _run_lintian(self): """Runs lintian on either the source or binary changes file. Returns the filename of the created lintian output file. """ # Determine whether to use the source or binary build for lintian if self._build_log: build_changes = self._package + "_" + strip_epoch(self._version) + \ "_" + self._builder.get_architecture() + ".changes" changes_for_lintian = os.path.join(self._buildresult, build_changes) else: changes_for_lintian = self._changes_file # Check lintian assert os.path.isfile(changes_for_lintian), "%s does not exist." % \ (changes_for_lintian) cmd = ["lintian", "-IE", "--pedantic", "-q", "--profile", "ubuntu", changes_for_lintian] lintian_filename = os.path.join(self._workdir, self._package + "_" + strip_epoch(self._version) + ".lintian") Logger.command(cmd + [">", lintian_filename]) process = subprocess.Popen(cmd, stdout=subprocess.PIPE) report = process.communicate()[0] # write lintian report file lintian_file = open(lintian_filename, "w") lintian_file.writelines(report) lintian_file.close() return lintian_filename
def update(self, dist): cmd = ["sudo", "-E", "ARCH=" + self.architecture, "DIST=" + dist, self.name, "--update", "--architecture", self.architecture, "--distribution", dist] Logger.command(cmd) returncode = subprocess.call(cmd) return self._update_failure(returncode, dist)
def build(self, dsc_file, dist, result_directory): _build_preparation(result_directory) cmd = [self.name, dist, self.architecture, "build", dsc_file, "--buildresult", result_directory] Logger.command(cmd) returncode = subprocess.call(cmd) return self._build_failure(returncode, dsc_file)
def _download_and_change_into(task, dsc_file, patch, branch): """Downloads the patch and branch and changes into the source directory.""" if branch: branch_dir = download_branch(task.get_branch_link()) # change directory Logger.command(["cd", branch_dir]) os.chdir(branch_dir) else: if patch: patch.download() Logger.info("Ubuntu package: %s" % (task.package)) if task.is_merge(): Logger.info("The task is a merge request.") if task.is_sync(): Logger.info("The task is a sync request.") extract_source(dsc_file, Logger.verbose) # change directory directory = task.package + '-' + task.get_version().upstream_version Logger.command(["cd", directory]) os.chdir(directory)
def apply(self, task): """Applies the patch in the current directory.""" assert self._changed_files is not None, "You forgot to download the patch." edit = False if self.is_debdiff(): cmd = [ "patch", "--merge", "--force", "-p", str(self.get_strip_level()), "-i", self._full_path ] Logger.command(cmd) if subprocess.call(cmd) != 0: Logger.error("Failed to apply debdiff %s to %s %s.", self._patch_file, task.package, task.get_version()) if not edit: ask_for_manual_fixing() edit = True else: cmd = ["add-patch", self._full_path] Logger.command(cmd) if subprocess.call(cmd) != 0: Logger.error("Failed to apply diff %s to %s %s.", self._patch_file, task.package, task.get_version()) if not edit: ask_for_manual_fixing() edit = True return edit
def _update_maintainer_field(): """Update the Maintainer field in debian/control.""" Logger.command(["update-maintainer"]) try: update_maintainer("debian", Logger.verbose) except MaintainerUpdateException as e: Logger.error("update-maintainer failed: %s", str(e)) sys.exit(1)
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) if subprocess.call(cmd) != 0: Logger.error("Extraction of %s failed." % (os.path.basename(dsc_file))) sys.exit(1)
def unpack(self, destdir=None): "Unpack in workdir" cmd = ['dpkg-source', '-x', self.dsc_name] if destdir: cmd.append(destdir) Logger.command(cmd) if subprocess.call(cmd, cwd=self.workdir): Logger.error('Source unpack failed.') sys.exit(1)
def merge_branch(branch): edit = False cmd = ["bzr", "merge", branch] Logger.command(cmd) if subprocess.call(cmd) != 0: Logger.error("Failed to merge branch %s." % (branch)) ask_for_manual_fixing() edit = True return edit
def build(self, dsc_file, dist, result_directory): _build_preparation(result_directory) cmd = ["sudo", "-E", "ARCH=" + self.architecture, "DIST=" + dist, self.name, "--build", "--architecture", self.architecture, "--distribution", dist, "--buildresult", result_directory, dsc_file] Logger.command(cmd) returncode = subprocess.call(cmd) return self._build_failure(returncode, dsc_file)
def download_branch(branch): dir_name = os.path.basename(branch) if os.path.isdir(dir_name): shutil.rmtree(dir_name) cmd = ["bzr", "branch", branch] Logger.command(cmd) if subprocess.call(cmd) != 0: Logger.error("Failed to download branch %s." % (branch)) sys.exit(1) return dir_name
def _create_and_change_into(workdir): """Create (if it does not exits) and change into given working directory.""" if not os.path.isdir(workdir): try: os.makedirs(workdir) except os.error as error: Logger.error( "Failed to create the working directory %s [Errno %i]: %s." % (workdir, error.errno, error.strerror)) sys.exit(1) if workdir != os.getcwd(): Logger.command(["cd", workdir]) os.chdir(workdir)
def edit_source(): # Spawn shell to allow modifications cmd = [get_user_shell()] Logger.command(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 process, exit the shell such that it returns an exit code other than zero. """ % (os.getcwd()), end=' ') returncode = subprocess.call(cmd) if returncode != 0: Logger.error("Shell exited with exit value %i." % (returncode)) sys.exit(1)
def generate_debdiff(self, dsc_file): """Generates a debdiff between the given .dsc file and this source package.""" assert os.path.isfile(dsc_file), "%s does not exist." % (dsc_file) 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: cmd.insert(1, "-q") Logger.command(cmd + [">", self._debdiff_filename]) process = subprocess.Popen(cmd, stdout=subprocess.PIPE) debdiff = process.communicate()[0] # write debdiff file debdiff_file = open(self._debdiff_filename, "w") debdiff_file.writelines(debdiff) debdiff_file.close()
def sync(self, upload, series, bug_number, requester): """Does a sync of the source package.""" if upload == "ubuntu": cmd = ["syncpackage", self._package, "-b", str(bug_number), "-f", "-s", requester, "-V", str(self._version), "-d", series] Logger.command(cmd) if subprocess.call(cmd) != 0: Logger.error("Syncing of %s %s failed.", self._package, str(self._version)) sys.exit(1) else: # FIXME: Support this use case! Logger.error("Uploading a synced package other than to Ubuntu " "is not supported yet!") sys.exit(1) return True
def debdiff(self, newpkg, diffstat=False): """Write a debdiff comparing this src pkg to a newer one. Optionally print diffstat. Return the debdiff filename. """ cmd = ['debdiff', self.dsc_name, newpkg.dsc_name] difffn = newpkg.dsc_name[:-3] + 'debdiff' Logger.command(cmd + ['> %s' % difffn]) with open(difffn, 'w') as f: if subprocess.call(cmd, stdout=f, cwd=self.workdir) > 2: Logger.error('Debdiff failed.') sys.exit(1) if diffstat: cmd = ('diffstat', '-p1', difffn) Logger.command(cmd) if subprocess.call(cmd): Logger.error('diffstat failed.') sys.exit(1) return os.path.abspath(difffn)
def ask_and_upload(self, upload): """Ask the user before uploading the source package. Returns true if the source package is uploaded successfully. Returns false if the user wants to change something. """ # Upload package if upload: self._print_logs() if upload == "ubuntu": target = "the official Ubuntu archive" else: target = upload question = Question(["yes", "edit", "no"]) answer = question.ask("Do you want to upload the package to %s" % target, "no") if answer == "edit": return False elif answer == "no": user_abort() cmd = ["dput", "--force", upload, self._changes_file] Logger.command(cmd) if subprocess.call(cmd) != 0: Logger.error("Upload of %s to %s failed." % (os.path.basename(self._changes_file), upload)) sys.exit(1) # Push the branch if the package is uploaded to the Ubuntu archive. if upload == "ubuntu" and self._branch: cmd = ['debcommit'] Logger.command(cmd) if subprocess.call(cmd) != 0: Logger.error('Bzr commit failed.') sys.exit(1) cmd = ['bzr', 'mark-uploaded'] Logger.command(cmd) if subprocess.call(cmd) != 0: Logger.error('Bzr tagging failed.') sys.exit(1) cmd = ['bzr', 'push', ':parent'] Logger.command(cmd) if subprocess.call(cmd) != 0: Logger.error('Bzr push failed.') sys.exit(1) return True
def build(self, dsc_file, dist, result_directory): _build_preparation(result_directory) workdir = os.getcwd() Logger.command(["cd", result_directory]) os.chdir(result_directory) cmd = ["sbuild", "--arch-all", "--dist=" + dist, "--arch=" + self.architecture, dsc_file] Logger.command(cmd) returncode = subprocess.call(cmd) Logger.command(["cd", workdir]) os.chdir(workdir) return self._build_failure(returncode, dsc_file)
def update(self, dist): cmd = [self.name, dist, self.architecture, "update"] Logger.command(cmd) returncode = subprocess.call(cmd) return self._update_failure(returncode, dist)
def _update_timestamp(): """Run dch to update the timestamp of debian/changelog.""" cmd = ["dch", "--maintmaint", "--release", ""] Logger.command(cmd) if subprocess.call(cmd) != 0: Logger.info("Failed to update timestamp in debian/changelog.")