From aa929502b5878f0f550ef71f123da6f13921d482 Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Tue, 24 Dec 2024 21:30:02 +0100 Subject: [PATCH] init --- .envrc | 9 ++ README.md | 5 + devenv.nix | 14 +++ flake.lock | 307 ++++++++++++++++++++++++++++++++++++++++++++++++++++ flake.nix | 50 +++++++++ package.nix | 13 +++ taft | 98 +++++++++++++++++ 7 files changed, 496 insertions(+) create mode 100644 .envrc create mode 100644 README.md create mode 100644 devenv.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 package.nix create mode 100644 taft diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..cb982f0 --- /dev/null +++ b/.envrc @@ -0,0 +1,9 @@ +watch_file flake.nix +watch_file flake.lock + +DEVENV_ROOT_FILE="$(mktemp)" +printf %s "$PWD" > "$DEVENV_ROOT_FILE" +if ! use flake . --override-input devenv-root "file+file://$DEVENV_ROOT_FILE" +then + echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 +fi diff --git a/README.md b/README.md new file mode 100644 index 0000000..12326d9 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# taft — Totally Adequate File Transfer + +A simple wrapper around nc(1) and tar(1). + +*Named after William Howard Taft, [America's greatest president by volume](https://idlewords.com/talks/website_obesity.htm)*. diff --git a/devenv.nix b/devenv.nix new file mode 100644 index 0000000..67c93b5 --- /dev/null +++ b/devenv.nix @@ -0,0 +1,14 @@ +{ + pre-commit.hooks = { + # Nix + alejandra.enable = true; + deadnix.enable = true; + statix.enable = true; + + # Flakes + flake-checker.enable = true; + + # Shell + shellcheck.enable = true; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..0f62628 --- /dev/null +++ b/flake.lock @@ -0,0 +1,307 @@ +{ + "nodes": { + "cachix": { + "inputs": { + "devenv": [ + "devenv" + ], + "flake-compat": [ + "devenv" + ], + "git-hooks": [ + "devenv" + ], + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1728672398, + "narHash": "sha256-KxuGSoVUFnQLB2ZcYODW7AVPAh9JqRlD5BrfsC/Q4qs=", + "owner": "cachix", + "repo": "cachix", + "rev": "aac51f698309fd0f381149214b7eee213c66ef0a", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "latest", + "repo": "cachix", + "type": "github" + } + }, + "devenv": { + "inputs": { + "cachix": "cachix", + "flake-compat": "flake-compat", + "git-hooks": "git-hooks", + "nix": "nix", + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1734951937, + "narHash": "sha256-oYitbnWHQIEmd5e/e8yvuy6T41zVVe/V8868nOnwNfk=", + "owner": "cachix", + "repo": "devenv", + "rev": "4b8677f62022e6a235cc4e93a6bbc3d57b77817f", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "devenv-root": { + "flake": false, + "locked": { + "narHash": "sha256-d6xi4mKdjkX2JFicDIv5niSzpyI0m/Hnm8GGAIU04kY=", + "type": "file", + "url": "file:///dev/null" + }, + "original": { + "type": "file", + "url": "file:///dev/null" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "devenv", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1733312601, + "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "git-hooks": { + "inputs": { + "flake-compat": [ + "devenv" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-stable": [ + "devenv" + ] + }, + "locked": { + "lastModified": 1730302582, + "narHash": "sha256-W1MIJpADXQCgosJZT8qBYLRuZls2KSiKdpnTVdKBuvU=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "af8a16fe5c264f5e9e18bcee2859b40a656876cf", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "devenv", + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "libgit2": { + "flake": false, + "locked": { + "lastModified": 1697646580, + "narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=", + "owner": "libgit2", + "repo": "libgit2", + "rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5", + "type": "github" + }, + "original": { + "owner": "libgit2", + "repo": "libgit2", + "type": "github" + } + }, + "nix": { + "inputs": { + "flake-compat": [ + "devenv" + ], + "flake-parts": "flake-parts", + "libgit2": "libgit2", + "nixpkgs": "nixpkgs_2", + "nixpkgs-23-11": [ + "devenv" + ], + "nixpkgs-regression": [ + "devenv" + ], + "pre-commit-hooks": [ + "devenv" + ] + }, + "locked": { + "lastModified": 1727438425, + "narHash": "sha256-X8ES7I1cfNhR9oKp06F6ir4Np70WGZU5sfCOuNBEwMg=", + "owner": "domenkozar", + "repo": "nix", + "rev": "f6c5ae4c1b2e411e6b1e6a8181cc84363d6a7546", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "devenv-2.24", + "repo": "nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1730531603, + "narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7ffd9ae656aec493492b44d0ddfb28e79a1ea25d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1733096140, + "narHash": "sha256-1qRH7uAUsyQI7R1Uwl4T+XvdNv778H0Nb5njNrqvylY=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1717432640, + "narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "88269ab3044128b7c2f4c7d68448b2fb50456870", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1716977621, + "narHash": "sha256-Q1UQzYcMJH4RscmpTkjlgqQDX5yi1tZL0O345Ri6vXQ=", + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "4267e705586473d3e5c8d50299e71503f16a6fb6", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1734649271, + "narHash": "sha256-4EVBRhOjMDuGtMaofAIqzJbg4Ql7Ai0PSeuVZTHjyKQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d70bd19e0a38ad4790d3913bf08fcbfc9eeca507", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "devenv-root": "devenv-root", + "flake-parts": "flake-parts_2", + "nixpkgs": "nixpkgs_4" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..c54f336 --- /dev/null +++ b/flake.nix @@ -0,0 +1,50 @@ +{ + description = "Fast file transfer utility"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + flake-parts.url = "github:hercules-ci/flake-parts"; + + devenv-root = { + url = "file+file:///dev/null"; + flake = false; + }; + devenv.url = "github:cachix/devenv"; + }; + + outputs = { + self, + nixpkgs, + flake-parts, + ... + } @ inputs: + flake-parts.lib.mkFlake {inherit inputs;} { + imports = [ + inputs.devenv.flakeModule + ]; + + systems = nixpkgs.lib.systems.flakeExposed; + + perSystem = { + pkgs, + inputs', + ... + }: { + devenv.shells.default = { + devenv.root = let + devenvRootFileContent = builtins.readFile inputs.devenv-root.outPath; + in + pkgs.lib.mkIf (devenvRootFileContent != "") devenvRootFileContent; + + name = "taft"; + + imports = [ + ./devenv.nix + ]; + }; + + packages.default = pkgs.callPackage ./package.nix {}; + }; + }; +} diff --git a/package.nix b/package.nix new file mode 100644 index 0000000..366b495 --- /dev/null +++ b/package.nix @@ -0,0 +1,13 @@ +{ + writeShellApplication, + gnutar, + netcat-openbsd, +}: +writeShellApplication { + name = "taft"; + runtimeInputs = [ + gnutar + netcat-openbsd + ]; + text = builtins.readFile ./taft; +} diff --git a/taft b/taft new file mode 100644 index 0000000..e167e35 --- /dev/null +++ b/taft @@ -0,0 +1,98 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +progname="$0" + +error() { + for line in "$@"; do + printf '%s\n' "$progname: $line" 1>&2 + done + + exit 1 +} + +opts=$(getopt --options p:P:vc: --longoptions=port:,path:,verbose,compress: --name "$progname" -- "$@") + +eval set -- "$opts" + +port=1337 +path=. +tarflags=() +ncflags=() +while true; do + case "$1" in + (-p | --port) + port=$2 + shift 2 + ;; + (-P | --path) + path=$2 + shift 2 + ;; + (-v | --verbose) + tarflags+=(--verbose) + ncflags+=(-v) + shift + ;; + (-c | --compress) + algo=$2 + case $algo in + (none) + ;; + (xz) + tarflags+=(--xz) + ;; + (zstd) + tarflags+=(--zstd) + ;; + (*) + error 'invalid compression algorithm' + ;; + esac + shift 2 + ;; + (--) + shift + break + ;; + esac +done + +if [[ $# == 0 ]]; then + error 'a subcommand is required' +fi + +subcommand=$1 + +case $subcommand in + (send) + shift + + if [[ $# -lt 1 ]]; then + error 'the destination address is required' + fi + + if [[ $# -gt 1 ]]; then + error 'too many arguments' + fi + + dest=$1 + + tar --create "${tarflags[@]}" -- "$path" | nc -q 1 "${ncflags[@]}" -- "$dest" "$port" + ;; + (recv | receive) + shift + + if [[ $# -gt 0 ]]; then + error 'too many arguments' + fi + + nc -q 1 -l -p "$port" "${ncflags[@]}" | tar --extract "${tarflags[@]}" + ;; + (*) + error 'invalid subcommand' + ;; +esac