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)
|
||||
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:
|
||||
from .ExecContext import ExecContext
|
||||
src: ExecContext|None = None
|
||||
dst: ExecContext|None = None
|
||||
def __ec(uri: str) -> tuple[ExecContext, str]:
|
||||
return ExecContext.create(uri), urlparse(uri).path
|
||||
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]:
|
||||
if not isinstance(src_uri, str):
|
||||
ret: list[str] = []
|
||||
for uri in src_uri: # TODO: Group identical netlocs into one CopyContext
|
||||
rr = ret.append(await copy(uri, dst, owner, group, mode, throw))
|
||||
if isinstance(rr, Exception):
|
||||
return rr
|
||||
return ret
|
||||
from .CopyContext import CopyContext
|
||||
async with CopyContext(src_uri, dst) as ctx:
|
||||
try:
|
||||
src, src_path = __ec(src_uri)
|
||||
content = (await src.get(src_path, throw=True)).stdout
|
||||
dst, dst_path = __ec(dst_uri)
|
||||
if await dst.is_dir(path):
|
||||
dst_path += os.path.basename(src_path)
|
||||
await dst.put(path=dst_path, content=content, owner=owner, group=group, mode=mode, throw=True)
|
||||
content = (await ctx.src.get(ctx.src.root, throw=True)).stdout
|
||||
dst_path = ctx.dst.root
|
||||
if await ctx.dst.is_dir(ctx.dst.root):
|
||||
dst_path += '/' + os.path.basename(src_uri)
|
||||
await ctx.dst.put(path=dst_path, content=content, owner=owner, group=group, mode=mode, throw=True)
|
||||
return dst_path
|
||||
except Exception as e:
|
||||
if throw:
|
||||
raise
|
||||
log(ERR, f'Failed to copy {src_uri} -> {dst_uri} ({str(e)})')
|
||||
log(ERR, f'Failed to copy {src_uri} -> {dst} ({str(e)})')
|
||||
return e
|
||||
finally:
|
||||
for ec in [src, dst]:
|
||||
if ec is not None:
|
||||
await ec.close()
|
||||
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
|
||||
url_user = None if url is None else Uri(url).username
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue