lib.ExecContext.close(): Add method

Add ExecContext.close() as a hook to clean up async resources living
longer than an ExecContext method call.

Also, implement __aenter__() and __aexit__(), to allow using
ExecContext as context manager.  close() is invoked it goes out of
scope.

Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
Jan Lindemann 2026-04-15 21:00:58 +02:00
commit 1214451c15
2 changed files with 29 additions and 10 deletions

View file

@ -32,16 +32,23 @@ class CmdListRepos(Cmd): # export
match url.scheme:
case 'ssh':
if re.match(r'ssh://.*git\.janware\.com/', args.base_url):
from jw.pkg.lib.ec.SSHClient import ssh_client
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
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:
ssh.close()
case 'https':
from jw.pkg.lib.ExecContext import InputMode
cmd_input = InputMode.NonInteractive

View file

@ -171,6 +171,12 @@ class ExecContext(abc.ABC):
self.__verbose_default = verbose_default
assert verbose_default is not None
async def __aenter__(self):
return self
async def __aexit__(self, exc_type, exc, tb):
await self.close()
@property
def uri(self) -> str:
return self.__uri
@ -402,6 +408,12 @@ class ExecContext(abc.ABC):
return await self._put(content, path, wd=wd, throw=throw, verbose=verbose,
title=title, owner=owner, group=group, mode=mode)
async def _close(self) -> None:
pass
async def close(self) -> None:
await self._close()
@classmethod
def create(cls, uri: str, *args, **kwargs) -> Self:
tokens = re.split(r'://', uri)