diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,9 @@
+# Version 0.1.0.0 (2026-10-21)
+* Forked from [nix-derivation-1.1.3](https://hackage.haskell.org/package/nix-derivation)
+* Merged with derivation types of `hnix-store-core`
+
+---
+
+`hnix-store-aterm` uses [PVP Versioning][1].
+
+[1]: https://pvp.haskell.org
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2017 Gabriella Gonzalez
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of Gabriella Gonzalez nor the names of other contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/bench/Main.hs b/bench/Main.hs
new file mode 100644
--- /dev/null
+++ b/bench/Main.hs
@@ -0,0 +1,28 @@
+{-# LANGUAGE OverloadedStrings #-}
+import Criterion (Benchmark)
+
+import Criterion qualified
+import Criterion.Main qualified
+import Data.Attoparsec.Text.Lazy qualified
+import Data.Text.Lazy.IO qualified
+
+import System.Nix.StorePath
+import System.Nix.Derivation.ATerm qualified
+
+main :: IO ()
+main = Criterion.Main.defaultMain benchmarks
+
+benchmarks :: [Benchmark]
+benchmarks =
+    [ Criterion.Main.env
+        (Data.Text.Lazy.IO.readFile "tests/example1.drv")
+        bench0
+    ]
+  where
+    bench0 example =
+        Criterion.bench "example" (Criterion.nf parseExample example)
+
+    parseExample =
+        Data.Attoparsec.Text.Lazy.parse $
+            System.Nix.Derivation.ATerm.parseTraditionalDerivation
+               (StoreDir "/nix/store")
diff --git a/hnix-store-aterm.cabal b/hnix-store-aterm.cabal
new file mode 100644
--- /dev/null
+++ b/hnix-store-aterm.cabal
@@ -0,0 +1,115 @@
+Cabal-Version: 2.2
+Name: hnix-store-aterm
+Version: 0.1.0.0
+Build-Type: Simple
+Tested-With: GHC == 9.8.4, GHC == 9.6.6, GHC == 9.4.8
+License: BSD-3-Clause
+License-File: LICENSE
+Category: Nix
+Copyright: 2017 Gabriella Gonzalez
+Author: Gabriella Gonzalez
+Maintainer: srk@48.io
+Synopsis: Parse and render *.drv files
+Description:
+    Use this package to parse and render Nix derivation files (i.e. *.drv files),
+    i.e. Nix Derivations in "ATerm" format.
+    .
+    See
+    https://nix.dev/manual/nix/latest/protocols/derivation-aterm.html
+    for more details about this format.
+    .
+    This package also provides a @pretty-derivation@ executable which reads a
+    derivation on standard input and outputs the pretty-printed Haskell
+    representation on standard output
+
+extra-doc-files:
+    CHANGELOG.md
+
+Extra-Source-Files:
+    tests/example0.drv
+    tests/example1.drv
+Source-Repository head
+    Type: git
+    Location: https://github.com/haskell-nix/hnix-store
+
+Common commons
+    Default-Extensions:
+        ImportQualifiedPost
+    Default-Language: Haskell2010
+
+Library
+    Import: commons
+    Hs-Source-Dirs: src
+    Build-Depends:
+        attoparsec      >= 0.12.0.0 && < 0.15,
+        base            >= 4.6.0.0  && < 5   ,
+        constraints-extras,
+        containers                     < 0.9 ,
+        deepseq         >= 1.4.0.0  && < 1.6 ,
+        dependent-sum,
+        hnix-store-core,
+        monoidal-containers,
+        some,
+        text            >= 0.8.0.0  && < 2.2 ,
+        these,
+        vector                         < 0.14,
+    Exposed-Modules:
+        System.Nix.Derivation.ATerm
+        System.Nix.Derivation.Traditional
+    Other-Modules:
+        System.Nix.Derivation.ATerm.Builder,
+        System.Nix.Derivation.ATerm.Parser
+    GHC-Options: -Wall
+
+Executable pretty-derivation
+    Import: commons
+    Hs-Source-Dirs: pretty-derivation
+    Build-Depends:
+        base           >= 4.6.0.0  && < 5   ,
+        attoparsec     >= 0.12.0.0 && < 0.15,
+        pretty-show    >= 1.6.11   && < 1.11,
+        text                                ,
+        hnix-store-core                     ,
+        hnix-store-aterm
+    GHC-Options: -Wall
+    Main-Is: Main.hs
+
+Test-Suite aterm
+    Import: commons
+    Type: exitcode-stdio-1.0
+    Hs-Source-Dirs: tests
+    Main-Is: Driver.hs
+    Other-Modules:
+        Derivation
+        Property
+    GHC-Options: -Wall
+    Build-Tool-Depends:
+        tasty-discover:tasty-discover
+    Build-Depends:
+        base            >= 4.6.0.0  && < 5   ,
+        attoparsec      >= 0.12.0.0 && < 0.15,
+        data-default-class                    ,
+        generic-arbitrary              < 1.1 ,
+        hnix-store-core                       ,
+        hnix-store-aterm                      ,
+        hnix-store-tests                      ,
+        QuickCheck                     < 2.20,
+        tasty                                 ,
+        tasty-golden                          ,
+        tasty-quickcheck                      ,
+        text
+
+Benchmark benchmark
+    Import: commons
+    Type:             exitcode-stdio-1.0
+    HS-Source-Dirs:   bench
+    Main-Is:          Main.hs
+    GHC-Options:      -Wall
+
+    Build-Depends:
+        base            >= 4.6.0.0  && < 5   ,
+        attoparsec      >= 0.12.0.0 && < 0.15,
+        criterion       >= 1.1.4.0  && < 1.7 ,
+        hnix-store-core                      ,
+        hnix-store-aterm                     ,
+        text
diff --git a/pretty-derivation/Main.hs b/pretty-derivation/Main.hs
new file mode 100644
--- /dev/null
+++ b/pretty-derivation/Main.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Main where
+
+import Data.Attoparsec.Text.Lazy (Result(..))
+import Data.Attoparsec.Text.Lazy qualified
+import Data.Text.Lazy.IO qualified
+import Text.Show.Pretty qualified
+
+import System.Nix.StorePath
+import System.Nix.Derivation.ATerm qualified
+
+main :: IO ()
+main = do
+    text <- Data.Text.Lazy.IO.getContents
+    case
+      Data.Attoparsec.Text.Lazy.parse
+        (System.Nix.Derivation.ATerm.parseTraditionalDerivation
+          (StoreDir "/nix/store"))
+        text
+      of
+        Fail _ _ err      -> fail err
+        Done _ derivation -> Text.Show.Pretty.pPrint derivation
diff --git a/src/System/Nix/Derivation/ATerm.hs b/src/System/Nix/Derivation/ATerm.hs
new file mode 100644
--- /dev/null
+++ b/src/System/Nix/Derivation/ATerm.hs
@@ -0,0 +1,104 @@
+-- | Use this package to parse and render Nix derivations such as those stored
+-- in @\/nix\/store\/*.drv@ files.  For example, if you had the following derivation
+-- saved at
+-- @\/nix\/store\/zzhs4fb83x5ygvjqn5rdpmpnishpdgy6-perl-MIME-Types-2.13.drv@:
+--
+-- > Derive([("devdoc","/nix/store/15x9ii8c3n5wb5lg80cm8x0yk6zy7rha-perl-MIME-Types-2
+-- > .13-devdoc","",""),("out","/nix/store/93d75ghjyibmbxgfzwhh4b5zwsxzs44w-perl-MIME
+-- > -Types-2.13","","")],[("/nix/store/57h2hjsdkdiwbzilcjqkn46138n1xb4a-perl-5.22.3.
+-- > drv",["out"]),("/nix/store/cvdbbvnvg131bz9bwyyk97jpq1crclqr-MIME-Types-2.13.tar.
+-- > gz.drv",["out"]),("/nix/store/p5g31bc5x92awghx9dlm065d7j773l0r-stdenv.drv",["out
+-- > "]),("/nix/store/x50y5qihwsn0lfjhrf1s81b5hgb9w632-bash-4.4-p5.drv",["out"])],["/
+-- > nix/store/cdips4lakfk1qbf1x68fq18wnn3r5r14-builder.sh"],"x86_64-linux","/nix/sto
+-- > re/fi3mbd2ml4pbgzyasrlnp0wyy6qi48fh-bash-4.4-p5/bin/bash",["-e","/nix/store/cdip
+-- > s4lakfk1qbf1x68fq18wnn3r5r14-builder.sh"],[("AUTOMATED_TESTING","1"),("PERL_AUTO
+-- > INSTALL","--skipdeps"),("buildInputs",""),("builder","/nix/store/fi3mbd2ml4pbgzy
+-- > asrlnp0wyy6qi48fh-bash-4.4-p5/bin/bash"),("checkTarget","test"),("devdoc","/nix/
+-- > store/15x9ii8c3n5wb5lg80cm8x0yk6zy7rha-perl-MIME-Types-2.13-devdoc"),("doCheck",
+-- > "1"),("installTargets","pure_install"),("name","perl-MIME-Types-2.13"),("nativeB
+-- > uildInputs","/nix/store/nsa311yg8h93wfaacjk16c96a98bs09f-perl-5.22.3"),("out","/
+-- > nix/store/93d75ghjyibmbxgfzwhh4b5zwsxzs44w-perl-MIME-Types-2.13"),("outputs","ou
+-- > t devdoc"),("propagatedBuildInputs",""),("propagatedNativeBuildInputs",""),("src
+-- > ","/nix/store/5smhymz7viq8p47mc3jgyvqd003ab732-MIME-Types-2.13.tar.gz"),("stdenv
+-- > ","/nix/store/s3rlr45jzlzx0d6k2azlpxa5zwzr7xyy-stdenv"),("system","x86_64-linux"
+-- > )])
+--
+-- ... you could parse that derivation using:
+--
+-- >>> text <- Data.Text.Lazy.IO.readFile "/nix/store/zzhs4fb83x5ygvjqn5rdpmpnishpdgy6-perl-MIME-Types-2.13.drv"
+-- >>> let result = Data.Attoparsec.Text.Lazy.parse System.Nix.Derivation.ATerm.parseDerivation text
+-- >>> result
+-- Done "" (Derivation {outputs = fromList [("devdoc",DerivationOutput {path = File
+-- Path "/nix/store/15x9ii8c3n5wb5lg80cm8x0yk6zy7rha-perl-MIME-Types-2.13-devdoc", 
+-- hashAlgo = "", hash = ""}),("out",DerivationOutput {path = FilePath "/nix/store/
+-- 93d75ghjyibmbxgfzwhh4b5zwsxzs44w-perl-MIME-Types-2.13", hashAlgo = "", hash = ""
+-- })], inputDrvs = fromList [(FilePath "/nix/store/57h2hjsdkdiwbzilcjqkn46138n1xb4
+-- a-perl-5.22.3.drv",fromList ["out"]),(FilePath "/nix/store/cvdbbvnvg131bz9bwyyk9
+-- 7jpq1crclqr-MIME-Types-2.13.tar.gz.drv",fromList ["out"]),(FilePath "/nix/store/
+-- p5g31bc5x92awghx9dlm065d7j773l0r-stdenv.drv",fromList ["out"]),(FilePath "/nix/s
+-- tore/x50y5qihwsn0lfjhrf1s81b5hgb9w632-bash-4.4-p5.drv",fromList ["out"])], input
+-- Srcs = fromList [FilePath "/nix/store/cdips4lakfk1qbf1x68fq18wnn3r5r14-builder.s
+-- h"], platform = "x86_64-linux", builder = FilePath "/nix/store/fi3mbd2ml4pbgzyas
+-- rlnp0wyy6qi48fh-bash-4.4-p5/bin/bash", args = ["-e","/nix/store/cdips4lakfk1qbf1
+-- x68fq18wnn3r5r14-builder.sh"], env = fromList [("AUTOMATED_TESTING","1"),("PERL_
+-- AUTOINSTALL","--skipdeps"),("buildInputs",""),("builder","/nix/store/fi3mbd2ml4p
+-- bgzyasrlnp0wyy6qi48fh-bash-4.4-p5/bin/bash"),("checkTarget","test"),("devdoc","/
+-- nix/store/15x9ii8c3n5wb5lg80cm8x0yk6zy7rha-perl-MIME-Types-2.13-devdoc"),("doChe
+-- ck","1"),("installTargets","pure_install"),("name","perl-MIME-Types-2.13"),("nat
+-- iveBuildInputs","/nix/store/nsa311yg8h93wfaacjk16c96a98bs09f-perl-5.22.3"),("out
+-- ","/nix/store/93d75ghjyibmbxgfzwhh4b5zwsxzs44w-perl-MIME-Types-2.13"),("outputs"
+-- ,"out devdoc"),("propagatedBuildInputs",""),("propagatedNativeBuildInputs",""),(
+-- "src","/nix/store/5smhymz7viq8p47mc3jgyvqd003ab732-MIME-Types-2.13.tar.gz"),("st
+-- denv","/nix/store/s3rlr45jzlzx0d6k2azlpxa5zwzr7xyy-stdenv"),("system","x86_64-li
+-- nux")]})
+--
+-- ... and render the result back to the original derivation:
+--
+-- >>> fmap buildDerivation result
+-- Done "" "Derive([(\"devdoc\",\"/nix/store/15x9ii8c3n5wb5lg80cm8x0yk6zy7rha-perl-
+-- MIME-Types-2.13-devdoc\",\"\",\"\"),(\"out\",\"/nix/store/93d75ghjyibmbxgfzwhh4b
+-- 5zwsxzs44w-perl-MIME-Types-2.13\",\"\",\"\")],[(\"/nix/store/57h2hjsdkdiwbzilcjq
+-- kn46138n1xb4a-perl-5.22.3.drv\",[\"out\"]),(\"/nix/store/cvdbbvnvg131bz9bwyyk97j
+-- pq1crclqr-MIME-Types-2.13.tar.gz.drv\",[\"out\"]),(\"/nix/store/p5g31bc5x92awghx
+-- 9dlm065d7j773l0r-stdenv.drv\",[\"out\"]),(\"/nix/store/x50y5qihwsn0lfjhrf1s81b5h
+-- gb9w632-bash-4.4-p5.drv\",[\"out\"])],[\"/nix/store/cdips4lakfk1qbf1x68fq18wnn3r
+-- 5r14-builder.sh\"],\"x86_64-linux\",\"/nix/store/fi3mbd2ml4pbgzyasrlnp0wyy6qi48f
+-- h-bash-4.4-p5/bin/bash\",[\"-e\",\"/nix/store/cdips4lakfk1qbf1x68fq18wnn3r5r14-b
+-- uilder.sh\"],[(\"AUTOMATED_TESTING\",\"1\"),(\"PERL_AUTOINSTALL\",\"--skipdeps\"
+-- ),(\"buildInputs\",\"\"),(\"builder\",\"/nix/store/fi3mbd2ml4pbgzyasrlnp0wyy6qi4
+-- 8fh-bash-4.4-p5/bin/bash\"),(\"checkTarget\",\"test\"),(\"devdoc\",\"/nix/store/
+-- 15x9ii8c3n5wb5lg80cm8x0yk6zy7rha-perl-MIME-Types-2.13-devdoc\"),(\"doCheck\",\"1
+-- \"),(\"installTargets\",\"pure_install\"),(\"name\",\"perl-MIME-Types-2.13\"),(\
+-- "nativeBuildInputs\",\"/nix/store/nsa311yg8h93wfaacjk16c96a98bs09f-perl-5.22.3\"
+-- ),(\"out\",\"/nix/store/93d75ghjyibmbxgfzwhh4b5zwsxzs44w-perl-MIME-Types-2.13\")
+-- ,(\"outputs\",\"out devdoc\"),(\"propagatedBuildInputs\",\"\"),(\"propagatedNati
+-- veBuildInputs\",\"\"),(\"src\",\"/nix/store/5smhymz7viq8p47mc3jgyvqd003ab732-MIM
+-- E-Types-2.13.tar.gz\"),(\"stdenv\",\"/nix/store/s3rlr45jzlzx0d6k2azlpxa5zwzr7xyy
+-- -stdenv\"),(\"system\",\"x86_64-linux\")])"
+
+module System.Nix.Derivation.ATerm
+    ( -- * Types
+      TraditionalDerivation'(..)
+    , FreeformDerivationOutput(..)
+    , FreeformDerivationOutputs
+    , TraditionalDerivationInputs(..)
+    , DerivedPathMap(..)
+
+      -- * Parse derivations
+    , parseTraditionalDerivation
+    , parseTraditionalDerivationWith
+    , parseFreeformDerivationOutput
+    , parseTraditionalDerivationInputs
+    , textParser
+
+      -- * Render derivations
+    , buildTraditionalDerivation
+    , buildTraditionalDerivationWith
+    , buildFreeformDerivationOutput
+    , buildTraditionalDerivationInputs
+    ) where
+
+import System.Nix.Derivation
+import System.Nix.Derivation.Traditional
+import System.Nix.Derivation.ATerm.Builder
+import System.Nix.Derivation.ATerm.Parser
diff --git a/src/System/Nix/Derivation/ATerm/Builder.hs b/src/System/Nix/Derivation/ATerm/Builder.hs
new file mode 100644
--- /dev/null
+++ b/src/System/Nix/Derivation/ATerm/Builder.hs
@@ -0,0 +1,150 @@
+{-# LANGUAGE LambdaCase        #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards   #-}
+
+-- | Rendering logic
+
+module System.Nix.Derivation.ATerm.Builder
+    ( -- * Builder
+      buildTraditionalDerivation
+    , buildTraditionalDerivationWith
+    , buildFreeformDerivationOutput
+    , buildTraditionalDerivationInputs
+    ) where
+
+import Data.Map (Map)
+import Data.Set (Set)
+import Data.Text (Text)
+import Data.Text.Lazy.Builder (Builder)
+import Data.Vector (Vector)
+import System.Nix.Derivation
+    ( FreeformDerivationOutput(..)
+    , FreeformDerivationOutputs
+    )
+import System.Nix.Derivation.Traditional
+import System.Nix.StorePath
+import System.Nix.OutputName
+
+import Data.Map qualified
+import Data.Set qualified
+import Data.Text qualified
+import Data.Text.Lazy.Builder qualified
+import Data.Vector qualified
+
+-- | Render a derivation as a `Builder`
+buildTraditionalDerivation
+    :: StoreDir
+    -> TraditionalDerivation' TraditionalDerivationInputs FreeformDerivationOutputs
+    -> Builder
+buildTraditionalDerivation sd =
+    buildTraditionalDerivationWith
+        (buildTraditionalDerivationInputs sd)
+        (\_ -> buildFreeformDerivationOutput sd)
+
+-- | Render a derivation as a `Builder` using custom
+-- renderer for storePaths, texts, outputNames and derivation inputs/outputs
+buildTraditionalDerivationWith
+    :: (drvInputs -> Builder)
+    -> (OutputName -> drvOutput -> Builder)
+    -> TraditionalDerivation' drvInputs (Map OutputName drvOutput)
+    -> Builder
+buildTraditionalDerivationWith drvInputs drvOutput (TraditionalDerivation {..}) =
+        "Derive("
+    <>  mapOf keyValue0 anonOutputs
+    <>  ","
+    <>  drvInputs anonInputs
+    <>  ","
+    <>  string anonPlatform
+    <>  ","
+    <>  string anonBuilder
+    <>  ","
+    <>  vectorOf string anonArgs
+    <>  ","
+    <>  mapOf keyValue1 anonEnv
+    <>  ")"
+  where
+    keyValue0 (key, output) =
+            "("
+        <>  buildOutputName key
+        <>  ","
+        <>  drvOutput key output
+        <>  ")"
+
+    keyValue1 (key, value) =
+            "("
+        <>  string key
+        <>  ","
+        <>  string value
+        <>  ")"
+
+-- | Render a @FreeformDerivationOutput@ as a `Builder` using custom
+-- renderer for storePaths
+buildFreeformDerivationOutput
+    :: StoreDir
+    -> FreeformDerivationOutput
+    -> Builder
+buildFreeformDerivationOutput storeDir =
+  ( \RawDerivationOutput {..} ->
+        string rawPath
+    <>  ","
+    <>  string rawMethodHashAlgo
+    <>  ","
+    <>  string rawHash
+  )
+  . renderRawDerivationOutput storeDir
+
+-- | Render a @TraditionalDerivationInputs@ as a `Builder` using custom
+-- renderer for storePaths and output names
+buildTraditionalDerivationInputs
+    :: StoreDir
+    -> TraditionalDerivationInputs
+    -> Builder
+buildTraditionalDerivationInputs storeDir (TraditionalDerivationInputs {..}) =
+        mapOf keyValue traditionalDrvs
+    <>  ","
+    <>  setOf (storePath storeDir) traditionalSrcs
+  where
+    keyValue (key, value) =
+            "("
+        <>  storePath storeDir key
+        <>  ","
+        <>  setOf buildOutputName value
+        <>  ")"
+
+mapOf :: ((k, v) -> Builder) -> Map k v -> Builder
+mapOf keyValue m = listOf keyValue (Data.Map.toList m)
+
+listOf :: (a -> Builder) -> [a] -> Builder
+listOf _          []  = "[]"
+listOf element (x:xs) =
+        "["
+    <>  element x
+    <>  foldMap rest xs
+    <>  "]"
+  where
+    rest y = "," <> element y
+
+setOf :: (a -> Builder) -> Set a -> Builder
+setOf element xs = listOf element (Data.Set.toList xs)
+
+vectorOf :: (a -> Builder) -> Vector a -> Builder
+vectorOf element xs = listOf element (Data.Vector.toList xs)
+
+string :: Text -> Builder
+string =
+    Data.Text.Lazy.Builder.fromText
+    . (\input -> Data.Text.concat ["\"", Data.Text.concatMap escapeChar input, "\""])
+  where
+    escapeChar :: Char -> Text
+    escapeChar '\"' = "\\\""
+    escapeChar '\\' = "\\\\"
+    escapeChar '\n' = "\\n"
+    escapeChar '\r' = "\\r"
+    escapeChar '\t' = "\\t"
+    escapeChar c    = Data.Text.singleton c
+
+buildOutputName :: OutputName -> Builder
+buildOutputName = string . outputNameToText
+
+storePath :: StoreDir -> StorePath -> Builder
+storePath sd = string . storePathToText sd
diff --git a/src/System/Nix/Derivation/ATerm/Parser.hs b/src/System/Nix/Derivation/ATerm/Parser.hs
new file mode 100644
--- /dev/null
+++ b/src/System/Nix/Derivation/ATerm/Parser.hs
@@ -0,0 +1,187 @@
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE MultiWayIf #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards   #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
+
+-- | Parsing logic
+
+module System.Nix.Derivation.ATerm.Parser
+    ( -- * Parser
+      parseTraditionalDerivation
+    , parseTraditionalDerivationWith
+    , parseFreeformDerivationOutput
+    , parseTraditionalDerivationInputs
+    , textParser
+    ) where
+
+import Data.Attoparsec.Text qualified
+import Data.Attoparsec.Text.Lazy (Parser)
+import Data.Attoparsec.Text.Lazy qualified
+import Data.Map (Map)
+import Data.Map qualified
+import Data.Set (Set)
+import Data.Set qualified
+import Data.Text (Text)
+import Data.Text qualified
+import Data.Vector (Vector)
+import Data.Vector qualified
+
+import System.Nix.Derivation
+    ( FreeformDerivationOutput(..)
+    , FreeformDerivationOutputs
+    )
+import System.Nix.Derivation.Traditional
+import System.Nix.StorePath
+import System.Nix.OutputName
+
+listOf :: Parser a -> Parser [a]
+listOf element = do
+    "["
+    es <- Data.Attoparsec.Text.Lazy.sepBy element ","
+    "]"
+    pure es
+
+-- | Parse a derivation
+parseTraditionalDerivation
+  :: StoreDir
+  -> Parser (TraditionalDerivation' TraditionalDerivationInputs FreeformDerivationOutputs)
+parseTraditionalDerivation sd =
+    parseTraditionalDerivationWith
+        (parseTraditionalDerivationInputs sd)
+        (\_ -> parseFreeformDerivationOutput sd)
+
+-- | Parse a derivation using custom
+-- parsers for filepaths, texts, outputNames and derivation inputs/outputs
+parseTraditionalDerivationWith
+    :: Parser drvInputs
+    -> (OutputName -> Parser drvOutput)
+    -> Parser (TraditionalDerivation' drvInputs (Map OutputName drvOutput))
+parseTraditionalDerivationWith parseInputs parseOutput = do
+    "Derive("
+
+    let keyValue0 = do
+            "("
+            key <- outputNameParser
+            ","
+            drvOutput <- parseOutput key
+            ")"
+            return (key, drvOutput)
+    anonOutputs <- mapOf keyValue0
+
+    ","
+
+    anonInputs <- parseInputs
+
+    ","
+
+    anonPlatform <- textParser
+
+    ","
+
+    anonBuilder <- textParser
+
+    ","
+
+    anonArgs <- vectorOf textParser
+
+    ","
+
+    let keyValue1 = do
+            "("
+            key <- textParser
+            ","
+            value <- textParser
+            ")"
+            pure (key, value)
+    anonEnv <- mapOf keyValue1
+
+    ")"
+
+    pure TraditionalDerivation {..}
+
+-- | Parse a derivation output
+parseFreeformDerivationOutput :: StoreDir -> Parser FreeformDerivationOutput
+parseFreeformDerivationOutput sd = do
+    rawPath <- textParser
+    ","
+    rawMethodHashAlgo <- textParser
+    ","
+    rawHash <- textParser
+    parseRawDerivationOutput sd $ RawDerivationOutput {..}
+
+-- | Parse a derivation inputs
+parseTraditionalDerivationInputs :: StoreDir -> Parser TraditionalDerivationInputs
+parseTraditionalDerivationInputs sd = do
+    traditionalDrvs <- mapOf $ do
+         "("
+         key <- storePathParser sd
+         ","
+         value <- setOf outputNameParser
+         ")"
+         pure (key, value)
+
+    ","
+
+    traditionalSrcs <- setOf $ storePathParser sd
+    pure TraditionalDerivationInputs {..}
+
+textParser :: Parser Text
+textParser = do
+    "\""
+
+    let predicate c = not (c == '"' || c == '\\')
+
+    let loop = do
+            text0 <- Data.Attoparsec.Text.takeWhile predicate
+
+            char0 <- Data.Attoparsec.Text.anyChar
+
+            case char0 of
+                '"'  -> do
+                    pure [ text0 ]
+
+                _    -> do
+                    char1 <- Data.Attoparsec.Text.anyChar
+
+                    char2 <- case char1 of
+                        'n' -> pure '\n'
+                        'r' -> pure '\r'
+                        't' -> pure '\t'
+                        _   -> pure char1
+
+                    textChunks <- loop
+
+                    pure (text0 : Data.Text.singleton char2 : textChunks)
+
+    Data.Text.concat <$> loop
+
+outputNameParser :: Parser OutputName
+outputNameParser = do
+  n <- textParser
+  case mkOutputName n of
+    Left e -> fail $ show e -- TODO
+    Right sp -> pure sp
+
+storePathParser :: StoreDir -> Parser StorePath
+storePathParser sd = do
+  f <- textParser
+  case System.Nix.StorePath.parsePathFromText sd f of
+    Left e -> fail $ show e -- TODO
+    Right sp -> pure sp
+
+setOf :: Ord a => Parser a -> Parser (Set a)
+setOf element = do
+    es <- listOf element
+    pure (Data.Set.fromList es)
+
+vectorOf :: Parser a -> Parser (Vector a)
+vectorOf element = do
+    es <- listOf element
+    pure (Data.Vector.fromList es)
+
+mapOf :: Ord k => Parser (k, v) -> Parser (Map k v)
+mapOf keyValue = do
+    keyValues <- listOf keyValue
+    pure (Data.Map.fromList keyValues)
diff --git a/src/System/Nix/Derivation/Traditional.hs b/src/System/Nix/Derivation/Traditional.hs
new file mode 100644
--- /dev/null
+++ b/src/System/Nix/Derivation/Traditional.hs
@@ -0,0 +1,201 @@
+{-# LANGUAGE DeriveGeneric     #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE KindSignatures    #-}
+{-# LANGUAGE LambdaCase        #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE NamedFieldPuns    #-}
+{-# LANGUAGE RankNTypes        #-}
+{-# LANGUAGE RecordWildCards   #-}
+{-# LANGUAGE ScopedTypeVariables  #-}
+{-# LANGUAGE TypeApplications  #-}
+
+-- | Shared types
+
+module System.Nix.Derivation.Traditional
+    ( RawDerivationOutput(..)
+    , parseRawDerivationOutput
+    , renderRawDerivationOutput
+    , TraditionalDerivation'(..)
+    , withName
+    , withoutName
+    , TraditionalDerivationInputs(..)
+    , inputsToTraditional
+    , inputsFromTraditional
+    ) where
+
+
+import Control.DeepSeq (NFData(..))
+import Data.Constraint.Extras (Has(has))
+import Data.Dependent.Sum (DSum(..))
+import Data.Map (Map)
+import Data.Map qualified
+import Data.Map.Monoidal (MonoidalMap(..))
+import Data.Map.Monoidal qualified
+import Data.Maybe (fromMaybe)
+import Data.Set (Set)
+import Data.Some
+import Data.Text (Text)
+import Data.Text qualified
+import Data.These (These(..))
+import Data.Vector (Vector)
+import Data.Traversable (for)
+import GHC.Generics (Generic, (:.:)(..))
+
+import System.Nix.ContentAddress (ContentAddressMethod(..))
+import System.Nix.Derivation
+import System.Nix.Hash
+import System.Nix.OutputName (OutputName)
+import System.Nix.StorePath
+
+-- | Useful for the ATerm format, and remote protocols that need the same parsing
+-- If it won't for the protocol, we would just inline this into the ATerm code proper.
+data RawDerivationOutput = RawDerivationOutput
+    { rawPath :: Text
+    , rawMethodHashAlgo :: Text
+    , rawHash :: Text
+    } deriving (Eq, Generic, Ord, Show)
+
+parseRawDerivationOutput
+  :: forall m
+  .  MonadFail m
+  => StoreDir
+  -> RawDerivationOutput
+  -> m FreeformDerivationOutput
+parseRawDerivationOutput storeDir (RawDerivationOutput {..}) = do
+  let onNonEmptyText :: Text -> (Text -> m a) -> m (Maybe a)
+      onNonEmptyText = flip $ \f -> \case
+        "" -> pure Nothing
+        t -> Just <$> f t
+  mPath <- onNonEmptyText rawPath $ \t -> case System.Nix.StorePath.parsePathFromText storeDir t of
+    Left e -> fail $ show e -- TODO
+    Right sp -> pure sp
+  mMethodHashAlgo <- onNonEmptyText rawMethodHashAlgo splitMethodHashAlgo
+  mHash0 <- onNonEmptyText rawHash pure
+  mContentAddressing <- case mMethodHashAlgo of
+    Nothing -> case mHash0 of
+      Nothing -> pure Nothing
+      Just _ -> fail "Hash without method and hash algo is not allowed"
+    Just (method, Some hashAlgo) -> do
+      mHash <- for mHash0 $ \hash0 ->
+        either fail pure $ has @NamedAlgo hashAlgo $
+          decodeDigestWith NixBase32 hash0
+      pure $ Just (method, hashAlgo :=> Comp1 mHash)
+  pure FreeformDerivationOutput { mPath, mContentAddressing }
+
+renderRawDerivationOutput
+    :: StoreDir
+    -> FreeformDerivationOutput
+    -> RawDerivationOutput
+renderRawDerivationOutput storeDir (FreeformDerivationOutput {..}) =
+  RawDerivationOutput
+    { rawPath = fromMaybe "" $ storePathToText storeDir <$> mPath
+    , rawMethodHashAlgo = flip (maybe "") mContentAddressing $ \(method, hashAlgo :=> _) ->
+        buildMethodHashAlgo method $ Some hashAlgo
+    , rawHash = fromMaybe "" $ mContentAddressing >>= \(_, _ :=> Comp1 hash') ->
+        encodeDigestWith NixBase32 <$> hash'
+    }
+
+buildMethodHashAlgo :: ContentAddressMethod -> Some HashAlgo -> Text
+buildMethodHashAlgo method hashAlgo = Data.Text.intercalate ":" $
+  (case method of
+    ContentAddressMethod_NixArchive -> ["r"]
+    ContentAddressMethod_Text -> ["text"]
+    ContentAddressMethod_Flat -> [])
+  <>
+  [withSome hashAlgo algoToText]
+
+splitMethodHashAlgo :: MonadFail m => Text -> m (ContentAddressMethod, Some HashAlgo)
+splitMethodHashAlgo methodHashAlgo = do
+  (method, hashAlgoS) <- case Data.Text.splitOn ":" methodHashAlgo of
+    ["r", hashAlgo] -> pure (ContentAddressMethod_NixArchive, hashAlgo)
+    ["text", hashAlgo] -> pure (ContentAddressMethod_Text, hashAlgo)
+    [hashAlgo] -> pure (ContentAddressMethod_Flat, hashAlgo)
+    _ -> fail "invalid number of colons or unknown CA method prefix"
+  hashAlgo <- either fail pure $ textToAlgo hashAlgoS
+  pure (method, hashAlgo)
+
+----------------
+
+-- | The ATerm format doesn't include the derivation name. That must
+-- instead be gotten out of band, e.g. from the Store Path.
+data TraditionalDerivation' inputs outputs = TraditionalDerivation
+    { anonOutputs   :: outputs
+    -- ^ Outputs produced by this derivation where keys are output names
+    , anonInputs    :: inputs
+    -- ^ Inputs (sources and derivations)
+    , anonPlatform  :: Text
+    -- ^ Platform required for this derivation
+    , anonBuilder   :: Text
+    -- ^ Code to build the derivation, which can be a path or a builtin function
+    , anonArgs      :: Vector Text
+    -- ^ Arguments passed to the executable used to build to derivation
+    , anonEnv       :: Map Text Text
+    -- ^ Environment variables provided to the executable used to build the
+    -- derivation
+    } deriving (Eq, Generic, Ord, Show)
+
+instance (NFData inputs, NFData outputs) => NFData (TraditionalDerivation' inputs outputs)
+
+withName :: StorePathName -> TraditionalDerivation' inputs outputs -> Derivation' inputs outputs
+withName name drv0 = Derivation
+  { name = name
+  , outputs = anonOutputs drv0
+  , inputs = anonInputs drv0
+  , platform = anonPlatform drv0
+  , builder = anonBuilder drv0
+  , args = anonArgs drv0
+  , env = anonEnv drv0
+  }
+
+withoutName :: Derivation' inputs outputs -> TraditionalDerivation' inputs outputs
+withoutName drv0 = TraditionalDerivation
+  { anonOutputs = outputs drv0
+  , anonPlatform = platform drv0
+  , anonInputs = inputs drv0
+  , anonBuilder = builder drv0
+  , anonArgs = args drv0
+  , anonEnv = env drv0
+  }
+
+----------------
+
+-- | Useful for the ATerm format
+data TraditionalDerivationInputs = TraditionalDerivationInputs
+    { traditionalSrcs :: Set StorePath
+    -- ^ Inputs that are sources
+    , traditionalDrvs :: Map StorePath (Set OutputName)
+    -- ^ Inputs that are derivations where keys specify derivation paths and
+    -- values specify which output names are used by this derivation
+    } deriving (Eq, Generic, Ord, Show)
+
+instance NFData TraditionalDerivationInputs
+
+instance Semigroup TraditionalDerivationInputs where
+  TraditionalDerivationInputs x0 x1 <> TraditionalDerivationInputs y0 y1 = TraditionalDerivationInputs
+    (x0 <> y0)
+    (x1 <> y1)
+
+instance Monoid TraditionalDerivationInputs where
+  mempty = TraditionalDerivationInputs mempty mempty
+
+inputsToTraditional :: DerivationInputs -> Either StorePath TraditionalDerivationInputs
+inputsToTraditional is = (\drvs -> TraditionalDerivationInputs
+  { traditionalSrcs = srcs is
+  , traditionalDrvs = drvs
+  }) <$> go (drvs is)
+  where
+   go = fmap getMonoidalMap
+     . Data.Map.Monoidal.traverseWithKey
+       (\storePath -> (\case
+           This os -> Right os
+           _ -> Left storePath -- TODO make better error, e.g. by partitioning the map
+        ) . unChildNode)
+     . unDerivedPathMap
+
+inputsFromTraditional :: TraditionalDerivationInputs -> DerivationInputs
+inputsFromTraditional TraditionalDerivationInputs { traditionalSrcs, traditionalDrvs } = DerivationInputs
+  { srcs = traditionalSrcs
+  , drvs = DerivedPathMap $ Data.Map.Monoidal.fromList $
+      fmap (fmap ChildNode . fmap This) (Data.Map.toList traditionalDrvs)
+  }
diff --git a/tests/Derivation.hs b/tests/Derivation.hs
new file mode 100644
--- /dev/null
+++ b/tests/Derivation.hs
@@ -0,0 +1,41 @@
+module Derivation where
+
+import Test.Tasty (TestTree, testGroup)
+import Test.Tasty.Golden (goldenVsFile)
+
+import System.Nix.Derivation.ATerm (parseTraditionalDerivation, buildTraditionalDerivation)
+
+import Data.Default.Class (Default(def))
+import Data.Attoparsec.Text.Lazy qualified
+import Data.Text.Lazy.IO qualified
+import Data.Text.Lazy.Builder qualified
+
+processDerivation :: FilePath -> FilePath -> IO ()
+processDerivation source dest = do
+  contents <- Data.Text.Lazy.IO.readFile source
+  either
+    fail
+    (Data.Text.Lazy.IO.writeFile dest
+      . Data.Text.Lazy.Builder.toLazyText
+      . buildTraditionalDerivation def
+    )
+    (Data.Attoparsec.Text.Lazy.parseOnly
+      (parseTraditionalDerivation def)
+      contents
+    )
+
+test_derivation :: TestTree
+test_derivation =
+  testGroup "golden" $ fmap mk [0 .. 1]
+ where
+  mk :: Int -> TestTree
+  mk n =
+    goldenVsFile
+      ("derivation roundtrip of " <> drv)
+      drv
+      act
+      (processDerivation drv act)
+   where
+    drv = fp <> show n <> ".drv"
+    act = fp <> show n <> ".actual"
+    fp  = "tests/example"
diff --git a/tests/Driver.hs b/tests/Driver.hs
new file mode 100644
--- /dev/null
+++ b/tests/Driver.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF tasty-discover #-}
diff --git a/tests/Property.hs b/tests/Property.hs
new file mode 100644
--- /dev/null
+++ b/tests/Property.hs
@@ -0,0 +1,64 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE DerivingVia #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE UndecidableInstances #-}
+-- due to recent generic-arbitrary
+{-# OPTIONS_GHC -fconstraint-solver-iterations=0 #-}
+{-# OPTIONS_GHC -Wno-orphans #-}
+
+module Property where
+
+import Prelude hiding (FilePath, either)
+
+import Data.Attoparsec.Text.Lazy qualified
+import Data.Text.Lazy.Builder qualified
+import Test.QuickCheck (Arbitrary)
+import Test.QuickCheck.Property (failed, succeeded, Result(..))
+import Test.QuickCheck.Arbitrary.Generic (Arg, GenericArbitrary(..))
+
+import System.Nix.StorePath
+import System.Nix.Arbitrary.Derivation ()
+import System.Nix.Derivation
+import System.Nix.Derivation.ATerm qualified
+import System.Nix.Derivation.Traditional
+
+deriving via GenericArbitrary TraditionalDerivationInputs
+  instance Arbitrary TraditionalDerivationInputs
+
+deriving via GenericArbitrary (TraditionalDerivation' inputs outputs)
+  instance
+    ( Arbitrary inputs
+    , Arbitrary outputs
+    , Arg (TraditionalDerivation' inputs outputs) inputs
+    , Arg (TraditionalDerivation' inputs outputs) outputs
+    ) => Arbitrary (TraditionalDerivation' inputs outputs)
+
+prop_roundtrip
+  :: StoreDir
+  -> TraditionalDerivation'
+     TraditionalDerivationInputs
+     FreeformDerivationOutputs
+  -> Result
+prop_roundtrip storeDir derivation0 =
+    if either == expected
+    then succeeded
+    else failed { reason = unlines ["", show either, show expected] }
+  where
+    builder = System.Nix.Derivation.ATerm.buildTraditionalDerivation storeDir derivation0
+
+    text = Data.Text.Lazy.Builder.toLazyText builder
+
+    result =
+        Data.Attoparsec.Text.Lazy.parse
+          (System.Nix.Derivation.ATerm.parseTraditionalDerivation storeDir)
+          text
+
+    either, expected :: Either String (TraditionalDerivation' TraditionalDerivationInputs FreeformDerivationOutputs)
+
+    either =
+        Data.Attoparsec.Text.Lazy.eitherResult result
+
+    expected = Right derivation0
diff --git a/tests/example0.drv b/tests/example0.drv
new file mode 100644
--- /dev/null
+++ b/tests/example0.drv
@@ -0,0 +1,1 @@
+Derive([("devdoc","/nix/store/15x9ii8c3n5wb5lg80cm8x0yk6zy7rha-perl-MIME-Types-2.13-devdoc","",""),("out","/nix/store/93d75ghjyibmbxgfzwhh4b5zwsxzs44w-perl-MIME-Types-2.13","","")],[("/nix/store/cvdbbvnvg131bz9bwyyk97jpq1crclqr-MIME-Types-2.13.tar.gz.drv",["out"]),("/nix/store/p5g31bc5x92awghx9dlm065d7j773l0r-stdenv.drv",["out"]),("/nix/store/x50y5qihwsn0lfjhrf1s81b5hgb9w632-bash-4.4-p5.drv",["out"]),("/nix/store/57h2hjsdkdiwbzilcjqkn46138n1xb4a-perl-5.22.3.drv",["out"])],["/nix/store/cdips4lakfk1qbf1x68fq18wnn3r5r14-builder.sh"],"x86_64-linux","/nix/store/fi3mbd2ml4pbgzyasrlnp0wyy6qi48fh-bash-4.4-p5/bin/bash",["-e","/nix/store/cdips4lakfk1qbf1x68fq18wnn3r5r14-builder.sh"],[("AUTOMATED_TESTING","1"),("PERL_AUTOINSTALL","--skipdeps"),("buildInputs",""),("builder","/nix/store/fi3mbd2ml4pbgzyasrlnp0wyy6qi48fh-bash-4.4-p5/bin/bash"),("checkTarget","test"),("devdoc","/nix/store/15x9ii8c3n5wb5lg80cm8x0yk6zy7rha-perl-MIME-Types-2.13-devdoc"),("doCheck","1"),("installTargets","pure_install"),("name","perl-MIME-Types-2.13"),("nativeBuildInputs","/nix/store/nsa311yg8h93wfaacjk16c96a98bs09f-perl-5.22.3"),("out","/nix/store/93d75ghjyibmbxgfzwhh4b5zwsxzs44w-perl-MIME-Types-2.13"),("outputs","out devdoc"),("propagatedBuildInputs",""),("propagatedNativeBuildInputs",""),("src","/nix/store/5smhymz7viq8p47mc3jgyvqd003ab732-MIME-Types-2.13.tar.gz"),("stdenv","/nix/store/s3rlr45jzlzx0d6k2azlpxa5zwzr7xyy-stdenv"),("system","x86_64-linux")])
diff --git a/tests/example1.drv b/tests/example1.drv
new file mode 100644
--- /dev/null
+++ b/tests/example1.drv
@@ -0,0 +1,1 @@
+Derive([("out","/nix/store/w3zbr9zj9mn08hnirn34wsxhry40qi3c-ghc-8.0.2-with-packages","","")],[("/nix/store/r44a3jm3q5rhi75rl1m6jr1vgwpiyw02-hnix-0.3.4.drv",["out"]),("/nix/store/clxg57lhlflbjrk6w3fv51fxjnqkk7q4-transformers-compat-0.5.1.4.drv",["out"]),("/nix/store/z036z61lsrk2gqbwljix0akzhz2bgl8j-semigroups-0.18.2.drv",["out"]),("/nix/store/fyi4gg70v1lgjz03v07flnmjr8x55mqk-async-2.1.1.1.drv",["out"]),("/nix/store/qi0668xlc3q03n74k1wrqri7ss7bvphk-stm-2.4.4.1.drv",["out"]),("/nix/store/nwapw7zf014frf49c0b7y5694jyc38hm-streaming-commons-0.1.17.drv",["out"]),("/nix/store/rqcq6jigs1sj53f8wrbff3s06wzazfqw-comonad-5.0.1.drv",["out"]),("/nix/store/dg6n7519y227s9c867wqi2v40cj41zqy-attoparsec-0.13.1.0.drv",["out"]),("/nix/store/y4ll9c29g76jzycl7zhdmqzxgciyrfr1-case-insensitive-1.2.0.9.drv",["out"]),("/nix/store/a2ar311g8chbi4ila55qzi3dfp9g5zr6-blaze-html-0.8.1.3.drv",["out"]),("/nix/store/2bmxgjskcw4vdmcqrw9pc9yjffsqn3i9-byteable-0.1.1.drv",["out"]),("/nix/store/xbygsq84395vhj7bnh7786i9864jf9i9-ghc-8.0.2.drv",["out"]),("/nix/store/wx9vx1z55bzkzym0lzbgpzd7rrsx9w9b-scientific-0.3.4.12.drv",["out"]),("/nix/store/zvxd18a65gwcg3bz7v1rb0h59w9wwi9d-network-2.6.3.1.drv",["out"]),("/nix/store/y8l0lv08hfi6qnrzd25dxgi4712yjf9f-base-orphans-0.5.4.drv",["out"]),("/nix/store/0w9vy2hmz50j0yhlbj519hnpjbvqhjrj-cookie-0.4.2.1.drv",["out"]),("/nix/store/xp7jayhmiphx0zqxx9dxrk673shhj89l-optparse-applicative-0.13.2.0.drv",["out"]),("/nix/store/xzda3rxckhf0h3lp1hr6wanyig9s9y1p-utf8-string-1.0.1.1.drv",["out"]),("/nix/store/zg5as9jrs5vfa5iw7539vihmwm436g1q-network-uri-2.6.1.0.drv",["out"]),("/nix/store/5x6d3f9krpqlmzhmk71qf7m97g38hba1-base-prelude-1.0.1.1.drv",["out"]),("/nix/store/d1n1p6mdabwkgkc7y6151j37c4kqh1a2-exceptions-0.8.3.drv",["out"]),("/nix/store/m7l8bg4k82snsl759k2mlkjlb8g0352a-foundation-0.0.7.drv",["out"]),("/nix/store/l3wmibr3b1b3a8ql8ypy860209iqbasg-connection-0.2.8.drv",["out"]),("/nix/store/gq055a1910w9q6mbb5kf6p6igzg6b5ai-StateVar-1.1.0.4.drv",["out"]),("/nix/store/pra6ynwnksgks1xxv2l7h48swjq4vb2j-data-default-class-0.1.2.0.drv",["out"]),("/nix/store/as62r0pdaq0q76rxz719xy33vqa7xcal-double-conversion-2.0.2.0.drv",["out"]),("/nix/store/0cyv377kjnhjc9j1pb0m530lczqj4ksm-optparse-generic-1.1.5.drv",["out"]),("/nix/store/75iir4x52007r0fq41kwk5cdfvmi02jp-profunctors-5.2.drv",["out"]),("/nix/store/z8vpk1rwkikc8pg20vyg5kvsdv626ksw-dhall-1.3.0.drv",["out"]),("/nix/store/ckl2x2vkqj82k4b7c5l8p611g6jmfbsz-zlib-0.6.1.2.drv",["out"]),("/nix/store/x50y5qihwsn0lfjhrf1s81b5hgb9w632-bash-4.4-p5.drv",["out"]),("/nix/store/fdq2dn4gal13xl9jbyk8igvaw5f2x9b5-blaze-builder-0.4.0.2.drv",["out"]),("/nix/store/9w2n7jqc9ll78r7xj31ckrqcq6g8g8kf-integer-logarithms-1.0.1.drv",["out"]),("/nix/store/lvm3zp40qfdqr0v9i27z7dqpdwlxprbl-text-1.2.2.1.drv",["out"]),("/nix/store/bwf0a834k4jf5ss2ccribn9w7g2r3j3m-stdenv.drv",["out"]),("/nix/store/1b75igh40c9agy3sfyl5n7av4070swvn-old-locale-1.0.0.7.drv",["out"]),("/nix/store/lnxgjiywc89iaby3g0na1sc4hryvnikq-trifecta-1.6.2.1.drv",["out"]),("/nix/store/mq338r0an8lj00g88c6rpylbnmds7fbx-adjunctions-4.3.drv",["out"]),("/nix/store/qr8wf0b1lqwxwi6ban2k307jy91bj640-reducers-3.12.1.drv",["out"]),("/nix/store/56l353i7v6i7i5vkk2qx4wi4r6p4xll1-void-0.7.2.drv",["out"]),("/nix/store/8p1f0rs49czq74yxlfcimlag9wnbwsc5-http-client-tls-0.3.4.1.drv",["out"]),("/nix/store/nv7frilmipcpylijp492l3hc0s2cmgw6-tls-1.3.10.drv",["out"]),("/nix/store/7ah4kd8kbwsfr350wkr0y4i0h6gm7vc8-base64-bytestring-1.0.0.1.drv",["out"]),("/nix/store/ginljsxbpxli394mc06gvqkmvddhqwlc-x509-store-1.6.2.drv",["out"]),("/nix/store/w6a3c55nhmpcia6cvdg31nqsc7v910lc-ansi-terminal-0.6.2.3.drv",["out"]),("/nix/store/7545pmiaccgvkxjfvl9cm0qk7y1x96wi-reflection-2.1.2.drv",["out"]),("/nix/store/ahypsxsxcczsllax40jnccdg5ilps2lq-http-client-0.5.6.1.drv",["out"]),("/nix/store/6n2kl1fnn66a24ipjm1dxjhhvni1404r-mtl-2.2.1.drv",["out"]),("/nix/store/fr1acpclaljwizrvic520wdf36kmxjwr-blaze-markup-0.7.1.1.drv",["out"]),("/nix/store/vpqjk2wral953nnqnhvp8zbmkbhnyxls-x509-validation-1.6.5.drv",["out"]),("/nix/store/sdx411558r03fdvfi3p6wzfsi701sv4w-system-fileio-0.3.16.3.drv",["out"]),("/nix/store/pz3s86hbxvwr7m4x7cpz5h8z124wgk4x-x509-1.6.5.drv",["out"]),("/nix/store/v0srwl68sz6dirasq53bd3ddjipa1d5b-deriving-compat-0.3.6.drv",["out"]),("/nix/store/61fzrmaxsfc9q4qzsdcrsaqgg05hr6xi-bifunctors-5.4.2.drv",["out"]),("/nix/store/vr8scnq8lxgc0m6k7bqjwi4fg0k55lxn-data-fix-0.0.4.drv",["out"]),("/nix/store/zdx2r8q401h7xcyh7jg0cnp092iwlhmv-contravariant-1.4.drv",["out"]),("/nix/store/n4wyn46xw0nw8a3rhqw47xd4h6bgnn5w-lens-4.15.1.drv",["out"]),("/nix/store/j6zji0jn6cm8b4i0fmakksk1cp54bhn0-asn1-types-0.3.2.drv",["out"]),("/nix/store/pcg29qa8fm9niixbjy0r7bbp3s4jxk62-neat-interpolation-0.3.2.1.drv",["out"]),("/nix/store/5hx7hjjrwqa4zjd9ql224aif86ncj764-hook.drv",["out"]),("/nix/store/lg64zgciix9644hzkfc02rfbq4qgcrf8-memory-0.14.3.drv",["out"]),("/nix/store/f67vqhk71lrab7ncx8fz8bj7iggmm66f-cryptonite-0.21.drv",["out"]),("/nix/store/5rpa05i9i5p3i0a06lhyvgg1nvlwnlfi-unordered-containers-0.2.8.0.drv",["out"]),("/nix/store/20m5alpbwyvyhh43aq3prw07g48apdnj-parsers-0.12.4.drv",["out"]),("/nix/store/f3l740wl94r84fgsiindy88jppcjya6l-text-format-0.3.1.1.drv",["out"]),("/nix/store/7f6ddryzkw9jckayqs1gdz18njrqd0fq-random-1.1.drv",["out"]),("/nix/store/vwhic7ibwkzqk65mqicb29d5qz06gkns-socks-0.5.5.drv",["out"]),("/nix/store/wld7wjy6lws02rky68mpg0x591wv0j6v-pem-0.2.2.drv",["out"]),("/nix/store/43hyjsydndk7vsdjs94why36s8isn6fw-kan-extensions-5.0.1.drv",["out"]),("/nix/store/ql8bpbnl7x7ybn3rnsknpkpwvlz7s2nz-distributive-0.5.2.drv",["out"]),("/nix/store/s1ymda8d763cn5gq4cw107h19xs1ddz0-ansi-wl-pprint-0.6.7.3.drv",["out"]),("/nix/store/3fji5p4x9j0cb3q3lp8amrj0qak9d471-asn1-encoding-0.9.5.drv",["out"]),("/nix/store/mi1fdfdkc5qc7iq2ry6095ayp9cqn075-x509-system-1.6.4.drv",["out"]),("/nix/store/6qggipw2ra59q6333y25gywllbbcx3p5-hourglass-0.2.10.drv",["out"]),("/nix/store/b67b65arib97rsl4z5iqz03gf24ymvz5-http-types-0.9.1.drv",["out"]),("/nix/store/7d6yxihb828lgs4199f81k17jh8987z6-lndir-1.0.3.drv",["out"]),("/nix/store/pg609c09rfqzyfn8l4hsc1q2xy50w4p8-semigroupoids-5.1.drv",["out"]),("/nix/store/6l4s2nlxc9fq8c3y3j2k2c7af5llx278-hashable-1.2.6.0.drv",["out"]),("/nix/store/5d3v9g9jjqznbpxrlgvcyvmqqz2ffpgc-fingertree-0.1.1.0.drv",["out"]),("/nix/store/ip7nh1r7mj4qwgra27x8i6nyz6yd1ggd-prelude-extras-0.4.0.3.drv",["out"]),("/nix/store/bczn7hbvp39aplp70gvmyijdysvkyspg-primitive-0.6.1.0.drv",["out"]),("/nix/store/x8k0rsb1ig82vdls0dc6jdlny7r04izj-parallel-3.2.1.1.drv",["out"]),("/nix/store/iqd84gv7b8dq5kddxyjimaqqlxjpqdzk-vector-0.11.0.0.drv",["out"]),("/nix/store/1g2qxhbpk7qjyz8qbami29bn7qmnmgpk-tagged-0.8.5.drv",["out"]),("/nix/store/x2dkgpklc1adq1cgg1k8ykdqv7ghwhzm-system-filepath-0.4.13.4.drv",["out"]),("/nix/store/hhx5xjb6cm5rdkri763669bf6karrnpn-parsec-3.1.11.drv",["out"]),("/nix/store/j24c6d5zv7nim3rkmzzapk6x61lzgizq-charset-0.3.7.1.drv",["out"]),("/nix/store/5c748d8gmrmg2gy4792a0kzp5bjw8sgr-cereal-0.5.4.0.drv",["out"]),("/nix/store/mpql2q0b6a1m2vkb114f9l2s8dhy09zv-asn1-parse-0.9.4.drv",["out"]),("/nix/store/4hkya8j2isw660pj6b0q3by85q2wz1zw-free-4.12.4.drv",["out"]),("/nix/store/wdgbs33iwqadfmlaymw00k6iwnf3as7z-mime-types-0.1.0.7.drv",["out"])],["/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"],"x86_64-linux","/nix/store/fi3mbd2ml4pbgzyasrlnp0wyy6qi48fh-bash-4.4-p5/bin/bash",["-e","/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"],[("allowSubstitutes",""),("buildCommand","mkdir -p $out\nfor i in $paths; do\n  /nix/store/lnai0im3lcpb03arxfi0wx1dm7anf4f8-lndir-1.0.3/bin/lndir $i $out\ndone\n. /nix/store/plmya6mkfvq658ba7z6j6n36r5pdbxk5-hook/nix-support/setup-hook\n\n# wrap compiler executables with correct env variables\n\nfor prg in ghc ghci ghc-8.0.2 ghci-8.0.2; do\n  if [[ -x \"/nix/store/s0hpng652hsn40jy4kjdh1x0jm86dx9l-ghc-8.0.2/bin/$prg\" ]]; then\n    rm -f $out/bin/$prg\n    makeWrapper /nix/store/s0hpng652hsn40jy4kjdh1x0jm86dx9l-ghc-8.0.2/bin/$prg $out/bin/$prg                           \\\n      --add-flags '\"-B$NIX_GHC_LIBDIR\"'                   \\\n      --set \"NIX_GHC\"        \"$out/bin/ghc\"     \\\n      --set \"NIX_GHCPKG\"     \"$out/bin/ghc-pkg\" \\\n      --set \"NIX_GHC_DOCDIR\" \"$out/share/doc/ghc/html\"                  \\\n      --set \"NIX_GHC_LIBDIR\" \"$out/lib/ghc-8.0.2\"                  \\\n      \n  fi\ndone\n\nfor prg in runghc runhaskell; do\n  if [[ -x \"/nix/store/s0hpng652hsn40jy4kjdh1x0jm86dx9l-ghc-8.0.2/bin/$prg\" ]]; then\n    rm -f $out/bin/$prg\n    makeWrapper /nix/store/s0hpng652hsn40jy4kjdh1x0jm86dx9l-ghc-8.0.2/bin/$prg $out/bin/$prg                           \\\n      --add-flags \"-f $out/bin/ghc\"                           \\\n      --set \"NIX_GHC\"        \"$out/bin/ghc\"     \\\n      --set \"NIX_GHCPKG\"     \"$out/bin/ghc-pkg\" \\\n      --set \"NIX_GHC_DOCDIR\" \"$out/share/doc/ghc/html\"                  \\\n      --set \"NIX_GHC_LIBDIR\" \"$out/lib/ghc-8.0.2\"\n  fi\ndone\n\nfor prg in ghc-pkg ghc-pkg-8.0.2; do\n  if [[ -x \"/nix/store/s0hpng652hsn40jy4kjdh1x0jm86dx9l-ghc-8.0.2/bin/$prg\" ]]; then\n    rm -f $out/bin/$prg\n    makeWrapper /nix/store/s0hpng652hsn40jy4kjdh1x0jm86dx9l-ghc-8.0.2/bin/$prg $out/bin/$prg --add-flags \"--global-package-db=$out/lib/ghc-8.0.2/package.conf.d\"\n  fi\ndone\n$out/bin/ghc-pkg recache\n\n$out/bin/ghc-pkg check\n\n"),("buildInputs",""),("builder","/nix/store/fi3mbd2ml4pbgzyasrlnp0wyy6qi48fh-bash-4.4-p5/bin/bash"),("extraOutputsToInstall","out doc"),("ignoreCollisions",""),("name","ghc-8.0.2-with-packages"),("nativeBuildInputs",""),("out","/nix/store/w3zbr9zj9mn08hnirn34wsxhry40qi3c-ghc-8.0.2-with-packages"),("passAsFile","buildCommand"),("paths","/nix/store/rlsammwp1ib8d3d9qgbppmdhkbdfg3i9-deriving-compat-0.3.6 /nix/store/v2qsqznrik64f46msahvgg7dmaiag18k-hnix-0.3.4 /nix/store/vbkqj8zdckqqiyjh08ykx75fwc90gwg4-optparse-applicative-0.13.2.0 /nix/store/6m7qia8q0rkdkzvmiak38kdscf27malf-optparse-generic-1.1.5 /nix/store/r687llig7vn9x15hhkmfak01ff7082n6-utf8-string-1.0.1.1 /nix/store/j6gvad67dav8fl3vdbqmar84kgmh5gar-reducers-3.12.1 /nix/store/i8wf08764lknc0f9ja12miqvg509jn1k-fingertree-0.1.1.0 /nix/store/301hq4fabrpbi3l47n908gvakkzq1s88-blaze-markup-0.7.1.1 /nix/store/055mhi44s20x5xgxdjr82vmhnyv79pzl-blaze-html-0.8.1.3 /nix/store/vnc1yyig90skcwx3l1xrbp1jqwmmb9xv-trifecta-1.6.2.1 /nix/store/vraffi24marw5sks8b78xrim6c8i1ng6-double-conversion-2.0.2.0 /nix/store/kwdk03p0lyk5lyll1fp7a6z20j17b3sx-text-format-0.3.1.1 /nix/store/zn5hlw3y94sbli4ssygr2w04mpb396zs-system-filepath-0.4.13.4 /nix/store/jn7lbnk0gsirj8kb02an31v8idy7ym3c-system-fileio-0.3.16.3 /nix/store/9frfci9ywf9lc216ci9nwc1yy0qwrn1b-integer-logarithms-1.0.1 /nix/store/rps46jwa7yyab629p27lar094gk8dal2-scientific-0.3.4.12 /nix/store/c4a3ynvnv3kdxgd7ngmnjhka4mvfk8ll-attoparsec-0.13.1.0 /nix/store/kc34l1gpzh65y4gclmv4dgv6agpmagdi-parsers-0.12.4 /nix/store/1kf78yxf3lliagb5rc5din24iq40g96y-base-prelude-1.0.1.1 /nix/store/hi868d12pkzcbzyvp7a7cigc58mp2lmg-neat-interpolation-0.3.2.1 /nix/store/h00jrbdvzj4yfy796j8vq00lkd1gxr6w-primitive-0.6.1.0 /nix/store/vys8qsf317rn8qwy00p80zlywb47lqwz-vector-0.11.0.0 /nix/store/wchch11312m3lxkwl8rad04x02svcs3i-reflection-2.1.2 /nix/store/jj1kfv52mjxp54flz8v5ba64va3hvy22-parallel-3.2.1.1 /nix/store/jwj23y7vfvs14jdrkw1py9q7lm9fyhy4-adjunctions-4.3 /nix/store/px4979la9b98knwv36551zg3p5jb69lw-kan-extensions-5.0.1 /nix/store/2cp1ar0f73jrcn231ai07zpwayy735j2-semigroupoids-5.1 /nix/store/3nkxw5wdadckz28laijrvwdkkfqp07sb-profunctors-5.2 /nix/store/bd3njvy0ahcsqw47vaz5zayhx34hari7-prelude-extras-0.4.0.3 /nix/store/zdp7zqasz1l1wifpngbg6ngq189gbbqh-free-4.12.4 /nix/store/n7c5ynfqc6j570bbyaajqx34c3pvfvph-tagged-0.8.5 /nix/store/xdkhd7mkqj2mmcami8ycmf7j0valwp5h-distributive-0.5.2 /nix/store/9dxba4g9x0xjj21r3vchqnh4rdwbc31b-void-0.7.2 /nix/store/dahah2ivrn4hc5gjygnlvxlad2399zqh-StateVar-1.1.0.4 /nix/store/f2rdi1bx46fs165n1j316k5w90ab6lwy-contravariant-1.4 /nix/store/mgg9rsvhvn4dd4qzv559nn24iqvspjnb-comonad-5.0.1 /nix/store/18n8i570pf4gpszdyc0bki9qxm1p9xd7-bifunctors-5.4.2 /nix/store/d8ys5wq4wrvdjqw0bzv3y23zqprkhjs2-base-orphans-0.5.4 /nix/store/j4hbyhnj4a2z4z4vb1437vk7ha0b287a-lens-4.15.1 /nix/store/ra3jh12mbyz82n4gvj2bam77vl8aabbq-x509-system-1.6.4 /nix/store/ps8915q1047frp891jg1anp85ads0s9b-x509-validation-1.6.5 /nix/store/5vrgrls6l1cdsbbznis39chx8scq2r98-x509-store-1.6.2 /nix/store/7vvg8y8fp0s50qiciq11irfvh31f1q58-pem-0.2.2 /nix/store/myv75wk9s19f8vms2dcy6sl773288zy4-asn1-parse-0.9.4 /nix/store/kwyc1jdz09lazw21qpc96wyamxalcg11-x509-1.6.5 /nix/store/gadc7c6d1lqn0wqk29bhn56is67x0r45-cryptonite-0.21 /nix/store/ix26y5rpidwpgjzrsixz0ff59j1p1swr-foundation-0.0.7 /nix/store/n784p4qh18zx9v8ag3n3ypszq1kifjjr-memory-0.14.3 /nix/store/h3qq6m5ahdb4kw784gcvx2skil8ilks8-hourglass-0.2.10 /nix/store/dn65dl65spk4j0sky2zpdig75c42ycj1-asn1-types-0.3.2 /nix/store/s5jklkk0y6i7d8h3akgsciv1kv2js786-asn1-encoding-0.9.5 /nix/store/g5qjgns5cyz9c5xw4w5s2iji1kbhg47z-tls-1.3.10 /nix/store/iyllk46by75f428pwis9v74jpr1rmk4x-cereal-0.5.4.0 /nix/store/b22wyyl3wdl6kb7gkpk3yxnynk340lya-socks-0.5.5 /nix/store/05r3i8w2n7hbxqyb4w8rina9rldyacd3-byteable-0.1.1 /nix/store/xjbl6w60czyfqlfwwfs5q93by144yr1n-connection-0.2.8 /nix/store/j10yqzk323rvnwgsk3nj7rgmvqlv035a-http-client-tls-0.3.4.1 /nix/store/vf84v2398g55mai2gjh2d9gipwizhhzd-zlib-0.6.1.2 /nix/store/7h7vy3mi603y536dgvxwfglaacxw5ra8-async-2.1.1.1 /nix/store/y6hh2ifv35afw1j5phpzp1y72x532izn-streaming-commons-0.1.17 /nix/store/f5jdarp8djisa1wrv4bv1saimrabcb3f-random-1.1 /nix/store/18vpnmd28bnjib6andw8bx522wcb3zwa-parsec-3.1.11 /nix/store/i3ra66pcpj0v9wq3m00gh9i72br2bki3-network-uri-2.6.1.0 /nix/store/2ck9avbwacfpi16p2ib2shw951mx33pz-network-2.6.3.1 /nix/store/rz0227nv8n8kdrxjg3arya6r2ixxjh4h-mime-types-0.1.0.7 /nix/store/rx71j4kg0l02dginiswnmwswdq9i9msv-http-types-0.9.1 /nix/store/y2ca4scn0n2f9qsmvsiixcnx11793jlf-transformers-compat-0.5.1.4 /nix/store/bzicr83ibzzzbab6cjkb3i95sc8cvxy9-stm-2.4.4.1 /nix/store/qk5pl6r2h0vfkhhwjgrv8x1ldf8dyj5a-mtl-2.2.1 /nix/store/0d6k71ljl108dgq1l7l3pz12bfwv0z4h-exceptions-0.8.3 /nix/store/z5k23ymwjhhpd670a7mcsm1869hlpncf-old-locale-1.0.0.7 /nix/store/k4an783d4j3m48fqhx7gpnizqg2ns38j-data-default-class-0.1.2.0 /nix/store/p5867jsig02zi0ynww9w4916nm0k527s-cookie-0.4.2.1 /nix/store/wy7j42kqlw1sskagmyc1bzb0xv04s2na-case-insensitive-1.2.0.9 /nix/store/j35339b0nk7k3qaq3m75nl3i4x603rqf-blaze-builder-0.4.0.2 /nix/store/33mip0ql9x1jjbhi34kf8izh4ilyf2k0-base64-bytestring-1.0.0.1 /nix/store/29a73kd2jkwvfdcrhysmi5xjr7nysrxf-http-client-0.5.6.1 /nix/store/d2hy666g79qvhmbh520x5jclwvnr1gk2-text-1.2.2.1 /nix/store/2bdzia66lg08d5zngmllcjry2c08m96j-hashable-1.2.6.0 /nix/store/7kdgc6c0b21s9j5qgg0s0gxj7iid2wk5-unordered-containers-0.2.8.0 /nix/store/zsryzwadshszfnkm740b2412v88iqgi4-semigroups-0.18.2 /nix/store/h2c0kz3m83x6fkl2jzkmin8xvkmfgs7s-charset-0.3.7.1 /nix/store/gapj6j0ya5bi9q9dxspda15k50gx8f1v-ansi-terminal-0.6.2.3 /nix/store/l46769n2p6rlh936zrbwznq3zxxa6mjd-ansi-wl-pprint-0.6.7.3 /nix/store/p7zmpgz0sq5pamgrf1xvhvidc3m4cfmk-dhall-1.3.0 /nix/store/938ndd0mqfm148367lwhl6pk5smv5bm0-data-fix-0.0.4 /nix/store/s0hpng652hsn40jy4kjdh1x0jm86dx9l-ghc-8.0.2"),("preferLocalBuild","1"),("propagatedBuildInputs",""),("propagatedNativeBuildInputs",""),("stdenv","/nix/store/685n25b9yc8sds57vljk459ldly1xyhn-stdenv"),("system","x86_64-linux")])
