forked from maralorn/nix-output-monitor
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Nix.Derivation: vendor parser from sorki's Haskell-Nix-Derivation-Lib…
…rary fork All credit goes to @sorki and @rickynils for their work on: - Gabriella439/Haskell-Nix-Derivation-Library#26 - Gabriella439/Haskell-Nix-Derivation-Library#24 and of course to @Gabriella439 for the entire library! This commit takes the changes relevant to `Nix.Derivation` and vendors them in-tree. Co-Authored-By: Gabriella Gonzalez <[email protected]> Co-Authored-By: sorki <[email protected]> Co-Authored-By: Rickard Nilsson <[email protected]>
- Loading branch information
1 parent
7c72280
commit ed3d927
Showing
6 changed files
with
309 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
module Nix.Derivation | ||
( -- * Types | ||
Derivation (..), | ||
DerivationInputs (..), | ||
DerivationOutput (..), | ||
|
||
-- * Parse derivations | ||
parseDerivation, | ||
parseDerivationWith, | ||
textParser, | ||
) | ||
where | ||
|
||
import Nix.Derivation.Parser | ||
( parseDerivation, | ||
parseDerivationWith, | ||
textParser, | ||
) | ||
import Nix.Derivation.Types | ||
( Derivation (..), | ||
DerivationInputs (..), | ||
DerivationOutput (..), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
{-# LANGUAGE MultiWayIf #-} | ||
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-} | ||
|
||
-- | Parsing logic | ||
module Nix.Derivation.Parser | ||
( -- * Parser | ||
parseDerivation, | ||
parseDerivationWith, | ||
textParser, | ||
) | ||
where | ||
|
||
import Control.Applicative (Applicative (pure)) | ||
import Control.Monad (MonadFail (fail)) | ||
import Data.Attoparsec.Text qualified | ||
import Data.Attoparsec.Text.Lazy (Parser) | ||
import Data.Attoparsec.Text.Lazy qualified | ||
import Data.Bool (Bool (..), not, otherwise, (&&), (||)) | ||
import Data.Eq (Eq (..)) | ||
import Data.Functor ((<$>)) | ||
import Data.Map (Map) | ||
import Data.Map qualified | ||
import Data.Maybe (Maybe (Just)) | ||
import Data.Monoid (Monoid (mempty)) | ||
import Data.Ord (Ord) | ||
import Data.Semigroup (Semigroup ((<>))) | ||
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 Nix.Derivation.Types | ||
( Derivation (..), | ||
DerivationInputs (..), | ||
DerivationOutput (..), | ||
) | ||
import System.FilePath (FilePath) | ||
import System.FilePath qualified | ||
|
||
listOf :: Parser a -> Parser [a] | ||
listOf element = do | ||
"[" | ||
es <- Data.Attoparsec.Text.Lazy.sepBy element "," | ||
"]" | ||
pure es | ||
|
||
-- | Parse a derivation | ||
parseDerivation :: | ||
Parser | ||
( Derivation | ||
FilePath | ||
Text | ||
Text | ||
DerivationOutput | ||
DerivationInputs | ||
) | ||
parseDerivation = | ||
parseDerivationWith | ||
textParser | ||
textParser | ||
(parseDerivationOutputWith filepathParser) | ||
(parseDerivationInputsWith filepathParser textParser) | ||
|
||
-- | Parse a derivation using custom | ||
-- parsers for filepaths, texts, outputNames and derivation inputs/outputs | ||
parseDerivationWith :: | ||
( Ord txt, | ||
Ord outputName | ||
) => | ||
Parser txt -> | ||
Parser outputName -> | ||
Parser (drvOutput fp) -> | ||
Parser (drvInputs fp outputName) -> | ||
Parser (Derivation fp txt outputName drvOutput drvInputs) | ||
parseDerivationWith string outputName parseOutput parseInputs = do | ||
"Derive(" | ||
let keyValue0 = do | ||
"(" | ||
key <- outputName | ||
"," | ||
out <- parseOutput | ||
")" | ||
pure (key, out) | ||
outputs <- mapOf keyValue0 | ||
"," | ||
inputs <- parseInputs | ||
"," | ||
platform <- string | ||
"," | ||
builder <- string | ||
"," | ||
args <- vectorOf string | ||
"," | ||
let keyValue1 = do | ||
"(" | ||
key <- string | ||
"," | ||
value <- string | ||
")" | ||
pure (key, value) | ||
env <- mapOf keyValue1 | ||
")" | ||
pure Derivation {..} | ||
|
||
-- | Parse a derivation output | ||
parseDerivationOutputWith :: | ||
( Eq fp, | ||
Monoid fp | ||
) => | ||
Parser fp -> | ||
Parser (DerivationOutput fp) | ||
parseDerivationOutputWith filepath = do | ||
path <- filepath | ||
"," | ||
hashAlgo <- textParser | ||
"," | ||
hash <- textParser | ||
if | ||
| path /= mempty && hashAlgo == mempty && hash == mempty -> | ||
pure DerivationOutput {..} | ||
| path /= mempty && hashAlgo /= mempty && hash /= mempty -> | ||
pure FixedDerivationOutput {..} | ||
| path == mempty && hashAlgo /= mempty && hash == mempty -> | ||
pure ContentAddressedDerivationOutput {..} | ||
| otherwise -> | ||
fail "bad output in derivation" | ||
|
||
-- | Parse a derivation inputs | ||
parseDerivationInputsWith :: | ||
( Ord fp, | ||
Ord outputName | ||
) => | ||
Parser fp -> | ||
Parser outputName -> | ||
Parser (DerivationInputs fp outputName) | ||
parseDerivationInputsWith filepath outputName = do | ||
let keyValue = do | ||
"(" | ||
key <- filepath | ||
"," | ||
value <- setOf outputName | ||
")" | ||
pure (key, value) | ||
drvs <- mapOf keyValue | ||
"," | ||
srcs <- setOf filepath | ||
pure DerivationInputs {..} | ||
|
||
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 | ||
|
||
filepathParser :: Parser FilePath | ||
filepathParser = do | ||
text <- textParser | ||
let str = Data.Text.unpack text | ||
case (Data.Text.uncons text, System.FilePath.isValid str) of | ||
(Just ('/', _), True) -> do | ||
pure str | ||
_ -> do | ||
fail ("bad path ‘" <> Data.Text.unpack text <> "’ in derivation") | ||
|
||
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
{-# OPTIONS_GHC -Wno-partial-fields #-} | ||
-- | Shared types | ||
module Nix.Derivation.Types | ||
( -- * Types | ||
Derivation (..), | ||
DerivationInputs (..), | ||
DerivationOutput (..), | ||
) | ||
where | ||
|
||
import Control.DeepSeq (NFData) | ||
import Data.Map (Map) | ||
import Data.Set (Set) | ||
import Data.Text (Text) | ||
import Data.Vector (Vector) | ||
import GHC.Generics (Generic) | ||
import Prelude (Eq, Ord, Show) | ||
|
||
-- | A Nix derivation | ||
data Derivation fp txt outputName drvOutput drvInputs = Derivation | ||
{ -- | Outputs produced by this derivation where keys are output names | ||
outputs :: Map outputName (drvOutput fp), | ||
-- | Inputs (sources and derivations) | ||
inputs :: drvInputs fp outputName, | ||
-- | Platform required for this derivation | ||
platform :: txt, | ||
-- | Code to build the derivation, which can be a path or a builtin function | ||
builder :: txt, | ||
-- | Arguments passed to the executable used to build to derivation | ||
args :: Vector txt, | ||
-- | Environment variables provided to the executable used to build the | ||
-- derivation | ||
env :: Map txt txt | ||
} | ||
deriving stock (Eq, Generic, Ord, Show) | ||
|
||
instance | ||
( NFData fp, | ||
NFData txt, | ||
NFData outputName, | ||
NFData (drvOutput fp), | ||
NFData (drvInputs fp outputName) | ||
) => | ||
NFData (Derivation fp txt outputName drvOutput drvInputs) | ||
|
||
data DerivationInputs fp drvOutput = DerivationInputs | ||
{ -- | Inputs that are derivations where keys specify derivation paths and | ||
-- values specify which output names are used by this derivation | ||
drvs :: Map fp (Set drvOutput), | ||
-- | Inputs that are sources | ||
srcs :: Set fp | ||
} | ||
deriving stock (Eq, Generic, Ord, Show) | ||
|
||
instance (NFData a, NFData b) => NFData (DerivationInputs a b) | ||
|
||
-- | An output of a Nix derivation | ||
data DerivationOutput fp | ||
= DerivationOutput | ||
{ -- | Path where the output will be saved | ||
path :: fp | ||
} | ||
| FixedDerivationOutput | ||
{ -- | Path where the output will be saved | ||
path :: fp, | ||
-- | Hash used for expected hash computation | ||
hashAlgo :: Text, | ||
-- | Expected hash | ||
hash :: Text | ||
} | ||
| ContentAddressedDerivationOutput | ||
{ -- | Hash used for expected hash computation | ||
hashAlgo :: Text | ||
} | ||
deriving stock (Eq, Generic, Ord, Show) | ||
|
||
instance (NFData a) => NFData (DerivationOutput a) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters