Skip to content

Commit 38f398d

Browse files
committed
issue2551233 - create new roundup-admin command "templates"
add a command to list all templates, the directory where they are defined, and a description. If called as templates trace_dir also list all directores that are search for templates even if none are found.
1 parent db237e0 commit 38f398d

File tree

4 files changed

+62
-7
lines changed

4 files changed

+62
-7
lines changed

CHANGES.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ Features:
6666
- sqlite databases use WAL mode when *created* to improve read
6767
concurrency. Existing sqlite database still use rollback journal
6868
mode. See upgrading.txt for details. (John Rouillard)
69+
- issue2551233 - create new roundup-admin command "templates"
70+
list all template names, location and descriptions. Should help
71+
find where /usr/share/roundup/templates is buried during some
72+
install mechanisms. (John Rouillard)
6973

7074
2022-07-13 2.2.0
7175

roundup/admin.py

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ def do_help(self, args, nl_re=re.compile('[\r\n]'),
289289
print(line)
290290
return 0
291291

292-
def listTemplates(self):
292+
def listTemplates(self, trace_search=False):
293293
""" List all the available templates.
294294
295295
Look in the following places, where the later rules take precedence:
@@ -327,7 +327,7 @@ def listTemplates(self):
327327
for _i in range(N):
328328
path = os.path.dirname(path)
329329
tdir = os.path.join(path, 'share', 'roundup', 'templates')
330-
if debug: print(tdir)
330+
if debug or trace_search: print(tdir)
331331
if os.path.isdir(tdir):
332332
templates = init.listTemplates(tdir)
333333
if debug: print(" Found templates breaking loop")
@@ -349,7 +349,7 @@ def listTemplates(self):
349349
# path is /usr/local/lib/python3.10/site-packages
350350
tdir = os.path.join(path, sys.prefix[1:], 'share',
351351
'roundup', 'templates')
352-
if debug: print(tdir)
352+
if debug or trace_search: print(tdir)
353353
if os.path.isdir(tdir):
354354
templates.update(init.listTemplates(tdir))
355355

@@ -359,27 +359,27 @@ def listTemplates(self):
359359
# path is /usr/local/lib/python3.10/site-packages
360360
tdir = os.path.join(path, sys.base_prefix[1:], 'local', 'share',
361361
'roundup', 'templates')
362-
if debug: print(tdir)
362+
if debug or trace_search: print(tdir)
363363
if os.path.isdir(tdir):
364364
templates.update(init.listTemplates(tdir))
365365
# path is /usr/local/lib/python3.10/site-packages
366366

367367

368368
tdir = os.path.join(path, sys.base_prefix[1:], 'share',
369369
'roundup', 'templates')
370-
if debug: print(tdir)
370+
if debug or trace_search: print(tdir)
371371
if os.path.isdir(tdir):
372372
templates.update(init.listTemplates(tdir))
373373
except AttributeError:
374374
pass # sys.base_prefix doesn't work under python2
375375

376376
# Try subdirs of the current dir
377377
templates.update(init.listTemplates(os.getcwd()))
378-
if debug: print(os.getcwd() + '/*')
378+
if debug or trace_search: print(os.getcwd() + '/*')
379379

380380
# Finally, try the current directory as a template
381381
template = init.loadTemplateInfo(os.getcwd())
382-
if debug: print(os.getcwd() + '/*')
382+
if debug or trace_search: print(os.getcwd())
383383
if template:
384384
if debug: print(" Found template %s"%template['name'])
385385
templates[template['name']] = template
@@ -1080,6 +1080,34 @@ def do_list(self, args):
10801080
print(_('%(nodeid)4s: %(value)s') % locals())
10811081
return 0
10821082

1083+
def do_templates(self, args):
1084+
''"""Usage: templates [trace_search]
1085+
List templates and their installed directories.
1086+
1087+
With trace_search also list all directories that are
1088+
searched for templates.
1089+
"""
1090+
import textwrap
1091+
1092+
trace_search = False
1093+
if args and args[0] == "trace_search":
1094+
trace_search = True
1095+
1096+
templates = self.listTemplates(trace_search=trace_search)
1097+
1098+
for name in sorted(list(templates.keys())):
1099+
templates[name]['description'] = textwrap.fill(
1100+
"\n".join([ line.lstrip() for line in
1101+
templates[name]['description'].split("\n")]),
1102+
70,
1103+
subsequent_indent=" "
1104+
)
1105+
print("""
1106+
Name: %(name)s
1107+
Path: %(path)s
1108+
Desc: %(description)s
1109+
"""%templates[name])
1110+
10831111
def do_table(self, args):
10841112
''"""Usage: table classname [property[,property]*]
10851113
List the instances of a class in tabular form.
@@ -1713,6 +1741,8 @@ def run_command(self, args):
17131741
except UsageError as message: # noqa: F841
17141742
print(_('Error: %(message)s') % locals())
17151743
return 1
1744+
elif command == "templates":
1745+
return self.do_templates(args[1:])
17161746

17171747
# get the tracker
17181748
try:

share/man/man1/roundup-admin.1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ ids for the multilink as comma-separated numbers (ie "1,2,3").
237237
\fBspecification\fP \fIclassname\fP
238238
Show the properties for a classname.
239239
.TP
240+
\fBtemplates\fP \fI[trace_search]]\fP
241+
Lists the names, location and description of all known templates.
242+
.TP
240243
\fBtable\fP \fIclassname [property[,property]*]\fP
241244
Lists all instances of the given class. If the properties are not
242245
specified, all properties are displayed. By default, the column

test/test_admin.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,24 @@ def testTable(self):
12501250
print(expected)
12511251
self.assertEqual(out, expected)
12521252

1253+
def testTemplates(self):
1254+
1255+
self.install_init()
1256+
self.admin=AdminTool()
1257+
1258+
with captured_output() as (out, err):
1259+
# command does not require a tracker home. use zZzZ to cause error
1260+
sys.argv=['main', '-i', "zZzZ", 'templates' ]
1261+
ret = self.admin.main()
1262+
1263+
out = out.getvalue().strip()
1264+
1265+
for tracker in ['Name: classic\nPath:',
1266+
'Name: devel\nPath:',
1267+
'Name: jinja2\nPath:',
1268+
'Name: minimal\nPath:',
1269+
'Name: responsive\nPath:']:
1270+
self.assertIn(tracker, out)
12531271

12541272
class anydbmAdminTest(AdminTest, unittest.TestCase):
12551273
backend = 'anydbm'

0 commit comments

Comments
 (0)