Browse Source

opts, help: contextual usage screens

The following invocations now produce different output:

    $ mmgen-txcreate --usage
    $ mmgen-txcreate --usage --coin=eth
The MMGen Project 2 months ago
parent
commit
4eb7c64560
7 changed files with 37 additions and 9 deletions
  1. 4 0
      mmgen/cfg.py
  2. 1 1
      mmgen/help/__init__.py
  3. 5 0
      mmgen/help/help_notes.py
  4. 3 1
      mmgen/main_txcreate.py
  5. 3 2
      mmgen/main_txdo.py
  6. 4 2
      mmgen/opts.py
  7. 17 3
      test/cmdtest_d/ct_help.py

+ 4 - 0
mmgen/cfg.py

@@ -533,6 +533,10 @@ class Config(Lockable):
 		self.coin = self.coin.upper()
 		self.token = self.token.upper() if self.token else None
 
+		if 'usage' in self._uopts: # requires self.coin
+			import importlib
+			getattr(importlib.import_module(UserOpts.help_pkg), 'usage')(self) # exits
+
 		# self.color is finalized, so initialize color:
 		if self.color: # MMGEN_DISABLE_COLOR sets this to False
 			from .color import init_color

+ 1 - 1
mmgen/help/__init__.py

@@ -80,7 +80,7 @@ def make_usage_str(cfg, caller):
 			yield '{a:{w}} {b} {c}'.format(
 				a = ulbl,
 				b = gc.prog_name,
-				c = line,
+				c = cfg._usage_code(*gen_arg_tuple(cfg, cfg._usage_code, line)) if cfg._usage_code else line,
 				w = col1_w)
 			ulbl = ''
 	return ('\n' + (' ' * indent)).join(gen())

+ 5 - 0
mmgen/help/help_notes.py

@@ -20,6 +20,11 @@ class help_notes:
 		self.proto = proto
 		self.cfg = cfg
 
+	def txcreate_args(self):
+		return (
+			'<addr,amt>' if self.proto.base_coin == 'ETH' else
+			'[<addr,amt> ...] <change addr, addrlist ID or addr type>')
+
 	def account_info_desc(self):
 		return 'account info' if self.proto.base_coin == 'ETH' else 'unspent outputs'
 

+ 3 - 1
mmgen/main_txcreate.py

@@ -28,7 +28,7 @@ opts_data = {
 	'sets': [('yes', True, 'quiet', True)],
 	'text': {
 		'desc': f'Create a transaction with outputs to specified coin or {gc.proj_name} addresses',
-		'usage':   '[opts]  [<addr,amt> ...] <change addr, addrlist ID or addr type> [addr file ...]',
+		'usage':   '[opts] {u_args} [addr file ...]',
 		'options': """
 -h, --help            Print this help message
 --, --longhelp        Print help message for long (global) options
@@ -68,6 +68,8 @@ opts_data = {
 		'notes': '\n{c}\n{F}\n{x}',
 	},
 	'code': {
+		'usage': lambda cfg, proto, help_notes, s: s.format(
+			u_args = help_notes('txcreate_args')),
 		'options': lambda cfg, proto, help_notes, s: s.format(
 			a_info = help_notes('account_info_desc'),
 			fu     = help_notes('rel_fee_desc'),

+ 3 - 2
mmgen/main_txdo.py

@@ -28,8 +28,7 @@ opts_data = {
 	'sets': [('yes', True, 'quiet', True)],
 	'text': {
 		'desc': f'Create, sign and send an {gc.proj_name} transaction',
-		'usage':   '[opts]  [<addr,amt> ...] <change addr, addrlist ID or addr type> [addr file ...] ' +
-					'[seed source ...]',
+		'usage':   '[opts] {u_args} [addr file ...] [seed source ...]',
 		'options': """
 -h, --help             Print this help message
 --, --longhelp         Print help message for long (global) options
@@ -102,6 +101,8 @@ FMT CODES:
 {x}"""
 	},
 	'code': {
+		'usage': lambda cfg, proto, help_notes, s: s.format(
+			u_args  = help_notes('txcreate_args')),
 		'options': lambda cfg, proto, help_notes, s: s.format(
 			gc      = gc,
 			cfg     = cfg,

+ 4 - 2
mmgen/opts.py

@@ -262,8 +262,10 @@ class Opts:
 		cfg._parsed_opts = po
 		cfg._use_env = True
 		cfg._use_cfg_file = not 'skip_cfg_file' in uopts
-		# Make this available to usage()
+
+		# Make these available to usage():
 		cfg._usage_data = opts_data['text'].get('usage2') or opts_data['text']['usage']
+		cfg._usage_code = opts_data.get('code', {}).get('usage')
 
 		if os.getenv('MMGEN_DEBUG_OPTS'):
 			opt_preproc_debug(po)
@@ -276,7 +278,7 @@ class Opts:
 class UserOpts(Opts):
 
 	help_pkg = 'mmgen.help'
-	info_funcs = ('usage', 'version', 'show_hash_presets')
+	info_funcs = ('version', 'show_hash_presets')
 
 	global_opts_data = {
 		#  coin code : cmd code : opt : opt param : text

+ 17 - 3
test/cmdtest_d/ct_help.py

@@ -26,7 +26,9 @@ class CmdTestHelp(CmdTestBase):
 	passthru_opts = ('daemon_data_dir', 'rpc_port', 'coin', 'testnet')
 	cmd_group = (
 		('usage1',            (1, 'usage message (via --usage)', [])),
-		('usage2',            (1, 'usage message (via bad invocation)', [])),
+		('usage2',            (1, 'usage message (via --usage)', [])),
+		('usage3',            (1, 'usage message (via bad invocation)', [])),
+		('usage4',            (1, 'usage message (via bad invocation, with --coin)', [])),
 		('version',           (1, 'version message', [])),
 		('license',           (1, 'license message', [])),
 		('helpscreens',       (1, 'help screens',             [])),
@@ -39,15 +41,27 @@ class CmdTestHelp(CmdTestBase):
 	)
 
 	def usage1(self):
-		t = self.spawn('mmgen-txsend', ['--usage'], no_passthru_opts=True)
-		t.expect('USAGE: mmgen-txsend')
+		t = self.spawn('mmgen-walletgen', ['--usage'], no_passthru_opts=True)
+		t.expect('USAGE: mmgen-walletgen')
 		return t
 
 	def usage2(self):
+		cmd = 'xmrwallet' if self.coin == 'xmr' else 'txcreate'
+		t = self.spawn(f'mmgen-{cmd}', ['--usage', f'--coin={self.coin}'], no_passthru_opts=True)
+		t.expect(f'USAGE: mmgen-{cmd}')
+		return t
+
+	def usage3(self):
 		t = self.spawn('mmgen-walletgen', ['foo'], exit_val=1, no_passthru_opts=True)
 		t.expect('USAGE: mmgen-walletgen')
 		return t
 
+	def usage4(self):
+		cmd = 'xmrwallet' if self.coin == 'xmr' else 'addrgen'
+		t = self.spawn(f'mmgen-{cmd}', [f'--coin={self.coin}'], exit_val=1, no_passthru_opts=True)
+		t.expect(f'USAGE: mmgen-{cmd}')
+		return t
+
 	def version(self):
 		t = self.spawn('mmgen-tool', ['--version'], exit_val=0)
 		t.expect('MMGEN-TOOL version')