comparison roundup/admin.py @ 7802:7c0a8088b053

feat: add support for controlling readline history features You can disable loading or saving the history file and disable loading the readline rc file. This is controlled by pragma history_features which is a bit string. Setting a bit disables the feature. Also cleaned up a python traceback if an invalid pragma was specified on the command line. Just displays an error message and drops into interactive mode. I had a hand when running regression tests with tet-admin.py::testBasicInteractive. It was loading the history file and saving the commands making the file huge. So disable all history_features by default when testing by setting pragma to 7.
author John Rouillard <rouilj@ieee.org>
date Wed, 13 Mar 2024 12:18:36 -0400
parents 2d4684e4702d
children aa1fd8704469
comparison
equal deleted inserted replaced
7801:af898d1d66dc 7802:7c0a8088b053
112 self.force = None 112 self.force = None
113 self.settings = { 113 self.settings = {
114 'display_header': False, 114 'display_header': False,
115 'display_protected': False, 115 'display_protected': False,
116 'indexer_backend': "as set in config.ini", 116 'indexer_backend': "as set in config.ini",
117 'history_features': 0,
117 'history_length': -1, 118 'history_length': -1,
118 '_reopen_tracker': False, 119 '_reopen_tracker': False,
119 'savepoint_limit': self._default_savepoint_setting, 120 'savepoint_limit': self._default_savepoint_setting,
120 'show_retired': "no", 121 'show_retired': "no",
121 '_retired_val': False, 122 '_retired_val': False,
129 " []'s before items. Includes retired/active status.\n"), 130 " []'s before items. Includes retired/active status.\n"),
130 131
131 'display_protected': 132 'display_protected':
132 _("Have 'display designator' and 'specification class' show\n" 133 _("Have 'display designator' and 'specification class' show\n"
133 " protected fields: creator, id etc.\n"), 134 " protected fields: creator, id etc.\n"),
135
136 'history_features':
137 _("Controls history options. It is a bitstring where setting\n"
138 " the bit disables the feature. A value of 0 (default)\n"
139 " enables all features. Value 1 disables loading of\n"
140 " history. Value 2 disables saving history. Value 4\n"
141 " disables loading init file. Since it is a bitstring a\n"
142 " value of 6 disables both loading init file and saving\n"
143 " history.\n"),
134 144
135 'history_length': 145 'history_length':
136 _("Set the number of lines of history to keep for this session.\n" 146 _("Set the number of lines of history to keep for this session.\n"
137 " -1 is infinite.\n"), 147 " -1 is infinite.\n"),
138 148
2261 import traceback 2271 import traceback
2262 traceback.print_exc() 2272 traceback.print_exc()
2263 ret = 1 2273 ret = 1
2264 return ret 2274 return ret
2265 2275
2276 def history_features(self, feature):
2277 """ self.settings['history_features'] = 0: load rc, load/save history
2278 self.settings['history_features'] = 1: do not load history
2279 self.settings['history_features'] = 2: do not save history
2280 self.settings['history_features'] = 4: don't load rc
2281 """
2282
2283 features = { # bit bashing
2284 'load_history': 1,
2285 'save_history': 2,
2286 'load_rc': 4}
2287
2288 # setting the bit disables the feature, so use not.
2289 return not self.settings['history_features'] & features[feature]
2290
2266 def interactive(self): 2291 def interactive(self):
2267 """Run in an interactive mode 2292 """Run in an interactive mode
2268 """ 2293 """
2269 print(_('Roundup %s ready for input.\nType "help" for help.') 2294 print(_('Roundup %s ready for input.\nType "help" for help.')
2270 % roundup_version) 2295 % roundup_version)
2275 ".roundup_admin_history") 2300 ".roundup_admin_history")
2276 2301
2277 try: 2302 try:
2278 import readline 2303 import readline
2279 try: 2304 try:
2280 readline.read_init_file(initfile) 2305 if self.history_features('load_rc'):
2306 readline.read_init_file(initfile)
2281 except IOError: # FileNotFoundError under python3 2307 except IOError: # FileNotFoundError under python3
2282 # file is optional 2308 # file is optional
2283 pass 2309 pass
2284 2310
2285 try: 2311 try:
2286 readline.read_history_file(histfile) 2312 if self.history_features('load_history'):
2313 readline.read_history_file(histfile)
2287 except IOError: # FileNotFoundError under python3 2314 except IOError: # FileNotFoundError under python3
2288 # no history file yet 2315 # no history file yet
2289 pass 2316 pass
2290 2317
2291 # Default history length is unlimited. 2318 # Default history length is unlimited.
2320 if commit and commit[0].lower() == 'y': 2347 if commit and commit[0].lower() == 'y':
2321 self.db.commit() 2348 self.db.commit()
2322 2349
2323 # looks like histfile is saved with mode 600 2350 # looks like histfile is saved with mode 600
2324 if readline: 2351 if readline:
2325 readline.write_history_file(histfile) 2352 if self.history_features('save_history'):
2353 readline.write_history_file(histfile)
2326 return 0 2354 return 0
2327 2355
2328 def main(self): # noqa: PLR0912, PLR0911 2356 def main(self): # noqa: PLR0912, PLR0911
2329 try: 2357 try:
2330 opts, args = getopt.getopt(sys.argv[1:], 'i:u:hcdP:sS:vV') 2358 opts, args = getopt.getopt(sys.argv[1:], 'i:u:hcdP:sS:vV')
2372 return 1 2400 return 1
2373 self.separator = ' ' 2401 self.separator = ' '
2374 elif opt == '-d': 2402 elif opt == '-d':
2375 self.print_designator = 1 2403 self.print_designator = 1
2376 elif opt == '-P': 2404 elif opt == '-P':
2377 self.do_pragma([arg]) 2405 try:
2406 self.do_pragma([arg])
2407 except UsageError as e:
2408 print('\n%s\n' % e)
2378 elif opt == '-u': 2409 elif opt == '-u':
2379 login_opt = arg.split(':') 2410 login_opt = arg.split(':')
2380 self.name = login_opt[0] 2411 self.name = login_opt[0]
2381 if len(login_opt) > 1: 2412 if len(login_opt) > 1:
2382 self.password = login_opt[1] 2413 self.password = login_opt[1]

Roundup Issue Tracker: http://roundup-tracker.org/