Files
nemo-repo-properties/nemoRepoProperties.py
T
dualfroz ceaad70eda refactor: rebuild as a property page plugin on nemo-repo-core
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.
2026-08-05 20:07:13 +02:00

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"]