Skip to content

Commit 2819a59

Browse files
authored
Add support for the new LTS formats. (input-output-hk#78)
* Add support for the new LTS formats. * Cleanup * drop pkg_versions.txt
1 parent 6ab8159 commit 2819a59

File tree

3 files changed

+58
-31
lines changed

3 files changed

+58
-31
lines changed

nix-tools/lib/Stack2nix/Stack.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module Stack2nix.Stack
1515
, StackSnapshot(..)
1616
, PackageFlags
1717
, GhcOptions
18+
, parsePackageIdentifier
1819
) where
1920

2021
import Data.Char (isDigit)
@@ -162,6 +163,12 @@ suffix = option Nothing (Just <$> (Left <$> sha256Suffix) +++ (Right <$> revSuff
162163
pkgIndex :: ReadP r Dependency
163164
pkgIndex = PkgIndex <$> parse <*> suffix <* eof
164165

166+
167+
parsePackageIdentifier :: String -> Maybe (PackageIdentifier, Maybe (Either Sha256 CabalRev))
168+
parsePackageIdentifier input = case readP_to_S pkgIndex input of
169+
[(PkgIndex d rev,"")] -> Just (d, rev)
170+
_ -> Nothing
171+
165172
--------------------------------------------------------------------------------
166173
-- JSON/YAML destructors
167174

nix-tools/lts2nix/Main.hs

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,32 @@
33
{-# LANGUAGE OverloadedStrings #-}
44
module Main where
55

6-
import Data.Foldable (toList)
7-
import System.Environment (getArgs)
6+
import System.Environment (getArgs,lookupEnv)
7+
import Data.Maybe (fromMaybe)
8+
9+
import Distribution.Text (disp)
810

911
import Data.Yaml (decodeFileEither)
1012

13+
import Data.Text (Text)
14+
import qualified Data.Text as Text
15+
1116
import Nix.Pretty (prettyNix)
1217
import Nix.Expr
1318

1419
import Data.Aeson
1520
import qualified Data.HashMap.Strict as Map
21+
import qualified Data.Vector as V
1622
import Lens.Micro
1723
import Lens.Micro.Aeson
1824

1925
import Cabal2Nix.Plan
2026

27+
import Stack2nix.Stack (parsePackageIdentifier)
28+
import Distribution.Types.PackageId
29+
30+
type CompilerPackages = Map.HashMap Text (Map.HashMap Text Text)
31+
2132
main :: IO ()
2233
main = getArgs >>= \case
2334
[file] -> do
@@ -26,34 +37,42 @@ main = getArgs >>= \case
2637

2738
ltsPackages :: FilePath -> IO NExpr
2839
ltsPackages lts = do
40+
-- use yaml here, so we don't have to deal with yaml AND json.
41+
-- pull it from https://raw.githubusercontent.com/commercialhaskell/stackage-content/master/stack/global-hints.yaml
42+
cpYaml <- fromMaybe "./global-hints.yaml" <$> lookupEnv "GLOBAL_HINTS"
43+
compilerPackages <- decodeFileEither cpYaml >>= \case
44+
Left e -> error $ "Parsing " ++ show cpYaml ++ ": " ++ show e
45+
Right value -> pure value
2946
evalue <- decodeFileEither lts
3047
case evalue of
31-
Left e -> error (show e)
32-
Right value -> pure $ plan2nix $ lts2plan value
33-
34-
lts2plan :: Value -> Plan
35-
lts2plan lts = Plan { packages , compilerVersion , compilerPackages }
36-
where
37-
packages = mappend compilerPackages' $ fmap Just $ lts ^. key "packages" . _Object <&> \v -> Package
38-
{ packageVersion = v ^. key "version" . _String
39-
, packageRevision = v ^? key "cabal-file-info" . key "hashes" . key "SHA256" . _String
40-
, packageFlags = Map.mapMaybe (^? _Bool) $ v ^. key "constraints" . key "flags" . _Object
41-
}
42-
compilerVersion = lts ^. key "system-info" . key "ghc-version" . _String
43-
compilerPackages =
44-
(lts ^. key "system-info" . key "core-packages" . _Object <&> (Just . (^. _String)))
45-
<> Map.fromList
46-
[ (p, Nothing) -- core-executables is just a list of
47-
-- exe names shipped with GHC, which
48-
-- lots of packages depend on
49-
-- (e.g. hsc2hs)
50-
| p <- toList $ lts ^. key "system-info" . key "core-executables" . _Array <&> (^. _String)
51-
]
52-
compilerPackages' = fmap
53-
(fmap $ \v -> Package
54-
{ packageVersion = v
55-
, packageRevision = Nothing
56-
, packageFlags = Map.empty
57-
}
58-
)
59-
compilerPackages
48+
Left e -> error $ "Parsing " ++ show lts ++ ": " ++ show e
49+
Right value -> pure $ plan2nix $ lts2plan compilerPackages value
50+
51+
-- pretty crude hack to get the compiler version. Assuming ghc-X.Y.Z
52+
parseCompilerVersion :: Text -> Text
53+
parseCompilerVersion c
54+
| "ghc-" `Text.isPrefixOf` c = Text.drop 4 c
55+
| otherwise = error $ "Unable to parse version from compiler: " ++ Text.unpack c
56+
57+
lts2plan :: CompilerPackages -> Value -> Plan
58+
lts2plan compilerPackagesMap lts = Plan { packages, compilerVersion, compilerPackages }
59+
where
60+
compilerName = lts ^. key "resolver" . key "compiler" . _String
61+
compilerVersion = parseCompilerVersion compilerName
62+
compilerPackages = Just <$> Map.lookupDefault (error $ "failed to lookup the compiler packages for compiler: " ++ Text.unpack compilerName) compilerName compilerPackagesMap
63+
64+
-- turn flags into HashMap Text (HashMap Text Bool)
65+
flags :: Map.HashMap Text (Map.HashMap Text Bool)
66+
flags = lts ^. key "flags" . _Object <&> (\v -> Map.mapMaybe (^? _Bool) $ v ^. _Object)
67+
packages = Map.fromList . V.toList $ lts ^. key "packages" . _Array <&> \v ->
68+
let (pkg, rev) = case (parsePackageIdentifier . Text.unpack $ v ^. key "hackage" . _String) of
69+
Just p -> p
70+
_ -> error $ "failed to parse: " ++ Text.unpack (v ^. key "hackage" . _String)
71+
name = Text.pack (show (disp (pkgName pkg)))
72+
in (name, Just $ Package
73+
{ packageVersion = Text.pack (show (disp (pkgVersion pkg)))
74+
, packageRevision = case rev of
75+
Just (Left sha) -> Just $ Text.pack sha
76+
_ -> Nothing
77+
, packageFlags = Map.lookupDefault Map.empty name flags
78+
})

nix-tools/nix-tools.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ executable lts-to-nix
152152
, filepath
153153
, directory
154154
, unordered-containers
155+
, vector
155156
, Cabal
156157
hs-source-dirs: lts2nix
157158
default-language: Haskell2010

0 commit comments

Comments
 (0)