Skip to content

Commit ea3fc41

Browse files
author
Arun Persaud
committed
Closes #3803: new theme diff command
1 parent 0f4c230 commit ea3fc41

File tree

2 files changed

+63
-11
lines changed

2 files changed

+63
-11
lines changed

CHANGES.txt

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Features
1111
via an optional ``conf.py`` method ``TEMPLATE_ENGINE_FACTORY``.
1212
* Switch to pyproject.toml
1313
* Add path handler ``slug_source`` linking to source of post.
14+
* Provide a command to show diffs between custom templates and the original files
1415

1516
Bugfixes
1617
--------

nikola/plugins/command/theme.py

+62-11
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@
2727
"""Manage themes."""
2828

2929
import configparser
30+
import difflib
3031
import io
3132
import json.decoder
3233
import os
34+
from pathlib import Path
3335
import shutil
3436
import sys
3537
import time
@@ -49,9 +51,9 @@ class CommandTheme(Command):
4951
"""Manage themes."""
5052

5153
json = None
52-
name = "theme"
53-
doc_usage = "[-u url] [-i theme_name] [-r theme_name] [-l] [--list-installed] [-g] [-n theme_name] [-c template_name]"
54-
doc_purpose = "manage themes"
54+
name = 'theme'
55+
doc_usage = '[-u url] [-i theme_name] [-r theme_name] [-l] [--list-installed] [-g] [-n theme_name] [-c template_name] [-d]'
56+
doc_purpose = 'manage themes'
5557
output_dir = 'themes'
5658
cmd_options = [
5759
{
@@ -138,6 +140,14 @@ class CommandTheme(Command):
138140
'default': False,
139141
'help': 'Create legacy meta files for new theme',
140142
},
143+
{
144+
'name': 'diff',
145+
'short': 'd',
146+
'long': 'diff',
147+
'type': bool,
148+
'default': False,
149+
'help': 'Show diffs of custom templates compared to base file',
150+
},
141151
]
142152

143153
def _execute(self, options, args):
@@ -155,14 +165,20 @@ def _execute(self, options, args):
155165
new_engine = options.get('new_engine')
156166
new_parent = options.get('new_parent')
157167
new_legacy_meta = options.get('new_legacy_meta')
158-
command_count = [bool(x) for x in (
159-
install,
160-
uninstall,
161-
list_available,
162-
list_installed,
163-
get_path,
164-
copy_template,
165-
new)].count(True)
168+
diff = options.get('diff')
169+
command_count = [
170+
bool(x)
171+
for x in (
172+
install,
173+
uninstall,
174+
list_available,
175+
list_installed,
176+
get_path,
177+
copy_template,
178+
new,
179+
diff,
180+
)
181+
].count(True)
166182
if command_count > 1 or command_count == 0:
167183
print(self.help())
168184
return 2
@@ -181,6 +197,8 @@ def _execute(self, options, args):
181197
return self.copy_template(copy_template)
182198
elif new:
183199
return self.new_theme(new, new_engine, new_parent, new_legacy_meta)
200+
elif diff:
201+
return self.diff_custom_templates()
184202

185203
def do_install_deps(self, url, name):
186204
"""Install themes and their dependencies."""
@@ -324,6 +342,39 @@ def copy_template(self, template):
324342
LOGGER.error("This file already exists in your templates directory ({0}).".format(base))
325343
return 3
326344

345+
def diff_custom_templates(self) -> None:
346+
"""Print the diff between a custom template and the original file."""
347+
# list of all theme and all its parents
348+
theme_paths = self.site.THEMES
349+
theme_path = utils.get_theme_path(theme_paths[0])
350+
if theme_path.startswith('themes' + os.sep):
351+
# this is a custom theme
352+
base = theme_path
353+
theme_paths = theme_paths[1:]
354+
else:
355+
# not a full custom theme, just modified single templates
356+
base = '.'
357+
358+
local = Path(base)
359+
for f in local.rglob('templates/*tmpl'):
360+
orig = Path(utils.get_asset_path(f.relative_to(base), theme_paths))
361+
362+
lines = f.read_text().splitlines()
363+
original_lines = orig.read_text().splitlines()
364+
365+
# Create a unified diff
366+
diff = difflib.unified_diff(
367+
original_lines,
368+
lines,
369+
fromfile=str(orig),
370+
tofile=str(f),
371+
lineterm='',
372+
)
373+
374+
for line in diff:
375+
print(line.rstrip())
376+
print()
377+
327378
def new_theme(self, name, engine, parent, create_legacy_meta=False):
328379
"""Create a new theme."""
329380
base = 'themes'

0 commit comments

Comments
 (0)