diff options
author | Profpatsch <mail@profpatsch.de> | 2022-09-12 22:07:20 +0200 |
---|---|---|
committer | Profpatsch <mail@profpatsch.de> | 2022-11-04 18:14:33 +0100 |
commit | 3b0b6d1b612e85b7aebcb089e8c59b8614c21a05 (patch) | |
tree | 56c02a836a2985c9426b8a3415de9a17ecec03a3 | |
parent | 484bce31b7cf3541e01835545453c7545d20d043 (diff) |
tree-sitter/update: move atomically-write to python
It should do the same thing, but take with a grain of salt maybe.
-rw-r--r-- | pkgs/development/tools/parsing/tree-sitter/update.nix | 25 | ||||
-rw-r--r-- | pkgs/development/tools/parsing/tree-sitter/update_impl.py | 62 |
2 files changed, 34 insertions, 53 deletions
diff --git a/pkgs/development/tools/parsing/tree-sitter/update.nix b/pkgs/development/tools/parsing/tree-sitter/update.nix index 055f42dc720a3..78b07c59d44e5 100644 --- a/pkgs/development/tools/parsing/tree-sitter/update.nix +++ b/pkgs/development/tools/parsing/tree-sitter/update.nix @@ -392,7 +392,6 @@ let binaries = { curl = "${curl}/bin/curl"; nix-prefetch-git = "${nix-prefetch-git}/bin/nix-prefetch-git"; - inherit atomically-write; printf = "${coreutils}/bin/printf"; }; inherit @@ -460,30 +459,6 @@ let })" ''; - # Atomically write a file (just `>` redirection in bash - # empties a file even if the command crashes). - # - # Maybe there is an existing tool for that? - # But it’s easy enough to implement. - # - # Example: - # atomically-write - # ./to - # echo "foo" - # - # will atomically write the string "foo" into ./to - atomically-write = writeShellScript "atomically-write" '' - set -e - to=$1 - shift - # assumes that the tempfile is on the same file system, (or in memory) - # for the `mv` at the end to be more-or-less atomic. - tmp=$(${coreutils}/bin/mktemp -d) - trap 'rm -r "$tmp"' EXIT - "$@" \ - > "$tmp/out" - mv "$tmp/out" "$to" - ''; in update-all-grammars diff --git a/pkgs/development/tools/parsing/tree-sitter/update_impl.py b/pkgs/development/tools/parsing/tree-sitter/update_impl.py index e9113c1ebd31b..92db75ef6502b 100644 --- a/pkgs/development/tools/parsing/tree-sitter/update_impl.py +++ b/pkgs/development/tools/parsing/tree-sitter/update_impl.py @@ -4,6 +4,7 @@ import subprocess as sub import os import sys from typing import Iterator, Any, Literal, TypedDict +from tempfile import NamedTemporaryFile debug: bool = True if os.environ.get("DEBUG", False) else False Bin = str @@ -20,6 +21,23 @@ def log(msg: str) -> None: print(msg, file=sys.stderr) +def atomically_write(file_path: str, content: bytes) -> None: + """atomically write the content into `file_path`""" + with NamedTemporaryFile( + # write to the parent dir, so that it’s guaranteed to be on the same filesystem + dir=os.path.dirname(file_path), + delete=False + ) as tmp: + try: + tmp.write(content) + os.rename( + src=tmp.name, + dst=file_path + ) + except Exception: + os.unlink(tmp.name) + + def curl_github_args(token: str | None, url: str) -> Args: """Query the github API via curl""" yield bins["curl"] @@ -69,12 +87,6 @@ def run_cmd(args: Args) -> bytes: Dir = str -def atomically_write_args(to: Dir, cmd: Args) -> Args: - yield bins["atomically-write"] - yield to - yield from cmd - - def fetchRepo() -> None: """fetch the given repo and write its nix-prefetch output to the corresponding grammar json file""" match jsonArg: @@ -104,19 +116,18 @@ def fetchRepo() -> None: log(f"Fetching latest release ({release}) of {orga}/{repo} …") res = run_cmd( - atomically_write_args( - os.path.join( - outputDir, - f"{nixRepoAttrName}.json" - ), - nix_prefetch_git_args( - url=f"https://github.com/{quote(orga)}/{quote(repo)}", - version_rev=release - - ) + nix_prefetch_git_args( + url=f"https://github.com/{quote(orga)}/{quote(repo)}", + version_rev=release ) ) - sys.stdout.buffer.write(res) + atomically_write( + file_path=os.path.join( + outputDir, + f"{nixRepoAttrName}.json" + ), + content=res + ) case _: sys.exit("input json must have `orga` and `repo` keys") @@ -184,18 +195,13 @@ def printAllGrammarsNixFile() -> None: yield "}" yield "" - out = run_cmd( - # TODO: implement atomic file write in python - atomically_write_args( - os.path.join( - outputDir, - "default.nix" - ), - iter([bins["printf"], "%s", "\n".join(list(file()))]) - ) + atomically_write( + file_path=os.path.join( + outputDir, + "default.nix" + ), + content="\n".join(file()).encode() ) - if out: - log(str(out)) match mode: |