elm2nix 0.4.0 → 0.5.0
raw patch · 10 files changed
+301/−310 lines, 10 filesdep +prettyprinterdep −ansi-wl-pprintsetup-changedPVP ok
version bump matches the API change (PVP)
Dependencies added: prettyprinter
Dependencies removed: ansi-wl-pprint
API changes (from Hackage documentation)
Files
- CHANGELOG.md +7/−0
- README.md +15/−67
- Setup.hs +1/−0
- data/default.nix +34/−28
- elm2nix.cabal +7/−6
- elm2nix/Main.hs +26/−21
- src/Elm2Nix.hs +39/−36
- src/Elm2Nix/ElmJson.hs +36/−32
- src/Elm2Nix/FixedOutput.hs +42/−34
- src/Elm2Nix/PackagesSnapshot.hs +94/−86
CHANGELOG.md view
@@ -1,5 +1,12 @@ # Changelog for elm2nix +## Unreleased++## 0.5.0 (2025-09-09)++- Fix inconsistent indentation in generated elm-srcs.nix, now compatible with nixfmt-rfc-style (@sander)+- Format the `default.nix` generated by `elm2nix init`, now compatible with nixfmt-rfc-style (@sander)+ ## 0.4.0 (2024-09-23) - snapshot creates a minimal registry.dat from elm.json without network access (@bmillwood)
README.md view
@@ -1,6 +1,6 @@ # elm2nix -+[](https://github.com/cachix/elm2nix/actions/workflows/test.yml) [](https://hackage.haskell.org/package/elm2nix) Convert an [Elm](http://elm-lang.org/) project into@@ -18,28 +18,22 @@ ## Installation -### From nixpkgs (recommended)--Make sure you have up to date stable or unstable nixpkgs channel.-- $ nix-env -i elm2nix--### From source+It's already included in [devenv](https://devenv.sh/getting-started/) when using Elm: - $ git clone https://github.com/domenkozar/elm2nix.git- $ cd elm2nix- $ nix-env -if .+```nix+{+ langauges.elm.enable = true; -## Usage+ tasks = {+ "frontend:elm2nix" = {+ exec = "cd frontend && elm2nix convert > elm-srcs.nix && elm2nix snapshot";+ execIfModified = [ "frontend/elm.json" ];+ before = [ "devenv:enterShell" ];+ };+ }; - $ git clone https://github.com/evancz/elm-todomvc.git- $ cd elm-todomvc- $ elm2nix init > default.nix- $ elm2nix convert > elm-srcs.nix- # generates ./registry.dat- $ elm2nix snapshot- $ nix-build- $ chromium ./result/Main.html+}+``` ## Running tests (as per CI) @@ -55,53 +49,7 @@ Instead of running `elm2nix init`, create a `default.nix` with the following derivation: -```nix-{ pkgs ? import <nixpkgs> {}-}:--let- yarnPkg = pkgs.mkYarnPackage {- name = "myproject-node-packages";- src = pkgs.lib.cleanSourceWith {- src = ./.;- name = "myproject-node-packages.json";- filter = name: type: baseNameOf (toString name) == "package.json";- };- yarnLock = ./yarn.lock;- publishBinsFor = ["parcel"];- };-in pkgs.stdenv.mkDerivation {- name = "myproject-frontend";- src = pkgs.lib.cleanSource ./.;-- buildInputs = with pkgs.elmPackages; [- elm- elm-format- yarnPkg- pkgs.yarn- ];-- patchPhase = ''- rm -rf elm-stuff- ln -sf ${yarnPkg}/node_modules .- '';-- shellHook = ''- ln -fs ${yarnPkg}/node_modules .- '';-- configurePhase = pkgs.elmPackages.fetchElmDeps {- elmPackages = import ./elm-srcs.nix;- elmVersion = "0.19.1";- registryDat = ./registry.dat;- };-- installPhase = ''- mkdir -p $out- parcel build --dist-dir $out index.html- '';-}-```+https://github.com/cachix/elm2nix/issues/49#issuecomment-1696082884 [parceljs]: https://parceljs.org/ [yarn-v1]: https://classic.yarnpkg.com/lang/en/
Setup.hs view
@@ -1,2 +1,3 @@ import Distribution.Simple+ main = defaultMain
data/default.nix view
@@ -1,24 +1,25 @@-{ nixpkgs ? <nixpkgs>-, config ? {}+{+ nixpkgs ? <nixpkgs>,+ config ? { }, }: with (import nixpkgs config); let mkDerivation =- { srcs ? ./elm-srcs.nix- , src- , name- , srcdir ? "./src"- , targets ? []- , registryDat ? ./registry.dat- , outputJavaScript ? false+ {+ srcs ? ./elm-srcs.nix,+ src,+ name,+ srcdir ? "./src",+ targets ? [ ],+ registryDat ? ./registry.dat,+ outputJavaScript ? false, }: stdenv.mkDerivation { inherit name src; - buildInputs = [ elmPackages.elm ]- ++ lib.optional outputJavaScript nodePackages.uglify-js;+ buildInputs = [ elmPackages.elm ] ++ lib.optional outputJavaScript nodePackages.uglify-js; buildPhase = pkgs.elmPackages.fetchElmDeps { elmPackages = import srcs;@@ -26,27 +27,32 @@ inherit registryDat; }; - installPhase = let- elmfile = module: "\${srcdir}/\${builtins.replaceStrings ["."] ["/"] module}.elm";- extension = if outputJavaScript then "js" else "html";- in ''- mkdir -p \$out/share/doc- \${lib.concatStrings (map (module: ''- echo "compiling \${elmfile module}"- elm make \${elmfile module} --output \$out/\${module}.\${extension} --docs \$out/share/doc/\${module}.json- \${lib.optionalString outputJavaScript ''- echo "minifying \${elmfile module}"- uglifyjs $out/\${module}.\${extension} --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' \\- | uglifyjs --mangle --output $out/\${module}.min.\${extension}- ''}- '') targets)}- '';+ installPhase =+ let+ elmfile = module: "\${srcdir}/\${builtins.replaceStrings [ "." ] [ "/" ] module}.elm";+ extension = if outputJavaScript then "js" else "html";+ in+ ''+ mkdir -p \$out/share/doc+ \${lib.concatStrings (+ map (module: ''+ echo "compiling \${elmfile module}"+ elm make \${elmfile module} --output \$out/\${module}.\${extension} --docs \$out/share/doc/\${module}.json+ \${lib.optionalString outputJavaScript ''+ echo "minifying \${elmfile module}"+ uglifyjs \$out/\${module}.\${extension} --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' \\+ | uglifyjs --mangle --output \$out/\${module}.min.\${extension}+ ''}+ '') targets+ )}+ ''; };-in mkDerivation {+in+mkDerivation { name = "${name}"; srcs = ./elm-srcs.nix; src = ./.;- targets = ["Main"];+ targets = [ "Main" ]; srcdir = "${srcdir}"; outputJavaScript = false; }
elm2nix.cabal view
@@ -1,9 +1,9 @@ name: elm2nix-version: 0.4.0+version: 0.5.0 synopsis: Turn your Elm project into buildable Nix project-description: Please see the README on Github at <https://github.com/domenkozar/elm2nix#readme>-homepage: https://github.com/domenkozar/elm2nix#readme-bug-reports: https://github.com/domenkozar/elm2nix/issues+description: Please see the README on Github at <https://github.com/cachix/elm2nix#readme>+homepage: https://github.com/cachix/elm2nix#readme+bug-reports: https://github.com/cachix/elm2nix/issues author: Domen Kozar maintainer: domen@dev.si copyright: 2017-2022 Domen Kozar@@ -19,7 +19,7 @@ source-repository head type: git- location: https://github.com/domenkozar/elm2nix+ location: https://github.com/cachix/elm2nix library hs-source-dirs:@@ -32,6 +32,7 @@ , binary , containers , here+ , prettyprinter , process , text , transformers@@ -61,7 +62,7 @@ , elm2nix , optparse-applicative , here- , ansi-wl-pprint+ , prettyprinter default-language: Haskell2010 test-suite elm2nix-test
elm2nix/Main.hs view
@@ -1,22 +1,23 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE QuasiQuotes #-}+ module Main- ( main- ) where+ ( main,+ )+where -import Data.Version (showVersion) import Data.String.Here (hereLit)-import Options.Applicative-import System.IO+import Data.Version (showVersion) import qualified Elm2Nix+import Options.Applicative import qualified Paths_elm2nix as This-import qualified Text.PrettyPrint.ANSI.Leijen as PP-+import qualified Prettyprinter as PP+import System.IO data Command = Init | Convert- | Snapshot { elmJson :: FilePath, writeTo :: FilePath }+ | Snapshot {elmJson :: FilePath, writeTo :: FilePath} main :: IO () main = do@@ -26,20 +27,22 @@ case cmd of Convert -> Elm2Nix.convert Init -> Elm2Nix.initialize- Snapshot { elmJson, writeTo } -> Elm2Nix.snapshot elmJson writeTo+ Snapshot {elmJson, writeTo} -> Elm2Nix.snapshot elmJson writeTo getOpts :: IO Command getOpts = customExecParser p (infoH opts rest) where infoH a = info (helper <*> a)- rest = fullDesc- <> progDesc "Convert Elm project to Nix expressions"- <> header ("elm2nix " ++ showVersion This.version)- <> footerDoc (Just $ PP.string exampleText)+ rest =+ fullDesc+ <> progDesc "Convert Elm project to Nix expressions"+ <> header ("elm2nix " ++ showVersion This.version)+ <> footerDoc (Just $ PP.pretty exampleText) p = prefs showHelpOnEmpty exampleText :: String- exampleText = [hereLit|+ exampleText =+ [hereLit| Usage: @@ -57,12 +60,14 @@ <$> (arg "elm-json" <|> pure "elm.json") <*> (arg "write-to" <|> pure "registry.dat") where- arg name = strOption $- long name <> metavar "FILENAME" <> completer (bashCompleter "file")+ arg name =+ strOption $+ long name <> metavar "FILENAME" <> completer (bashCompleter "file") opts :: Parser Command- opts = subparser- ( command "init" (infoH (pure Init) (progDesc "Generate default.nix (printed to stdout)"))- <> command "convert" (infoH (pure Convert) (progDesc "Generate Nix expressions for elm.json using nix-prefetch-url"))- <> command "snapshot" (infoH snapshotOpts (progDesc "Generate registry.dat"))- )+ opts =+ subparser+ ( command "init" (infoH (pure Init) (progDesc "Generate default.nix (printed to stdout)"))+ <> command "convert" (infoH (pure Convert) (progDesc "Generate Nix expressions for elm.json using nix-prefetch-url"))+ <> command "snapshot" (infoH snapshotOpts (progDesc "Generate registry.dat"))+ )
src/Elm2Nix.hs view
@@ -1,30 +1,30 @@-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-} module Elm2Nix- ( convert- , initialize- , snapshot- ) where+ ( convert,+ initialize,+ snapshot,+ )+where import Control.Concurrent.Async (mapConcurrently)-import Control.Monad.IO.Class (liftIO, MonadIO)+import Control.Monad.IO.Class (MonadIO, liftIO) import Control.Monad.Trans.Except (ExceptT, runExceptT, throwE) import Data.List (intercalate) import Data.String.Here import Data.Text (Text)-import System.Exit (exitFailure)-import System.IO (hPutStrLn, stderr)- import qualified Data.Text as Text--import Elm2Nix.ElmJson (Elm2NixError(..), readElmJson, toErrorMessage)-import Elm2Nix.FixedOutput (FixedDerivation(..), prefetch)+import Elm2Nix.ElmJson (Elm2NixError (..), readElmJson, toErrorMessage)+import Elm2Nix.FixedOutput (FixedDerivation (..), prefetch) import Elm2Nix.PackagesSnapshot (snapshot)-+import Prettyprinter (Doc, Pretty (..), align, braces, defaultLayoutOptions, dquotes, equals, layoutPretty, line, nest, punctuate, semi, vsep)+import Prettyprinter.Render.String (renderString)+import System.Exit (exitFailure)+import System.IO (hPutStrLn, stderr) -newtype Elm2Nix a = Elm2Nix { runElm2Nix_ :: ExceptT Elm2NixError IO a }+newtype Elm2Nix a = Elm2Nix {runElm2Nix_ :: ExceptT Elm2NixError IO a} deriving (Functor, Applicative, Monad, MonadIO) runElm2Nix :: Elm2Nix a -> IO (Either Elm2NixError a)@@ -46,10 +46,11 @@ liftIO (putStrLn (generateNixSources sources)) initialize :: IO ()-initialize = runCLI $- liftIO (putStrLn [template|data/default.nix|])+initialize =+ runCLI $+ liftIO (putStrLn [template|data/default.nix|]) where- -- | Converts Package.Name to Nix friendly name+ -- \| Converts Package.Name to Nix friendly name baseName :: Text baseName = "elm-app" version :: Text@@ -67,27 +68,29 @@ runCLI m = do result <- runElm2Nix m case result of- Right a ->- return a- Left err -> do- depErrToStderr err- exitFailure+ Right a ->+ return a+ Left err -> do+ depErrToStderr err+ exitFailure depErrToStderr :: Elm2NixError -> IO () depErrToStderr = hPutStrLn stderr . toErrorMessage generateNixSources :: [FixedDerivation] -> String-generateNixSources dss =- [iTrim|-{-${intercalate "\n" (map f dss)}-}- |]+generateNixSources dss = renderString (layoutPretty defaultLayoutOptions (nixSources dss)) where- f :: FixedDerivation -> String- f ds =- [i|- "${drvName ds}" = {- sha256 = "${drvHash ds}";- version = "${drvVersion ds}";- };|]+ nixSources :: [FixedDerivation] -> Doc ann+ nixSources drvs = braces (nest 2 (line <> vsep entries) <> line)+ where+ entries = map nixEntry drvs++ nixEntry :: FixedDerivation -> Doc ann+ nixEntry drv =+ dquotes (pretty (drvName drv)) <> " = " <> braces (nest 2 (line <> attrs) <> line) <> semi+ where+ attrs =+ vsep+ [ "sha256 = " <> dquotes (pretty (drvHash drv)) <> semi,+ "version = " <> dquotes (pretty (drvVersion drv)) <> semi+ ]
src/Elm2Nix/ElmJson.hs view
@@ -1,13 +1,16 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-}+ module Elm2Nix.ElmJson- ( Dep- , Elm2NixError(..), toErrorMessage- , readElmJson- ) where+ ( Dep,+ Elm2NixError (..),+ toErrorMessage,+ readElmJson,+ )+where import Control.Monad (liftM2)-import Data.Aeson (Value(..))+import Data.Aeson (Value (..)) import Data.List (nub) import Data.Text (Text) @@ -18,18 +21,17 @@ import qualified Data.HashMap.Strict as HM #endif -import qualified Data.ByteString.Lazy as LBS import qualified Data.Aeson as Json+import qualified Data.ByteString.Lazy as LBS import qualified Data.Text as Text - type Dep = (String, String) -data Elm2NixError =- ElmJsonReadError String+data Elm2NixError+ = ElmJsonReadError String | UnexpectedValue Value | KeyNotFound Text- deriving Show+ deriving (Show) toErrorMessage :: Elm2NixError -> String toErrorMessage err =@@ -49,9 +51,11 @@ parseElmJson :: Value -> Either Elm2NixError [Dep] parseElmJson obj =- nub <$> liftM2 (++)- (parseElmJsonDeps "dependencies" obj)- (parseElmJsonDeps "test-dependencies" obj)+ nub+ <$> liftM2+ (++)+ (parseElmJsonDeps "dependencies" obj)+ (parseElmJsonDeps "test-dependencies" obj) parseElmJsonDeps :: Text -> Value -> Either Elm2NixError [Dep] parseElmJsonDeps depsKey obj =@@ -60,35 +64,35 @@ deps <- tryLookup hm depsKey case deps of Object dhm -> do- direct <- tryLookup dhm "direct"+ direct <- tryLookup dhm "direct" indirect <- tryLookup dhm "indirect" liftM2 (++) (parseDeps direct) (parseDeps indirect) v -> Left (UnexpectedValue v) v -> Left (UnexpectedValue v)- where+ #if MIN_VERSION_aeson(2,0,0)- parseDep :: Json.Key -> Value -> Either Elm2NixError Dep- parseDep name (String ver) = Right (Text.unpack (AK.toText name), Text.unpack ver)+parseDep :: Json.Key -> Value -> Either Elm2NixError Dep+parseDep name (String ver) = Right (Text.unpack (AK.toText name), Text.unpack ver) #else- parseDep :: Text -> Value -> Either Elm2NixError Dep- parseDep name (String ver) = Right (Text.unpack name, Text.unpack ver)+parseDep :: Text -> Value -> Either Elm2NixError Dep+parseDep name (String ver) = Right (Text.unpack name, Text.unpack ver) #endif- parseDep _ v = Left (UnexpectedValue v)+parseDep _ v = Left (UnexpectedValue v) - parseDeps :: Value -> Either Elm2NixError [Dep]- parseDeps (Object hm) = mapM (uncurry parseDep) (HM.toList hm)- parseDeps v = Left (UnexpectedValue v)+parseDeps :: Value -> Either Elm2NixError [Dep]+parseDeps (Object hm) = mapM (uncurry parseDep) (HM.toList hm)+parseDeps v = Left (UnexpectedValue v) - maybeToRight :: b -> Maybe a -> Either b a- maybeToRight _ (Just x) = Right x- maybeToRight y Nothing = Left y+maybeToRight :: b -> Maybe a -> Either b a+maybeToRight _ (Just x) = Right x+maybeToRight y Nothing = Left y #if MIN_VERSION_aeson(2,0,0)- tryLookup :: HM.KeyMap Value -> Text -> Either Elm2NixError Value- tryLookup hm key =- maybeToRight (KeyNotFound key) (HM.lookup (AK.fromText key) hm)+tryLookup :: HM.KeyMap Value -> Text -> Either Elm2NixError Value+tryLookup hm key =+ maybeToRight (KeyNotFound key) (HM.lookup (AK.fromText key) hm) #else- tryLookup :: HM.HashMap Text Value -> Text -> Either Elm2NixError Value- tryLookup hm key =- maybeToRight (KeyNotFound key) (HM.lookup key hm)+tryLookup :: HM.HashMap Text Value -> Text -> Either Elm2NixError Value+tryLookup hm key =+ maybeToRight (KeyNotFound key) (HM.lookup key hm) #endif
src/Elm2Nix/FixedOutput.hs view
@@ -1,54 +1,62 @@ {-# LANGUAGE OverloadedStrings #-}+ module Elm2Nix.FixedOutput- ( FixedDerivation(..)- , prefetch- ) where+ ( FixedDerivation (..),+ prefetch,+ )+where +import qualified Data.ByteString.Lazy.Char8 as BS import System.Exit import System.Process-import qualified Data.ByteString.Lazy.Char8 as BS - -- fixed output derivation metadata data FixedDerivation = FixedDerivation- { drvHash :: String -- ^ Computed sha256 hash- , drvPath :: String -- ^ Nix store path of the derivation- , drvUrl :: String -- ^ URL to the tarball- , drvName :: String- , drvVersion :: String- } deriving (Show, Eq)+ { -- | Computed sha256 hash+ drvHash :: String,+ -- | Nix store path of the derivation+ drvPath :: String,+ -- | URL to the tarball+ drvUrl :: String,+ drvName :: String,+ drvVersion :: String+ }+ deriving (Show, Eq) -- | Use nix-prefetch-url to obtain resulting path and it's hash -- | Partially taken from cabal2nix/src/Distribution/Nixpkgs/Fetch.hs prefetch :: String -> String -> IO FixedDerivation prefetch name version = do (Nothing, Just stdoutH, _, processH) <-- createProcess (proc "nix-prefetch-url" args) { env = Nothing- , std_in = Inherit- , std_err = Inherit- , std_out = CreatePipe- }+ createProcess+ (proc "nix-prefetch-url" args)+ { env = Nothing,+ std_in = Inherit,+ std_err = Inherit,+ std_out = CreatePipe+ } exitCode <- waitForProcess processH case exitCode of ExitFailure _ -> error "nix-prefetch-url exited with non-zero"- ExitSuccess -> do+ ExitSuccess -> do buf <- BS.hGetContents stdoutH- let ls = BS.lines buf- case length ls of- 0 -> error "unknown nix-prefetch-url output"- 2 -> return $ FixedDerivation (BS.unpack $ head ls)- (BS.unpack $ head $ tail ls)- url- name- version+ case BS.lines buf of+ [x, xs] ->+ return $+ FixedDerivation+ (BS.unpack x)+ (BS.unpack xs)+ url+ name+ version _ -> error "unknown nix-prefetch-url output" where- url :: String- url =- "https://github.com/"- ++ name- ++ "/archive/"- ++ version- ++ ".tar.gz"- args :: [String]- args = ["--print-path", url]+ url :: String+ url =+ "https://github.com/"+ ++ name+ ++ "/archive/"+ ++ version+ ++ ".tar.gz"+ args :: [String]+ args = ["--print-path", url]
src/Elm2Nix/PackagesSnapshot.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE BangPatterns #-} {- Writes a binary serialized package registry for the Elm compiler to consume. Takes Elm upstream code from:@@ -5,35 +6,34 @@ - https://github.com/elm/compiler/blob/master/compiler/src/Elm/Package.hs -} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE BangPatterns #-}+ module Elm2Nix.PackagesSnapshot- ( snapshot- ) where+ ( snapshot,+ )+where import Control.Monad (liftM2, liftM3)+import Data.Binary (Binary, get, getWord8, put, putWord8) import qualified Data.Binary as Binary-import Data.Binary (Binary, put, get, putWord8, getWord8)-import Data.Binary.Put (putBuilder) import Data.Binary.Get.Internal (readN)-import qualified Data.Map as Map+import Data.Binary.Put (putBuilder)+import qualified Data.ByteString as BS+import qualified Data.ByteString.Builder as BS+import qualified Data.List as List import Data.Map (Map)+import qualified Data.Map as Map import Data.Text (Text) import qualified Data.Text as Text import qualified Data.Text.Encoding as Text import Data.Word (Word16)-import qualified Data.List as List-import qualified Data.ByteString as BS-import qualified Data.ByteString.Builder as BS- import Elm2Nix.ElmJson (readElmJson, toErrorMessage) --data Name =- Name- { _author :: !Text- , _project :: !Text- }- deriving (Eq, Ord)+data Name+ = Name+ { _author :: !Text,+ _project :: !Text+ }+ deriving (Eq, Ord) parseName :: (MonadFail m) => Text -> m Name parseName n =@@ -41,93 +41,101 @@ [author, package] -> pure $ Name author package lst -> fail $ "wrong package name: " <> show lst -data Package =- Package- { _name :: !Name- , _version :: !Version- }- deriving (Eq, Ord)+data Package+ = Package+ { _name :: !Name,+ _version :: !Version+ }+ deriving (Eq, Ord) -data Version =- Version- { _major :: {-# UNPACK #-} !Word16- , _minor :: {-# UNPACK #-} !Word16- , _patch :: {-# UNPACK #-} !Word16- }- deriving (Eq, Ord)+data Version+ = Version+ { _major :: {-# UNPACK #-} !Word16,+ _minor :: {-# UNPACK #-} !Word16,+ _patch :: {-# UNPACK #-} !Word16+ }+ deriving (Eq, Ord) parseVersion :: (MonadFail m) => Text -> m Version parseVersion x =- case Text.splitOn "." x of- [major, minor, patch] ->- return $ Version- (read (Text.unpack major))- (read (Text.unpack minor))- (read (Text.unpack patch))- _ ->- fail "failure parsing version"+ case Text.splitOn "." x of+ [major, minor, patch] ->+ return $+ Version+ (read (Text.unpack major))+ (read (Text.unpack minor))+ (read (Text.unpack patch))+ _ ->+ fail "failure parsing version" -data KnownVersions =- KnownVersions- { _newest :: Version- , _previous :: ![Version]- }+data KnownVersions+ = KnownVersions+ { _newest :: Version,+ _previous :: ![Version]+ } -data Registry =- Registry- { _count :: !Int- , _versions :: !(Map Name KnownVersions)- }+data Registry+ = Registry+ { _count :: !Int,+ _versions :: !(Map Name KnownVersions)+ } putUnder256 :: BS.ByteString -> Binary.Put putUnder256 bs =- do putWord8 (fromIntegral (BS.length bs))- putBuilder (BS.byteString bs)+ do+ putWord8 (fromIntegral (BS.length bs))+ putBuilder (BS.byteString bs) getUnder256 :: Binary.Get (BS.ByteString) getUnder256 =- do word <- getWord8- let !n = fromIntegral word- readN n id+ do+ word <- getWord8+ let !n = fromIntegral word+ readN n id instance Binary Name where get =- liftM2 Name+ liftM2+ Name (fmap Text.decodeUtf8 getUnder256) (fmap Text.decodeUtf8 getUnder256) put (Name author project) =- do putUnder256 (Text.encodeUtf8 author)- putUnder256 (Text.encodeUtf8 project)+ do+ putUnder256 (Text.encodeUtf8 author)+ putUnder256 (Text.encodeUtf8 project) instance Binary Package where get = liftM2 Package get get put (Package name version) =- do put name- put version+ do+ put name+ put version instance Binary Version where get =- do word <- getWord8- if word == 255- then liftM3 Version get get get- else- do minor <- fmap fromIntegral getWord8- patch <- fmap fromIntegral getWord8- return (Version (fromIntegral word) minor patch)+ do+ word <- getWord8+ if word == 255+ then liftM3 Version get get get+ else do+ minor <- fmap fromIntegral getWord8+ patch <- fmap fromIntegral getWord8+ return (Version (fromIntegral word) minor patch) put (Version major minor patch) =- if major < 256 && minor < 256 && patch < 256 then- do putWord8 (fromIntegral major)- putWord8 (fromIntegral minor)- putWord8 (fromIntegral patch)- else- do putWord8 255- put major- put minor- put patch+ if major < 256 && minor < 256 && patch < 256+ then do+ putWord8 (fromIntegral major)+ putWord8 (fromIntegral minor)+ putWord8 (fromIntegral patch)+ else do+ putWord8 255+ put major+ put minor+ put patch instance Binary KnownVersions where get = liftM2 KnownVersions get get@@ -140,11 +148,10 @@ snapshot :: FilePath -> FilePath -> IO () snapshot elmJson writeTo = do deps <- either (error . toErrorMessage) id <$> readElmJson elmJson- let- parseDep (k, v) = do- name <- parseName (Text.pack k)- version <- parseVersion (Text.pack v)- pure (name, [version])+ let parseDep (k, v) = do+ name <- parseName (Text.pack k)+ version <- parseVersion (Text.pack v)+ pure (name, [version]) packages <- toKnownVersions . Map.fromListWith (<>) <$> mapM parseDep deps let size = Map.foldr' addEntry 0 packages registry = Registry size packages@@ -155,10 +162,11 @@ Binary.encodeFile writeTo registry -toKnownVersions :: Map.Map Name [Version] -> Map.Map Name KnownVersions-toKnownVersions =- fmap (\versions ->- case List.sortBy (flip compare) versions of- v:vs -> KnownVersions v vs- [] -> undefined- )+toKnownVersions :: Map.Map Name [Version] -> Map.Map Name KnownVersions+toKnownVersions =+ fmap+ ( \versions ->+ case List.sortBy (flip compare) versions of+ v : vs -> KnownVersions v vs+ [] -> undefined+ )