diff --git a/app/Niv.hs b/app/Niv.hs index 2603ab0..22a7b6d 100644 --- a/app/Niv.hs +++ b/app/Niv.hs @@ -1,4 +1,5 @@ {-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} @@ -11,6 +12,7 @@ import Control.Monad import Control.Monad.State import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey) import Data.Char (isSpace, toUpper) +import Data.FileEmbed (embedFile) import Data.Functor ((<&>)) import Data.Hashable (Hashable) import Data.Maybe (mapMaybe, fromMaybe) @@ -23,6 +25,7 @@ import UnliftIO import qualified Data.Aeson as Aeson import qualified Data.Aeson.Encode.Pretty as AesonPretty import qualified Data.ByteString as B +import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy as L import qualified Data.HashMap.Strict as HMap import qualified Data.Text as T @@ -319,7 +322,7 @@ cmdInit = do if shouldUpdateNixSourcesNix content then do putStrLn "Updating sources.nix" - writeFile path initNixSourcesNixContent + B.writeFile path initNixSourcesNixContent else putStrLn "Not updating sources.nix" ) , ( pathNixSourcesJson @@ -336,14 +339,14 @@ cmdInit = do , \path _content -> dontCreateFile path) ] $ \(path, onCreate, onUpdate) -> do exists <- Dir.doesFileExist path - if exists then readFile path >>= onUpdate path else onCreate path + if exists then B.readFile path >>= onUpdate path else onCreate path where - createFile :: FilePath -> String -> IO () + createFile :: FilePath -> B.ByteString -> IO () createFile path content = do let dir = takeDirectory path Dir.createDirectoryIfMissing True dir putStrLn $ "Creating " <> path - writeFile path content + B.writeFile path content dontCreateFile :: FilePath -> IO () dontCreateFile path = putStrLn $ "Not creating " <> path @@ -611,24 +614,24 @@ nixPrefetchURL unpack url = -- | Checks if content is different than default and if it does /not/ contain -- a comment line with @niv: no_update@ -shouldUpdateNixSourcesNix :: String -> Bool +shouldUpdateNixSourcesNix :: B.ByteString -> Bool shouldUpdateNixSourcesNix content = content /= initNixSourcesNixContent && - not (any lineForbids (lines content)) + not (any lineForbids (B8.lines content)) where - lineForbids :: String -> Bool + lineForbids :: B8.ByteString -> Bool lineForbids str = - case dropWhile isSpace str of - '#':rest -> case dropWhile isSpace rest of - 'n':'i':'v':':':rest' -> case dropWhile isSpace rest' of - 'n':'o':'_':'u':'p':'d':'a':'t':'e':_ -> True + case B8.uncons (B8.dropWhile isSpace str) of + Just ('#',rest) -> case B8.stripPrefix "niv:" (B8.dropWhile isSpace rest) of + Just rest' -> case B8.stripPrefix "no_update" (B8.dropWhile isSpace rest') of + Just{} -> True _ -> False _ -> False _ -> False warnIfOutdated :: IO () warnIfOutdated = do - tryAny (readFile pathNixSourcesNix) >>= \case + tryAny (B.readFile pathNixSourcesNix) >>= \case Left e -> putStrLn $ unlines [ "Could not read " <> pathNixSourcesNix , "Error: " <> show e @@ -650,51 +653,15 @@ pathNixSourcesNix :: FilePath pathNixSourcesNix = "nix" "sources.nix" -- | Glue code between nix and sources.json -initNixSourcesNixContent :: String -initNixSourcesNixContent = [s| -# This file has been generated by Niv. - -# A record, from name to path, of the third-party packages -with rec -{ - pkgs = import {}; - - sources = builtins.fromJSON (builtins.readFile ./sources.json); - - mapAttrs = builtins.mapAttrs or - (f: set: with builtins; - listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))); - - getFetcher = spec: - let fetcherName = - if builtins.hasAttr "type" spec - then builtins.getAttr "type" spec - else "tarball"; - in builtins.getAttr fetcherName { - "tarball" = pkgs.fetchzip; - "file" = pkgs.fetchurl; - }; -}; -# NOTE: spec must _not_ have an "outPath" attribute -mapAttrs (_: spec: - if builtins.hasAttr "outPath" spec - then abort - "The values in sources.json should not have an 'outPath' attribute" - else - if builtins.hasAttr "url" spec && builtins.hasAttr "sha256" spec - then - spec // - { outPath = getFetcher spec { inherit (spec) url sha256; } ; } - else spec - ) sources -|] +initNixSourcesNixContent :: B.ByteString +initNixSourcesNixContent = $(embedFile "nix/sources.nix") -- | @nix/sources.json" pathNixSourcesJson :: FilePath pathNixSourcesJson = "nix" "sources.json" -- | Empty JSON map -initNixSourcesJsonContent :: String +initNixSourcesJsonContent :: B.ByteString initNixSourcesJsonContent = "{}" ------------------------------------------------------------------------------- diff --git a/default.nix b/default.nix index 0b22727..2c46a64 100644 --- a/default.nix +++ b/default.nix @@ -4,6 +4,8 @@ with rec [ "^package.yaml$" "^app.*$" "^README.md$" + "^nix$" + "^nix.sources.nix$" ]; haskellPackages = pkgs.haskellPackages.override { overrides = _: haskellPackages: diff --git a/package.yaml b/package.yaml index 9ec6318..3a7c28b 100644 --- a/package.yaml +++ b/package.yaml @@ -11,6 +11,7 @@ executable: dependencies: - base - hashable + - file-embed - process - text - bytestring @@ -24,3 +25,5 @@ executable: - optparse-applicative - unliftio - unordered-containers + data-files: + - nix/sources.nix