Keeps only the PropertyPageProvider from the single file extension; the config, git and cache layers come from nemo-repo-core. Opening Properties is an explicit request for current state, so the page now bypasses the shared TTL cache and asks git directly. The grid gains a summary row and the row builder is split out so the page body reads as a list of fields.
113 lines
3.5 KiB
Python
113 lines
3.5 KiB
Python
#!/usr/bin/python3
|
|
"""nemo-repo-properties: a "Git" tab in the folder Properties dialog.
|
|
|
|
Right click a repository folder, choose Properties, and the Git tab shows
|
|
the branch, its upstream, how far ahead or behind it is, the working tree
|
|
counts and the last commit. Values are selectable so they can be copied.
|
|
|
|
Requires nemo-repo-core: https://github.com/dualfroz/nemo-repo-core
|
|
"""
|
|
|
|
import importlib.util
|
|
import os
|
|
import sys
|
|
|
|
|
|
def _ensureCoreOnPath():
|
|
if importlib.util.find_spec("nemoRepoCore") is not None:
|
|
return
|
|
dataHome = os.environ.get("XDG_DATA_HOME") or os.path.expanduser("~/.local/share")
|
|
dataDirs = (os.environ.get("XDG_DATA_DIRS") or "/usr/local/share:/usr/share").split(":")
|
|
for base in [dataHome] + dataDirs:
|
|
candidate = os.path.join(base, "nemo-repo-core")
|
|
if os.path.isdir(os.path.join(candidate, "nemoRepoCore")):
|
|
sys.path.insert(0, candidate)
|
|
return
|
|
|
|
|
|
_ensureCoreOnPath()
|
|
|
|
import gi
|
|
|
|
gi.require_version("Gtk", "3.0")
|
|
gi.require_version("Nemo", "3.0")
|
|
from gi.repository import GObject, Gtk, Nemo
|
|
|
|
from nemoRepoCore import (findRepoRoot, repoCache, requireCore,
|
|
singleLocalDirectory)
|
|
|
|
requireCore("1.0.0")
|
|
|
|
|
|
def _buildGrid():
|
|
grid = Gtk.Grid()
|
|
grid.set_row_spacing(6)
|
|
grid.set_column_spacing(12)
|
|
grid.set_margin_start(12)
|
|
grid.set_margin_end(12)
|
|
grid.set_margin_top(12)
|
|
grid.set_margin_bottom(12)
|
|
return grid
|
|
|
|
|
|
def _addRow(grid, row, labelText, valueText):
|
|
label = Gtk.Label(label=labelText)
|
|
label.set_xalign(0)
|
|
label.get_style_context().add_class("dim-label")
|
|
value = Gtk.Label(label=valueText)
|
|
value.set_xalign(0)
|
|
value.set_selectable(True)
|
|
value.set_line_wrap(True)
|
|
grid.attach(label, 0, row, 1, 1)
|
|
grid.attach(value, 1, row, 1, 1)
|
|
return row + 1
|
|
|
|
|
|
def _fillGrid(grid, repoRoot, info):
|
|
if info.error:
|
|
_addRow(grid, 0, "Status", info.error)
|
|
return
|
|
|
|
row = 0
|
|
row = _addRow(grid, row, "Repository", repoRoot)
|
|
row = _addRow(grid, row, "Branch", info.branchLabel)
|
|
row = _addRow(grid, row, "Upstream", info.upstream if info.hasUpstream else "(none)")
|
|
row = _addRow(grid, row, "Ahead / behind",
|
|
"%d ahead, %d behind" % (info.ahead, info.behind))
|
|
row = _addRow(grid, row, "Staged changes", str(info.staged))
|
|
row = _addRow(grid, row, "Unstaged changes", str(info.unstaged))
|
|
row = _addRow(grid, row, "Untracked files", str(info.untracked))
|
|
row = _addRow(grid, row, "Summary", info.summary)
|
|
if info.lastCommit:
|
|
commit = info.lastCommit
|
|
row = _addRow(grid, row, "Last commit",
|
|
"%s %s" % (commit.hash, commit.subject))
|
|
row = _addRow(grid, row, "",
|
|
"by %s, %s" % (commit.author, commit.relativeDate))
|
|
|
|
|
|
class RepoPropertyPageProvider(GObject.GObject, Nemo.PropertyPageProvider,
|
|
Nemo.NameAndDescProvider):
|
|
|
|
def get_property_pages(self, files):
|
|
path = singleLocalDirectory(files)
|
|
if path is None:
|
|
return []
|
|
|
|
repoRoot = findRepoRoot(path)
|
|
if repoRoot is None:
|
|
return []
|
|
|
|
info = repoCache.refresh(repoRoot)
|
|
|
|
grid = _buildGrid()
|
|
_fillGrid(grid, repoRoot, info)
|
|
grid.show_all()
|
|
|
|
return [Nemo.PropertyPage(name="NemoRepoProperties::git",
|
|
label=Gtk.Label(label="Git"),
|
|
page=grid)]
|
|
|
|
def get_name_and_desc(self):
|
|
return ["nemo-repo-properties:::Git tab in the folder Properties dialog"]
|