Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graphviz export #81

Merged
merged 3 commits into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ nix run github:utdemir/nix-tree -- --help

```console
$ nix-tree --help
Usage: nix-tree [INSTALLABLE] [--store STORE] [--version] [--derivation] [--impure]
Usage: nix-tree [INSTALLABLE] [--store STORE] [--version] [--derivation] [--impure] [--dot]

Interactively browse dependency graphs of Nix derivations.

Expand All @@ -43,6 +43,7 @@ Available options:
--version Show the nix-tree version
--derivation Operate on the store derivation rather than its outputs
--impure Allow access to mutable paths and repositories
--dot Print the dependency graph in dot format
-h,--help Show this help text

Keybindings:
Expand Down
1 change: 1 addition & 0 deletions nix-tree.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ common common-options
, directory
, optparse-applicative
, microlens
, dot

executable nix-tree
import: common-options
Expand Down
8 changes: 6 additions & 2 deletions src/NixTree/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ data Opts = Opts
oStore :: String,
oVersion :: Bool,
oDerivation :: Bool,
oImpure :: Bool
oImpure :: Bool,
oDot :: Bool
}

optsParser :: Opts.ParserInfo Opts
Expand Down Expand Up @@ -65,6 +66,7 @@ optsParser =
<*> Opts.switch (Opts.long "version" <> Opts.help "Show the nix-tree version")
<*> Opts.switch (Opts.long "derivation" <> Opts.help "Operate on the store derivation rather than its outputs")
<*> Opts.switch (Opts.long "impure" <> Opts.help "Allow access to mutable paths and repositories")
<*> Opts.switch (Opts.long "dot" <> Opts.help "Print the dependency graph in dot format")

keybindingsHelp :: Opts.Doc
keybindingsHelp =
Expand Down Expand Up @@ -123,7 +125,9 @@ main = do
& chunks 50
& mapConcurrently_ (mapM_ (\p -> evaluate (rnf p) >> incProgress bar 1))

run env
if opts & oDot
then putTextLn $ storeEnvToDot env
else run env

chunks :: Int -> [a] -> [[a]]
chunks _ [] = []
Expand Down
36 changes: 36 additions & 0 deletions src/NixTree/StorePath.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module NixTree.StorePath
seBottomUp,
seFetchRefs,
mkStoreName,
storeEnvToDot,
)
where

Expand All @@ -25,7 +26,9 @@ import Data.Aeson.Types (Parser)
import qualified Data.ByteString.Lazy as BL
import qualified Data.HashMap.Strict as HM
import qualified Data.HashSet as HS
import qualified Data.Set as Set
import qualified Data.Text as T
import qualified Dot
import System.FilePath.Posix (addTrailingPathSeparator, splitDirectories, (</>))
import System.IO (hPutStrLn)
import System.Process.Typed (proc, readProcessStdout_)
Expand Down Expand Up @@ -319,6 +322,39 @@ seBottomUp f StoreEnv {sePaths, seRoots} =

--------------------------------------------------------------------------------

storeEnvToDot :: StoreEnv s a -> Text
storeEnvToDot env =
seBottomUp go env
& seGetRoots
& toList
& map spPayload
& mconcat
& render
where
go sp =
fromList [Set.singleton (spName sp, spName ref) <> spPayload ref | ref <- spRefs sp]
& mconcat

render :: Set (StoreName s, StoreName s) -> Text
render edges =
Dot.DotGraph
Dot.Strict
Dot.Directed
Nothing
[ Dot.StatementEdge
( Dot.EdgeStatement
(Dot.ListTwo (Dot.EdgeNode (mkNodeId from)) (Dot.EdgeNode (mkNodeId to)) [])
[]
)
| (from, to) <- toList edges
]
& Dot.encode

mkNodeId :: StoreName s -> Dot.NodeId
mkNodeId = fromString . toString . storeNameToShortText

--------------------------------------------------------------------------------

data NixPathInfo = NixPathInfo
{ npiPath :: FilePath,
npiNarSize :: Int,
Expand Down