mirror of
https://github.com/nmattia/niv.git
synced 2024-09-20 20:07:38 +03:00
commit
65786ee156
156
app/Niv.hs
156
app/Niv.hs
@ -11,7 +11,7 @@ import Control.Applicative
|
|||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
|
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
|
||||||
import Data.Char (isSpace, toUpper)
|
import Data.Char (isSpace)
|
||||||
import Data.FileEmbed (embedFile)
|
import Data.FileEmbed (embedFile)
|
||||||
import Data.Functor ((<&>))
|
import Data.Functor ((<&>))
|
||||||
import Data.Hashable (Hashable)
|
import Data.Hashable (Hashable)
|
||||||
@ -27,8 +27,9 @@ import qualified Data.Aeson.Encode.Pretty as AesonPretty
|
|||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import qualified Data.ByteString.Char8 as B8
|
import qualified Data.ByteString.Char8 as B8
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import qualified Data.HashMap.Strict as HMap
|
import qualified Data.HashMap.Strict as HMS
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Text.IO as T
|
||||||
import qualified GitHub as GH
|
import qualified GitHub as GH
|
||||||
import qualified GitHub.Data.Name as GH
|
import qualified GitHub.Data.Name as GH
|
||||||
import qualified Options.Applicative as Opts
|
import qualified Options.Applicative as Opts
|
||||||
@ -53,7 +54,7 @@ parseCommand = Opts.subparser (
|
|||||||
Opts.command "drop" parseCmdDrop )
|
Opts.command "drop" parseCmdDrop )
|
||||||
|
|
||||||
newtype Sources = Sources
|
newtype Sources = Sources
|
||||||
{ unSources :: HMap.HashMap PackageName PackageSpec }
|
{ unSources :: HMS.HashMap PackageName PackageSpec }
|
||||||
deriving newtype (FromJSON, ToJSON)
|
deriving newtype (FromJSON, ToJSON)
|
||||||
|
|
||||||
getSources :: IO Sources
|
getSources :: IO Sources
|
||||||
@ -67,19 +68,18 @@ getSources = do
|
|||||||
decodeFileStrict pathNixSourcesJson >>= \case
|
decodeFileStrict pathNixSourcesJson >>= \case
|
||||||
Just (Aeson.Object obj) ->
|
Just (Aeson.Object obj) ->
|
||||||
fmap (Sources . mconcat) $
|
fmap (Sources . mconcat) $
|
||||||
forM (HMap.toList obj) $ \(k, v) ->
|
forM (HMS.toList obj) $ \(k, v) ->
|
||||||
case v of
|
case v of
|
||||||
Aeson.Object v' ->
|
Aeson.Object v' ->
|
||||||
pure $ HMap.singleton (PackageName (T.unpack k)) (PackageSpec v')
|
pure $ HMS.singleton (PackageName k) (PackageSpec v')
|
||||||
_ -> abortAttributeIsntAMap
|
_ -> abortAttributeIsntAMap
|
||||||
Just _ -> abortSourcesIsntAMap
|
Just _ -> abortSourcesIsntAMap
|
||||||
Nothing -> abortSourcesIsntJSON
|
Nothing -> abortSourcesIsntJSON
|
||||||
|
|
||||||
-- TODO: pretty
|
|
||||||
setSources :: Sources -> IO ()
|
setSources :: Sources -> IO ()
|
||||||
setSources sources = encodeFile pathNixSourcesJson sources
|
setSources sources = encodeFile pathNixSourcesJson sources
|
||||||
|
|
||||||
newtype PackageName = PackageName { unPackageName :: String }
|
newtype PackageName = PackageName { unPackageName :: T.Text }
|
||||||
deriving newtype (Eq, Hashable, FromJSONKey, ToJSONKey, Show)
|
deriving newtype (Eq, Hashable, FromJSONKey, ToJSONKey, Show)
|
||||||
|
|
||||||
parsePackageName :: Opts.Parser PackageName
|
parsePackageName :: Opts.Parser PackageName
|
||||||
@ -91,10 +91,10 @@ newtype PackageSpec = PackageSpec { _unPackageSpec :: Aeson.Object }
|
|||||||
|
|
||||||
parsePackageSpec :: Opts.Parser PackageSpec
|
parsePackageSpec :: Opts.Parser PackageSpec
|
||||||
parsePackageSpec =
|
parsePackageSpec =
|
||||||
(PackageSpec . HMap.fromList . fmap fixupAttributes) <$>
|
(PackageSpec . HMS.fromList . fmap fixupAttributes) <$>
|
||||||
many parseAttribute
|
many parseAttribute
|
||||||
where
|
where
|
||||||
parseAttribute :: Opts.Parser (String, String)
|
parseAttribute :: Opts.Parser (T.Text, T.Text)
|
||||||
parseAttribute =
|
parseAttribute =
|
||||||
Opts.option (Opts.maybeReader parseKeyVal)
|
Opts.option (Opts.maybeReader parseKeyVal)
|
||||||
( Opts.long "attribute" <>
|
( Opts.long "attribute" <>
|
||||||
@ -116,32 +116,32 @@ parsePackageSpec =
|
|||||||
))
|
))
|
||||||
|
|
||||||
-- Parse "key=val" into ("key", "val")
|
-- Parse "key=val" into ("key", "val")
|
||||||
parseKeyVal :: String -> Maybe (String, String)
|
parseKeyVal :: String -> Maybe (T.Text, T.Text)
|
||||||
parseKeyVal str = case span (/= '=') str of
|
parseKeyVal str = case span (/= '=') str of
|
||||||
(key, '=':val) -> Just (key, val)
|
(key, '=':val) -> Just (T.pack key, T.pack val)
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
-- Shortcuts for common attributes
|
-- Shortcuts for common attributes
|
||||||
shortcutAttributes :: Opts.Parser (String, String)
|
shortcutAttributes :: Opts.Parser (T.Text, T.Text)
|
||||||
shortcutAttributes = foldr (<|>) empty $ mkShortcutAttribute <$>
|
shortcutAttributes = foldr (<|>) empty $ mkShortcutAttribute <$>
|
||||||
[ "branch", "owner", "repo", "version" ]
|
[ "branch", "owner", "repo", "version" ]
|
||||||
|
|
||||||
mkShortcutAttribute :: String -> Opts.Parser (String, String)
|
mkShortcutAttribute :: T.Text -> Opts.Parser (T.Text, T.Text)
|
||||||
mkShortcutAttribute = \case
|
mkShortcutAttribute = \case
|
||||||
attr@(c:_) -> (attr,) <$> Opts.strOption
|
attr@(T.uncons -> Just (c,_)) -> (attr,) <$> Opts.strOption
|
||||||
( Opts.long attr <>
|
( Opts.long (T.unpack attr) <>
|
||||||
Opts.short c <>
|
Opts.short c <>
|
||||||
Opts.metavar (toUpper <$> attr) <>
|
Opts.metavar (T.unpack $ T.toUpper attr) <>
|
||||||
Opts.help
|
Opts.help
|
||||||
(
|
( T.unpack $
|
||||||
"Equivalent to --attribute " <>
|
"Equivalent to --attribute " <>
|
||||||
attr <> "=<" <> (toUpper <$> attr) <> ">"
|
attr <> "=<" <> (T.toUpper attr) <> ">"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
_ -> empty
|
_ -> empty
|
||||||
|
|
||||||
fixupAttributes :: (String, String) -> (T.Text, Aeson.Value)
|
fixupAttributes :: (T.Text, T.Text) -> (T.Text, Aeson.Value)
|
||||||
fixupAttributes (k, v) = (T.pack k, Aeson.String (T.pack v))
|
fixupAttributes (k, v) = (k, Aeson.String v)
|
||||||
|
|
||||||
parsePackage :: Opts.Parser (PackageName, PackageSpec)
|
parsePackage :: Opts.Parser (PackageName, PackageSpec)
|
||||||
parsePackage = (,) <$> parsePackageName <*> parsePackageSpec
|
parsePackage = (,) <$> parsePackageName <*> parsePackageSpec
|
||||||
@ -251,10 +251,10 @@ completePackageSpec = execStateT $ do
|
|||||||
whenNotSet "url_template" $
|
whenNotSet "url_template" $
|
||||||
setPackageSpecAttr
|
setPackageSpecAttr
|
||||||
"url_template"
|
"url_template"
|
||||||
(Aeson.String $ T.pack githubURLTemplate)
|
(Aeson.String githubURLTemplate)
|
||||||
|
|
||||||
where
|
where
|
||||||
githubURLTemplate :: String
|
githubURLTemplate :: T.Text
|
||||||
githubURLTemplate =
|
githubURLTemplate =
|
||||||
"https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
"https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||||
|
|
||||||
@ -283,18 +283,18 @@ getPackageSpecAttr
|
|||||||
-> StateT PackageSpec IO (Maybe Aeson.Value)
|
-> StateT PackageSpec IO (Maybe Aeson.Value)
|
||||||
getPackageSpecAttr attrName = do
|
getPackageSpecAttr attrName = do
|
||||||
PackageSpec obj <- get
|
PackageSpec obj <- get
|
||||||
pure $ HMap.lookup attrName obj
|
pure $ HMS.lookup attrName obj
|
||||||
|
|
||||||
setPackageSpecAttr
|
setPackageSpecAttr
|
||||||
:: T.Text -> Aeson.Value
|
:: T.Text -> Aeson.Value
|
||||||
-> StateT PackageSpec IO ()
|
-> StateT PackageSpec IO ()
|
||||||
setPackageSpecAttr attrName attrValue = do
|
setPackageSpecAttr attrName attrValue = do
|
||||||
PackageSpec obj <- get
|
PackageSpec obj <- get
|
||||||
let obj' = HMap.insert attrName attrValue obj
|
let obj' = HMS.insert attrName attrValue obj
|
||||||
put (PackageSpec obj')
|
put (PackageSpec obj')
|
||||||
|
|
||||||
packageSpecStringValues :: PackageSpec -> [(String, String)]
|
packageSpecStringValues :: PackageSpec -> [(String, String)]
|
||||||
packageSpecStringValues (PackageSpec m) = mapMaybe toVal (HMap.toList m)
|
packageSpecStringValues (PackageSpec m) = mapMaybe toVal (HMS.toList m)
|
||||||
where
|
where
|
||||||
toVal :: (T.Text, Aeson.Value) -> Maybe (String, String)
|
toVal :: (T.Text, Aeson.Value) -> Maybe (String, String)
|
||||||
toVal = \case
|
toVal = \case
|
||||||
@ -334,12 +334,12 @@ cmdInit = do
|
|||||||
createFile path initNixSourcesJsonContent
|
createFile path initNixSourcesJsonContent
|
||||||
-- Imports @niv@ and @nixpkgs@ (18.09)
|
-- Imports @niv@ and @nixpkgs@ (18.09)
|
||||||
putStrLn "Importing 'niv' ..."
|
putStrLn "Importing 'niv' ..."
|
||||||
cmdAdd Nothing (PackageName "nmattia/niv", PackageSpec HMap.empty)
|
cmdAdd Nothing (PackageName "nmattia/niv", PackageSpec HMS.empty)
|
||||||
putStrLn "Importing 'nixpkgs' ..."
|
putStrLn "Importing 'nixpkgs' ..."
|
||||||
cmdAdd
|
cmdAdd
|
||||||
(Just (PackageName "nixpkgs"))
|
(Just (PackageName "nixpkgs"))
|
||||||
( PackageName "NixOS/nixpkgs-channels"
|
( PackageName "NixOS/nixpkgs-channels"
|
||||||
, PackageSpec (HMap.singleton "branch" "nixos-18.09"))
|
, PackageSpec (HMS.singleton "branch" "nixos-18.09"))
|
||||||
, \path _content -> dontCreateFile path)
|
, \path _content -> dontCreateFile path)
|
||||||
] $ \(path, onCreate, onUpdate) -> do
|
] $ \(path, onCreate, onUpdate) -> do
|
||||||
exists <- Dir.doesFileExist path
|
exists <- Dir.doesFileExist path
|
||||||
@ -385,12 +385,13 @@ cmdAdd :: Maybe PackageName -> (PackageName, PackageSpec) -> IO ()
|
|||||||
cmdAdd mPackageName (PackageName str, spec) = do
|
cmdAdd mPackageName (PackageName str, spec) = do
|
||||||
|
|
||||||
-- Figures out the owner and repo
|
-- Figures out the owner and repo
|
||||||
(packageName, spec') <- flip runStateT spec $ case span (/= '/') str of
|
(packageName, spec') <- flip runStateT spec $ case T.span (/= '/') str of
|
||||||
(owner@(_:_), '/':repo@(_:_)) -> do
|
( owner@(T.null -> False)
|
||||||
|
, T.uncons -> Just ('/', repo@(T.null -> False))) -> do
|
||||||
whenNotSet "owner" $
|
whenNotSet "owner" $
|
||||||
setPackageSpecAttr "owner" (Aeson.String $ T.pack owner)
|
setPackageSpecAttr "owner" (Aeson.String owner)
|
||||||
whenNotSet "repo" $ do
|
whenNotSet "repo" $ do
|
||||||
setPackageSpecAttr "repo" (Aeson.String $ T.pack repo)
|
setPackageSpecAttr "repo" (Aeson.String repo)
|
||||||
pure (PackageName repo)
|
pure (PackageName repo)
|
||||||
_ -> pure (PackageName str)
|
_ -> pure (PackageName str)
|
||||||
|
|
||||||
@ -398,14 +399,14 @@ cmdAdd mPackageName (PackageName str, spec) = do
|
|||||||
|
|
||||||
let packageName' = fromMaybe packageName mPackageName
|
let packageName' = fromMaybe packageName mPackageName
|
||||||
|
|
||||||
when (HMap.member packageName' sources) $
|
when (HMS.member packageName' sources) $
|
||||||
abortCannotAddPackageExists packageName'
|
abortCannotAddPackageExists packageName'
|
||||||
|
|
||||||
spec'' <- updatePackageSpec =<< completePackageSpec spec'
|
spec'' <- updatePackageSpec =<< completePackageSpec spec'
|
||||||
|
|
||||||
putStrLn $ "Writing new sources file"
|
putStrLn $ "Writing new sources file"
|
||||||
setSources $ Sources $
|
setSources $ Sources $
|
||||||
HMap.insert packageName' spec'' sources
|
HMS.insert packageName' spec'' sources
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- SHOW
|
-- SHOW
|
||||||
@ -421,8 +422,8 @@ cmdShow = do
|
|||||||
sources <- unSources <$> getSources
|
sources <- unSources <$> getSources
|
||||||
|
|
||||||
forWithKeyM_ sources $ \key (PackageSpec spec) -> do
|
forWithKeyM_ sources $ \key (PackageSpec spec) -> do
|
||||||
putStrLn $ "Package: " <> unPackageName key
|
T.putStrLn $ "Package: " <> unPackageName key
|
||||||
forM_ (HMap.toList spec) $ \(attrName, attrValValue) -> do
|
forM_ (HMS.toList spec) $ \(attrName, attrValValue) -> do
|
||||||
let attrValue = case attrValValue of
|
let attrValue = case attrValValue of
|
||||||
Aeson.String str -> str
|
Aeson.String str -> str
|
||||||
_ -> "<barabajagal>"
|
_ -> "<barabajagal>"
|
||||||
@ -452,10 +453,10 @@ parseCmdUpdate =
|
|||||||
cmdUpdate :: Maybe (PackageName, PackageSpec) -> IO ()
|
cmdUpdate :: Maybe (PackageName, PackageSpec) -> IO ()
|
||||||
cmdUpdate = \case
|
cmdUpdate = \case
|
||||||
Just (packageName, packageSpec) -> do
|
Just (packageName, packageSpec) -> do
|
||||||
putStrLn $ "Updating single package: " <> unPackageName packageName
|
T.putStrLn $ "Updating single package: " <> unPackageName packageName
|
||||||
sources <- unSources <$> getSources
|
sources <- unSources <$> getSources
|
||||||
|
|
||||||
packageSpec' <- case HMap.lookup packageName sources of
|
packageSpec' <- case HMS.lookup packageName sources of
|
||||||
Just packageSpec' -> do
|
Just packageSpec' -> do
|
||||||
|
|
||||||
-- TODO: something fishy happening here
|
-- TODO: something fishy happening here
|
||||||
@ -465,14 +466,14 @@ cmdUpdate = \case
|
|||||||
Nothing -> abortCannotUpdateNoSuchPackage packageName
|
Nothing -> abortCannotUpdateNoSuchPackage packageName
|
||||||
|
|
||||||
setSources $ Sources $
|
setSources $ Sources $
|
||||||
HMap.insert packageName packageSpec' sources
|
HMS.insert packageName packageSpec' sources
|
||||||
|
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
sources <- unSources <$> getSources
|
sources <- unSources <$> getSources
|
||||||
|
|
||||||
sources' <- forWithKeyM sources $
|
sources' <- forWithKeyM sources $
|
||||||
\packageName packageSpec -> do
|
\packageName packageSpec -> do
|
||||||
putStrLn $ "Package: " <> unPackageName packageName
|
T.putStrLn $ "Package: " <> unPackageName packageName
|
||||||
updatePackageSpec =<< completePackageSpec packageSpec
|
updatePackageSpec =<< completePackageSpec packageSpec
|
||||||
|
|
||||||
setSources $ Sources sources'
|
setSources $ Sources sources'
|
||||||
@ -504,29 +505,29 @@ parseCmdDrop =
|
|||||||
cmdDrop :: PackageName -> [T.Text] -> IO ()
|
cmdDrop :: PackageName -> [T.Text] -> IO ()
|
||||||
cmdDrop packageName = \case
|
cmdDrop packageName = \case
|
||||||
[] -> do
|
[] -> do
|
||||||
putStrLn $ "Dropping package: " <> unPackageName packageName
|
T.putStrLn $ "Dropping package: " <> unPackageName packageName
|
||||||
sources <- unSources <$> getSources
|
sources <- unSources <$> getSources
|
||||||
|
|
||||||
when (not $ HMap.member packageName sources) $
|
when (not $ HMS.member packageName sources) $
|
||||||
abortCannotDropNoSuchPackage packageName
|
abortCannotDropNoSuchPackage packageName
|
||||||
|
|
||||||
setSources $ Sources $
|
setSources $ Sources $
|
||||||
HMap.delete packageName sources
|
HMS.delete packageName sources
|
||||||
attrs -> do
|
attrs -> do
|
||||||
putStrLn $ "Dropping attributes :" <>
|
putStrLn $ "Dropping attributes :" <>
|
||||||
(T.unpack (T.intercalate " " attrs))
|
(T.unpack (T.intercalate " " attrs))
|
||||||
putStrLn $ "In package: " <> unPackageName packageName
|
T.putStrLn $ "In package: " <> unPackageName packageName
|
||||||
sources <- unSources <$> getSources
|
sources <- unSources <$> getSources
|
||||||
|
|
||||||
packageSpec <- case HMap.lookup packageName sources of
|
packageSpec <- case HMS.lookup packageName sources of
|
||||||
Nothing ->
|
Nothing ->
|
||||||
abortCannotAttributesDropNoSuchPackage packageName
|
abortCannotAttributesDropNoSuchPackage packageName
|
||||||
Just (PackageSpec packageSpec) -> pure $ PackageSpec $
|
Just (PackageSpec packageSpec) -> pure $ PackageSpec $
|
||||||
HMap.mapMaybeWithKey
|
HMS.mapMaybeWithKey
|
||||||
(\k v -> if k `elem` attrs then Nothing else Just v) packageSpec
|
(\k v -> if k `elem` attrs then Nothing else Just v) packageSpec
|
||||||
|
|
||||||
setSources $ Sources $
|
setSources $ Sources $
|
||||||
HMap.insert packageName packageSpec sources
|
HMS.insert packageName packageSpec sources
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- Aux
|
-- Aux
|
||||||
@ -556,14 +557,14 @@ encodeFile fp = L.writeFile fp . AesonPretty.encodePretty' config
|
|||||||
|
|
||||||
forWithKeyM
|
forWithKeyM
|
||||||
:: (Eq k, Hashable k, Monad m)
|
:: (Eq k, Hashable k, Monad m)
|
||||||
=> HMap.HashMap k v1
|
=> HMS.HashMap k v1
|
||||||
-> (k -> v1 -> m v2)
|
-> (k -> v1 -> m v2)
|
||||||
-> m (HMap.HashMap k v2)
|
-> m (HMS.HashMap k v2)
|
||||||
forWithKeyM = flip mapWithKeyM
|
forWithKeyM = flip mapWithKeyM
|
||||||
|
|
||||||
forWithKeyM_
|
forWithKeyM_
|
||||||
:: (Eq k, Hashable k, Monad m)
|
:: (Eq k, Hashable k, Monad m)
|
||||||
=> HMap.HashMap k v1
|
=> HMS.HashMap k v1
|
||||||
-> (k -> v1 -> m ())
|
-> (k -> v1 -> m ())
|
||||||
-> m ()
|
-> m ()
|
||||||
forWithKeyM_ = flip mapWithKeyM_
|
forWithKeyM_ = flip mapWithKeyM_
|
||||||
@ -571,20 +572,20 @@ forWithKeyM_ = flip mapWithKeyM_
|
|||||||
mapWithKeyM
|
mapWithKeyM
|
||||||
:: (Eq k, Hashable k, Monad m)
|
:: (Eq k, Hashable k, Monad m)
|
||||||
=> (k -> v1 -> m v2)
|
=> (k -> v1 -> m v2)
|
||||||
-> HMap.HashMap k v1
|
-> HMS.HashMap k v1
|
||||||
-> m (HMap.HashMap k v2)
|
-> m (HMS.HashMap k v2)
|
||||||
mapWithKeyM f m = do
|
mapWithKeyM f m = do
|
||||||
fmap mconcat $ forM (HMap.toList m) $ \(k, v) ->
|
fmap mconcat $ forM (HMS.toList m) $ \(k, v) ->
|
||||||
HMap.singleton k <$> f k v
|
HMS.singleton k <$> f k v
|
||||||
|
|
||||||
mapWithKeyM_
|
mapWithKeyM_
|
||||||
:: (Eq k, Hashable k, Monad m)
|
:: (Eq k, Hashable k, Monad m)
|
||||||
=> (k -> v1 -> m ())
|
=> (k -> v1 -> m ())
|
||||||
-> HMap.HashMap k v1
|
-> HMS.HashMap k v1
|
||||||
-> m ()
|
-> m ()
|
||||||
mapWithKeyM_ f m = do
|
mapWithKeyM_ f m = do
|
||||||
forM_ (HMap.toList m) $ \(k, v) ->
|
forM_ (HMS.toList m) $ \(k, v) ->
|
||||||
HMap.singleton k <$> f k v
|
HMS.singleton k <$> f k v
|
||||||
|
|
||||||
-- | Renders the template. Returns 'Nothing' if some of the attributes are
|
-- | Renders the template. Returns 'Nothing' if some of the attributes are
|
||||||
-- missing.
|
-- missing.
|
||||||
@ -601,9 +602,9 @@ renderTemplate vals = \case
|
|||||||
c:str -> (c:) <$> renderTemplate vals str
|
c:str -> (c:) <$> renderTemplate vals str
|
||||||
[] -> Just []
|
[] -> Just []
|
||||||
|
|
||||||
abort :: String -> IO a
|
abort :: T.Text -> IO a
|
||||||
abort msg = do
|
abort msg = do
|
||||||
putStrLn msg
|
T.putStrLn msg
|
||||||
exitFailure
|
exitFailure
|
||||||
|
|
||||||
nixPrefetchURL :: Bool -> String -> IO String
|
nixPrefetchURL :: Bool -> String -> IO String
|
||||||
@ -638,18 +639,18 @@ shouldUpdateNixSourcesNix content =
|
|||||||
warnIfOutdated :: IO ()
|
warnIfOutdated :: IO ()
|
||||||
warnIfOutdated = do
|
warnIfOutdated = do
|
||||||
tryAny (B.readFile pathNixSourcesNix) >>= \case
|
tryAny (B.readFile pathNixSourcesNix) >>= \case
|
||||||
Left e -> putStrLn $ unlines
|
Left e -> T.putStrLn $ T.unlines
|
||||||
[ "Could not read " <> pathNixSourcesNix
|
[ "Could not read " <> T.pack pathNixSourcesNix
|
||||||
, "Error: " <> show e
|
, "Error: " <> tshow e
|
||||||
]
|
]
|
||||||
Right content ->
|
Right content ->
|
||||||
if shouldUpdateNixSourcesNix content
|
if shouldUpdateNixSourcesNix content
|
||||||
then
|
then
|
||||||
putStrLn $ unlines
|
T.putStrLn $ T.unlines
|
||||||
[ "WARNING: " <> pathNixSourcesNix <> " is out of date."
|
[ "WARNING: " <> T.pack pathNixSourcesNix <> " is out of date."
|
||||||
, "Please run"
|
, "Please run"
|
||||||
, " niv init"
|
, " niv init"
|
||||||
, "or add the following line in the " <> pathNixSourcesNix <> " file:"
|
, "or add the following line in the " <> T.pack pathNixSourcesNix <> " file:"
|
||||||
, " # niv: no_update"
|
, " # niv: no_update"
|
||||||
]
|
]
|
||||||
else pure ()
|
else pure ()
|
||||||
@ -700,17 +701,17 @@ Make sure the repository exists.
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
abortSourcesDoesntExist :: IO a
|
abortSourcesDoesntExist :: IO a
|
||||||
abortSourcesDoesntExist = abort $ unlines [ line1, line2 ]
|
abortSourcesDoesntExist = abort $ T.unlines [ line1, line2 ]
|
||||||
where
|
where
|
||||||
line1 = "Cannot use " <> pathNixSourcesJson
|
line1 = "Cannot use " <> T.pack pathNixSourcesJson
|
||||||
line2 = [s|
|
line2 = [s|
|
||||||
The sources file does not exist! You may need to run 'niv init'.
|
The sources file does not exist! You may need to run 'niv init'.
|
||||||
|]
|
|]
|
||||||
|
|
||||||
abortSourcesIsntAMap :: IO a
|
abortSourcesIsntAMap :: IO a
|
||||||
abortSourcesIsntAMap = abort $ unlines [ line1, line2 ]
|
abortSourcesIsntAMap = abort $ T.unlines [ line1, line2 ]
|
||||||
where
|
where
|
||||||
line1 = "Cannot use " <> pathNixSourcesJson
|
line1 = "Cannot use " <> T.pack pathNixSourcesJson
|
||||||
line2 = [s|
|
line2 = [s|
|
||||||
The sources file should be a JSON map from package name to package
|
The sources file should be a JSON map from package name to package
|
||||||
specification, e.g.:
|
specification, e.g.:
|
||||||
@ -718,9 +719,9 @@ specification, e.g.:
|
|||||||
|]
|
|]
|
||||||
|
|
||||||
abortAttributeIsntAMap :: IO a
|
abortAttributeIsntAMap :: IO a
|
||||||
abortAttributeIsntAMap = abort $ unlines [ line1, line2 ]
|
abortAttributeIsntAMap = abort $ T.unlines [ line1, line2 ]
|
||||||
where
|
where
|
||||||
line1 = "Cannot use " <> pathNixSourcesJson
|
line1 = "Cannot use " <> T.pack pathNixSourcesJson
|
||||||
line2 = [s|
|
line2 = [s|
|
||||||
The package specifications in the sources file should be JSON maps from
|
The package specifications in the sources file should be JSON maps from
|
||||||
attribute name to attribute value, e.g.:
|
attribute name to attribute value, e.g.:
|
||||||
@ -728,13 +729,13 @@ attribute name to attribute value, e.g.:
|
|||||||
|]
|
|]
|
||||||
|
|
||||||
abortSourcesIsntJSON :: IO a
|
abortSourcesIsntJSON :: IO a
|
||||||
abortSourcesIsntJSON = abort $ unlines [ line1, line2 ]
|
abortSourcesIsntJSON = abort $ T.unlines [ line1, line2 ]
|
||||||
where
|
where
|
||||||
line1 = "Cannot use " <> pathNixSourcesJson
|
line1 = "Cannot use " <> T.pack pathNixSourcesJson
|
||||||
line2 = "The sources file should be JSON."
|
line2 = "The sources file should be JSON."
|
||||||
|
|
||||||
abortCannotAddPackageExists :: PackageName -> IO a
|
abortCannotAddPackageExists :: PackageName -> IO a
|
||||||
abortCannotAddPackageExists (PackageName n) = abort $ unlines
|
abortCannotAddPackageExists (PackageName n) = abort $ T.unlines
|
||||||
[ "Cannot add package " <> n <> "."
|
[ "Cannot add package " <> n <> "."
|
||||||
, "The package already exists. Use"
|
, "The package already exists. Use"
|
||||||
, " niv drop " <> n
|
, " niv drop " <> n
|
||||||
@ -744,7 +745,7 @@ abortCannotAddPackageExists (PackageName n) = abort $ unlines
|
|||||||
]
|
]
|
||||||
|
|
||||||
abortCannotUpdateNoSuchPackage :: PackageName -> IO a
|
abortCannotUpdateNoSuchPackage :: PackageName -> IO a
|
||||||
abortCannotUpdateNoSuchPackage (PackageName n) = abort $ unlines
|
abortCannotUpdateNoSuchPackage (PackageName n) = abort $ T.unlines
|
||||||
[ "Cannot update package " <> n <> "."
|
[ "Cannot update package " <> n <> "."
|
||||||
, "The package doesn't exist. Use"
|
, "The package doesn't exist. Use"
|
||||||
, " niv add " <> n
|
, " niv add " <> n
|
||||||
@ -752,13 +753,13 @@ abortCannotUpdateNoSuchPackage (PackageName n) = abort $ unlines
|
|||||||
]
|
]
|
||||||
|
|
||||||
abortCannotDropNoSuchPackage :: PackageName -> IO a
|
abortCannotDropNoSuchPackage :: PackageName -> IO a
|
||||||
abortCannotDropNoSuchPackage (PackageName n) = abort $ unlines
|
abortCannotDropNoSuchPackage (PackageName n) = abort $ T.unlines
|
||||||
[ "Cannot drop package " <> n <> "."
|
[ "Cannot drop package " <> n <> "."
|
||||||
, "The package doesn't exist."
|
, "The package doesn't exist."
|
||||||
]
|
]
|
||||||
|
|
||||||
abortCannotAttributesDropNoSuchPackage :: PackageName -> IO a
|
abortCannotAttributesDropNoSuchPackage :: PackageName -> IO a
|
||||||
abortCannotAttributesDropNoSuchPackage (PackageName n) = abort $ unlines
|
abortCannotAttributesDropNoSuchPackage (PackageName n) = abort $ T.unlines
|
||||||
[ "Cannot drop attributes of package " <> n <> "."
|
[ "Cannot drop attributes of package " <> n <> "."
|
||||||
, "The package doesn't exist."
|
, "The package doesn't exist."
|
||||||
]
|
]
|
||||||
@ -772,3 +773,6 @@ ticket:
|
|||||||
|
|
||||||
Thanks! I'll buy you a beer.
|
Thanks! I'll buy you a beer.
|
||||||
|]
|
|]
|
||||||
|
|
||||||
|
tshow :: Show a => a -> T.Text
|
||||||
|
tshow = T.pack . show
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="1f2ba40b461bae96af1073b4f3fbfdf2" baseProfile="full" viewBox="0 0 703 523" width="703" version="1.1">
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="e7be124f4eec8170d74afbc28a4a5f02" baseProfile="full" viewBox="0 0 703 523" width="703" version="1.1">
|
||||||
<defs>
|
<defs>
|
||||||
<termtosvg:template_settings xmlns:termtosvg="https://github.com/nbedos/termtosvg">
|
<termtosvg:template_settings xmlns:termtosvg="https://github.com/nbedos/termtosvg">
|
||||||
<termtosvg:screen_geometry columns="82" rows="26"/>
|
<termtosvg:screen_geometry columns="82" rows="26"/>
|
||||||
@ -44,5 +44,5 @@
|
|||||||
<circle cx="44" cy="23" r="7" class="color3"/>
|
<circle cx="44" cy="23" r="7" class="color3"/>
|
||||||
<circle cx="64" cy="23" r="7" class="color2"/>
|
<circle cx="64" cy="23" r="7" class="color2"/>
|
||||||
<svg id="screen" width="656" x="23" y="50" viewBox="0 0 656 442" preserveAspectRatio="xMidYMin meet">
|
<svg id="screen" width="656" x="23" y="50" viewBox="0 0 656 442" preserveAspectRatio="xMidYMin meet">
|
||||||
<rect class="background" height="100%" width="100%" x="0" y="0"/><g display="none"><rect class="foreground" height="17" width="8" x="0" y="85"/><use y="85" xlink:href="#g1"/><animate attributeName="display" begin="0ms; anim_last.end" dur="1500ms" from="inline" to="inline"/></g><g display="none"><rect class="foreground" height="17" width="8" x="0" y="187"/><use y="187" xlink:href="#g1"/><animate attributeName="display" begin="1500ms; anim_last.end+1500ms" dur="1500ms" from="inline" to="inline"/></g><g display="none"><rect class="foreground" height="17" width="8" x="0" y="306"/><use y="306" xlink:href="#g1"/><animate attributeName="display" begin="3000ms; anim_last.end+3000ms" dur="1500ms" from="inline" to="inline"/></g><g display="none"><use y="0" xlink:href="#g2"/><use y="17" xlink:href="#g3"/><use y="34" xlink:href="#g4"/><use y="51" xlink:href="#g5"/><use y="68" xlink:href="#g6"/><animate attributeName="display" begin="0ms; anim_last.end" dur="5500ms" from="inline" to="inline"/></g><g display="none"><use y="85" xlink:href="#g7"/><use y="102" xlink:href="#g8"/><use y="119" xlink:href="#g9"/><use y="136" xlink:href="#g10"/><use y="153" xlink:href="#g11"/><use y="170" xlink:href="#g6"/><animate attributeName="display" begin="1500ms; anim_last.end+1500ms" dur="4000ms" from="inline" to="inline"/></g><g display="none"><use y="272" xlink:href="#g12"/><use y="289" xlink:href="#g6"/><use y="187" xlink:href="#g7"/><use y="204" xlink:href="#g13"/><use y="221" xlink:href="#g14"/><use y="238" xlink:href="#g10"/><animate attributeName="display" begin="3000ms; anim_last.end+3000ms" dur="2500ms" from="inline" to="inline"/></g><g display="none"><use y="306" xlink:href="#g7"/><use y="323" xlink:href="#g15"/><use y="340" xlink:href="#g16"/><use y="357" xlink:href="#g10"/><rect class="foreground" height="17" width="8" x="0" y="374"/><use y="374" xlink:href="#g1"/><animate attributeName="display" begin="4500ms; anim_last.end+4500ms" dur="1000ms" from="inline" to="inline" id="anim_last"/></g><defs><g id="g1"><text class="background" textLength="8" x="0"> </text></g><g id="g2"><text class="foreground" textLength="80" x="0">$ niv init</text></g><g id="g3"><text class="foreground" textLength="192" x="0">Creating nix/sources.nix</text></g><g id="g4"><text class="foreground" textLength="200" x="0">Creating nix/sources.json</text></g><g id="g5"><text class="foreground" textLength="152" x="0">Importing 'niv' ...</text></g><g id="g6"><text class="foreground" textLength="160" x="0">Reading sources file</text></g><g id="g7"><text class="foreground" textLength="96" x="0">unpacking...</text></g><g id="g8"><text class="foreground" textLength="656" x="0">path is '/nix/store/d2ibkfdbsqkr6avllvkqcwdyj771qmvv-30f55f14e1580325f65dd2bd0be4e</text></g><g id="g9"><text class="foreground" textLength="152" x="0">bd0797a8c83.tar.gz'</text></g><g id="g10"><text class="foreground" textLength="192" x="0">Writing new sources file</text></g><g id="g11"><text class="foreground" textLength="184" x="0">Importing 'nixpkgs' ...</text></g><g id="g12"><text class="foreground" textLength="168" x="0">$ niv add stedolan/jq</text></g><g id="g13"><text class="foreground" textLength="656" x="0">path is '/nix/store/qbzbhgq78m94j4dm026y7mi7nkd4lgh4-a7e559a5504572008567383c3dc8e</text></g><g id="g14"><text class="foreground" textLength="152" x="0">142fa7a8633.tar.gz'</text></g><g id="g15"><text class="foreground" textLength="656" x="0">path is '/nix/store/yjz2v8kfk2jkzc0w7lh43hfmcafpqs33-ad9fc9f559e78a764aac20f669f23</text></g><g id="g16"><text class="foreground" textLength="152" x="0">cdd020cd943.tar.gz'</text></g></defs></svg>
|
<rect class="background" height="100%" width="100%" x="0" y="0"/><g display="none"><rect class="foreground" height="17" width="8" x="0" y="85"/><use y="85" xlink:href="#g1"/><animate attributeName="display" begin="0ms; anim_last.end" dur="1500ms" from="inline" to="inline"/></g><g display="none"><rect class="foreground" height="17" width="8" x="0" y="187"/><use y="187" xlink:href="#g1"/><animate attributeName="display" begin="1500ms; anim_last.end+1500ms" dur="1500ms" from="inline" to="inline"/></g><g display="none"><rect class="foreground" height="17" width="8" x="0" y="306"/><use y="306" xlink:href="#g1"/><animate attributeName="display" begin="3000ms; anim_last.end+3000ms" dur="1500ms" from="inline" to="inline"/></g><g display="none"><use y="0" xlink:href="#g2"/><use y="17" xlink:href="#g3"/><use y="34" xlink:href="#g4"/><use y="51" xlink:href="#g5"/><use y="68" xlink:href="#g6"/><animate attributeName="display" begin="0ms; anim_last.end" dur="5500ms" from="inline" to="inline"/></g><g display="none"><use y="85" xlink:href="#g7"/><use y="102" xlink:href="#g8"/><use y="119" xlink:href="#g9"/><use y="136" xlink:href="#g10"/><use y="153" xlink:href="#g11"/><use y="170" xlink:href="#g6"/><animate attributeName="display" begin="1500ms; anim_last.end+1500ms" dur="4000ms" from="inline" to="inline"/></g><g display="none"><use y="272" xlink:href="#g12"/><use y="289" xlink:href="#g6"/><use y="187" xlink:href="#g7"/><use y="204" xlink:href="#g13"/><use y="221" xlink:href="#g14"/><use y="238" xlink:href="#g10"/><animate attributeName="display" begin="3000ms; anim_last.end+3000ms" dur="2500ms" from="inline" to="inline"/></g><g display="none"><use y="306" xlink:href="#g7"/><use y="323" xlink:href="#g15"/><use y="340" xlink:href="#g16"/><use y="357" xlink:href="#g10"/><rect class="foreground" height="17" width="8" x="0" y="374"/><use y="374" xlink:href="#g1"/><animate attributeName="display" begin="4500ms; anim_last.end+4500ms" dur="1000ms" from="inline" to="inline" id="anim_last"/></g><defs><g id="g1"><text class="background" textLength="8" x="0"> </text></g><g id="g2"><text class="foreground" textLength="80" x="0">$ niv init</text></g><g id="g3"><text class="foreground" textLength="192" x="0">Creating nix/sources.nix</text></g><g id="g4"><text class="foreground" textLength="200" x="0">Creating nix/sources.json</text></g><g id="g5"><text class="foreground" textLength="152" x="0">Importing 'niv' ...</text></g><g id="g6"><text class="foreground" textLength="160" x="0">Reading sources file</text></g><g id="g7"><text class="foreground" textLength="96" x="0">unpacking...</text></g><g id="g8"><text class="foreground" textLength="656" x="0">path is '/nix/store/bypafdfyf7q6fg1m1xxps4gv4adwwlxb-2f95c55006d6138aafe44e452350c</text></g><g id="g9"><text class="foreground" textLength="152" x="0">e7fa3211dfd.tar.gz'</text></g><g id="g10"><text class="foreground" textLength="192" x="0">Writing new sources file</text></g><g id="g11"><text class="foreground" textLength="184" x="0">Importing 'nixpkgs' ...</text></g><g id="g12"><text class="foreground" textLength="168" x="0">$ niv add stedolan/jq</text></g><g id="g13"><text class="foreground" textLength="656" x="0">path is '/nix/store/qbzbhgq78m94j4dm026y7mi7nkd4lgh4-a7e559a5504572008567383c3dc8e</text></g><g id="g14"><text class="foreground" textLength="152" x="0">142fa7a8633.tar.gz'</text></g><g id="g15"><text class="foreground" textLength="656" x="0">path is '/nix/store/yjz2v8kfk2jkzc0w7lh43hfmcafpqs33-ad9fc9f559e78a764aac20f669f23</text></g><g id="g16"><text class="foreground" textLength="152" x="0">cdd020cd943.tar.gz'</text></g></defs></svg>
|
||||||
</svg>
|
</svg>
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Loading…
Reference in New Issue
Block a user