class cmd_up_thread(breezy.commands.Command): """Move the branch up to the top thread in the loom. This merges the changes done in this thread but not incorporated into the next thread up into the next thread up and switches your tree to be that thread. Unless there are conflicts, or --manual is specified, it will then commit and repeat the process. """ takes_args = ['thread?'] takes_options = [ 'merge-type', Option('auto', help='Deprecated - now the default.'), Option('manual', help='Perform commit manually.'), ] _see_also = ['down-thread', 'switch'] 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)
class cmd_qunshelve(QBzrCommand): """Restore shalved changes.""" takes_options = [ ui_mode_option, brz_option('unshelve', 'directory'), Option('complete', help='Show complete files.'), Option( 'ignore-whitespace', short_name='w', help= "Ignore whitespace when finding differences.(Only work when --list specified)" ), Option('encoding', type=check_encoding, help='Encoding of files content (default: utf-8).'), ] def _qbrz_run(self, directory=None, ui_mode=False, complete=False, ignore_whitespace=False, encoding=None): self.main_window = ShelveWindow(directory=directory, ui_mode=ui_mode, initial_tab=1, complete=complete, ignore_whitespace=ignore_whitespace, encoding=encoding) self.main_window.show() self._application.exec_()
class cmd_qcat(QBzrCommand): """View the contents of a file as of a given revision. If no revision is nominated, the last revision is used. """ takes_options = [ 'revision', Option('encoding', type=check_encoding, help='Encoding of files content (default: utf-8).'), Option('native', help='Show file with native application.'), ] takes_args = ['filename'] 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_()
class cmd_qrun(QBzrCommand): """Run arbitrary bzr command. If you wish to pass options to COMMAND, use ``--`` beforehand so that the options aren't treated as options to the qrun command itself. For example:: bzr qrun shelve -- --list NOTE: you should use only canonical name of the COMMAND, not the alias. """ takes_args = ['command?', 'parameters*'] takes_options = [ ui_mode_option, Option( 'directory', help='Working directory.', short_name='d', type=str, ), Option( 'category', help='Initial category selection.', type=str, ), execute_option, ] aliases = ['qcmd'] def _qbrz_run(self, command=None, parameters_list=None, ui_mode=False, directory=None, category=None, execute=False): from breezy.plugins.qbrz.lib.run import QBzrRunDialog if parameters_list: def quote_spaces(s): if " " in s: s = '"%s"' % s return s parameters = " ".join([quote_spaces(i) for i in parameters_list]) else: parameters = None if not command: execute = False window = QBzrRunDialog(command=command, parameters=parameters, workdir=directory, category=category, ui_mode=ui_mode, execute=execute) window.show() self._application.exec_()
class cmd_svn_branching_scheme(Command): """Show or change the branching scheme for a Subversion repository. This command is deprecated in favour of "bzr svn-layout". It should only be used if you need compatibility with bzr-svn 0.4.x. See 'bzr help svn-branching-schemes' for details. """ takes_args = ['location?'] takes_options = [ Option('set', help="Change the branching scheme. "), Option('repository-wide', help="Act on repository-wide setting rather than local.") ] hidden = True 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))
class cmd_merge(breezy.builtins.cmd_merge, DiffArgProvider): __doc__ = breezy.builtins.cmd_merge.__doc__ takes_options = breezy.builtins.cmd_merge.takes_options + [ Option( 'qpreview', help='Instead of merging, show a diff of the merge in a GUI window.' ), Option( 'encoding', type=check_encoding, help= 'Encoding of files content, used with --qpreview (default: utf-8).' ), ] def run(self, *args, **kw): self.qpreview = ('qpreview' in kw) if self.qpreview: kw['preview'] = kw['qpreview'] del kw['qpreview'] self._encoding = kw.get('encoding') if self._encoding: del kw['encoding'] return breezy.builtins.cmd_merge.run(self, *args, **kw) def get_diff_window_args(self, processEvents, add_cleanup): tree_merger = self.merger.make_merger() self.tt = tree_merger.make_preview_transform() result_tree = self.tt.get_preview_tree() return {"old_tree": self.merger.this_tree, "new_tree": result_tree} @install_gettext @report_missing_pyqt def _do_qpreview(self, merger): # Set up global execption handeling. from breezy.plugins.qbrz.lib.trace import excepthook sys.excepthook = excepthook self.merger = merger try: window = DiffWindow(self, encoding=self._encoding) window.show() self._application.exec_() finally: if self.tt: self.tt.finalize() def _do_preview(self, merger, *args, **kw): if self.qpreview: self._do_qpreview(merger) else: breezy.builtins.cmd_merge._do_preview(self, merger, *args, **kw)
class cmd_build(Command): """Build a tree based on a branch or a recipe. Pass the path of a recipe file or a branch to build and the directory to work in. See "bzr help builder" for more information on what a recipe is. """ takes_args = ["location", "working_directory"] takes_options = [ Option('manifest', type=str, argname="path", help="Path to write the manifest to."), Option('if-changed-from', type=str, argname="path", help="Only build if the outcome would be different " "to that specified in the specified manifest."), 'revision', ] 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)
class cmd_bug_url(commands.Command): """Print full URL to a specific bug, or open it in your browser.""" takes_args = ['bug_id'] takes_options = [ Option('open', help='Open the URL in a web browser.'), ] 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)
class cmd_loomify(breezy.commands.Command): """Add a loom to this branch. This creates a loom in your branch, which will alter the behaviour of bzr for a number of commands to manage a group of patches being evolved in parallel. You must have a branch nickname explicitly set to use this command, as the branch nickname becomes the 'base thread' of the loom. You can specify the branch nick with the --base option. """ takes_args = ['location?'] takes_options = [ Option('base', type=str, help='The name to use for the base thread.') ] 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)
class cmd_revert_loom(breezy.commands.Command): """Revert part or all of a loom. This will update the current loom to be the same as the basis when --all is supplied. If no parameters or options are supplied then nothing will happen. If a thread is named, then only that thread is reverted to its state in the last committed loom. """ takes_args = ['thread?'] takes_options = [ Option('all', help='Revert all threads.'), ] def run(self, thread=None, all=None): if thread is None and all is None: breezy.trace.note('Please see revert-loom -h.') return (tree, path) = workingtree.WorkingTree.open_containing('.') branch.require_loom_branch(tree.branch) tree = LoomTreeDecorator(tree) if all: tree.revert_loom() breezy.trace.note('All threads reverted.') else: tree.revert_loom(thread) breezy.trace.note("thread '%s' reverted.", thread)
class cmd_fix_svn_ancestry(Command): """Fix the SVN ancestry of a repository. This will fix revisions that were imported from Subversion with older versions of bzr-svn but have some incorrect metadata. This command should be used in the bzr branch with the broken imported revisions, and takes the location of the SVN repository to fetch the fixed revisions from as an argument. """ takes_args = ['svn_repository'] takes_options = [ 'directory', Option('no-reconcile', help="Don't reconcile the new repository.") ] def run(self, svn_repository, directory=".", no_reconcile=False): from breezy.controldir import ControlDir from breezy.repository import InterRepository, Repository from breezy import trace correct_dir = ControlDir.open_containing(svn_repository)[0] correct_repo = correct_dir.find_repository() repo_to_fix = Repository.open(directory) revids = repo_to_fix.all_revision_ids() present_revisions = correct_repo.has_revisions(revids) dir_to_fix = repo_to_fix.controldir old_repo_format = repo_to_fix._format del repo_to_fix trace.note("Renaming existing repository to repository.backup.") dir_to_fix.control_transport.rename('repository', 'repository.backup') backup_transport = dir_to_fix.control_transport.clone( 'repository.backup') old_repo = old_repo_format.open(dir_to_fix, _found=True, _override_transport=backup_transport) new_repo = dir_to_fix.create_repository(shared=old_repo.is_shared()) working_trees = old_repo.make_working_trees() if working_trees is not None: new_repo.set_make_working_trees(working_trees) interrepo = InterRepository.get(correct_repo, new_repo) revisionfinder = interrepo.get_revision_finder(True) trace.note("Finding revisions to fetch from SVN") for revid in present_revisions: foreign_revid, mapping = correct_repo.lookup_bzr_revision_id(revid) revisionfinder.find_until(foreign_revid, mapping, find_ghosts=False, exclude_non_mainline=False) trace.note("Fetching correct SVN revisions") interrepo.fetch(needed=revisionfinder.get_missing()) trace.note("Fetching other revisions") new_repo.fetch(old_repo) if not no_reconcile: from breezy.reconcile import reconcile trace.note("Reconciling new repository.") reconcile(dir_to_fix) trace.note('Removing backup') dir_to_fix.control_transport.delete_tree('repository.backup')
class cmd_qshelve(QBzrCommand): """Shelve selected changes away.""" takes_args = ['file*'] takes_options = [ ui_mode_option, brz_option('shelve', 'list'), brz_option('shelve', 'directory'), brz_option('shelve', 'message'), Option('all', help='Select all changes.'), Option('complete', help='Show complete files.'), Option( 'ignore-whitespace', short_name='w', help= "Ignore whitespace when finding differences.(Only work when --list specified)" ), Option('encoding', type=check_encoding, help='Encoding of files content (default: utf-8).'), ] def _qbrz_run(self, file_list=None, list=False, directory=None, ui_mode=False, complete=False, ignore_whitespace=False, encoding=None, all=False, message=None): if list: initial_tab = 1 else: initial_tab = 0 self.main_window = ShelveWindow(file_list=file_list, directory=directory, ui_mode=ui_mode, initial_tab=initial_tab, complete=complete, ignore_whitespace=ignore_whitespace, encoding=encoding, select_all=all, message=message) self.main_window.show() self._application.exec_()
class cmd_qlog(QBzrCommand): """Show log of a repository, branch, file, or directory in a Qt window. By default show the log of the branch containing the working directory. If multiple files are speciffied, they must be from the same branch. :Examples: Log the current branch:: bzr qlog Log of files:: bzr qlog foo.c bar.c Log from different branches:: bzr qlog ~/branch1 ~/branch2 """ takes_args = ['locations*'] takes_options = [ ui_mode_option, Option('no-graph', help="Shows the log with no graph."), Option( 'show-trees', help="Show working trees that have changes as nodes in the graph"), ] def _qbrz_run(self, locations_list=None, ui_mode=False, no_graph=False, show_trees=False): window = LogWindow(locations_list, None, None, ui_mode=ui_mode, no_graph=no_graph, show_trees=show_trees) window.show() self._application.exec_()
class cmd_svn_branches(Command): """Print the branches and tags in a repository. """ takes_args = ["location"] takes_options = [ Option('layout', type=get_layout, help='Repository layout (none, trunk, etc). ' 'Default: auto.') ] hidden = True def run(self, location, layout=None): from breezy import errors from breezy.controldir import ControlDir from breezy.plugins.svn import gettext from breezy.plugins.svn.remote import SvnRemoteAccess from breezy.plugins.svn.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 as e: 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))
class cmd_qviewer(QBzrCommand): """Simple file viewer.""" aliases = [] takes_args = ['filename'] takes_options = [ Option('encoding', type=check_encoding, help='Encoding of file content (default: utf-8).'), ] _see_also = ['qcat'] def _qbrz_run(self, filename, encoding=None): window = QBzrViewWindow(filename=filename, encoding=encoding) window.show() self._application.exec_()
class cmd_qsubprocess(Command): """Run some bzr command as subprocess. Used with most of subprocess-based dialogs of QBzr. If CMD argument starts with @ characters then it used as name of file with actual cmd string (in utf-8). With --bencode option cmd string interpreted as bencoded list of utf-8 strings. This is the recommended way to launch qsubprocess. """ takes_args = ['cmd'] takes_options = [ Option("bencoded", help="Pass command as bencoded string.") ] hidden = True def run(self, cmd, bencoded=False): from breezy.plugins.qbrz.lib.subprocess import run_subprocess_command return run_subprocess_command(cmd, bencoded)
class cmd_qcommit(QBzrCommand): """GUI for committing revisions.""" takes_args = ['selected*'] takes_options = [ brz_option('commit', 'message'), brz_option('commit', 'local'), brz_option('commit', 'file'), Option('file-encoding', type=check_encoding, help='Encoding of commit message file content.'), ui_mode_option, ] aliases = ['qci'] 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_()
class cmd_qverify_signatures(QBzrCommand): """Shows digital signature statuses for branch commits""" takes_options = [ Option( 'acceptable-keys', help='Comma separated list of GPG key patterns which are' ' acceptable for verification.', short_name='k', type=str, ), 'revision', ] takes_args = ['location?'] def _qbrz_run(self, acceptable_keys=None, revision=None, location=CUR_DIR): if gpg.GPGStrategy.verify_signatures_available(): window = QBzrVerifySignaturesWindow(acceptable_keys, revision, location) window.show() self._application.exec_() else: raise errors.DependencyNotPresent("python-gpgme", "python-gpgme not installed")
class cmd_qannotate(QBzrCommand): """Show the origin of each line in a file.""" takes_args = ['filename'] takes_options = [ 'revision', Option('encoding', type=check_encoding, help='Encoding of files content (default: utf-8).'), ui_mode_option, Option('no-graph', help="Shows the log with no graph."), Option('line', short_name='L', type=int, argname='N', param_name='activate_line', help='Activate line N on start.'), ] aliases = ['qann', 'qblame'] 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, filename=None, revision=None, encoding=None, ui_mode=False, no_graph=False, activate_line=None): win = AnnotateWindow(None, None, None, None, None, encoding=encoding, ui_mode=ui_mode, loader=self._load_branch, loader_args=(filename, revision), no_graph=no_graph, activate_line=activate_line) win.show() self._application.exec_()
class cmd_svn_import(Command): """Convert a Subversion repository to a Bazaar repository. To save disk space, only branches will be created by default (no working trees). To create a tree for a branch, run "bzr co" in it. This command is resumable; any previously imported revisions will be skipped. """ _see_also = ['formats'] takes_args = ['from_location', 'to_location?'] takes_options = [ RegistryOption( 'format', help='Specify a format for this repository. See' ' "bzr help formats" for details. Must support rich-root.', lazy_registry=('breezy.controldir', 'format_registry'), converter=controldir.format_registry.make_controldir, value_switches=False, title='Repository format'), Option('trees', help='Create working trees.'), Option('standalone', help='Create standalone branches.'), Option('all', help='Convert all revisions, even those not in ' 'current branch history.'), Option('layout', type=get_layout, help='Repository layout (none, trunk, etc). Default: auto.'), Option('keep', help="Don't delete branches removed in Subversion."), Option('restore', help="Restore branches that were removed but have " "not been changed since the last import."), Option('prefix', type=str, hidden=True, help='Only consider branches of which path starts with ' 'prefix.'), Option('until', type=int, help="Only import revisions up to specified Subversion revnum"), Option('colocated', help='Create colocated branches.'), ] def run(self, from_location, to_location=None, format=None, trees=False, standalone=False, layout=None, all=False, prefix=None, keep=False, restore=False, until=None, colocated=False): from breezy import ( osutils, trace, urlutils, ) from breezy.controldir import ControlDir from breezy.errors import ( BzrCommandError, NoRepositoryPresent, ) from . import gettext from .convert import convert_repository from .remote import SvnRemoteAccess from .repository import SvnRepository from .workingtree import SvnCheckout import os from subvertpy import NODE_NONE if to_location is None: to_location = os.path.basename(from_location.rstrip("/\\")) if all: # All implies shared repository # (otherwise there is no repository to store revisions in) standalone = False if os.path.isfile(from_location): from .convert import load_dumpfile import tempfile tmp_repos = tempfile.mkdtemp(prefix='bzr-svn-dump-') load_dumpfile(from_location, tmp_repos) from_location = tmp_repos else: tmp_repos = None from_dir = ControlDir.open(from_location) if not (isinstance(from_dir, SvnRemoteAccess) or isinstance(from_dir, SvnCheckout)): raise BzrCommandError(gettext( "Source repository is not a Subversion repository.")) try: from_repos = from_dir.open_repository() except NoRepositoryPresent: if prefix is not None: raise BzrCommandError( gettext("Path inside repository specified " "and --prefix specified")) from_repos = from_dir.find_repository(_ignore_branch_path=True) assert from_dir.root_transport.base.startswith(from_repos.base) prefix = from_dir.root_transport.base[ len(from_repos.base):].strip("/") prefix = prefix.encode("utf-8") if not isinstance(from_repos, SvnRepository): raise BzrCommandError( gettext("Not a Subversion repository: %s") % from_location) if until is None: to_revnum = from_repos.get_latest_revnum() else: to_revnum = min(until, from_repos.get_latest_revnum()) with from_repos.lock_read(): if prefix is not None: if layout is None: overall_layout = from_repos.get_guessed_layout() else: overall_layout = layout prefix = prefix.strip("/") + "/" if overall_layout.is_branch(prefix): raise BzrCommandError( gettext("%s appears to contain a branch. " "For individual branches, use 'bzr branch'.") % from_location) # FIXME: Hint about is_tag() elif overall_layout.is_branch_parent(prefix): self.outf.write( gettext("Importing branches with prefix %s\n") % ("/" + urlutils.unescape_for_display(prefix, self.outf.encoding))) else: raise BzrCommandError( gettext("The specified path is inside a branch. " "Specify a different URL or a different " "repository layout (see also " "'bzr help svn-layout').")) if (prefix is not None and from_repos.transport.check_path(prefix, to_revnum) == NODE_NONE): raise BzrCommandError("Prefix %s does not exist" % prefix) def filter_branch(branch): if (prefix is not None and not branch.get_branch_path().startswith(prefix)): return False return True trace.note(gettext("Using repository layout: %s"), layout or from_repos.get_layout()) convert_repository( from_repos, to_location, layout, not standalone, trees, all, format=format, filter_branch=filter_branch, keep=keep, incremental=not restore, to_revnum=to_revnum, prefix=prefix, colocated=colocated, remember_parent=(tmp_repos is None)) if tmp_repos is not None: osutils.rmtree(tmp_repos) if not trees: trace.note( gettext("Use 'bzr checkout' to create a working tree in " "the newly created branches."))
class cmd_dailydeb(Command): """Build a deb based on a 'recipe' or from a branch. See "bzr help builder" for more information on what a recipe is. If you do not specify a working directory then a temporary directory will be used and it will be removed when the command finishes. """ takes_options = cmd_build.takes_options + [ Option("package", type=str, help="The package name to use in the changelog entry. " "If not specified then the package from the " "previous changelog entry will be used, so it " "must be specified if there is no changelog."), Option("distribution", type=str, help="The distribution to target. If not specified " "then the same distribution as the last entry " "in debian/changelog will be used."), Option("dput", type=str, argname="target", help="dput the built package to the specified " "dput target."), Option("key-id", type=str, short_name="k", help="Sign the packages with the specified GnuPG key. " "Must be specified if you use --dput."), Option("no-build", help="Just ready the source package and don't " "actually build it."), Option("watch-ppa", help="Watch the PPA the package was " "dput to and exit with 0 only if it builds and " "publishes successfully."), Option("append-version", type=str, help="Append the " "specified string to the end of the version used " "in debian/changelog."), Option("safe", help="Error if the recipe would cause" " arbitrary code execution."), Option("allow-fallback-to-native", help="Allow falling back to a native package if the upstream " "tarball can not be found."), ] takes_args = ["location", "working_basedir?"] 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) finally:
class cmd_combine_thread(breezy.commands.Command): __doc__ = """Combine the current thread with the thread below it. This will currently refuse to operate on the last thread, but in the future will just turn the loom into a normal branch again. Use combine-thread to remove a thread which has been merged into upstream. In precise terms this will: * Remove the entry from the loom for the current thread. * Change threads to the thread below. """ takes_options = [ Option('force', help='Combine even if work in the thread is not ' 'integrated up or down the loom.'), ] 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)
class cmd_qdiff(QBzrCommand, DiffArgProvider): """Show differences in working tree in a GUI window.""" takes_args = ['file*'] takes_options = [ 'revision', Option('complete', help='Show complete files.'), Option('encoding', type=check_encoding, help='Encoding of files content (default: utf-8).'), Option('added', short_name='A', help='Show diff for added files.'), Option('deleted', short_name='K', help='Show diff for deleted files.'), Option('modified', short_name='M', help='Show diff for modified files.'), Option('renamed', short_name='R', help='Show diff for renamed files.'), Option('ignore-whitespace', short_name='w', help="Ignore whitespace when finding differences"), brz_option('diff', 'old'), brz_option('diff', 'new'), ] if 'change' in Option.OPTIONS: takes_options.append('change') aliases = ['qdi'] def get_diff_window_args(self, processEvents, add_cleanup): # RJL if you get a ``AttributeError: 'function' object has no attribute 'enter_context'`` # error, or something similar, use something like: # # exit_stack = contextlib.ExitStack() # # and pass that as add_cleanup # args = {} (args["old_tree"], args["new_tree"], args["old_branch"], args["new_branch"], args["specific_files"], _) = get_trees_and_branches_to_diff_locked(self.file_list, self.revision, self.old, self.new, add_cleanup) args["ignore_whitespace"] = self.ignore_whitespace return args def get_ext_diff_args(self, processEvents): args = [] if self.revision and len(self.revision) == 1: args.append("-r%s" % (self.revision[0].user_spec, )) elif self.revision and len(self.revision) == 2: args.append( "-r%s..%s" % (self.revision[0].user_spec, self.revision[1].user_spec)) if self.new and not self.new == CUR_DIR: args.append("--new=%s" % self.new) if self.old and not self.old == CUR_DIR: args.append("--old=%s" % self.old) if self.file_list: args.extend(self.file_list) return None, args 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_()
main_window = getattr(self, "main_window", None) if main_window is not None: # 0.20 special: We check hasattr() first to work around # <http://bugs.python.org/issue4230> if hasattr(main_window, "return_code"): ret_code = main_window.return_code return ret_code except Exception: ui_mode = kwargs.get("ui_mode", False) from breezy.plugins.qbrz.lib.trace import report_exception return report_exception(ui_mode=ui_mode) finally: ui.ui_factory = std_ui_factory ui_mode_option = Option( "ui-mode", help="Causes dialogs to wait after the operation is complete.") execute_option = Option( "execute", short_name='e', help= "Causes dialogs to start the underlying action immediately without waiting for user input." ) # A special option so 'revision' can be passed as a simple string, when we do # *not* want breezy's feature of parsing the revision string before passing it. # This is used when we just want a plain string to pass to our dialog for it to # display in the UI, and we will later pass it to bzr for parsing. If you want # breezy to parse and pass a revisionspec object, just pass the string # 'revision' as normal. simple_revision_option = Option("revision", short_name='r',