From a9475de48e8210ff5b6622405fa2bb7db83f185e Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Sat, 25 Apr 2026 08:29:55 +0200 Subject: [PATCH] lib.ExecContext: Add open() + close() around _run() Enclose ExecContext._run() in an open() / close() - pair. This is convenient for the caller in that it doesn't need to take care of opening and closing for one call only, and inconvenient in that it forces the caller to conciously add an open() / close() - pair around multiple run() calls where it wants the context to stay open in between. Or use the ExecContext as a context manager. Signed-off-by: Jan Lindemann --- .../jw/pkg/cmds/projects/CmdListRepos.py | 25 ++++----- src/python/jw/pkg/lib/ExecContext.py | 52 ++++++++++++------- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/python/jw/pkg/cmds/projects/CmdListRepos.py b/src/python/jw/pkg/cmds/projects/CmdListRepos.py index 56340d64..6761c095 100644 --- a/src/python/jw/pkg/cmds/projects/CmdListRepos.py +++ b/src/python/jw/pkg/cmds/projects/CmdListRepos.py @@ -33,22 +33,15 @@ class CmdListRepos(Cmd): # export case 'ssh': if re.match(r'ssh://.*git\.janware\.com/', args.base_url): from jw.pkg.lib.ec.SSHClient import SSHClient, ssh_client - ssh: SSHClient|None = None - try: - ssh = ssh_client(args.base_url, interactive=self.app.interactive, verbose_default=self.app.verbose) - if username is not None: - ssh.set_username(username) - if password is not None: - ssh.set_password(password) - cmd = ['/opt/jw-pkg/bin/git-srv-admin.sh', '-u', args.from_owner, '-j', 'list-personal-projects'] - result = await ssh.run(cmd) - print('\n'.join(result.stdout.decode().splitlines())) - return - except: - raise - finally: - if ssh is not None: - await ssh.close() + ssh = ssh_client(args.base_url, interactive=self.app.interactive, verbose_default=self.app.verbose) + if username is not None: + ssh.set_username(username) + if password is not None: + ssh.set_password(password) + cmd = ['/opt/jw-pkg/bin/git-srv-admin.sh', '-u', args.from_owner, '-j', 'list-personal-projects'] + result = await ssh.run(cmd) + print('\n'.join(result.stdout.decode().splitlines())) + return case 'https': from jw.pkg.lib.base import InputMode cmd_input = InputMode.NonInteractive diff --git a/src/python/jw/pkg/lib/ExecContext.py b/src/python/jw/pkg/lib/ExecContext.py index b4b5e015..cc1aa926 100644 --- a/src/python/jw/pkg/lib/ExecContext.py +++ b/src/python/jw/pkg/lib/ExecContext.py @@ -287,22 +287,30 @@ class ExecContext(Base): # be returned by CallContext and is very much allowed assert cmd_input is not None, 'Invalid: cmd_input is None' - ret = Result(None, None, 1) - with self.CallContext(self, title=title, cmd=cmd, cmd_input=cmd_input, mod_env=mod_env, wd=wd, - log_prefix='|', throw=throw, verbose=verbose) as cc: - try: - ret = await self._run( - cmd = cc.cmd, - wd = wd, - verbose = cc.verbose, - cmd_input = cc.cmd_input, - mod_env = cc.mod_env, - interactive = cc.interactive, - log_prefix = cc.log_prefix - ) - except Exception as e: - return cc.exception(ret, e) - cc.check_exit_code(ret) + # Enclose multiple run() calls in an additional open() / close() pair + # if you want the context to stay open between the calls + await self.open() + + try: + ret = Result(None, None, 1) + with self.CallContext(self, title=title, cmd=cmd, cmd_input=cmd_input, mod_env=mod_env, wd=wd, + log_prefix='|', throw=throw, verbose=verbose) as cc: + try: + ret = await self._run( + cmd = cc.cmd, + wd = wd, + verbose = cc.verbose, + cmd_input = cc.cmd_input, + mod_env = cc.mod_env, + interactive = cc.interactive, + log_prefix = cc.log_prefix + ) + except Exception as e: + return cc.exception(ret, e) + cc.check_exit_code(ret) + finally: + await self.close() + return ret async def _sudo( @@ -482,10 +490,14 @@ class ExecContext(Base): cmds.append({'cmd': ['chmod', mode, out]}) if atomic: cmds.append({'cmd': ['mv', out, path]}) - for cmd in cmds: - log(DEBUG, f'{self.log_name}: Running {pretty_cmd(cmd['cmd'], wd)}') - ret = await __run(**cmd) - return ret + await self.open() + try: + for cmd in cmds: + log(DEBUG, f'{self.log_name}: Running {pretty_cmd(cmd['cmd'], wd)}') + ret = await __run(**cmd) + return ret + finally: + await self.close() except: if throw: raise