summary history branches tags files
commit:373eea9298fbd35d29f9c647fb99a72c52a49e0f
author:avh4
committer:avh4
date:Sun Jan 22 12:54:48 2023 -0800
parents:30b046520fe69011c0ac2a1e6fbb38dbd4a82034
Parse nix path-info output
diff --git a/shell.nix b/shell.nix
line changes: +1/-1
index 06a3cf1..91dc5fd
--- a/shell.nix
+++ b/shell.nix
@@ -6,7 +6,7 @@ let
 
 in pkgs.mkShell {
   nativeBuildInputs = [
-    (haskellPackages.ghcWithPackages (p: with p; [ typed-process ]))
+    (haskellPackages.ghcWithPackages (p: with p; [ aeson typed-process ]))
     haskellPackages.ghcid
     haskellPackages.haskell-language-server
 

diff --git a/sizer.hs b/sizer.hs
line changes: +41/-2
index edb1b2a..e113869
--- a/sizer.hs
+++ b/sizer.hs
@@ -1,8 +1,47 @@
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
 
-import System.Process.Typed (runProcess_)
+import Data.Aeson qualified as Aeson
+import Data.Aeson (ToJSON(..), FromJSON(..), Value(..), (.:), (.=), object)
+import Data.Aeson.Types (prependFailure, typeMismatch)
+import Data.Text (Text)
+import GHC.Base (quotInt)
+import System.Process.Typed (readProcess_, proc)
 
 main :: IO ()
 main = do
-  runProcess_ "false"
+  let gcroot = "per-user/avh4/current-home"
+  (json, _) <- readProcess_ $ proc "nix" [ "--extra-experimental-features", "nix-command"
+                                         , "path-info"
+                                         , "--recursive"
+                                         , "--size"
+                                         , "--json"
+                                         , "/nix/var/nix/gcroots/" ++ gcroot
+                                         ]
+  let pathInfos = Aeson.eitherDecode json :: Either String [PathInfo]
+  print $ fmap (formatFileSize. totalSize) pathInfos
+  return ()
 
+totalSize :: (Foldable f, Functor f) => f PathInfo -> Int
+totalSize = sum . fmap pathInfoNarSize
+
+formatFileSize :: Int -> String
+formatFileSize s
+  | s >= 10*1024*1024*1024 = show (s `quotInt` (1024*1024*1024)) ++ "GB"
+  | s >= 10*1024*1024 = show (s `quotInt` (1024*1024)) ++ "MB"
+  | s >= 10*1024 = show (s `quotInt` 1024) ++ "kb"
+  | otherwise = show s ++ "b"
+
+data PathInfo = PathInfo
+  { pathInfoNarSize :: Int
+  , pathInfoPath :: Text
+  } deriving (Show, Eq)
+
+instance FromJSON PathInfo where
+  parseJSON (Object v) = do
+    pathInfoNarSize <- v .: "narSize"
+    pathInfoPath <- v .: "path"
+    pure $ PathInfo{..}
+  parseJSON invalid = do
+    prependFailure "parsing PathInfo failed, "
+      (typeMismatch "Object" invalid)