Add comments

This commit is contained in:
Alexander Bantyev 2020-03-26 13:38:56 +03:00
parent dc671b5151
commit 4db1af47c3
Signed by: balsoft
GPG Key ID: E081FF12ADCB4AD5
2 changed files with 41 additions and 23 deletions

View File

@ -20,10 +20,13 @@ in rec {
phases = [ "buildPhase" ]; phases = [ "buildPhase" ];
}; };
# Generate a nix file from an opam file
opam2nix = { src, opamFile ? findOpamFile src, ... }@args: opam2nix = { src, opamFile ? findOpamFile src, ... }@args:
pkgs.runCommandNoCC (args.pname or opamFile + ".nix") 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"; "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: traverseOPAMRepo = repo: self: super:
let let
pkgNames = builtins.readDir "${repo}/packages"; pkgNames = builtins.readDir "${repo}/packages";
@ -53,6 +56,7 @@ in rec {
}) pkgNames; }) pkgNames;
in opamPkgs; in opamPkgs;
# Same as traverseOPAMRepo, but packages in super take precedence over packages from the new repo.
traverseOPAMRepo' = repo: self: super: traverseOPAMRepo' = repo: self: super:
let traversed = traverseOPAMRepo repo self super; let traversed = traverseOPAMRepo repo self super;
in traversed // builtins.mapAttrs (name: v: in traversed // builtins.mapAttrs (name: v:
@ -60,6 +64,7 @@ in rec {
versions = (traversed.${name} or { versions = { }; }).versions; versions = (traversed.${name} or { versions = { }; }).versions;
}) super; }) super;
# Extension that adds callOPAMPackage to the package set
callOPAMPackage = self: super: { callOPAMPackage = self: super: {
callOPAMPackage = src: newAttrs: overrides: callOPAMPackage = src: newAttrs: overrides:
(self.callPackage (opam2nix (newAttrs // { inherit src; })) (self.callPackage (opam2nix (newAttrs // { inherit src; }))

View File

@ -19,6 +19,8 @@ data OPAM
, checkPhase :: Maybe [[String]] , checkPhase :: Maybe [[String]]
, source :: Maybe String , source :: Maybe String
} deriving Show } deriving Show
-- Turn a description into a nix file
opam2nix :: OPAM -> String opam2nix :: OPAM -> String
opam2nix OPAM {..} = opam2nix OPAM {..} =
let let
@ -62,6 +64,7 @@ opam2nix OPAM {..} =
update :: Maybe a -> a -> Maybe a update :: Maybe a -> a -> Maybe a
update old new = if isNothing old then Just new else old update old new = if isNothing old then Just new else old
-- Evaluate a Field and update OPAM description accordingly
evaluateField :: OPAM -> Field -> OPAM evaluateField :: OPAM -> Field -> OPAM
evaluateField o@OPAM {..} = \case evaluateField o@OPAM {..} = \case
Name s -> o { name = update name s } Name s -> o { name = update name s }
@ -86,29 +89,18 @@ evaluateField o@OPAM {..} = \case
evaluateFields :: OPAM -> [Field] -> OPAM evaluateFields :: OPAM -> [Field] -> OPAM
evaluateFields = foldl evaluateField evaluateFields = foldl evaluateField
-- Descriptions for various Fields of an opam file
data Package data Package
= Package = Package
{ identifier :: String { identifier :: String
, additionalPackageInfo :: [String] , additionalPackageInfo :: [String]
} deriving Show } deriving Show
-- An expression as found in a Command
data Exp = Str String | Var String deriving Show 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 :: Exp -> String
evaluateExp = evaluateExp =
let let
@ -126,9 +118,27 @@ evaluateExp =
Var "jobs" -> "1" Var "jobs" -> "1"
Var s -> "${"<>s<>"}" 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 :: ParsecT String u Identity [Field]
opamFile = many field <* eof opamFile = many field <* eof
-- Each has a name and a type;
field :: ParsecT String u Identity Field field :: ParsecT String u Identity Field
field = Name <$> fieldParser "name" stringParser field = Name <$> fieldParser "name" stringParser
<|> Version <$> fieldParser "version" stringParser <|> Version <$> fieldParser "version" stringParser
@ -137,40 +147,43 @@ field = Name <$> fieldParser "name" stringParser
<|> sectionParser "url" (URL <$> (fieldParser "src" stringParser <* many (noneOf "}"))) <|> sectionParser "url" (URL <$> (fieldParser "src" stringParser <* many (noneOf "}")))
<|> Other <$> (many (noneOf "\n") <* char '\n') <|> 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 :: 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 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 :: 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 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 :: ParsecT String u Identity String
stringParser = between (char '"') (char '"') (many $ noneOf "\"") stringParser = between (char '"') (char '"') (many $ noneOf "\"")
-- Expression is either a string or a variable
expParser :: ParsecT String u Identity Exp expParser :: ParsecT String u Identity Exp
expParser = try (Str <$> stringParser) expParser = try (Str <$> stringParser)
<|> Var <$> many1 (noneOf " \n\"{}[]") <|> Var <$> many1 (noneOf " \n\"{}[]")
-- "Additional Info" is additional information about a package or command, "{like-this}"
additionalInfoParser :: ParsecT String u Identity [String] additionalInfoParser :: ParsecT String u Identity [String]
additionalInfoParser = option [] $ try additionalInfoParser = option [] $ try
$ between (many (char ' ') >> char '{') (char '}') $ between (many (char ' ') >> char '{') (char '}')
((many $ noneOf " &}") `sepBy` (oneOf " &")) ((many $ noneOf " &}") `sepBy` (oneOf " &"))
-- Command is a [expressions] with additionional information
commandParser :: ParsecT String u Identity Command commandParser :: ParsecT String u Identity Command
commandParser = do commandParser = Command <$> (listParser $ try expParser) <*> additionalInfoParser
command <- listParser $ try expParser
additionalInfo <- additionalInfoParser
return $ Command command additionalInfo
-- Comment starts with # and goes to the end of line
commentParser :: ParsecT String u Identity () commentParser :: ParsecT String u Identity ()
commentParser = optional $ do commentParser = optional $ do
void $ string "#" void $ string "#"
many $ noneOf "\n" many $ noneOf "\n"
-- Package is a "string" with additional information
packageParser :: ParsecT String u Identity Package packageParser :: ParsecT String u Identity Package
packageParser = do packageParser = Package <$> stringParser <*> additionalInfoParser
name <- stringParser
additionalInfo <- additionalInfoParser
return $ Package name additionalInfo
listParser :: ParsecT String u Identity t -> ParsecT String u Identity [t] listParser :: ParsecT String u Identity t -> ParsecT String u Identity [t]
listParser valueParser = listParser valueParser =