lib.util.copy(): Tolerate list[str] and FileContext args
Modify copy():
- Allow the source argument src_uri to be a list of URIs, in which case copy should return a list of paths instead of one path- Change the dst_uri parameter to dst, signalling that it now also tolerates a FileContext- Use the CopyContext class to manage the source and target FileContext instancesSigned-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
d9746cd20b
commit
5837d10a1c
1 changed files with 23 additions and 23 deletions
|
|
@ -101,29 +101,29 @@ async def run_sudo(cmd: list[str], *args, interactive: bool=True, ec: ExecContex
|
||||||
ec = Local(interactive=interactive)
|
ec = Local(interactive=interactive)
|
||||||
return await ec.sudo(cmd, *args, **kwargs)
|
return await ec.sudo(cmd, *args, **kwargs)
|
||||||
|
|
||||||
async def copy(src_uri: str, dst_uri: str, owner: str|None=None, group: str|None=None, mode: int|None=None, throw=True) -> Exception|str:
|
async def copy(src_uri: str|Iterable[str], dst: str|FileContext, owner: str|None=None, group: str|None=None, mode: int|None=None, throw=True) -> Exception|str|list[str]:
|
||||||
from .ExecContext import ExecContext
|
if not isinstance(src_uri, str):
|
||||||
src: ExecContext|None = None
|
ret: list[str] = []
|
||||||
dst: ExecContext|None = None
|
for uri in src_uri: # TODO: Group identical netlocs into one CopyContext
|
||||||
def __ec(uri: str) -> tuple[ExecContext, str]:
|
rr = ret.append(await copy(uri, dst, owner, group, mode, throw))
|
||||||
return ExecContext.create(uri), urlparse(uri).path
|
if isinstance(rr, Exception):
|
||||||
try:
|
return rr
|
||||||
src, src_path = __ec(src_uri)
|
return ret
|
||||||
content = (await src.get(src_path, throw=True)).stdout
|
from .CopyContext import CopyContext
|
||||||
dst, dst_path = __ec(dst_uri)
|
async with CopyContext(src_uri, dst) as ctx:
|
||||||
if await dst.is_dir(path):
|
try:
|
||||||
dst_path += os.path.basename(src_path)
|
content = (await ctx.src.get(ctx.src.root, throw=True)).stdout
|
||||||
await dst.put(path=dst_path, content=content, owner=owner, group=group, mode=mode, throw=True)
|
dst_path = ctx.dst.root
|
||||||
except Exception as e:
|
if await ctx.dst.is_dir(ctx.dst.root):
|
||||||
if throw:
|
dst_path += '/' + os.path.basename(src_uri)
|
||||||
raise
|
await ctx.dst.put(path=dst_path, content=content, owner=owner, group=group, mode=mode, throw=True)
|
||||||
log(ERR, f'Failed to copy {src_uri} -> {dst_uri} ({str(e)})')
|
return dst_path
|
||||||
return e
|
except Exception as e:
|
||||||
finally:
|
if throw:
|
||||||
for ec in [src, dst]:
|
raise
|
||||||
if ec is not None:
|
log(ERR, f'Failed to copy {src_uri} -> {dst} ({str(e)})')
|
||||||
await ec.close()
|
return e
|
||||||
return dst_path
|
assert False, 'Unreachable code'
|
||||||
|
|
||||||
async def get_username(args: Namespace|None=None, url: str|None=None, askpass_env: list[str]=[], ec: ExecContext|None=None) -> str: # export
|
async def get_username(args: Namespace|None=None, url: str|None=None, askpass_env: list[str]=[], ec: ExecContext|None=None) -> str: # export
|
||||||
url_user = None if url is None else Uri(url).username
|
url_user = None if url is None else Uri(url).username
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue