Add comments
This commit is contained in:
parent
dc671b5151
commit
4db1af47c3
@ -20,10 +20,13 @@ in rec {
|
||||
phases = [ "buildPhase" ];
|
||||
};
|
||||
|
||||
# Generate a nix file from an opam file
|
||||
opam2nix = { src, opamFile ? findOpamFile src, ... }@args:
|
||||
pkgs.runCommandNoCC (args.pname or opamFile + ".nix") args
|
||||
"cat ${src}/${opamFile} | ${pkgs.glibc.bin}/bin/iconv -c -f utf-8 -t ascii | ${opam-parser} > $out";
|
||||
|
||||
# Traverse OPAM repository, producing an extension to
|
||||
# ocamlPackages than includes all the packages in the repo.
|
||||
traverseOPAMRepo = repo: self: super:
|
||||
let
|
||||
pkgNames = builtins.readDir "${repo}/packages";
|
||||
@ -53,6 +56,7 @@ in rec {
|
||||
}) pkgNames;
|
||||
in opamPkgs;
|
||||
|
||||
# Same as traverseOPAMRepo, but packages in super take precedence over packages from the new repo.
|
||||
traverseOPAMRepo' = repo: self: super:
|
||||
let traversed = traverseOPAMRepo repo self super;
|
||||
in traversed // builtins.mapAttrs (name: v:
|
||||
@ -60,6 +64,7 @@ in rec {
|
||||
versions = (traversed.${name} or { versions = { }; }).versions;
|
||||
}) super;
|
||||
|
||||
# Extension that adds callOPAMPackage to the package set
|
||||
callOPAMPackage = self: super: {
|
||||
callOPAMPackage = src: newAttrs: overrides:
|
||||
(self.callPackage (opam2nix (newAttrs // { inherit src; }))
|
||||
|
@ -19,6 +19,8 @@ data OPAM
|
||||
, checkPhase :: Maybe [[String]]
|
||||
, source :: Maybe String
|
||||
} deriving Show
|
||||
|
||||
-- Turn a description into a nix file
|
||||
opam2nix :: OPAM -> String
|
||||
opam2nix OPAM {..} =
|
||||
let
|
||||
@ -62,6 +64,7 @@ opam2nix OPAM {..} =
|
||||
update :: Maybe a -> a -> Maybe a
|
||||
update old new = if isNothing old then Just new else old
|
||||
|
||||
-- Evaluate a Field and update OPAM description accordingly
|
||||
evaluateField :: OPAM -> Field -> OPAM
|
||||
evaluateField o@OPAM {..} = \case
|
||||
Name s -> o { name = update name s }
|
||||
@ -86,29 +89,18 @@ evaluateField o@OPAM {..} = \case
|
||||
evaluateFields :: OPAM -> [Field] -> OPAM
|
||||
evaluateFields = foldl evaluateField
|
||||
|
||||
|
||||
-- Descriptions for various Fields of an opam file
|
||||
|
||||
data Package
|
||||
= Package
|
||||
{ identifier :: String
|
||||
, additionalPackageInfo :: [String]
|
||||
} deriving Show
|
||||
|
||||
-- An expression as found in a Command
|
||||
data Exp = Str String | Var String deriving Show
|
||||
|
||||
data Command
|
||||
= Command
|
||||
{ command :: [Exp]
|
||||
, additionalCommandInfo :: [String]
|
||||
} deriving Show
|
||||
|
||||
data Field
|
||||
= Name String
|
||||
| Version String
|
||||
| Depends [Package]
|
||||
| Build [Command]
|
||||
| URL String
|
||||
| Other String
|
||||
deriving Show
|
||||
|
||||
evaluateExp :: Exp -> String
|
||||
evaluateExp =
|
||||
let
|
||||
@ -126,9 +118,27 @@ evaluateExp =
|
||||
Var "jobs" -> "1"
|
||||
Var s -> "${"<>s<>"}"
|
||||
|
||||
data Command
|
||||
= Command
|
||||
{ command :: [Exp]
|
||||
, additionalCommandInfo :: [String]
|
||||
} deriving Show
|
||||
|
||||
data Field
|
||||
= Name String
|
||||
| Version String
|
||||
| Depends [Package]
|
||||
| Build [Command]
|
||||
| URL String
|
||||
| Other String
|
||||
deriving Show
|
||||
|
||||
|
||||
-- An opam file is a collection of fields,
|
||||
opamFile :: ParsecT String u Identity [Field]
|
||||
opamFile = many field <* eof
|
||||
|
||||
-- Each has a name and a type;
|
||||
field :: ParsecT String u Identity Field
|
||||
field = Name <$> fieldParser "name" stringParser
|
||||
<|> Version <$> fieldParser "version" stringParser
|
||||
@ -137,40 +147,43 @@ field = Name <$> fieldParser "name" stringParser
|
||||
<|> sectionParser "url" (URL <$> (fieldParser "src" stringParser <* many (noneOf "}")))
|
||||
<|> Other <$> (many (noneOf "\n") <* char '\n')
|
||||
|
||||
-- Field's structure is "name: value"
|
||||
fieldParser :: String -> ParsecT String u Identity t -> ParsecT String u Identity t
|
||||
fieldParser name valueParser = try $ between (string (name<>":") >> many (oneOf " \n")) (many $ oneOf " \n") valueParser <* commentParser
|
||||
|
||||
-- Sections's structure is "name { fields }"
|
||||
sectionParser :: String -> ParsecT String u Identity t -> ParsecT String u Identity t
|
||||
sectionParser name valueParser = try $ between (string name >> many (oneOf " ") >> string "{" >> many (oneOf " \n")) (many (oneOf " \n") >> char '}' >> char '\n') valueParser
|
||||
|
||||
-- String is enclosed in quotes
|
||||
stringParser :: ParsecT String u Identity String
|
||||
stringParser = between (char '"') (char '"') (many $ noneOf "\"")
|
||||
|
||||
-- Expression is either a string or a variable
|
||||
expParser :: ParsecT String u Identity Exp
|
||||
expParser = try (Str <$> stringParser)
|
||||
<|> Var <$> many1 (noneOf " \n\"{}[]")
|
||||
|
||||
-- "Additional Info" is additional information about a package or command, "{like-this}"
|
||||
additionalInfoParser :: ParsecT String u Identity [String]
|
||||
additionalInfoParser = option [] $ try
|
||||
$ between (many (char ' ') >> char '{') (char '}')
|
||||
((many $ noneOf " &}") `sepBy` (oneOf " &"))
|
||||
|
||||
-- Command is a [expressions] with additionional information
|
||||
commandParser :: ParsecT String u Identity Command
|
||||
commandParser = do
|
||||
command <- listParser $ try expParser
|
||||
additionalInfo <- additionalInfoParser
|
||||
return $ Command command additionalInfo
|
||||
commandParser = Command <$> (listParser $ try expParser) <*> additionalInfoParser
|
||||
|
||||
-- Comment starts with # and goes to the end of line
|
||||
commentParser :: ParsecT String u Identity ()
|
||||
commentParser = optional $ do
|
||||
void $ string "#"
|
||||
many $ noneOf "\n"
|
||||
|
||||
-- Package is a "string" with additional information
|
||||
packageParser :: ParsecT String u Identity Package
|
||||
packageParser = do
|
||||
name <- stringParser
|
||||
additionalInfo <- additionalInfoParser
|
||||
return $ Package name additionalInfo
|
||||
packageParser = Package <$> stringParser <*> additionalInfoParser
|
||||
|
||||
|
||||
listParser :: ParsecT String u Identity t -> ParsecT String u Identity [t]
|
||||
listParser valueParser =
|
||||
|
Loading…
Reference in New Issue
Block a user