Source code for wxyz.dvcs.tools.tool_remotes

"""baseline tools for working with remotes"""

# pylint: disable=unused-argument

import ipywidgets as W
import traitlets as T
from tornado.ioloop import IOLoop

from ..repos.repo_base import Repo

CSS_PREFIX = "jp-wxyz-dvcs-tool-remote"


[docs]class Remoter(W.VBox): """Adds remotes""" repo = T.Instance(Repo) remote = T.Unicode(allow_none=True) head = T.Unicode(allow_none=True) remotes = T.Instance(W.DOMWidget) heads = T.Instance(W.DOMWidget) push_btn = T.Instance(W.Button) fetch_btn = T.Instance(W.Button) merge_btn = T.Instance(W.Button) _remotes_link = None def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.children = [ W.HBox([self.remotes, self.fetch_btn]), W.HBox([self.heads, self.merge_btn, self.push_btn]), ] T.dlink((self.remotes, "value"), (self, "remote")) T.dlink((self.heads, "value"), (self, "head")) T.dlink((self, "remote"), (self.heads, "disabled"), lambda x: not x) T.dlink((self, "head"), (self.push_btn, "disabled"), lambda x: not x) self.fetch_btn.on_click(self._on_fetch_click) self.merge_btn.on_click(self._on_merge_click) # handlers def _on_fetch_click(self, *args): IOLoop.current().add_callback(self.repo.remotes[self.remote].fetch) def _on_push_click(self, *args): raise NotImplementedError() def _on_merge_click(self, *args): self.repo.merge(self.heads.value) # observers @T.observe("repo") def _on_repo(self, change): """handle the repo changing (including the first time)""" if self._remotes_link: self._remotes_link.unlink() if change.new: self._remotes_link = T.dlink( (change.new, "remotes"), (self.remotes, "options"), self._update_remote_options, ) def _update_remote_options(self, remotes): """format the remote options (TODO: nicely)""" return sorted((remotes)) def _update_head_options(self, change): """format the head options (TODO: nicely)""" self.heads.options = tuple( sorted( [(f"""{head} [{ref[:7]}]""", ref) for head, ref in change.new.items()] ) ) @T.observe("remote") def _on_remote(self, change): """handle the current remote name changing""" if change.new: remote = self.repo.remotes[change.new] remote.observe(self._update_head_options, "heads") else: self.heads.options = [] # defaults @T.default("remotes") def _default_remotes(self): """initialize the remotes widget""" return W.Dropdown(description="Remotes") @T.default("heads") def _default_heads(self): """initialize the heads widget""" return W.Dropdown(description="Heads") @T.default("fetch_btn") def _default_fetch_btn(self): """initialize the fetch widget""" return W.Button(description="Fetch", icon="cloud-download") @T.default("merge_btn") def _default_merge_btn(self): """initialize the merge widget""" return W.Button(description="Merge", icon="compress") @T.default("push_btn") def _default_push_btn(self): """initialize the push widget""" return W.Button(description="Push", icon="cloud-upload")