commit 15db339eec0f1c610ceb56196d203eb3b5798a2a
parent 238d7147e6e91099038ea347aa40f574b499c69d
Author: mtmn <miro@haravara.org>
Date: Thu, 14 May 2026 17:59:21 +0200
chore: remove backup
Diffstat:
5 files changed, 0 insertions(+), 271 deletions(-)
diff --git a/README.md b/README.md
@@ -4,7 +4,6 @@ Various tools I have been using throughout the years.
| tool | description |
|---|---|
-| [backup](backup/) | terminal backup orchestrator |
| [bandeno](bandeno/) | Bandcamp RSS feed proxy |
| [diffamer](diffamer/) | line-file syncer with rsync and coloured diff |
| [diggah](diggah/) | find files modified within a time range, locally or over SSH |
diff --git a/backup/.gitignore b/backup/.gitignore
@@ -1 +0,0 @@
-dist-*
diff --git a/backup/README.md b/backup/README.md
@@ -1,33 +0,0 @@
-# backup
-
-A backup orchestrator that commits and pushes git repos, snapshots directories with [plakar](https://github.com/PlakarKorp/plakar), and syncs files to S3 via `aws s3 sync`.
-
-## Building
-
-```sh
-cabal build
-```
-
-## Usage
-
-```sh
-backup [-t <target>] [--push] [--quiet] [--list]
-```
-
-### Targets
-
-| Target | Description |
-|--------|-------------|
-| `git` | Commit all git repos (push with `--push`) |
-| `plakar` | Snapshot to both plakar repos (`s3` and `hoo`) |
-| `mobius` | Sync all mobius targets to S3 |
-| `<backend>:<name>[:<sub>]` | Run a single target, e.g. `git:nix`, `plakar:s3`, `plakar:hoo`, `plakar:s3:src`, `mobius:www` |
-
-### Options
-
-| Flag | Description |
-|------|-------------|
-| `-p`, `--push` | Push after committing (for git targets) |
-| `-q`, `--quiet` | Suppress command output (default: stream output) |
-| `-l`, `--list` | List all configured backup targets and exit |
-| `-h`, `--help` | Show help |
diff --git a/backup/backup.cabal b/backup/backup.cabal
@@ -1,18 +0,0 @@
-cabal-version: 3.0
-name: backup
-version: 0.1.0
-build-type: Simple
-
-executable backup
- main-is: backup.hs
- hs-source-dirs: .
- default-language: GHC2024
- default-extensions: OverloadedStrings
- ghc-options: -Wall -O2
-
- build-depends:
- , base >= 4.14 && < 5
- , containers >= 0.6 && < 0.8
- , text >= 2.1
- , time >= 1.9 && < 1.15
- , turtle >= 1.6.2
diff --git a/backup/backup.hs b/backup/backup.hs
@@ -1,218 +0,0 @@
-module Main where
-
-import Control.Monad (forM_)
-import Data.List (sort)
-import Data.Map.Strict (Map)
-import Data.Map.Strict qualified as Map
-import Data.Text qualified as T
-import Data.Time (defaultTimeLocale, formatTime, getCurrentTime)
-import System.Environment (getArgs, withArgs)
-import Turtle hiding (sort)
-
-data Config = Config
- { cfgHome :: Text
- , cfgGitDirs :: Map Text Text
- , cfgPlakarDirs :: Map Text Text
- , cfgMobiusDirs :: Map Text Text
- }
-
-mkConfig :: Text -> Config
-mkConfig h =
- Config
- { cfgHome = h
- , cfgGitDirs =
- Map.fromList
- [ ("mpd", h <> "/.config/mpd")
- , ("nix", h <> "/src/sr.ht/nix")
- , ("nota", h <> "/misc/notes/nota")
- , ("pass", h <> "/.password-store")
- , ("releases", h <> "/src/haravara.org/releases")
- , ("bandcamp", h <> "/misc/music/backlog/_todo")
- ]
- , cfgPlakarDirs =
- Map.fromList
- [ ("src", h <> "/src")
- , ("misc", h <> "/misc")
- , ("local", h <> "/.local")
- , ("config", h <> "/.config")
- ]
- , cfgMobiusDirs =
- Map.fromList
- [ ("www", h <> "/misc/www")
- , ("notes", h <> "/misc/notes")
- , ("books", h <> "/misc/books")
- , ("docs", h <> "/misc/docs")
- , ("mobius", h <> "/misc/mobius")
- ]
- }
-
--- Logging
-
-ts :: IO Text
-ts =
- T.pack . formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%S%z"
- <$> getCurrentTime
-
-logMsg :: Text -> IO ()
-logMsg msg = ts >>= \t -> echo (unsafeTextToLine $ "[" <> t <> "]: " <> msg)
-
-fatal :: Text -> IO a
-fatal msg = do
- t <- ts
- err (unsafeTextToLine $ "[" <> t <> "]: " <> msg)
- exit (ExitFailure 1)
-
--- Process helpers
-
-run :: Bool -> Text -> [Text] -> IO ExitCode
-run verbose cmd args
- | verbose = proc cmd args stdin
- | otherwise = fst <$> procStrict cmd args empty
-
-gitPrefix :: Text -> [Text]
-gitPrefix dir = ["--git-dir=" <> dir <> "/.git", "--work-tree=" <> dir]
-
-git :: Bool -> Text -> [Text] -> IO ExitCode
-git verbose dir args = run verbose "git" (gitPrefix dir <> args)
-
-gitCapture :: Text -> [Text] -> IO (ExitCode, Text)
-gitCapture dir args = procStrict "git" (gitPrefix dir <> args) empty
-
-ok :: ExitCode -> Bool
-ok = (== ExitSuccess)
-
-expect :: Text -> ExitCode -> IO ()
-expect msg ec = unless (ok ec) $ fatal msg
-
--- Core logic
-
-syncRepos :: Text -> Bool -> IO ()
-syncRepos dir push = do
- git False dir ["add", "-A"]
- >>= expect ("Failed to stage changes in " <> dir)
-
- diffEc <- git False dir ["diff", "--cached", "--quiet"]
- if ok diffEc
- then logMsg $ "Nothing to commit in " <> dir
- else do
- (changedEc, changed) <-
- gitCapture dir ["diff", "--cached", "--name-only"]
- expect ("Failed to list staged changes in " <> dir) changedEc
- git True dir ["commit", "-m", T.unwords . T.lines $ changed]
- >>= expect ("Failed to commit changes in " <> dir)
- logMsg $ "Committed changes in " <> dir
-
- when push $ do
- logMsg $ "Pushing changes from " <> dir
- git True dir ["push"] >>= expect ("Failed to push changes from " <> dir)
- logMsg $ "Done pushing " <> dir
-
-runPlakar :: Bool -> Text -> [Text] -> Text -> IO ExitCode
-runPlakar verbose repo ignores dir =
- run verbose "plakar" $
- ["at", repo, "backup"]
- <> concatMap (\p -> ["--ignore", p]) ignores
- <> [dir]
-
-s3Ignores :: [Text]
-s3Ignores = ["**/.local/share/containers*", "**/Steam*", "**/mnt*", "**/.git*"]
-
-hooIgnores :: [Text]
-hooIgnores = ["**/.cache*", "**/Steam*", "**/mnt*", "**/.git*", "**/.nix*"]
-
-plakarS3 :: Bool -> Text -> Text -> IO ()
-plakarS3 verbose name dir = do
- logMsg $ "Syncing plakar/s3/" <> name <> " from " <> dir
- runPlakar verbose "@estri" s3Ignores dir
- >>= expect ("plakar @s3 failed for " <> name)
- logMsg $ "Done plakar/s3/" <> name
-
-plakarHoo :: Bool -> Text -> IO ()
-plakarHoo verbose dir = do
- logMsg $ "Syncing plakar/hoo from " <> dir
- runPlakar verbose "@hoo" hooIgnores dir
- >>= expect "plakar @hoo failed"
- logMsg "Done plakar/hoo"
-
-mobiusFilters :: Text -> [Text]
-mobiusFilters "www" =
- ["--exclude", "*", "--include", "*.html", "--include", "*.md"]
-mobiusFilters _ = ["--exclude", "*/.git/*"]
-
-mobiusSync :: Bool -> Text -> Text -> IO ()
-mobiusSync verbose name dir = do
- logMsg $ "Syncing mobius/" <> name <> " from " <> dir
- let args =
- ["s3", "sync"]
- <> mobiusFilters name
- <> ["--no-follow-symlinks", dir, "s3://mobius/" <> name]
- run verbose "aws" args
- >>= expect ("aws s3 sync failed for " <> name)
- logMsg $ "Done mobius/" <> name
-
-listTargets :: Config -> IO ()
-listTargets cfg = do
- let listKeys indent =
- mapM_ (echo . unsafeTextToLine . (indent <>)) . sort . Map.keys
- echo "git"
- listKeys " " (cfgGitDirs cfg)
- echo "plakar"
- echo " hoo"
- echo " s3"
- listKeys " " (cfgPlakarDirs cfg)
- echo "mobius"
- listKeys " " (cfgMobiusDirs cfg)
-
-backup :: Config -> Text -> Bool -> Bool -> IO ()
-backup cfg target push verbose = case T.splitOn ":" target of
- ["git"] ->
- forM_ (Map.toList (cfgGitDirs cfg)) $ \(name, dir) ->
- logMsg name >> syncRepos dir push
- ["plakar"] -> do
- forM_ (Map.toList (cfgPlakarDirs cfg)) $ uncurry (plakarS3 verbose)
- plakarHoo verbose (cfgHome cfg)
- ["mobius"] ->
- forM_ (Map.toList (cfgMobiusDirs cfg)) $ uncurry (mobiusSync verbose)
- ["git", name] -> case Map.lookup name (cfgGitDirs cfg) of
- Just dir -> syncRepos dir push
- Nothing -> fatal $ "Unknown git target: " <> name
- ["plakar", "s3"] ->
- forM_ (Map.toList (cfgPlakarDirs cfg)) $ uncurry (plakarS3 verbose)
- ["plakar", "hoo"] -> plakarHoo verbose (cfgHome cfg)
- ["plakar", "s3", name] -> case Map.lookup name (cfgPlakarDirs cfg) of
- Just dir -> plakarS3 verbose name dir
- Nothing -> fatal $ "Unknown plakar/s3 dir: " <> name
- ["mobius", name] -> case Map.lookup name (cfgMobiusDirs cfg) of
- Just dir -> mobiusSync verbose name dir
- Nothing -> fatal $ "Unknown mobius target: " <> name
- _ -> fatal $ "Unknown target: " <> target
-
-data Args = Args
- { argTarget :: Maybe Text
- , argPush :: Bool
- , argQuiet :: Bool
- , argList :: Bool
- }
-
-argsParser :: Parser Args
-argsParser =
- let targetHelp = "git, plakar, mobius, <backend>:<name>[:<sub>]"
- in Args
- <$> optional (optText "target" 't' targetHelp)
- <*> switch "push" 'p' "Push changes after commit"
- <*> switch "quiet" 'q' "Suppress command output"
- <*> switch "list" 'l' "List all configured backup targets"
-
-main :: IO ()
-main = do
- rawArgs <- getArgs
- let effArgs = if null rawArgs then ["--help"] else rawArgs
- Args mtarget pushFlag quietFlag listFlag <-
- withArgs effArgs $ options "" argsParser
- h <- need "HOME" >>= maybe (fatal "HOME not set") pure
- let cfg = mkConfig h
- if listFlag
- then listTargets cfg
- else case mtarget of
- Just target -> backup cfg target pushFlag (not quietFlag)
- Nothing -> fatal "no target given (use --list to list targets)"