Add write block in file functionality
This commit is contained in:
parent
aed0889c43
commit
e6df07e744
@ -39,6 +39,7 @@ from scone.default.utensils.basic_utensils import (
|
||||
HashFile,
|
||||
MakeDirectory,
|
||||
Stat,
|
||||
WriteBlockInFile,
|
||||
WriteFile,
|
||||
)
|
||||
from scone.head.head import Head
|
||||
@ -358,3 +359,87 @@ class Supermarket(Recipe):
|
||||
with open(dest_path + ".txt", "w") as fout:
|
||||
# leave a note so we can find out what this is if we need to.
|
||||
fout.write(note)
|
||||
|
||||
|
||||
class FridgeBlockInFile(Recipe):
|
||||
"""
|
||||
Declares that a file should be copied from the head to the sous.
|
||||
"""
|
||||
|
||||
_NAME = "fridge-block-in-file"
|
||||
|
||||
def __init__(self, recipe_context: RecipeContext, args: dict, head: Head):
|
||||
super().__init__(recipe_context, args, head)
|
||||
|
||||
search = fridge_steps.search_in_fridge(head, args["src"])
|
||||
if search is None:
|
||||
raise ValueError(f"Cannot find {args['src']} in the fridge.")
|
||||
|
||||
desugared_src, fp = search
|
||||
|
||||
unextended_path_str, meta = fridge_steps.decode_fridge_extension(str(fp))
|
||||
unextended_path = Path(unextended_path_str)
|
||||
|
||||
dest = args["dest"]
|
||||
if not isinstance(dest, str):
|
||||
raise ValueError("No destination provided or wrong type.")
|
||||
|
||||
if dest.endswith("/"):
|
||||
self.destination: Path = Path(args["dest"], unextended_path.parts[-1])
|
||||
else:
|
||||
self.destination = Path(args["dest"])
|
||||
|
||||
mode = args.get("mode", DEFAULT_MODE_FILE)
|
||||
assert isinstance(mode, str) or isinstance(mode, int)
|
||||
|
||||
self.fridge_path: str = check_type(args["src"], str)
|
||||
self.real_path: Path = fp
|
||||
self.fridge_meta: FridgeMetadata = meta
|
||||
self.mode = parse_mode(mode, directory=False)
|
||||
|
||||
self.targ_user = check_type_opt(args.get("owner"), str)
|
||||
self.targ_group = check_type_opt(args.get("group"), str)
|
||||
|
||||
self._desugared_src = desugared_src
|
||||
|
||||
self.marker_line_prefix = check_type_opt(
|
||||
args.get("marker_line_prefix", "# "), str
|
||||
)
|
||||
self.marker_name = check_type_opt(args.get("marker_name"), str)
|
||||
|
||||
def prepare(self, preparation: Preparation, head: Head) -> None:
|
||||
super().prepare(preparation, head)
|
||||
preparation.provides("file", str(self.destination))
|
||||
preparation.needs("directory", str(self.destination.parent))
|
||||
|
||||
if self.targ_user:
|
||||
preparation.needs("os-user", self.targ_user)
|
||||
|
||||
if self.targ_group:
|
||||
preparation.needs("os-group", self.targ_group)
|
||||
|
||||
async def cook(self, k: Kitchen) -> None:
|
||||
data = await load_and_transform(
|
||||
k, self.fridge_meta, self.real_path, self.recipe_context.variables
|
||||
)
|
||||
dest_str = str(self.destination)
|
||||
chan = await k.ut0(
|
||||
WriteBlockInFile(
|
||||
dest_str,
|
||||
self.mode,
|
||||
self.marker_line_prefix,
|
||||
self.marker_name,
|
||||
data.decode(),
|
||||
)
|
||||
)
|
||||
if await chan.recv() != "OK":
|
||||
raise RuntimeError(f"WriteBlockInFile failed to {self.destination}")
|
||||
|
||||
if self.targ_user or self.targ_group:
|
||||
await k.ut0(Chown(dest_str, self.targ_user, self.targ_group))
|
||||
|
||||
# this is the wrong thing
|
||||
# hash_of_data = sha256_bytes(data)
|
||||
# k.get_dependency_tracker().register_remote_file(dest_str, hash_of_data)
|
||||
|
||||
k.get_dependency_tracker().register_fridge_file(self._desugared_src)
|
||||
|
||||
@ -52,6 +52,43 @@ class WriteFile(Utensil):
|
||||
await channel.send("OK")
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
class WriteBlockInFile(Utensil):
|
||||
path: str
|
||||
mode: int
|
||||
marker_line_prefix: str
|
||||
marker_name: str
|
||||
data: str
|
||||
|
||||
async def execute(self, channel: Channel, worktop):
|
||||
start_marker = self.marker_line_prefix + "BEGIN " + self.marker_name + "\n"
|
||||
end_marker = self.marker_line_prefix + "END " + self.marker_name + "\n"
|
||||
|
||||
if os.path.exists(self.path):
|
||||
with open(self.path, "r") as fin:
|
||||
file_lines = fin.readlines()
|
||||
|
||||
try:
|
||||
start_index = file_lines.index(start_marker)
|
||||
end_index = file_lines.index(end_marker)
|
||||
file_lines = file_lines[:start_index] + file_lines[end_index + 1 :]
|
||||
except IndexError:
|
||||
pass
|
||||
else:
|
||||
file_lines = []
|
||||
|
||||
file_lines.append(start_marker + self.data + end_marker)
|
||||
|
||||
oldumask = os.umask(0)
|
||||
fdnum = os.open(self.path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, self.mode)
|
||||
os.umask(oldumask)
|
||||
|
||||
with open(fdnum, "w") as file:
|
||||
file.writelines(file_lines)
|
||||
|
||||
await channel.send("OK")
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
class MakeDirectory(Utensil):
|
||||
path: str
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user