chainlib

Generic blockchain access library and tooling
Log | Files | Refs | README | LICENSE

commit af7f977007db117a455c5c594669a3599be89542
parent 92fb0160148b7a84064d215c17aebbbbb0455cfa
Author: lash <dev@holbrook.no>
Date:   Wed, 23 Feb 2022 09:48:15 +0000

Add env/config descriptions from ini dir

Diffstat:
Mchainlib/cli/man.py | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Achainlib/data/env/env.ini | 14++++++++++++++
Mscripts/chainlib-man.py | 26++++++++++----------------
3 files changed, 113 insertions(+), 42 deletions(-)

diff --git a/chainlib/cli/man.py b/chainlib/cli/man.py @@ -1,29 +1,50 @@ +# standard imports +import os + +# external imports +import confini + # local imports from .base import ( Flag, argflag_std_target, ) -def apply_groff(collection, v, arg=None): +script_dir = os.path.dirname(os.path.realpath(__file__)) +data_dir = os.path.join(script_dir, '..', 'data') + + +def apply_groff(collection, v, arg=None, typ='arg'): s = '' for flag in collection: if len(s) > 0: s += ', ' - s += '\\fB' + flag - if arg != None: - s += ' \\fI' + arg - s += '\\fP' + s += format_groff(flag, v, arg=arg, typ=typ) + return s + + +def format_groff(k, v, arg=None, typ='arg'): + s = '' + if typ == 'env': + s += '\\fI' + else: + s += '\\fB' + s += k + if arg != None: + s += ' \\fI' + arg + s += '\\fP' s = "\n.TP\n" + s + "\n" + v return s class DocEntry: - def __init__(self, *args, argvalue=None): + def __init__(self, *args, argvalue=None, typ='arg'): self.flags = args self.v = argvalue self.render = self.get_empty self.groff = None + self.typ = typ def __check_line_default(self, m): @@ -51,7 +72,7 @@ class DocEntry: v = self.groff if v == None: v = self.plain - s = apply_groff(self.flags, v, arg=self.v) + s = apply_groff(self.flags, v, arg=self.v, typ=self.typ) return s @@ -61,11 +82,12 @@ class DocEntry: class DocGenerator: - def __init__(self, arg_flags, config): - self.config = config +# def __init__(self, arg_flags, config): + def __init__(self, arg_flags): + #self.config = config self.arg_flags = arg_flags self.docs = {} - self.envs = {} +# self.envs = {} def __str__(self): @@ -86,15 +108,6 @@ class DocGenerator: return s - def get_args(self): - s = '' - ks = list(self.docs.keys()) - ks.sort() - for k in ks: - s += str(self.docs[k]) + "\n" - return s - - def override_arg(self, k, v, args): o = self.docs[k] #g.docs[v[0]].groff = v[1].rstrip() @@ -105,12 +118,12 @@ class DocGenerator: for i in range(l): o.flags.append(args[i]) - - def process_env(self): - for k in self.config.all(): - if k[0] == '_': - continue - self.envs[k] = None +# +# def process_env(self): +# for k in self.config.all(): +# if k[0] == '_': +# continue +# self.envs[k] = None def process_arg(self): @@ -255,4 +268,54 @@ class DocGenerator: def process(self): self.process_arg() - self.process_env() +# self.process_env() + + +class EnvDocGenerator: + + def __init__(self, arg_flags, override=None): + self.arg_flags = arg_flags + self.envs = {} + env_dir = os.path.join(data_dir, 'env') + self.config = confini.Config(env_dir, override_dirs=override) + self.config.process() + + + def __add(self, k): + v = format_groff(k, self.config.get(k), None, typ='env') + self.envs[k] = v + + + def process(self): + ks = [] + if self.arg_flags & Flag.PROVIDER: + ks += [ + 'RPC_PROVIDER', + 'RPC_DIALECT', + ] + if self.arg_flags & Flag.RPC_AUTH: + ks += [ + 'RPC_AUTH', + 'RPC_CREDENTIALS', + ] + + if self.arg_flags & Flag.CHAIN_SPEC: + ks.append('CHAIN_SPEC') + + if self.arg_flags & Flag.KEY_FILE: + ks += [ + 'WALLET_KEY_FILE', + 'WALLET_PASSPHRASE', + ] + + for k in ks: + self.__add(k) + + + def __str__(self): + s = '' + ks = list(self.envs.keys()) + ks.sort() + for k in ks: + s += str(self.envs[k]) + "\n" + return s diff --git a/chainlib/data/env/env.ini b/chainlib/data/env/env.ini @@ -0,0 +1,14 @@ +[rpc] +provider = Fully-qualified URL to the RPC endpoint of the blockchain node. +auth = Authentication method to use for the \fIRPC_PROVIDER\fP. Currently only \fIbasic\fP is supported. +credentials = Authentication credentials to use for \fIRPC_AUTH\fP. For \fIbasic\fP authentication the value must be given as \fI<user>:<pass>\fP. +dialect = Enables translations of EVM node specific formatting and response codes. +scheme = (needs content) +verify = (needs content) + +[chain] +spec = String specifying the type of chain connected to, in the format \fI<engine>:<fork>:<network_id>:<common_name>\fP. For EVM nodes the \fIengine\fP value will always be \fIevm\fP. + +[wallet] +key_file = The wallet key file containing private key to use for transaction signing. Overridden by \fB-y\fP. +passphrase = Passphrase to unlock wallet. \fBWARNING:\fP it is \fBunsafe\fP to pass the passphrase as an environment variable. If the key unlocks something of value, the passphrase should rather be in a configuration file, preferably as an encrypted entry. Alternatively, a passphrase can be read from file using the \fB--passphrase-file\fP option. Files containing passphrases should only be accessible by the owner. diff --git a/scripts/chainlib-man.py b/scripts/chainlib-man.py @@ -10,6 +10,7 @@ import shutil from hexathon import strip_0x, add_0x from chainlib.cli.man import ( + EnvDocGenerator, DocGenerator, apply_groff, ) @@ -28,7 +29,7 @@ argparser.add_argument('-n', help='tool name to use for man filename') argparser.add_argument('-d', default='.', help='output directory') argparser.add_argument('-v', action='store_true', help='turn on debug logging') argparser.add_argument('--overrides-file', dest='overrides_file', help='load options description override from file') -argparser.add_argument('--overrides-env-file', dest='overrides_env_file', help='load envionment description overrides from file') +argparser.add_argument('--overrides-env-dir', dest='overrides_env_dir', help='load envionment description override config from directory') argparser.add_argument('header_file', help='groff file containing heading, synopsis and description') args = argparser.parse_args(sys.argv[1:]) @@ -39,9 +40,10 @@ if args.v: b = bytes.fromhex(strip_0x(args.b)) flags = int.from_bytes(b, byteorder='little') -empty_args = ChainlibArgumentParser(flags).parse_args([]) -config = Config.from_args(empty_args, arg_flags=flags) -g = DocGenerator(flags, config) +#empty_args = ChainlibArgumentParser(flags).parse_args([]) +#config = Config.from_args(empty_args, arg_flags=flags) +#g = DocGenerator(flags, config) +g = DocGenerator(flags) toolname = args.n if toolname == None: @@ -66,18 +68,8 @@ if args.overrides_file != None: f.close() -s_env = '' -if args.overrides_env_file != None: - f = open(args.overrides_env_file, 'r') - while True: - s = f.readline() - if len(s) == 0: - break - (k, description) = s.split('\t', maxsplit=1) - v = config.get(k) - s_env += apply_groff([k], description) - -print(s_env) +ge = EnvDocGenerator(flags, override=args.overrides_env_dir) +ge.process() f = open(args.header_file) head = f.read() @@ -87,6 +79,8 @@ f.close() f = os.fdopen(fd, 'w') f.write(head) f.write(str(g)) +f.write(".SH ENVIRONMENT\n\n") +f.write(str(ge)) f.close() dest = os.path.join(args.d, toolname + '.1')