def pre_commit_hook(local, master, old_revno, old_revid, future_revno, future_revid, tree_delta, future_tree): """Ensure packaging has gone through wrap-and-sort command""" if (master.get_parent() is None): return if (master.get_parent().find("ubuntu-ui-toolkit") == -1): return if not os.path.exists("/usr/bin/wrap-and-sort"): raise errors.BzrError("Please install 'devscripts' package.") return subprocess.call( ["cp", "-a", "debian", "debian-packaging-wraptest-temporary"]) subprocess.call(["wrap-and-sort", "-a", "-t"]) returncode = subprocess.call( ["diff", "-urN", "debian-packaging-wraptest-temporary", "debian"]) if returncode == 1: subprocess.call(["rm", "-rf", "debian-packaging-wraptest-temporary"]) raise errors.BzrError("Please run wrap-and-sort\ -a -t to clean up packaging.") subprocess.call(["rm", "-rf", "debian-packaging-wraptest-temporary"])
def _send_using_process(self): """Spawn a 'mail' subprocess to send the email.""" # TODO think up a good test for this, but I think it needs # a custom binary shipped with. RBC 20051021 try: process = subprocess.Popen(self._command_line(), stdin=subprocess.PIPE) try: message = self.body().encode('utf8') + self.get_diff() result = process.communicate(message)[0] if process.returncode is None: process.wait() if process.returncode != 0: raise errors.BzrError("Failed to send email") return result except OSError, e: if e.errno == errno.EPIPE: raise errors.BzrError("Failed to send email.") else: raise except ValueError: # bad subprocess parameters, should never happen. raise except OSError, e: if e.errno == errno.ENOENT: raise errors.BzrError("mail is not installed !?") else: raise
def create_now(cls, launchpad, bzr_branch): """Create a Bazaar branch on Launchpad for the supplied branch.""" url = cls.tweak_url(bzr_branch.get_push_location(), launchpad) if not cls.plausible_launchpad_url(url): raise errors.BzrError( gettext('%s is not registered on Launchpad') % bzr_branch.base) bzr_branch.create_clone_on_transport(transport.get_transport(url)) lp_branch = launchpad.branches.getByUrl(url=url) if lp_branch is None: raise errors.BzrError( gettext('%s is not registered on Launchpad') % url) return lp_branch
def dir_exporter_generator(tree, dest, root, subdir=None, force_mtime=None, fileobj=None): """Return a generator that exports this tree to a new directory. `dest` should either not exist or should be empty. If it does not exist it will be created holding the contents of this tree. :param fileobj: Is not used in this exporter :note: If the export fails, the destination directory will be left in an incompletely exported state: export is not transactional. """ try: os.mkdir(dest) except OSError, e: if e.errno == errno.EEXIST: # check if directory empty if os.listdir(dest) != []: raise errors.BzrError( "Can't export tree to non-empty directory.") else: raise
def read(self, length): self._next() result = self._string.read(length) if len(result) < length: raise errors.BzrError( 'request for too much data from a readv hunk.') return result
def convert(self): try: branch = self.bzrdir.open_branch() if branch.bzrdir.root_transport.base != \ self.bzrdir.root_transport.base: self.pb.note( "This is a checkout. The branch (%s) needs to be " "upgraded separately.", branch.bzrdir.root_transport.base) del branch except (errors.NotBranchError, errors.IncompatibleRepositories): # might not be a format we can open without upgrading; see e.g. # https://bugs.launchpad.net/bzr/+bug/253891 pass if not self.bzrdir.needs_format_conversion(self.format): raise errors.UpToDateFormat(self.bzrdir._format) if not self.bzrdir.can_convert_format(): raise errors.BzrError("cannot upgrade from bzrdir format %s" % self.bzrdir._format) if self.format is None: target_format = BzrDirFormat.get_default_format() else: target_format = self.format self.bzrdir.check_conversion_target(target_format) self.pb.note('starting upgrade of %s', self.transport.base) self._backup_control_dir() while self.bzrdir.needs_format_conversion(self.format): converter = self.bzrdir._format.get_converter(self.format) self.bzrdir = converter.convert(self.bzrdir, self.pb) self.pb.note("finished")
def readline(self): """Note that readline will not cross readv segments.""" self._next() result = self._string.readline() if self._string.tell() == self._string_length and result[-1] != '\n': raise errors.BzrError('short readline in the readvfile hunk.') return result
def write(self, bytes): try: #Using pump_string_file seems to make things crash osutils.pumpfile(StringIO(bytes), self.stream) except gio.Error, e: #self.transport._translate_gio_error(e,self.relpath) raise errors.BzrError(str(e))
def _unpack_inventory(self, elt, revision_id, entry_cache=None, return_from_cache=False): """Construct from XML Element """ root_id = elt.get('file_id') or inventory.ROOT_ID root_id = get_utf8_or_ascii(root_id) format = elt.get('format') if format is not None: if format != '5': raise errors.BzrError("invalid format version %r on inventory" % format) data_revision_id = elt.get('revision_id') if data_revision_id is not None: revision_id = cache_utf8.encode(data_revision_id) inv = inventory.Inventory(root_id, revision_id=revision_id) # Optimizations tested # baseline w/entry cache 2.85s # using inv._byid 2.55s # avoiding attributes 2.46s # adding assertions 2.50s # last_parent cache 2.52s (worse, removed) byid = inv._byid for e in elt: ie = unpack_inventory_entry(e, entry_cache=entry_cache, return_from_cache=return_from_cache) parent_id = ie.parent_id if parent_id is None: ie.parent_id = parent_id = root_id try: parent = byid[parent_id] except KeyError: raise errors.BzrError("parent_id {%s} not in inventory" % (parent_id,)) if ie.file_id in byid: raise errors.DuplicateFileId(ie.file_id, byid[ie.file_id]) if ie.name in parent.children: raise errors.BzrError("%s is already versioned" % (osutils.pathjoin(inv.id2path(parent_id), ie.name).encode('utf-8'),)) parent.children[ie.name] = ie byid[ie.file_id] = ie if revision_id is not None: inv.root.revision = revision_id self._check_cache_size(len(inv), entry_cache) return inv
def _mount_done_cb(self, obj, res): try: obj.mount_enclosing_volume_finish(res) self.loop.quit() except gio.Error, e: self.loop.quit() raise errors.BzrError("Failed to mount the given location: " + str(e))
def read(self, length): self._next() result = self._string.read(length) if len(result) < length: raise errors.BzrError('wanted %d bytes but next ' 'hunk only contains %d: %r...' % (length, len(result), result[:20])) return result
def test_bzrerror_from_literal_string(self): # Some code constructs BzrError from a literal string, in which case # no further formatting is done. (I'm not sure raising the base class # is a great idea, but if the exception is not intended to be caught # perhaps no more is needed.) try: raise errors.BzrError('this is my errors; %d is not expanded') except errors.BzrError, e: self.assertEqual('this is my errors; %d is not expanded', str(e))
def dir_exporter(tree, dest, root): """Export this tree to a new directory. `dest` should not exist, and will be created holding the contents of this tree. TODO: To handle subdirectories we need to create the directories first. :note: If the export fails, the destination directory will be left in a half-assed state. """ os.mkdir(dest) mutter('export version %r', tree) inv = tree.inventory entries = inv.iter_entries() entries.next() # skip root for dp, ie in entries: # The .bzr* namespace is reserved for "magic" files like # .bzrignore and .bzrrules - do not export these if dp.startswith(".bzr"): continue fullpath = osutils.pathjoin(dest, dp) if ie.kind == "file": fileobj = tree.get_file(ie.file_id) osutils.pumpfile(fileobj, file(fullpath, 'wb')) if tree.is_executable(ie.file_id): os.chmod(fullpath, 0755) elif ie.kind == "directory": os.mkdir(fullpath) elif ie.kind == "symlink": try: os.symlink(ie.symlink_target, fullpath) except OSError, e: raise errors.BzrError( "Failed to create symlink %r -> %r, error: %s" % (fullpath, self.symlink_target, e)) else: raise errors.BzrError("don't know how to export {%s} of kind %r" % (ie.file_id, ie.kind))
def execute_makecheck(local_branch, master_branch, old_revision_number, old_revision_id, future_revision_number, future_revision_id, tree_delta, future_tree): if (master_branch.get_parent().find("ubuntu-ui-toolkit") == -1): return print "Set work directory to %s" % local_path_from_url(master_branch.base) os.chdir(local_path_from_url(master_branch.base)) print "Execute 'make check'.." if (subprocess.call("make check", shell=True) != 0): raise errors.BzrError("Tests failed, fix them before commit!")
def prepare_tarball_item(tree, root, final_path, tree_path, entry, force_mtime=None): """Prepare a tarball item for exporting :param tree: Tree to export :param final_path: Final path to place item :param tree_path: Path for the entry in the tree :param entry: Entry to export :param force_mtime: Option mtime to force, instead of using tree timestamps. Returns a (tarinfo, fileobj) tuple """ filename = osutils.pathjoin(root, final_path).encode('utf8') item = tarfile.TarInfo(filename) if force_mtime is not None: item.mtime = force_mtime else: item.mtime = tree.get_file_mtime(entry.file_id, tree_path) if entry.kind == "file": item.type = tarfile.REGTYPE if tree.is_executable(entry.file_id, tree_path): item.mode = 0755 else: item.mode = 0644 # This brings the whole file into memory, but that's almost needed for # the tarfile contract, which wants the size of the file up front. We # want to make sure it doesn't change, and we need to read it in one # go for content filtering. content = tree.get_file_text(entry.file_id, tree_path) item.size = len(content) fileobj = StringIO.StringIO(content) elif entry.kind == "directory": item.type = tarfile.DIRTYPE item.name += '/' item.size = 0 item.mode = 0755 fileobj = None elif entry.kind == "symlink": item.type = tarfile.SYMTYPE item.size = 0 item.mode = 0755 item.linkname = tree.get_symlink_target(entry.file_id, tree_path) fileobj = None else: raise errors.BzrError("don't know how to export {%s} of kind %r" % (entry.file_id, entry.kind)) return (item, fileobj)
def check_path(name): """ Check if this tool is actually available on this system. """ found = False exe_path = environ.get('PATH', '') for path in exe_path.split(pathsep): if path and isfile(join(path, name)): found = True if not found: raise errors.BzrError("Cannot find '%s' in %s" % (name, exe_path)) return
def cleanup(self): """ Clean up a temporary directory and all its contents. """ # As a safety precaution, make sure we didn't get a completely bogus path: if (not self.path.endswith('_tmp')): raise errors.BzrError( "attempted to delete a non-tmp directory: %s" % self.path) if (not self.cleaned): self.cleaned = True osutils.rmtree(self.path) return
def tar_lzma_exporter_generator(tree, dest, root, subdir, force_mtime=None, fileobj=None, compression_format="alone"): """Export this tree to a new .tar.lzma file. `dest` will be created holding the contents of this tree; if it already exists, it will be clobbered, like with "tar -c". """ if dest == '-': raise errors.BzrError("Writing to stdout not supported for .tar.lzma") if fileobj is not None: raise errors.BzrError( "Writing to fileobject not supported for .tar.lzma") try: import lzma except ImportError, e: raise errors.DependencyNotPresent('lzma', e)
def __init__(self, args, body=None, body_stream=None): """Constructor. :param args: tuple of response arguments. :param body: string of a response body. :param body_stream: iterable of bytestrings to be streamed to the client. """ self.args = args if body is not None and body_stream is not None: raise errors.BzrError( "'body' and 'body_stream' are mutually exclusive.") self.body = body self.body_stream = body_stream
def get_target(self): """Return the 'LaunchpadBranch' for the target of this one.""" lp_branch = self.lp if lp_branch.project is not None: dev_focus = lp_branch.project.development_focus if dev_focus is None: raise errors.BzrError(gettext('%s has no development focus.') % lp_branch.bzr_identity) target = dev_focus.branch if target is None: raise errors.BzrError(gettext( 'development focus %s has no branch.') % dev_focus) elif lp_branch.sourcepackage is not None: target = lp_branch.sourcepackage.getBranch(pocket="Release") if target is None: raise errors.BzrError(gettext( 'source package %s has no branch.') % lp_branch.sourcepackage) else: raise errors.BzrError(gettext( '%s has no associated product or source package.') % lp_branch.bzr_identity) return LaunchpadBranch(target, target.bzr_identity)
def __init__(self, to_repository, from_repository, last_revision=None, pb=None, find_ghosts=True): """Create a repo fetcher. :param find_ghosts: If True search the entire history for ghosts. """ # result variables. self.failed_revisions = [] self.count_copied = 0 if to_repository.has_same_location(from_repository): # repository.fetch should be taking care of this case. raise errors.BzrError('RepoFetcher run ' 'between two objects at the same location: ' '%r and %r' % (to_repository, from_repository)) self.to_repository = to_repository self.from_repository = from_repository # must not mutate self._last_revision as its potentially a shared instance self._last_revision = last_revision self.find_ghosts = find_ghosts if pb is None: self.pb = bzrlib.ui.ui_factory.nested_progress_bar() self.nested_pb = self.pb else: self.pb = pb self.nested_pb = None self.from_repository.lock_read() try: self.to_repository.lock_write() try: self.to_repository.start_write_group() try: self.__fetch() except: self.to_repository.abort_write_group() raise else: self.to_repository.commit_write_group() finally: try: if self.nested_pb is not None: self.nested_pb.finished() finally: self.to_repository.unlock() finally: self.from_repository.unlock()
def _revision_identifier(self): """What revision did the user select? :return: None for the last revision. Otherwise the revision identifier as a string. """ if self.other_radio.isChecked(): result = unicode(self.other_revision.text()) if result: return result else: msg = gettext("No other revision specified.") raise errors.BzrError(msg) # Default is the tip revision return None
def pre_commit_hook(local, master, old_revno, old_revid, future_revno, future_revid, tree_delta, future_tree): success, fails = ([], []) for c in script_cmds: if (os.system(c) != 0): fails.append(c) else: success.append(c) print "\n### Patch safety report ###" for s in success: print ">>> " + s + ": Succeeded" for f in fails: print ">>> " + f + ": Failed !!" if len(fails) > 0: raise errors.BzrError("One or more scripts failed, fix the patch," " lazy!!\nNote: commit is not applied.") else: print "All tests succeeded, patch is safe.\n"
def send_request(self, method_name, method_params, authenticated): proxy = self.get_proxy(authenticated) method = getattr(proxy, method_name) try: result = method(*method_params) except xmlrpclib.ProtocolError, e: if e.errcode == 301: # TODO: This can give a ProtocolError representing a 301 error, whose # e.headers['location'] tells where to go and e.errcode==301; should # probably log something and retry on the new url. raise NotImplementedError( "should resend request to %s, but this isn't implemented" % e.headers.get('Location', 'NO-LOCATION-PRESENT')) else: # we don't want to print the original message because its # str representation includes the plaintext password. # TODO: print more headers to help in tracking down failures raise errors.BzrError( "xmlrpc protocol error connecting to %s: %s %s" % (self.service_url, e.errcode, e.errmsg))
def _open_handles(self, base_path): """Open the given file handles. This will attempt to open all of these file handles, but will not block while opening them, timing out after self._child_connect_timeout seconds. :param base_path: The directory where all FIFOs are located. :return: (stdin_fid, stdout_fid, stderr_fid). """ stdin_path, stdout_path, stderr_path = self._compute_paths(base_path) # These open calls will block until another process connects (which # must connect in the same order) fids = [] to_open = [(stdin_path, os.O_RDONLY), (stdout_path, os.O_WRONLY), (stderr_path, os.O_WRONLY)] # If we set it to 0, we won't get an alarm, so require some time > 0. signal.alarm(max(1, self._child_connect_timeout)) tstart = time.time() for path, flags in to_open: try: fids.append(os.open(path, flags)) except OSError: # In production code, signal.alarm will generally just kill # us. But if something installs a signal handler for SIGALRM, # do what we can to die gracefully. error = ('After %.3fs we failed to open %s, exiting' % (time.time() - tstart, path,)) trace.warning(error) for fid in fids: try: os.close(fid) except OSError: pass raise errors.BzrError(error) # If we get to here, that means all the handles were opened # successfully, so cancel the wakeup call. signal.alarm(0) return fids
def convert(self): try: branch = self.bzrdir.open_branch() if branch.user_url != self.bzrdir.user_url: ui.ui_factory.note(gettext( 'This is a checkout. The branch (%s) needs to be upgraded' ' separately.') % (urlutils.unescape_for_display( branch.user_url, 'utf-8'))) del branch except (errors.NotBranchError, errors.IncompatibleRepositories): # might not be a format we can open without upgrading; see e.g. # https://bugs.launchpad.net/bzr/+bug/253891 pass if self.format is None: try: rich_root = self.bzrdir.find_repository()._format.rich_root_data except errors.NoRepositoryPresent: rich_root = False # assume no rich roots if rich_root: format_name = "default-rich-root" else: format_name = "default" format = format_registry.make_bzrdir(format_name) else: format = self.format if not self.bzrdir.needs_format_conversion(format): raise errors.UpToDateFormat(self.bzrdir._format) if not self.bzrdir.can_convert_format(): raise errors.BzrError(gettext("cannot upgrade from bzrdir format %s") % self.bzrdir._format) self.bzrdir.check_conversion_target(format) ui.ui_factory.note(gettext('starting upgrade of %s') % urlutils.unescape_for_display(self.transport.base, 'utf-8')) self.backup_oldpath, self.backup_newpath = self.bzrdir.backup_bzrdir() while self.bzrdir.needs_format_conversion(format): converter = self.bzrdir._format.get_converter(format) self.bzrdir = converter.convert(self.bzrdir, None) ui.ui_factory.note(gettext('finished'))
def append_file(self, relpath, file, mode=None): """Append the text in the file-like object into the final location. """ #GIO append_to seems not to append but to truncate #Work around this. if 'gio' in debug.debug_flags: mutter("GIO append_file: %s" % relpath) tmppath = '%s.tmp.%.9f.%d.%d' % (relpath, time.time(), os.getpid(), random.randint(0, 0x7FFFFFFF)) try: result = 0 fo = self._get_GIO(tmppath) fi = self._get_GIO(relpath) fout = fo.create() try: info = GioStatResult(fi) result = info.st_size fin = fi.read() self._pump(fin, fout) fin.close() #This separate except is to catch and ignore the #gio.ERROR_NOT_FOUND for the already existing file. #It is valid to open a non-existing file for append. #This is caused by the broken gio append_to... except gio.Error, e: if e.code != gio.ERROR_NOT_FOUND: self._translate_gio_error(e, relpath) length = self._pump(file, fout) fout.close() info = GioStatResult(fo) if info.st_size != result + length: raise errors.BzrError("Failed to append size after " \ "(%d) is not original (%d) + written (%d) total (%d)" % \ (info.st_size, result, length, result + length)) fo.move(fi, flags=gio.FILE_COPY_OVERWRITE) return result
def _reconcile_repository(self): self.repo = self.bzrdir.find_repository() ui.ui_factory.note( gettext('Reconciling repository %s') % self.repo.user_url) self.pb.update(gettext("Reconciling repository"), 0, 1) if self.canonicalize_chks: try: self.repo.reconcile_canonicalize_chks except AttributeError: raise errors.BzrError( gettext("%s cannot canonicalize CHKs.") % (self.repo, )) repo_reconciler = self.repo.reconcile_canonicalize_chks() else: repo_reconciler = self.repo.reconcile(thorough=True) self.inconsistent_parents = repo_reconciler.inconsistent_parents self.garbage_inventories = repo_reconciler.garbage_inventories if repo_reconciler.aborted: ui.ui_factory.note( gettext( 'Reconcile aborted: revision index has inconsistent parents.' )) ui.ui_factory.note(gettext('Run "bzr check" for more details.')) else: ui.ui_factory.note(gettext('Reconciliation complete.'))
# Note in the case of revision trees, this does trigger a double inventory # lookup, hopefully it isn't too expensive. to_fetch = [] for dp, tp, ie in _export_iter_entries(tree, subdir): fullpath = osutils.pathjoin(dest, dp) if ie.kind == "file": to_fetch.append((ie.file_id, (dp, tp, ie.file_id))) elif ie.kind == "directory": os.mkdir(fullpath) elif ie.kind == "symlink": try: symlink_target = tree.get_symlink_target(ie.file_id, tp) os.symlink(symlink_target, fullpath) except OSError, e: raise errors.BzrError( "Failed to create symlink %r -> %r, error: %s" % (fullpath, symlink_target, e)) else: raise errors.BzrError("don't know how to export {%s} of kind %r" % (ie.file_id, ie.kind)) yield # The data returned here can be in any order, but we've already created all # the directories flags = os.O_CREAT | os.O_TRUNC | os.O_WRONLY | getattr(os, 'O_BINARY', 0) for (relpath, treepath, file_id), chunks in tree.iter_files_bytes(to_fetch): fullpath = osutils.pathjoin(dest, relpath) # We set the mode and let the umask sort out the file info mode = 0666 if tree.is_executable(file_id, treepath):
def __init__(self, branch, bzrdir, location, ui_mode = None): super(QBzrSwitchWindow, self).__init__( gettext("Switch"), name = "switch", default_size = (400, 400), ui_mode = ui_mode, dialog = True, parent = None, hide_progress=False, ) self.branch = branch gbSwitch = QtGui.QGroupBox(gettext("Switch checkout"), self) switch_box = QtGui.QFormLayout(gbSwitch) branchbase = None boundloc = branch.get_bound_location() if boundloc is not None: label = gettext("Heavyweight checkout:") branchbase = branch.base else: if bzrdir.root_transport.base != branch.bzrdir.root_transport.base: label = gettext("Lightweight checkout:") boundloc = branch.bzrdir.root_transport.base branchbase = bzrdir.root_transport.base else: raise errors.BzrError("This branch is not checkout.") switch_box.addRow(label, QtGui.QLabel(url_for_display(branchbase))) switch_box.addRow(gettext("Checkout of branch:"), QtGui.QLabel(url_for_display(boundloc))) self.boundloc = url_for_display(boundloc) throb_hbox = QtGui.QHBoxLayout() self.throbber = ThrobberWidget(self) throb_hbox.addWidget(self.throbber) self.throbber.hide() switch_box.addRow(throb_hbox) switch_hbox = QtGui.QHBoxLayout() branch_label = QtGui.QLabel(gettext("Switch to branch:")) branch_combo = QtGui.QComboBox() branch_combo.setEditable(True) self.branch_combo = branch_combo if location is not None: branch_combo.addItem(osutils.abspath(location)) elif boundloc is not None: branch_combo.addItem(url_for_display(boundloc)) browse_button = QtGui.QPushButton(gettext("Browse")) QtCore.QObject.connect(browse_button, QtCore.SIGNAL("clicked(bool)"), self.browse_clicked) switch_hbox.addWidget(branch_label) switch_hbox.addWidget(branch_combo) switch_hbox.addWidget(browse_button) switch_hbox.setStretchFactor(branch_label,0) switch_hbox.setStretchFactor(branch_combo,1) switch_hbox.setStretchFactor(browse_button,0) switch_box.addRow(switch_hbox) create_branch_box = QtGui.QCheckBox(gettext("Create Branch before switching")) create_branch_box.setChecked(False) switch_box.addRow(create_branch_box) self.create_branch_box = create_branch_box layout = QtGui.QVBoxLayout(self) layout.addWidget(gbSwitch) layout.addWidget(self.make_default_status_box()) layout.addWidget(self.buttonbox) self.branch_combo.setFocus()