27
27
"""Manage themes."""
28
28
29
29
import configparser
30
+ import difflib
30
31
import io
31
32
import json .decoder
32
33
import os
34
+ from pathlib import Path
33
35
import shutil
34
36
import sys
35
37
import time
@@ -49,9 +51,9 @@ class CommandTheme(Command):
49
51
"""Manage themes."""
50
52
51
53
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'
55
57
output_dir = 'themes'
56
58
cmd_options = [
57
59
{
@@ -138,6 +140,14 @@ class CommandTheme(Command):
138
140
'default' : False ,
139
141
'help' : 'Create legacy meta files for new theme' ,
140
142
},
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
+ },
141
151
]
142
152
143
153
def _execute (self , options , args ):
@@ -155,14 +165,20 @@ def _execute(self, options, args):
155
165
new_engine = options .get ('new_engine' )
156
166
new_parent = options .get ('new_parent' )
157
167
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 )
166
182
if command_count > 1 or command_count == 0 :
167
183
print (self .help ())
168
184
return 2
@@ -181,6 +197,8 @@ def _execute(self, options, args):
181
197
return self .copy_template (copy_template )
182
198
elif new :
183
199
return self .new_theme (new , new_engine , new_parent , new_legacy_meta )
200
+ elif diff :
201
+ return self .diff_custom_templates ()
184
202
185
203
def do_install_deps (self , url , name ):
186
204
"""Install themes and their dependencies."""
@@ -324,6 +342,39 @@ def copy_template(self, template):
324
342
LOGGER .error ("This file already exists in your templates directory ({0})." .format (base ))
325
343
return 3
326
344
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
+
327
378
def new_theme (self , name , engine , parent , create_legacy_meta = False ):
328
379
"""Create a new theme."""
329
380
base = 'themes'
0 commit comments