def _run_command(command, basedir, msg, error_msg, not_installed_msg=None, env=None, success_exit_codes=None, indata=None): """ Run a command in a subprocess. :param command: list with command and parameters :param msg: message to display to the user :param error_msg: message to display if something fails. :param not_installed_msg: the message to display if the command isn't available. :param env: Optional environment to use rather than os.environ. :param success_exit_codes: Exit codes to consider succesfull, defaults to [0]. :param indata: Data to write to standard input """ def subprocess_setup(): signal.signal(signal.SIGPIPE, signal.SIG_DFL) trace.note(msg) # Hide output if -q is in use. quiet = trace.is_quiet() if quiet: kwargs = {"stderr": subprocess.STDOUT, "stdout": subprocess.PIPE} else: kwargs = {} if env is not None: kwargs["env"] = env trace.mutter("running: %r", command) try: proc = subprocess.Popen(command, cwd=basedir, stdin=subprocess.PIPE, preexec_fn=subprocess_setup, **kwargs) except OSError as e: if e.errno != errno.ENOENT: raise if not_installed_msg is None: raise raise MissingDependency(msg=not_installed_msg) output = proc.communicate(indata) if success_exit_codes is None: success_exit_codes = [0] if proc.returncode not in success_exit_codes: if quiet: raise errors.BzrCommandError("%s: %s" % (error_msg, output)) else: raise errors.BzrCommandError(error_msg)
def _qbrz_run(self, selected_list=None, message=None, file=None, local=False, ui_mode=False, file_encoding=None): if message is not None and file: raise errors.BzrCommandError( "please specify either --message or --file") if file: f = open(file) try: message = f.read().decode(file_encoding or osutils.get_user_encoding()) finally: f.close() tree, selected_list = WorkingTree.open_containing_paths(selected_list) if selected_list == ['']: selected_list = None self.main_window = CommitWindow(tree, selected_list, dialog=False, message=message, local=local, ui_mode=ui_mode) self.main_window.show() self._application.exec_()
def run(self, location, working_directory, manifest=None, if_changed_from=None, revision=None): if revision is not None and len(revision) > 0: if len(revision) != 1: raise errors.BzrCommandError("only a single revision can be " "specified") revspec = revision[0] else: revspec = None possible_transports = [] base_branch = get_prepared_branch_from_location( location, possible_transports=possible_transports, revspec=revspec) if if_changed_from is not None: old_recipe = get_old_recipe(if_changed_from, possible_transports) else: old_recipe = None changed = resolve_revisions(base_branch, if_changed_from=old_recipe) if not changed: trace.note("Unchanged") return 0 manifest_path = manifest or os.path.join(working_directory, "bzr-builder.manifest") build_tree(base_branch, working_directory) write_manifest_to_transport(manifest_path, base_branch, possible_transports)
def check_expanded_deb_version(base_branch): checked_version = base_branch.deb_version if checked_version is None: return for token in ok_to_preserve: if issubclass(token, BranchSubstitutionVariable): for name in base_branch.list_branch_names(): checked_version = checked_version.replace( token.determine_name(name), "") checked_version = checked_version.replace( token.determine_name(None), "") else: checked_version = checked_version.replace(token.name, "") if "{" in checked_version: available_tokens = [ var.name for var in simple_vars if var.available_in(base_branch.format) ] for var_kls in branch_vars + deb_branch_vars: if not var_kls.available_in(base_branch.format): continue for name in base_branch.list_branch_names(): available_tokens.append(var_kls.determine_name(name)) available_tokens.append(var_kls.determine_name(None)) raise errors.BzrCommandError( "deb-version not fully " "expanded: %s. Valid substitutions in recipe format %s are: %s" % (base_branch.deb_version, base_branch.format, available_tokens))
def get_prepared_branch_from_location(location, safe=False, possible_transports=None, revspec=None): """Common code to prepare a branch and do substitutions. :param location: a path to a recipe file or branch to work from. :param if_changed_from: an optional location of a manifest to compare the recipe against. :param safe: if True, reject recipes that would cause arbitrary code execution. :return: A tuple with (retcode, base_branch). If retcode is None then the command execution should continue. """ try: base_branch = get_branch_from_recipe_location( location, safe=safe, possible_transports=possible_transports) except (_mod_transport.LateReadError, errors.ReadError): # Presume unable to read means location is a directory rather than a file base_branch = get_branch_from_branch_location( location, possible_transports=possible_transports) else: if revspec is not None: raise errors.BzrCommandError("--revision only supported when " "building from branch") return base_branch
def _load_branch(self, filename, revision): """To assist in getting a UI up as soon as possible, the UI calls back to this function to process the command-line args and convert them into the branch and tree etc needed by the UI. """ wt, branch, relpath = ControlDir.open_containing_tree_or_branch( filename) if wt is not None: wt.lock_read() else: branch.lock_read() try: if revision is None: if wt is not None: tree = wt else: tree = branch.repository.revision_tree( branch.last_revision()) elif len(revision) != 1: raise errors.BzrCommandError( 'brz qannotate --revision takes exactly 1 argument') else: tree = branch.repository.revision_tree( revision_id=revision[0].in_history(branch).rev_id) file_id = tree.path2id(relpath) if file_id is None: raise errors.NotVersionedError(filename) [(path, entry) ] = list(tree.iter_entries_by_dir(specific_files=[filename])) if entry.kind != 'file': raise errors.BzrCommandError( 'brz qannotate only works for files (got %r)' % entry.kind) #repo = branch.repository #w = repo.weave_store.get_weave(file_id, repo.get_transaction()) #content = list(w.annotate_iter(entry.revision)) #revision_ids = set(o for o, t in content) #revision_ids = [o for o in revision_ids if repo.has_revision(o)] #revisions = branch.repository.get_revisions(revision_ids) finally: if wt is not None: wt.unlock() else: branch.unlock() return branch, tree, wt, relpath, file_id
def _qbrz_run(self, ui_mode=False, execute=False): from breezy.plugins.qbrz.lib.unbind import QBzrUnbindDialog branch = Branch.open_containing(CUR_DIR)[0] if branch.get_bound_location() == None: raise errors.BzrCommandError("This branch is not bound.") self.main_window = QBzrUnbindDialog(branch, ui_mode, execute) self.main_window.show() self._application.exec_()
def force_native_format(working_tree_path, current_format): """Make sure a package is a format that supports native packages. :param working_tree_path: Path to the package """ if current_format == "3.0 (quilt)": convert_3_0_quilt_to_native(working_tree_path) elif current_format not in ("1.0", "3.0 (native)"): raise errors.BzrCommandError("Unknown source format %s" % current_format)
def add_autobuild_changelog_entry(base_branch, basedir, package, distribution=None, author_name=None, author_email=None, append_version=None): """Add a new changelog entry for an autobuild. :param base_branch: Recipe base branch :param basedir: Base working directory :param package: package name :param distribution: Optional distribution (defaults to last entry distribution) :param author_name: Name of the build requester :param author_email: Email of the build requester :param append_version: Optional version suffix to add """ debian_dir = os.path.join(basedir, "debian") if not os.path.exists(debian_dir): os.makedirs(debian_dir) cl_path = os.path.join(debian_dir, "changelog") file_found = False if os.path.exists(cl_path): file_found = True cl_f = open(cl_path) try: contents = cl_f.read() finally: cl_f.close() cl = changelog.Changelog(file=contents) else: cl = changelog.Changelog() if len(cl._blocks) > 0: if distribution is None: distribution = cl._blocks[0].distributions.split()[0] else: if file_found: if len(contents.strip()) > 0: reason = ("debian/changelog didn't contain any " "parseable stanzas") else: reason = "debian/changelog was empty" else: reason = "debian/changelog was not present" if distribution is None: distribution = DEFAULT_UBUNTU_DISTRIBUTION if base_branch.format in (0.1, 0.2, 0.3): try: substitute_changelog_vars(base_branch, None, cl) except SubstitutionUnavailable, e: raise errors.BzrCommandError( "No previous changelog to " "take the upstream version from as %s was " "used: %s: %s." % (e.name, e.reason, reason))
def run(self, to_location=None, force=False, create_branch=False, revision=None, directory=None): # The top of this is cribbed from bzr; because bzr isn't factored out # enough. if directory is None: directory = u'.' control_dir, path = controldir.ControlDir.open_containing(directory) if to_location is None: if revision is None: raise errors.BzrCommandError( 'You must supply either a revision or a location') to_location = '.' try: from_branch = control_dir.open_branch() except errors.NotBranchError: from_branch = None if create_branch: if from_branch is None: raise errors.BzrCommandError( 'cannot create branch without source branch') to_location = directory_service.directories.dereference( to_location) if from_branch is not None: # Note: reopens. (tree, path) = workingtree.WorkingTree.open_containing(directory) tree = LoomTreeDecorator(tree) try: if create_branch: return branch.create_thread(tree.branch, to_location) thread_name = self._get_thread_name(tree.branch, to_location) return tree.down_thread(thread_name) except (AttributeError, branch.NoSuchThread, branch.NotALoom): # When there is no thread its probably an external branch # that we have been given. raise errors.MustUseDecorated else: # switching to a relocated branch raise errors.MustUseDecorated
def run(self, location=None): root_transport = None loom = breezy.branch.Branch.open_containing('.')[0] if location is None: location = loom.get_config().get_user_option('export_loom_root') if location is None: raise errors.BzrCommandError('No export root known or specified.') root_transport = breezy.transport.get_transport( location, possible_transports=[loom.controldir.root_transport]) root_transport.ensure_base() loom.export_threads(root_transport)
def run(self, merge_type=None, manual=False, thread=None, auto=None): (tree, path) = workingtree.WorkingTree.open_containing('.') branch.require_loom_branch(tree.branch) tree = LoomTreeDecorator(tree) if manual: if thread is not None: raise errors.BzrCommandError('Specifying a thread does not' ' work with --manual.') return tree.up_thread(merge_type) else: return tree.up_many(merge_type, thread)
def run(self, bug_id, open=False): # we import from qbrz.lib.util here because that module # has dependency on PyQt4 (see bug #327487) from breezy.plugins.qbrz.lib.util import open_browser, url_for_display try: branch = Branch.open_containing('.')[0] except errors.NotBranchError: branch = FakeBranchForBugs() tokens = bug_id.split(':') if len(tokens) != 2: raise errors.BzrCommandError( "Invalid bug %s. Must be in the form of 'tag:id'." % bug_id) tag, tag_bug_id = tokens try: bug_url = bugtracker.get_bug_url(tag, branch, tag_bug_id) except errors.UnknownBugTrackerAbbreviation: raise errors.BzrCommandError('Unrecognized bug %s.' % bug_id) except errors.MalformedBugIdentifier: raise errors.BzrCommandError("Invalid bug identifier for %s." % bug_id) self.outf.write(url_for_display(bug_url) + "\n") if open: open_browser(bug_url)
def run(self, path="."): from breezy import ( errors, urlutils, ) from breezy.branch import Branch from . import gettext from breezy.repository import Repository from . import errors as bzrsvn_errors try: branch, _ = Branch.open_containing(path) repos = branch.repository except (errors.NotBranchError, errors.NoColocatedBranchSupport): repos = Repository.open(path) branch = None if getattr(repos, "uuid", None) is None: raise errors.BzrCommandError( gettext("Not a Subversion branch or repository.")) layout = repos.get_layout() self.outf.write(gettext("Repository root: %s\n") % repos.base) self.outf.write(gettext("Layout: %s\n") % str(layout)) if branch is not None: self.outf.write( gettext("Branch path: %s\n") % branch.get_branch_path()) if branch.project: self.outf.write(gettext("Project: %s\n") % branch.project) try: test_tag_path = layout.get_tag_path("test", branch.project) except bzrsvn_errors.NoLayoutTagSetSupport: self.outf.write(gettext("No tag support\n")) else: if test_tag_path: self.outf.write( gettext("Tag container directory: %s\n") % urlutils.dirname(test_tag_path)) try: test_branch_path = layout.get_branch_path( "test", branch.project) except bzrsvn_errors.NoCustomBranchPaths: self.outf.write(gettext("No custom branch support\n")) else: if test_branch_path: self.outf.write( gettext("Branch container directory: %s\n") % urlutils.dirname(test_branch_path)) self.outf.write( gettext("Push merged revisions: %s\n") % branch.get_push_merged_revisions())
def target_from_dput(dput): """Convert a dput specification to a LP API specification. :param dput: A dput command spec like ppa:team-name. :return: A LP API target like team-name/ppa. """ ppa_prefix = 'ppa:' if not dput.startswith(ppa_prefix): raise errors.BzrCommandError( '%r does not appear to be a PPA. ' 'A dput target like \'%suser[/name]\' must be used.' % (dput, ppa_prefix)) base, _, suffix = dput[len(ppa_prefix):].partition('/') if not suffix: suffix = 'ppa' return base, suffix
def run(self, location='.', base=None): (target, path) = breezy.branch.Branch.open_containing(location) target.lock_write() try: if base is not None: target.nick = base elif not target.get_config().has_explicit_nickname(): raise errors.BzrCommandError( 'You must specify --base or have a branch nickname set to' ' loomify a branch') branch.loomify(target) loom = target.controldir.open_branch() finally: target.unlock() # requires a new lock as its a new instance, XXX: teach bzrdir about # format changes ? loom.new_thread(loom.nick)
def run(self, thread=None): (wt, path) = workingtree.WorkingTree.open_containing('.') branch.require_loom_branch(wt.branch) tree = LoomTreeDecorator(wt) tree.lock_write() try: basis = wt.basis_tree() basis.lock_read() try: for change in wt.iter_changes(basis): raise errors.BzrCommandError( 'Working tree has uncommitted changes.') finally: basis.unlock() return tree.down_thread(thread) finally: tree.unlock()
def run(self, location): transport = get_transport(location) try: medium = transport.get_smart_medium() except errors.NoSmartMedium as e: raise errors.BzrCommandError(str(e)) client = _SmartClient(medium) # Use call_expecting_body (even though we don't expect a body) so that # we can see the response headers (if any) via the handler object. response, handler = client.call_expecting_body(b'hello') handler.cancel_read_body() self.outf.write('Response: %r\n' % (response, )) if getattr(handler, 'headers', None) is not None: headers = { k.decode('utf-8'): v.decode('utf-8') for (k, v) in viewitems(handler.headers) } self.outf.write('Headers: %r\n' % (headers, ))
def load(self): self.throbber.show() self.processEvents() try: if not self.tree: branch, relpath = Branch.open_containing(self.filename) self.branch = branch self.encoding = get_set_encoding(self.encoding, branch) self.encoding_selector.encoding = self.encoding if self.revision is None: self.tree = branch.basis_tree() else: revision_id = self.revision[0].in_branch(branch).rev_id self.tree = branch.repository.revision_tree(revision_id) self.file_id = self.tree.path2id(relpath) if not self.file_id: self.file_id = self.tree.path2id(self.filename) if not self.file_id: raise errors.BzrCommandError( "%r is not present in revision %s" % (self.filename, self.tree.get_revision_id())) self.tree.lock_read() try: kind = self.tree.kind(self.filename) if kind == 'file': text = self.tree.get_file_text(self.filename) elif kind == 'symlink': text = self.tree.get_symlink_target(self.filename) else: text = '' finally: self.tree.unlock() self.processEvents() self.text = text self.kind = kind self._create_and_show_browser(self.filename, text, kind) finally: self.throbber.hide()
def run(self, force=False): (tree, path) = workingtree.WorkingTree.open_containing('.') branch.require_loom_branch(tree.branch) self.add_cleanup(tree.lock_write().unlock) current_thread = tree.branch.nick state = tree.branch.get_loom_state() if not force: # Check for unmerged work. # XXX: Layering issue whom should be caring for the check, not the # command thats for sure. threads = state.get_threads() current_index = state.thread_index(current_thread) rev_below = None rev_current = threads[current_index][1] rev_above = None if current_index: # There is a thread below rev_below = threads[current_index - 1][1] if current_index < len(threads) - 1: rev_above = threads[current_index + 1][1] graph = tree.branch.repository.get_graph() candidates = [ rev for rev in (rev_below, rev_current, rev_above) if rev ] heads = graph.heads(candidates) # If current is not a head, its trivially merged, or # if current is == rev_below, its also merged, or # if there is only one thread its merged (well its not unmerged). if (rev_current == rev_below or rev_current not in heads or (rev_below is None and rev_above is None)): merged = True else: merged = False if not merged: raise errors.BzrCommandError( "Thread '%s' has unmerged work" ". Use --force to combine anyway." % current_thread) new_thread = state.get_new_thread_after_deleting(current_thread) if new_thread is None: raise branch.CannotCombineOnLastThread breezy.trace.note("Combining thread '%s' into '%s'", current_thread, new_thread) LoomTreeDecorator(tree).down_thread(new_thread) tree.branch.remove_thread(current_thread)
def _qbrz_run(self, filename, revision=None, encoding=None, native=None): if revision is not None and len(revision) != 1: raise errors.BzrCommandError( "brz qcat --revision takes exactly one revision specifier") if native: branch, relpath = Branch.open_containing(filename) if revision is None: tree = branch.basis_tree() else: revision_id = revision[0].in_branch(branch).rev_id tree = branch.repository.revision_tree(revision_id) result = cat_to_native_app(tree, relpath) return int(not result) window = QBzrCatWindow(filename=filename, revision=revision, encoding=encoding) window.show() self._application.exec_()
def _qbrz_run(self, revision=None, file_list=None, complete=False, encoding=None, ignore_whitespace=False, added=None, deleted=None, modified=None, renamed=None, old=None, new=None, ui_mode=False): if revision and len(revision) > 2: raise errors.BzrCommandError( 'brz qdiff --revision takes exactly one or two revision specifiers' ) # changes filter filter_options = FilterOptions(added=added, deleted=deleted, modified=modified, renamed=renamed) if not (added or deleted or modified or renamed): # if no filter option used then turn all on filter_options.all_enable() self.revision = revision self.file_list = file_list self.old = old self.new = new self.ignore_whitespace = ignore_whitespace window = DiffWindow(self, complete=complete, encoding=encoding, filter_options=filter_options, ui_mode=ui_mode) window.show() self._application.exec_()
def run(self, location=".", set=False, repository_wide=False): from breezy import errors as bzr_errors from breezy.controldir import ControlDir from breezy.msgeditor import edit_commit_message from breezy.trace import note from ..repository import SvnRepository from ..mapping3.base import ( BzrSvnMappingv3, config_set_scheme, get_property_scheme, set_property_scheme, ) from .scheme import ( scheme_from_branch_list, ) def scheme_str(scheme): if scheme is None: return "" return "".join(map(lambda x: x+"\n", scheme.to_lines())) dir = ControlDir.open_containing(location)[0] repos = dir.find_repository() if not isinstance(repos, SvnRepository): raise bzr_errors.BzrCommandError("Not a Subversion repository: %s" % location) if repository_wide: scheme = get_property_scheme(repos) else: scheme = BzrSvnMappingv3.from_repository(repos).scheme if set: schemestr = edit_commit_message("", start_message=scheme_str(scheme)) scheme = scheme_from_branch_list( map(lambda x:x.strip("\n"), schemestr.splitlines())) if repository_wide: set_property_scheme(repos, scheme) else: config_set_scheme(repos, scheme, None, mandatory=True) elif scheme is not None: note(scheme_str(scheme))
def script_runner(local_tree: WorkingTree, script: str, commit_pending: Optional[bool] = None) -> str: """Run a script in a tree and commit the result. This ignores newly added files. :param local_tree: Local tree to run script in :param script: Script to run :param commit_pending: Whether to commit pending changes (True, False or None: only commit if there were no commits by the script) :return: Description as reported by script """ last_revision = local_tree.last_revision() p = subprocess.Popen(script, cwd=local_tree.basedir, stdout=subprocess.PIPE, shell=True) (description_encoded, err) = p.communicate(b"") if p.returncode != 0: raise errors.BzrCommandError("Script %s failed with error code %d" % (script, p.returncode)) new_revision = local_tree.last_revision() description = description_encoded.decode() if last_revision == new_revision and commit_pending is None: # Automatically commit pending changes if the script did not # touch the branch. commit_pending = True if commit_pending: try: new_revision = local_tree.commit(description, allow_pointless=False) except PointlessCommit: pass if new_revision == last_revision: raise ScriptMadeNoChanges() return description
def get_branch_from_recipe_location( recipe_location, safe=False, possible_transports=None): """Return the base branch for the specified recipe. :param recipe_location: The URL of the recipe file to retrieve. :param safe: if True, reject recipes that would cause arbitrary code execution. """ if safe: permitted_instructions = SAFE_INSTRUCTIONS else: permitted_instructions = None try: (basename, f) = get_recipe_from_location( recipe_location, possible_transports) except errors.NoSuchFile: raise errors.BzrCommandError( "Specified recipe does not exist: %s" % recipe_location) try: parser = RecipeParser(f, filename=recipe_location) finally: f.close() return parser.parse(permitted_instructions=permitted_instructions)
def run(self, location, layout=None): from breezy import errors from breezy.controldir import ControlDir from . import gettext from .remote import SvnRemoteAccess from .workingtree import SvnCheckout dir = ControlDir.open(location) if not (isinstance(dir, SvnRemoteAccess) or isinstance(dir, SvnCheckout)): raise errors.BzrCommandError( gettext("Source repository is not a Subversion repository.")) try: repository = dir.open_repository() except errors.NoRepositoryPresent: repository = dir.find_repository(_ignore_branch_path=True) assert dir.root_transport.base.startswith(repository.base) prefix = dir.root_transport.base[len(repository.base):].strip("/") prefix = prefix.encode("utf-8") else: prefix = None revnum = repository.get_latest_revnum() if layout is None: layout = repository.get_guessed_layout() self.outf.write(gettext("Branches:\n")) for (project, path, name, has_props, revnum) in layout.get_branches( repository, revnum, prefix): self.outf.write("%s (%s)\n" % (path, name)) self.outf.write(gettext("Tags:\n")) for (project, path, name, has_props, revnum) in layout.get_tags( repository, revnum, prefix): self.outf.write("%s (%s)\n" % (path, name))
# switching to expecting (but not checking for) unicode rather than # bytestring inputs. Detect this and decode environment if needed. if getattr(changelog.Changelog, "__unicode__", None) is not None: enc = osutils.get_user_encoding() author_name = author_name.decode(enc) author_email = author_email.decode(enc) author = "%s <%s>" % (author_name, author_email) date = utils.formatdate(localtime=True) version = base_branch.deb_version if append_version is not None: version += append_version try: changelog.Version(version) except (changelog.VersionError, ValueError), e: raise errors.BzrCommandError("Invalid deb-version: %s: %s" % (version, e)) cl.new_block(package=package, version=version, distributions=distribution, urgency="low", changes=['', ' * Auto build.', ''], author=author, date=date) cl_f = open(cl_path, 'wb') try: cl.write_to_open_file(cl_f) finally: cl_f.close() def calculate_package_dir(package_name, package_version, working_basedir):
def fail_message(obj): raise errors.BzrCommandError("empty commit message")
def watch(owner_name, archive_name, package_name, version): """Watch a package build. :return: True once the package built and published, or False if it fails or there is a timeout waiting. """ version = str(version) trace.note("Logging into Launchpad") launchpad = get_lp() owner = launchpad.people[owner_name] archive = owner.getPPAByName(name=archive_name) end_states = ['FAILEDTOBUILD', 'FULLYBUILT'] important_arches = ['amd64', 'i386', 'armel'] trace.note("Waiting for version %s of %s to build." % (version, package_name)) start = time.time() while True: sourceRecords = list( archive.getPublishedSources(source_name=package_name, version=version)) if not sourceRecords: if time.time() - 900 > start: # Over 15 minutes and no source yet, upload FAIL. raise errors.BzrCommandError( "No source record in %s/%s for " "package %s=%s after 15 minutes." % (owner_name, archive_name, package_name, version)) return False trace.note("Source not available yet - waiting.") time.sleep(60) continue pkg = sourceRecords[0] if pkg.status.lower() not in ('published', 'pending'): trace.note("Package status: %s" % (pkg.status, )) time.sleep(60) continue # FIXME: LP should export this as an attribute. source_id = pkg.self_link.rsplit('/', 1)[1] buildSummaries = archive.getBuildSummariesForSourceIds( source_ids=[source_id])[source_id] if buildSummaries['status'] in end_states: break if buildSummaries['status'] == 'NEEDSBUILD': # We ignore non-virtual PPA architectures that are sparsely # supplied with buildds. missing = [] for build in buildSummaries['builds']: arch = build['arch_tag'] if arch in important_arches: missing.append(arch) if not missing: break extra = ' on ' + ', '.join(missing) else: extra = '' trace.note("%s is still in %s%s" % (pkg.display_name, buildSummaries['status'], extra)) time.sleep(60) trace.note("%s is now %s" % (pkg.display_name, buildSummaries['status'])) result = True if pkg.status.lower() != 'published': result = False # should this perhaps keep waiting? if buildSummaries['status'] != 'FULLYBUILT': if buildSummaries['status'] == 'NEEDSBUILD': # We're stopping early cause the important_arches are built. builds = pkg.getBuilds() for build in builds: if build.arch_tag in important_arches: if build.buildstate != 'Successfully built': result = False else: result = False return result
def run(self, location, working_basedir=None, manifest=None, if_changed_from=None, package=None, distribution=None, dput=None, key_id=None, no_build=None, watch_ppa=False, append_version=None, safe=False, allow_fallback_to_native=False): try: try: import debian except ImportError: # In older versions of python-debian the main package was named # debian_bundle import debian_bundle except ImportError: raise errors.BzrCommandError( "The 'debian' python module " "is required for 'bzr dailydeb'. Install the " "python-debian package.") from breezy.plugins.builder.deb_util import ( add_autobuild_changelog_entry, build_source_package, calculate_package_dir, changelog, debian_source_package_name, dput_source_package, extract_upstream_tarball, force_native_format, get_source_format, sign_source_package, target_from_dput, ) from breezy.plugins.builder.deb_version import ( check_expanded_deb_version, substitute_branch_vars, substitute_time, ) if dput is not None and key_id is None: raise errors.BzrCommandError("You must specify --key-id if you " "specify --dput.") if watch_ppa: if not dput: raise errors.BzrCommandError( "cannot watch a ppa without doing dput.") else: # Check we can calculate a PPA url. target_from_dput(dput) possible_transports = [] base_branch = get_prepared_branch_from_location( location, safe=safe, possible_transports=possible_transports) # Save the unsubstituted version template_version = base_branch.deb_version if if_changed_from is not None: old_recipe = get_old_recipe(if_changed_from, possible_transports) else: old_recipe = None if base_branch.deb_version is not None: time = datetime.datetime.utcnow() substitute_time(base_branch, time) changed = resolve_revisions( base_branch, if_changed_from=old_recipe, substitute_branch_vars=substitute_branch_vars) check_expanded_deb_version(base_branch) else: changed = resolve_revisions(base_branch, if_changed_from=old_recipe) if not changed: trace.note("Unchanged") return 0 if working_basedir is None: temp_dir = tempfile.mkdtemp(prefix="bzr-builder-") working_basedir = temp_dir else: temp_dir = None if not os.path.exists(working_basedir): os.makedirs(working_basedir) package_name = self._calculate_package_name(location, package) if template_version is None: working_directory = os.path.join(working_basedir, "%s-direct" % (package_name, )) else: working_directory = os.path.join( working_basedir, "%s-%s" % (package_name, template_version)) try: # we want to use a consistent package_dir always to support # updates in place, but debuild etc want PACKAGE-UPSTREAMVERSION # on disk, so we build_tree with the unsubstituted version number # and do a final rename-to step before calling into debian build # tools. We then rename the working dir back. manifest_path = os.path.join(working_directory, "debian", "bzr-builder.manifest") build_tree(base_branch, working_directory) control_path = os.path.join(working_directory, "debian", "control") if not os.path.exists(control_path): if package is None: raise errors.BzrCommandError( "No control file to " "take the package name from, and --package not " "specified.") else: package = debian_source_package_name(control_path) write_manifest_to_transport(manifest_path, base_branch, possible_transports) autobuild = (base_branch.deb_version is not None) if autobuild: # Add changelog also substitutes {debupstream}. add_autobuild_changelog_entry(base_branch, working_directory, package, distribution=distribution, append_version=append_version) else: if append_version: raise errors.BzrCommandError( "--append-version only " "supported for autobuild recipes (with a 'deb-version' " "header)") with open(os.path.join(working_directory, "debian", "changelog")) as cl_f: contents = cl_f.read() cl = changelog.Changelog(file=contents) package_name = cl.package package_version = cl.version package_dir = calculate_package_dir(package_name, package_version, working_basedir) # working_directory -> package_dir: after this debian stuff works. os.rename(working_directory, package_dir) try: current_format = get_source_format(package_dir) if (package_version.debian_version is not None or current_format == "3.0 (quilt)"): # Non-native package try: extract_upstream_tarball( base_branch.branch, package_name, package_version.upstream_version, working_basedir) except errors.NoSuchTag, e: if not allow_fallback_to_native: raise errors.BzrCommandError( "Unable to find the upstream source. Import it " "as tag %s or build with " "--allow-fallback-to-native." % e.tag_name) else: force_native_format(package_dir, current_format) if not no_build: build_source_package( package_dir, tgz_check=not allow_fallback_to_native) if key_id is not None: sign_source_package(package_dir, key_id) if dput is not None: dput_source_package(package_dir, dput) finally: if not no_build: # package_dir -> working_directory # FIXME: may fail in error unwind, masking the # original exception. os.rename(package_dir, working_directory) # Note that this may write a second manifest. if manifest is not None: write_manifest_to_transport(manifest, base_branch, possible_transports)