mirror of
https://github.com/nmattia/snack.git
synced 2024-12-01 03:03:55 +03:00
Merge pull request #99 from nmattia/nm-discovery
Implement discovery mode for package and snack.nix files
This commit is contained in:
commit
51c56ad3a3
@ -19,6 +19,11 @@ Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to
|
|||||||
- The `snack.nix` now describes the build environment and packages are
|
- The `snack.nix` now describes the build environment and packages are
|
||||||
described through `package.nix` (i.e. to migrate: rename `snack.nix` to
|
described through `package.nix` (i.e. to migrate: rename `snack.nix` to
|
||||||
`package.nix`).
|
`package.nix`).
|
||||||
|
- The same flag (`-p`) is used for specifying both a YAML or Nix file. When
|
||||||
|
none is provided snack tries to use either `./package.yaml` or
|
||||||
|
`./package.nix`.
|
||||||
|
- The flag `-s` is used to specify a `snack.nix`. By default `./snack.nix` is
|
||||||
|
used.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- The module import parsing when the CPP extension is enabled.
|
- The module import parsing when the CPP extension is enabled.
|
||||||
|
35
README.md
35
README.md
@ -81,14 +81,24 @@ The _snack_ executable is now in your `PATH`:
|
|||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
$ snack --help
|
$ snack --help
|
||||||
Usage: snack [-l|--lib DIR] [-b|--snack-nix PATH] [-j|--cores INT]
|
Usage: <interactive> [-l|--lib DIR] ([-s|--snack-nix PATH] | [--no-snack-nix])
|
||||||
([-s|--package-nix PATH] | [-p|--package-yaml PATH]) COMMAND
|
[-j|--cores INT] [-p|--package-file PATH] (COMMAND |
|
||||||
|
COMMAND)
|
||||||
|
|
||||||
Available options:
|
Available options:
|
||||||
-l,--lib DIR Path to the directory to use as the Nix library
|
-l,--lib DIR Path to the directory to use as the Nix library
|
||||||
instead of the default one bundled with the snack
|
instead of the default one bundled with the snack
|
||||||
executable.
|
executable.
|
||||||
|
-s,--snack-nix PATH Use the specified environment (snack.nix) file. When
|
||||||
|
none is provided ./snack.nix is used (if it exists).
|
||||||
|
(Use --no-snack-nix to disable this behavior)
|
||||||
|
--no-snack-nix Don't use ./snack.nix as the environment (snack.nix)
|
||||||
|
file.
|
||||||
-j,--cores INT How many cores to use during the build
|
-j,--cores INT How many cores to use during the build
|
||||||
|
-p,--package-file PATH Specifies a YAML or Nix file to use as package
|
||||||
|
description. If not provided, snack looks for either
|
||||||
|
'package.yaml' or 'package.nix' in the current
|
||||||
|
directory.
|
||||||
-h,--help Show this help text
|
-h,--help Show this help text
|
||||||
|
|
||||||
Available commands:
|
Available commands:
|
||||||
@ -106,13 +116,10 @@ suite its own package description.
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
There are two ways to tell snack about a package;
|
There are two ways to describe a package:
|
||||||
* Use [`--package-nix`](#nix) if you need more control over your build.
|
* Use [`package.yaml` file](#hpack) for simple builds or if you already have
|
||||||
* Use [`--package-yaml`](#hpack) for simple builds or if you already have
|
|
||||||
a `package.yaml` file.
|
a `package.yaml` file.
|
||||||
|
* Use a [`package.nix` file](#nix) if you need more control over your build.
|
||||||
If a package option is not supplied then snack will run as if
|
|
||||||
`--package-nix=package.nix` was given as the package option.
|
|
||||||
|
|
||||||
The next two sections show an example config for each option. They use the
|
The next two sections show an example config for each option. They use the
|
||||||
following example project which displays the title of the top-rated post on the
|
following example project which displays the title of the top-rated post on the
|
||||||
@ -190,19 +197,19 @@ default-extensions:
|
|||||||
This command will build the project and display the top-rated post's title:
|
This command will build the project and display the top-rated post's title:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
$ snack run --package-yaml ./package.yaml
|
$ snack run
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also build without executing:
|
You can also build without executing:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
$ snack build --package-yaml ./package.yaml
|
$ snack build
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively you can load up the project in `ghci`:
|
Alternatively you can load up the project in `ghci`:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
$ snack ghci --package-yaml ./package.yaml
|
$ snack ghci
|
||||||
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
|
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
|
||||||
[1 of 2] Compiling Lib ( /home/nicolas/projects/nmattia/snack/tests/readme/src/Lib.hs, interpreted )
|
[1 of 2] Compiling Lib ( /home/nicolas/projects/nmattia/snack/tests/readme/src/Lib.hs, interpreted )
|
||||||
[2 of 2] Compiling Main ( /home/nicolas/projects/nmattia/snack/tests/readme/app/Main.hs, interpreted )
|
[2 of 2] Compiling Main ( /home/nicolas/projects/nmattia/snack/tests/readme/app/Main.hs, interpreted )
|
||||||
@ -233,7 +240,7 @@ in
|
|||||||
Building and running the project is as simple as
|
Building and running the project is as simple as
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
$ snack run # looks for a file called package.nix by default
|
$ snack run
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, use `$ snack build` or `$ snack ghci` if you only want to build,
|
Alternatively, use `$ snack build` or `$ snack ghci` if you only want to build,
|
||||||
@ -310,7 +317,7 @@ If you are hacking on the _snack_ executable, just start _snack_ in a GHCi
|
|||||||
session:
|
session:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
$ snack ghci -s ./bin/package.nix
|
$ snack ghci -p ./bin/package.nix
|
||||||
Temporarily symlinking /nix/store/j1x5vkxjr2ibabddfkdih4sm4kwinfda-spec-json/spec.json to spec.json...
|
Temporarily symlinking /nix/store/j1x5vkxjr2ibabddfkdih4sm4kwinfda-spec-json/spec.json to spec.json...
|
||||||
done.
|
done.
|
||||||
Temporarily symlinking /nix/store/w42y6dzgfmli9r8kmgh8akqk6kyda31x-lib64/lib.tar.gz.b64 to lib.tar.gz.b64...
|
Temporarily symlinking /nix/store/w42y6dzgfmli9r8kmgh8akqk6kyda31x-lib64/lib.tar.gz.b64 to lib.tar.gz.b64...
|
||||||
@ -325,7 +332,7 @@ If you are hacking on the library, specify `-l/--lib` when running snack (this
|
|||||||
works in GHCi too):
|
works in GHCi too):
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
*Main> :main ghci -l ./snack-lib/ -s ./tests/readme/package.nix
|
*Main> :main ghci -l ./snack-lib/ -p ./tests/readme/package.nix
|
||||||
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
|
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
|
||||||
[1 of 2] Compiling Lib ( /home/nicolas/projects/nmattia/snack/tests/readme/src/Lib.hs, interpreted )
|
[1 of 2] Compiling Lib ( /home/nicolas/projects/nmattia/snack/tests/readme/src/Lib.hs, interpreted )
|
||||||
[2 of 2] Compiling Main ( /home/nicolas/projects/nmattia/snack/tests/readme/app/Main.hs, interpreted )
|
[2 of 2] Compiling Main ( /home/nicolas/projects/nmattia/snack/tests/readme/app/Main.hs, interpreted )
|
||||||
|
412
bin/Snack.hs
412
bin/Snack.hs
@ -15,13 +15,13 @@ module Main (main) where
|
|||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.IO.Class
|
import Control.Monad.IO.Class
|
||||||
import Data.Aeson (FromJSON, (.:), (.:?))
|
import Data.Aeson (FromJSON, (.:))
|
||||||
import Data.FileEmbed (embedStringFile)
|
import Data.FileEmbed (embedStringFile)
|
||||||
import Data.List (intercalate)
|
import Data.List (intercalate)
|
||||||
import Data.Semigroup ((<>))
|
import Data.Semigroup ((<>))
|
||||||
import Data.String.Interpolate
|
import Data.String.Interpolate
|
||||||
import Shelly (Sh)
|
import Shelly (Sh)
|
||||||
import System.Directory (canonicalizePath)
|
import System.Directory (doesFileExist, doesPathExist, canonicalizePath)
|
||||||
import System.Posix.Process (executeFile)
|
import System.Posix.Process (executeFile)
|
||||||
import UnliftIO.Exception
|
import UnliftIO.Exception
|
||||||
import qualified Data.Aeson as Aeson
|
import qualified Data.Aeson as Aeson
|
||||||
@ -32,7 +32,17 @@ import qualified Data.Text as T
|
|||||||
import qualified Options.Applicative as Opts
|
import qualified Options.Applicative as Opts
|
||||||
import qualified Shelly as S
|
import qualified Shelly as S
|
||||||
|
|
||||||
---
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
opts <-
|
||||||
|
prepareOptions =<<
|
||||||
|
Opts.execParser (Opts.info (parseOptions <**> Opts.helper) mempty)
|
||||||
|
runCommand (snackConfig opts) (package opts) (command opts)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Configuration
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Some config helpers
|
--- Some config helpers
|
||||||
|
|
||||||
data ConfigStage
|
data ConfigStage
|
||||||
@ -43,99 +53,126 @@ type family Config (c :: ConfigStage) ty1 ty2 where
|
|||||||
Config 'ConfigRaw ty1 _ = ty1
|
Config 'ConfigRaw ty1 _ = ty1
|
||||||
Config 'ConfigReady _ ty2 = ty2
|
Config 'ConfigReady _ ty2 = ty2
|
||||||
|
|
||||||
---
|
|
||||||
--- Configuration proper
|
--- Configuration proper
|
||||||
|
|
||||||
type Mode = Mode_ 'ConfigReady
|
|
||||||
|
|
||||||
type ModeRaw = Mode_ 'ConfigRaw
|
|
||||||
|
|
||||||
data Mode_ c
|
|
||||||
= Standalone (Config c FilePath PackageNix) -- Reads a package.nix file
|
|
||||||
| HPack (Config c FilePath PackageYaml) -- Reads a package.yaml
|
|
||||||
|
|
||||||
prepareMode :: ModeRaw -> IO Mode
|
|
||||||
prepareMode = \case
|
|
||||||
Standalone fp -> Standalone <$> mkPackageNix fp
|
|
||||||
HPack fp -> HPack <$> mkPackageYaml fp
|
|
||||||
|
|
||||||
-- | Like a FilePath, but Nix friendly
|
|
||||||
newtype PackageNix = PackageNix { unPackageNix :: FilePath }
|
|
||||||
|
|
||||||
mkPackageNix :: FilePath -> IO PackageNix
|
|
||||||
mkPackageNix = fmap PackageNix . canonicalizePath
|
|
||||||
|
|
||||||
-- | Like a FilePath, but Nix friendly
|
-- | Like a FilePath, but Nix friendly
|
||||||
newtype SnackNix = SnackNix FilePath
|
newtype SnackNix = SnackNix FilePath
|
||||||
|
|
||||||
|
data SnackNixConfig
|
||||||
|
= SnackNixSpecific FilePath
|
||||||
|
| SnackNixDiscovery
|
||||||
|
| SnackNixNone
|
||||||
|
|
||||||
|
parseSnackNixConfig :: Opts.Parser SnackNixConfig
|
||||||
|
parseSnackNixConfig =
|
||||||
|
SnackNixSpecific <$> Opts.strOption
|
||||||
|
(Opts.long "snack-nix"
|
||||||
|
<> Opts.short 's'
|
||||||
|
<> Opts.metavar "PATH"
|
||||||
|
<> Opts.help (unlines
|
||||||
|
[ "Use the specified environment (snack.nix) file."
|
||||||
|
, "When none is provided ./snack.nix is used (if it exists)."
|
||||||
|
, "(Use --no-snack-nix to disable this behavior)"
|
||||||
|
])
|
||||||
|
) <|>
|
||||||
|
Opts.flag'
|
||||||
|
SnackNixNone
|
||||||
|
(Opts.long "no-snack-nix"
|
||||||
|
<> Opts.help "Don't use ./snack.nix as the environment (snack.nix) file."
|
||||||
|
) <|>
|
||||||
|
pure SnackNixDiscovery
|
||||||
|
|
||||||
|
prepareSnackNix :: SnackNixConfig -> IO (Maybe SnackNix)
|
||||||
|
prepareSnackNix = \case
|
||||||
|
SnackNixNone -> pure Nothing
|
||||||
|
SnackNixSpecific fp -> Just <$> mkSnackNix fp
|
||||||
|
SnackNixDiscovery -> discoverSnackNix
|
||||||
|
|
||||||
|
discoverSnackNix :: IO (Maybe SnackNix)
|
||||||
|
discoverSnackNix = do
|
||||||
|
eSNix <- mkSnackNixEither "snack.nix"
|
||||||
|
case eSNix of
|
||||||
|
Left{} -> pure Nothing
|
||||||
|
Right sn -> pure (Just sn)
|
||||||
|
|
||||||
mkSnackNix :: FilePath -> IO SnackNix
|
mkSnackNix :: FilePath -> IO SnackNix
|
||||||
mkSnackNix = fmap SnackNix . canonicalizePath
|
mkSnackNix = fmap SnackNix . mkFilePath
|
||||||
|
|
||||||
|
mkSnackNixEither :: FilePath -> IO (Either String SnackNix)
|
||||||
|
mkSnackNixEither fp = fmap SnackNix <$> mkFilePathEither fp
|
||||||
|
|
||||||
-- | Like a FilePath, but Nix friendly
|
-- | Like a FilePath, but Nix friendly
|
||||||
newtype SnackLib = SnackLib FilePath
|
newtype SnackLib = SnackLib FilePath
|
||||||
|
|
||||||
mkSnackLib :: FilePath -> IO SnackLib
|
mkSnackLib :: FilePath -> IO SnackLib
|
||||||
mkSnackLib = fmap SnackLib . canonicalizePath
|
mkSnackLib = fmap SnackLib . mkDirPath
|
||||||
|
|
||||||
|
--- Package description (@package.yaml@, @package.nix@)
|
||||||
|
|
||||||
-- | Like a FilePath, but Nix friendly
|
-- | Like a FilePath, but Nix friendly
|
||||||
newtype PackageYaml = PackageYaml { unPackageYaml :: FilePath }
|
newtype PackageFile = PackageFile { unPackageFile :: FilePath }
|
||||||
|
|
||||||
mkPackageYaml :: FilePath -> IO PackageYaml
|
-- | What package description (@package.yaml@, @package.nix@) to use
|
||||||
mkPackageYaml = fmap PackageYaml . canonicalizePath
|
data PackageFileConfig
|
||||||
|
= PackageFileSpecific FilePath
|
||||||
|
-- ^ Use the specified file as package description
|
||||||
|
| PackageFileDiscovery
|
||||||
|
-- ^ Find a suitable package description
|
||||||
|
|
||||||
|
parsePackageFileConfig :: Opts.Parser PackageFileConfig
|
||||||
|
parsePackageFileConfig =
|
||||||
|
(PackageFileSpecific <$>
|
||||||
|
Opts.strOption
|
||||||
|
(Opts.long "package-file"
|
||||||
|
<> Opts.short 'p'
|
||||||
|
<> Opts.help (unlines
|
||||||
|
[ "Specifies a YAML or Nix file to use as package description."
|
||||||
|
, "If not provided, snack looks for either 'package.yaml' or 'package.nix' in the current directory."
|
||||||
|
]
|
||||||
|
)
|
||||||
|
<> Opts.metavar "PATH")
|
||||||
|
) <|> pure PackageFileDiscovery
|
||||||
|
|
||||||
|
-- Finding the package descriptions
|
||||||
|
|
||||||
|
mkPackageFileEither :: FilePath -> IO (Either String PackageFile)
|
||||||
|
mkPackageFileEither = fmap (fmap PackageFile) . mkFilePathEither
|
||||||
|
|
||||||
|
mkPackageFile :: FilePath -> IO PackageFile
|
||||||
|
mkPackageFile = fmap PackageFile . mkFilePath
|
||||||
|
|
||||||
|
preparePackage :: PackageFileConfig -> IO PackageFile
|
||||||
|
preparePackage = \case
|
||||||
|
PackageFileSpecific fp -> mkPackageFile fp
|
||||||
|
PackageFileDiscovery -> discoverPackageFile
|
||||||
|
|
||||||
|
-- | Tries to find a package description.
|
||||||
|
discoverPackageFile :: IO PackageFile
|
||||||
|
discoverPackageFile = do
|
||||||
|
eYaml <- mkPackageFileEither "package.yaml"
|
||||||
|
eNix <- mkPackageFileEither "package.nix"
|
||||||
|
case (eYaml, eNix) of
|
||||||
|
(Right (PackageFile yaml), Right (PackageFile nix)) ->
|
||||||
|
throwIO $ userError $ unlines
|
||||||
|
[ "Please specify which package file to use, e.g.: "
|
||||||
|
, " snack -p " <> yaml, "or"
|
||||||
|
, " snack -p " <> nix
|
||||||
|
]
|
||||||
|
(Right yaml, Left{}) -> pure yaml
|
||||||
|
(Left{}, Right nix) -> pure nix
|
||||||
|
(Left e1, Left e2) -> throwIO $ userError $ unlines
|
||||||
|
[ "Could not discover package file:"
|
||||||
|
, e1, e2
|
||||||
|
, "Please specify one with e.g.:"
|
||||||
|
, " snack -p <path-to-yaml-or-nix>"
|
||||||
|
]
|
||||||
|
|
||||||
|
--- Nix configuration
|
||||||
|
|
||||||
-- | How to call @nix-build@
|
-- | How to call @nix-build@
|
||||||
newtype NixConfig = NixConfig
|
newtype NixConfig = NixConfig
|
||||||
{ nixNCores :: Int }
|
{ nixNCores :: Int }
|
||||||
|
|
||||||
type SnackConfig = SnackConfig_ 'ConfigReady
|
|
||||||
type SnackConfigRaw = SnackConfig_ 'ConfigRaw
|
|
||||||
|
|
||||||
-- | Extra configuration for snack
|
|
||||||
data SnackConfig_ c = SnackConfig
|
|
||||||
{ snackLib :: Config c (Maybe FilePath) (Maybe SnackLib)
|
|
||||||
, snackNix :: Maybe (Config c FilePath SnackNix)
|
|
||||||
, snackNixCfg :: NixConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
data Command
|
|
||||||
= Build
|
|
||||||
| Run [String] -- Run with extra args
|
|
||||||
| Ghci
|
|
||||||
| Test
|
|
||||||
|
|
||||||
main :: IO ()
|
|
||||||
main = do
|
|
||||||
opts <-
|
|
||||||
prepareOptions =<<
|
|
||||||
Opts.execParser (Opts.info (parseOptions <**> Opts.helper) mempty)
|
|
||||||
runCommand (snackConfig opts) (mode opts) (command opts)
|
|
||||||
|
|
||||||
type OptionsRaw = Options_ 'ConfigRaw
|
|
||||||
type Options = Options_ 'ConfigReady
|
|
||||||
|
|
||||||
data Options_ c = Options
|
|
||||||
{ snackConfig :: SnackConfig_ c
|
|
||||||
, mode :: Mode_ c
|
|
||||||
, command :: Command
|
|
||||||
}
|
|
||||||
|
|
||||||
prepareOptions :: OptionsRaw -> IO Options
|
|
||||||
prepareOptions raw =
|
|
||||||
Options <$>
|
|
||||||
prepareSnackConfig (snackConfig raw) <*>
|
|
||||||
prepareMode (mode raw) <*>
|
|
||||||
pure (command raw)
|
|
||||||
|
|
||||||
prepareSnackConfig :: SnackConfigRaw -> IO SnackConfig
|
|
||||||
prepareSnackConfig raw =
|
|
||||||
SnackConfig <$>
|
|
||||||
(case snackLib raw of
|
|
||||||
Nothing -> pure Nothing
|
|
||||||
Just fp -> Just <$> mkSnackLib fp
|
|
||||||
) <*>
|
|
||||||
forM (snackNix raw) mkSnackNix <*>
|
|
||||||
pure (snackNixCfg raw)
|
|
||||||
|
|
||||||
parseNixConfig :: Opts.Parser NixConfig
|
parseNixConfig :: Opts.Parser NixConfig
|
||||||
parseNixConfig =
|
parseNixConfig =
|
||||||
(NixConfig <$>
|
(NixConfig <$>
|
||||||
@ -147,6 +184,25 @@ parseNixConfig =
|
|||||||
<> Opts.help "How many cores to use during the build")
|
<> Opts.help "How many cores to use during the build")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
--- Snack configuration (unrelated to packages)
|
||||||
|
|
||||||
|
type SnackConfig = SnackConfig_ 'ConfigReady
|
||||||
|
type SnackConfigRaw = SnackConfig_ 'ConfigRaw
|
||||||
|
|
||||||
|
-- | Extra configuration for snack
|
||||||
|
data SnackConfig_ c = SnackConfig
|
||||||
|
{ snackLib :: Maybe (Config c FilePath SnackLib)
|
||||||
|
, snackNix :: Config c SnackNixConfig (Maybe SnackNix)
|
||||||
|
, snackNixCfg :: NixConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareSnackConfig :: SnackConfigRaw -> IO SnackConfig
|
||||||
|
prepareSnackConfig raw =
|
||||||
|
SnackConfig <$>
|
||||||
|
forM (snackLib raw) mkSnackLib <*>
|
||||||
|
prepareSnackNix (snackNix raw) <*>
|
||||||
|
pure (snackNixCfg raw)
|
||||||
|
|
||||||
parseSnackConfig :: Opts.Parser SnackConfigRaw
|
parseSnackConfig :: Opts.Parser SnackConfigRaw
|
||||||
parseSnackConfig = SnackConfig <$> Opts.optional
|
parseSnackConfig = SnackConfig <$> Opts.optional
|
||||||
(Opts.strOption
|
(Opts.strOption
|
||||||
@ -160,40 +216,56 @@ parseSnackConfig = SnackConfig <$> Opts.optional
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) <*>
|
) <*> parseSnackNixConfig <*>
|
||||||
Opts.optional (
|
|
||||||
Opts.strOption
|
|
||||||
(Opts.long "snack-nix"
|
|
||||||
<> Opts.short 'b'
|
|
||||||
<> Opts.metavar "PATH")
|
|
||||||
) <*>
|
|
||||||
parseNixConfig
|
parseNixConfig
|
||||||
|
|
||||||
parseMode :: Opts.Parser ModeRaw
|
-- | What command to execute
|
||||||
parseMode =
|
data Command
|
||||||
(Standalone <$>
|
= Build
|
||||||
Opts.strOption
|
| Run [String] -- Run with extra args
|
||||||
(Opts.long "package-nix"
|
| Ghci
|
||||||
<> Opts.short 's'
|
| Test
|
||||||
<> Opts.value "./package.nix"
|
|
||||||
<> Opts.metavar "PATH")
|
parseCommand :: Opts.Parser Command
|
||||||
)
|
parseCommand =
|
||||||
<|>
|
Opts.hsubparser
|
||||||
(HPack <$>
|
( Opts.command "build" (Opts.info (pure Build) mempty)
|
||||||
Opts.strOption
|
<> Opts.command "run" (Opts.info
|
||||||
(Opts.long "package-yaml"
|
( Run <$> Opts.many (Opts.argument Opts.str (Opts.metavar "ARG"))
|
||||||
<> Opts.value "./package.yaml"
|
) mempty)
|
||||||
<> Opts.short 'p'
|
<> Opts.command "ghci" (Opts.info (pure Ghci) mempty)
|
||||||
<> Opts.metavar "PATH")
|
)
|
||||||
)
|
<|> Opts.hsubparser
|
||||||
|
( Opts.command "test" (Opts.info (pure Test) (Opts.progDesc "Use build, run or ghci commands with test suites."))
|
||||||
|
<> Opts.commandGroup "Unavailable commands:"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OptionsRaw = Options_ 'ConfigRaw
|
||||||
|
type Options = Options_ 'ConfigReady
|
||||||
|
|
||||||
|
-- | The whole set of CLI options
|
||||||
|
data Options_ c = Options
|
||||||
|
{ snackConfig :: SnackConfig_ c
|
||||||
|
, package :: Config c PackageFileConfig PackageFile
|
||||||
|
, command :: Command
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareOptions :: OptionsRaw -> IO Options
|
||||||
|
prepareOptions raw =
|
||||||
|
Options <$>
|
||||||
|
prepareSnackConfig (snackConfig raw) <*>
|
||||||
|
preparePackage (package raw) <*>
|
||||||
|
pure (command raw)
|
||||||
|
|
||||||
parseOptions :: Opts.Parser OptionsRaw
|
parseOptions :: Opts.Parser OptionsRaw
|
||||||
parseOptions =
|
parseOptions =
|
||||||
Options <$>
|
Options <$>
|
||||||
parseSnackConfig <*>
|
parseSnackConfig <*>
|
||||||
parseMode <*>
|
parsePackageFileConfig <*>
|
||||||
parseCommand
|
parseCommand
|
||||||
|
|
||||||
|
--- Build related types used when interfacing with Nix
|
||||||
|
|
||||||
newtype ModuleName = ModuleName T.Text
|
newtype ModuleName = ModuleName T.Text
|
||||||
deriving newtype (Ord, Eq, Aeson.FromJSONKey)
|
deriving newtype (Ord, Eq, Aeson.FromJSONKey)
|
||||||
deriving stock Show
|
deriving stock Show
|
||||||
@ -240,17 +312,16 @@ instance FromJSON ExecutableBuild where
|
|||||||
parseJSON = Aeson.withObject "executable build" $ \o ->
|
parseJSON = Aeson.withObject "executable build" $ \o ->
|
||||||
ExecutableBuild <$> o .: "exe_path"
|
ExecutableBuild <$> o .: "exe_path"
|
||||||
|
|
||||||
data MultiBuild = MultiBuild
|
newtype MultiBuild = MultiBuild
|
||||||
{ _librayBuild :: Maybe LibraryBuild
|
{ executableBuilds :: Map.Map T.Text ExecutableBuild
|
||||||
, executableBuilds :: Map.Map T.Text ExecutableBuild
|
|
||||||
}
|
}
|
||||||
deriving stock Show
|
deriving stock Show
|
||||||
|
|
||||||
instance Aeson.FromJSON MultiBuild where
|
instance Aeson.FromJSON MultiBuild where
|
||||||
parseJSON = Aeson.withObject "multi build" $ \o ->
|
parseJSON = Aeson.withObject "multi build" $ \o ->
|
||||||
MultiBuild
|
MultiBuild <$> o .: "executables"
|
||||||
<$> o .:? "library"
|
|
||||||
<*> o .: "executables"
|
--- Type-helpers for passing arguments to Nix
|
||||||
|
|
||||||
data NixArg = NixArg
|
data NixArg = NixArg
|
||||||
{ argType :: NixArgType
|
{ argType :: NixArgType
|
||||||
@ -268,12 +339,6 @@ newtype NixPath = NixPath T.Text
|
|||||||
deriving newtype FromJSON
|
deriving newtype FromJSON
|
||||||
deriving stock Show
|
deriving stock Show
|
||||||
|
|
||||||
decodeOrFail :: FromJSON a => BS.ByteString -> Sh a
|
|
||||||
decodeOrFail bs = case Aeson.decodeStrict' bs of
|
|
||||||
Just foo -> pure foo
|
|
||||||
Nothing -> throwIO $ userError $ unlines
|
|
||||||
[ "could not decode " <> show bs ]
|
|
||||||
|
|
||||||
nixBuild :: SnackConfig -> [NixArg] -> NixExpr -> Sh NixPath
|
nixBuild :: SnackConfig -> [NixArg] -> NixExpr -> Sh NixPath
|
||||||
nixBuild snackCfg extraNixArgs nixExpr =
|
nixBuild snackCfg extraNixArgs nixExpr =
|
||||||
NixPath <$> runStdin1
|
NixPath <$> runStdin1
|
||||||
@ -343,71 +408,38 @@ nixBuild snackCfg extraNixArgs nixExpr =
|
|||||||
: [ argName narg , argValue narg ]
|
: [ argName narg , argValue narg ]
|
||||||
nixCfg = snackNixCfg snackCfg
|
nixCfg = snackNixCfg snackCfg
|
||||||
|
|
||||||
snackBuild :: SnackConfig -> PackageNix -> Sh BuildResult
|
snackBuild :: SnackConfig -> PackageFile -> Sh BuildResult
|
||||||
snackBuild snackCfg packageNix = do
|
snackBuild snackCfg packageFile = do
|
||||||
NixPath out <- nixBuild snackCfg
|
NixPath out <- nixBuild snackCfg
|
||||||
[ NixArg
|
[ NixArg
|
||||||
{ argName = "packageNix"
|
{ argName = "packageFile"
|
||||||
, argValue = T.pack $ unPackageNix packageNix
|
, argValue = T.pack $ unPackageFile packageFile
|
||||||
, argType = Arg
|
, argType = Arg
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
$ NixExpr "snack.inferSnackBuild packageNix"
|
$ NixExpr "snack.inferBuild packageFile"
|
||||||
decodeOrFail =<< liftIO (BS.readFile $ T.unpack out)
|
decodeOrFail =<< liftIO (BS.readFile $ T.unpack out)
|
||||||
|
|
||||||
snackGhci :: SnackConfig -> PackageNix -> Sh GhciBuild
|
snackGhci :: SnackConfig -> PackageFile -> Sh GhciBuild
|
||||||
snackGhci snackCfg packageNix = do
|
snackGhci snackCfg packageFile = do
|
||||||
NixPath out <- nixBuild snackCfg
|
NixPath out <- nixBuild snackCfg
|
||||||
[ NixArg
|
[ NixArg
|
||||||
{ argName = "packageNix"
|
{ argName = "packageFile"
|
||||||
, argValue = T.pack $ unPackageNix packageNix
|
, argValue = T.pack $ unPackageFile packageFile
|
||||||
, argType = Arg
|
, argType = Arg
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
$ NixExpr "snack.inferSnackGhci packageNix"
|
$ NixExpr "snack.inferGhci packageFile"
|
||||||
liftIO (BS.readFile (T.unpack out)) >>= decodeOrFail >>= \case
|
liftIO (BS.readFile (T.unpack out)) >>= decodeOrFail >>= \case
|
||||||
BuiltGhci g -> pure g
|
BuiltGhci g -> pure g
|
||||||
b -> throwIO $ userError $ "Expected GHCi build, got " <> show b
|
b -> throwIO $ userError $ "Expected GHCi build, got " <> show b
|
||||||
|
|
||||||
snackBuildHPack :: SnackConfig -> PackageYaml -> Sh BuildResult
|
runCommand :: SnackConfig -> PackageFile -> Command -> IO ()
|
||||||
snackBuildHPack snackCfg packageYaml = do
|
runCommand snackCfg packageFile = \case
|
||||||
NixPath out <- nixBuild snackCfg
|
Build -> S.shelly $ void $ snackBuild snackCfg packageFile
|
||||||
[ NixArg
|
Run args -> quiet (snackBuild snackCfg packageFile) >>= runBuildResult args
|
||||||
{ argName = "packageYaml"
|
|
||||||
, argValue = T.pack $ unPackageYaml packageYaml
|
|
||||||
, argType = Arg
|
|
||||||
}
|
|
||||||
]
|
|
||||||
$ NixExpr "snack.inferHPackBuild packageYaml"
|
|
||||||
decodeOrFail =<< liftIO (BS.readFile (T.unpack out))
|
|
||||||
|
|
||||||
snackGhciHPack :: SnackConfig -> PackageYaml -> Sh GhciBuild
|
|
||||||
snackGhciHPack snackCfg packageYaml = do
|
|
||||||
NixPath out <- nixBuild snackCfg
|
|
||||||
[ NixArg
|
|
||||||
{ argName = "packageYaml"
|
|
||||||
, argValue = T.pack $ unPackageYaml packageYaml
|
|
||||||
, argType = Arg
|
|
||||||
}
|
|
||||||
]
|
|
||||||
$ NixExpr "snack.inferHPackGhci packageYaml"
|
|
||||||
liftIO (BS.readFile (T.unpack out)) >>= decodeOrFail >>= \case
|
|
||||||
BuiltGhci g -> pure g
|
|
||||||
b -> throwIO $ userError $ "Expected GHCi build, got " <> show b
|
|
||||||
|
|
||||||
runCommand :: SnackConfig -> Mode -> Command -> IO ()
|
|
||||||
runCommand snackCfg (Standalone packageNix) = \case
|
|
||||||
Build -> S.shelly $ void $ snackBuild snackCfg packageNix
|
|
||||||
Run args -> quiet (snackBuild snackCfg packageNix) >>= runBuildResult args
|
|
||||||
Ghci -> flip runExe [] =<<
|
Ghci -> flip runExe [] =<<
|
||||||
ghciExePath <$> (quiet (snackGhci snackCfg packageNix))
|
ghciExePath <$> (quiet (snackGhci snackCfg packageFile))
|
||||||
Test -> noTest
|
|
||||||
runCommand snackCfg (HPack packageYaml) = \case
|
|
||||||
Build -> S.shelly $ void $ snackBuildHPack snackCfg packageYaml
|
|
||||||
Run args ->
|
|
||||||
quiet (snackBuildHPack snackCfg packageYaml) >>= runBuildResult args
|
|
||||||
Ghci -> flip runExe [] =<<
|
|
||||||
ghciExePath <$> quiet (snackGhciHPack snackCfg packageYaml)
|
|
||||||
Test -> noTest
|
Test -> noTest
|
||||||
|
|
||||||
noTest :: IO a
|
noTest :: IO a
|
||||||
@ -421,29 +453,46 @@ runBuildResult args = \case
|
|||||||
runExe exe args
|
runExe exe args
|
||||||
b -> fail $ "Unexpected build type: " <> show b
|
b -> fail $ "Unexpected build type: " <> show b
|
||||||
|
|
||||||
quiet :: Sh a -> IO a
|
|
||||||
quiet = S.shelly . S.print_stdout False
|
|
||||||
|
|
||||||
runExe :: NixPath -> [String] -> IO ()
|
runExe :: NixPath -> [String] -> IO ()
|
||||||
runExe (NixPath fp) args = executeFile (T.unpack fp) True args Nothing
|
runExe (NixPath fp) args = executeFile (T.unpack fp) True args Nothing
|
||||||
|
|
||||||
parseCommand :: Opts.Parser Command
|
specJson :: T.Text
|
||||||
parseCommand =
|
specJson = $(embedStringFile "spec.json")
|
||||||
Opts.hsubparser
|
|
||||||
( Opts.command "build" (Opts.info (pure Build) mempty)
|
|
||||||
<> Opts.command "run" (Opts.info
|
|
||||||
( Run <$> Opts.many (Opts.argument Opts.str (Opts.metavar "ARG"))
|
|
||||||
) mempty)
|
|
||||||
<> Opts.command "ghci" (Opts.info (pure Ghci) mempty)
|
|
||||||
)
|
|
||||||
<|> Opts.hsubparser
|
|
||||||
( Opts.command "test" (Opts.info (pure Test) (Opts.progDesc "Use build, run or ghci commands with test suites."))
|
|
||||||
<> Opts.commandGroup "Unavailable commands:"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
libb64 :: T.Text
|
||||||
|
libb64 = $(embedStringFile "lib.tar.gz.b64")
|
||||||
|
|
||||||
|
--- Auxiliary
|
||||||
|
|
||||||
|
mkDirPath :: FilePath -> IO FilePath
|
||||||
|
mkDirPath fp = doesPathExist fp >>= \case
|
||||||
|
True -> doesFileExist fp >>= \case
|
||||||
|
True -> throwIO $ userError $ fp <> " is a file"
|
||||||
|
False -> canonicalizePath fp
|
||||||
|
False -> throwIO $ userError $ fp <> " does not exist"
|
||||||
|
|
||||||
|
mkFilePath :: FilePath -> IO FilePath
|
||||||
|
mkFilePath fp =
|
||||||
|
mkFilePathEither fp >>= either (throwIO . userError) pure
|
||||||
|
|
||||||
|
mkFilePathEither :: FilePath -> IO (Either String FilePath)
|
||||||
|
mkFilePathEither fp = doesFileExist fp >>= \case
|
||||||
|
True -> Right <$> canonicalizePath fp
|
||||||
|
False -> doesPathExist fp >>= \case
|
||||||
|
True -> pure (Left (fp <> " is a directory"))
|
||||||
|
False -> pure (Left (fp <> " does not exist"))
|
||||||
|
|
||||||
|
decodeOrFail :: FromJSON a => BS.ByteString -> Sh a
|
||||||
|
decodeOrFail bs = case Aeson.decodeStrict' bs of
|
||||||
|
Just foo -> pure foo
|
||||||
|
Nothing -> throwIO $ userError $ unlines
|
||||||
|
[ "could not decode " <> show bs ]
|
||||||
|
|
||||||
|
-- | Run the executable with given arguments
|
||||||
run :: S.FilePath -> [T.Text] -> Sh [T.Text]
|
run :: S.FilePath -> [T.Text] -> Sh [T.Text]
|
||||||
run p args = T.lines <$> S.run p args
|
run p args = T.lines <$> S.run p args
|
||||||
|
|
||||||
|
-- | Run the executable with given arguments, assuming a single line of output
|
||||||
runStdin1 :: T.Text -> S.FilePath -> [T.Text] -> Sh T.Text
|
runStdin1 :: T.Text -> S.FilePath -> [T.Text] -> Sh T.Text
|
||||||
runStdin1 stin p args = do
|
runStdin1 stin p args = do
|
||||||
S.setStdin stin
|
S.setStdin stin
|
||||||
@ -451,8 +500,5 @@ runStdin1 stin p args = do
|
|||||||
[out] -> pure out
|
[out] -> pure out
|
||||||
xs -> throwIO $ userError $ "unexpected output: " <> show xs
|
xs -> throwIO $ userError $ "unexpected output: " <> show xs
|
||||||
|
|
||||||
specJson :: T.Text
|
quiet :: Sh a -> IO a
|
||||||
specJson = $(embedStringFile "spec.json")
|
quiet = S.shelly . S.print_stdout False
|
||||||
|
|
||||||
libb64 :: T.Text
|
|
||||||
libb64 = $(embedStringFile "lib.tar.gz.b64")
|
|
||||||
|
@ -68,7 +68,7 @@ for t in $SNACK_TESTS; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
for t in $SNACK_TESTS; do
|
for t in $SNACK_TESTS; do
|
||||||
banner "Test $name"
|
banner "Test $t"
|
||||||
pushd "tests/$t"
|
pushd "tests/$t"
|
||||||
./test
|
./test
|
||||||
popd
|
popd
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# This is the entry point of the library, and badly needs documentation.
|
# This is the entry point of the library, and badly needs documentation.
|
||||||
# TODO: currently single out derivations prepend the PWD to the path
|
# TODO: currently single out derivations prepend the PWD to the path
|
||||||
# TODO: make sure that filters for "base" are airtight
|
# TODO: make sure that filters for "base" are airtight
|
||||||
|
# TODO: document the sh*t out of these functions
|
||||||
{ pkgs
|
{ pkgs
|
||||||
, ghc-version ? "ghc822"
|
, ghc-version ? "ghc822"
|
||||||
, ghcWithPackages ? pkgs.haskell.packages.${ghc-version}.ghcWithPackages
|
, ghcWithPackages ? pkgs.haskell.packages.${ghc-version}.ghcWithPackages
|
||||||
@ -67,6 +68,37 @@ let
|
|||||||
exe_path = "${drv.out}/${drv.relExePath}";
|
exe_path = "${drv.out}/${drv.relExePath}";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# TODO: deduplicate extensions + update README with --package-file
|
||||||
|
inferBuild = packageFile:
|
||||||
|
let
|
||||||
|
basename = builtins.baseNameOf packageFile;
|
||||||
|
components = pkgs.lib.strings.splitString "." basename;
|
||||||
|
ext =
|
||||||
|
if pkgs.lib.length components <= 1
|
||||||
|
then abort ("File " ++ packageFile ++ " does not have an extension")
|
||||||
|
else pkgs.lib.last components;
|
||||||
|
build =
|
||||||
|
if ext == "nix" then inferSnackBuild
|
||||||
|
else if ext == "yaml" then inferHPackBuild
|
||||||
|
else if ext == "yml" then inferHPackBuild
|
||||||
|
else abort ("Unknown extension " ++ ext ++ " of file " ++ packageFile);
|
||||||
|
in build packageFile;
|
||||||
|
|
||||||
|
inferGhci = packageFile:
|
||||||
|
let
|
||||||
|
basename = builtins.baseNameOf packageFile;
|
||||||
|
components = pkgs.lib.strings.splitString "." basename;
|
||||||
|
ext =
|
||||||
|
if pkgs.lib.length components <= 1
|
||||||
|
then abort ("File " ++ packageFile ++ " does not have an extension")
|
||||||
|
else pkgs.lib.last components;
|
||||||
|
ghci =
|
||||||
|
if ext == "nix" then inferSnackGhci
|
||||||
|
else if ext == "yaml" then inferHPackGhci
|
||||||
|
else if ext == "yml" then inferHPackGhci
|
||||||
|
else abort ("Unknown extension " ++ ext ++ " of file " ++ packageFile);
|
||||||
|
in ghci packageFile;
|
||||||
|
|
||||||
inferSnackBuild = packageNix: mkPackage (import packageNix);
|
inferSnackBuild = packageNix: mkPackage (import packageNix);
|
||||||
|
|
||||||
inferSnackGhci = packageNix: writeText "snack-ghci-json"
|
inferSnackGhci = packageNix: writeText "snack-ghci-json"
|
||||||
@ -152,6 +184,8 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit
|
inherit
|
||||||
|
inferBuild
|
||||||
|
inferGhci
|
||||||
inferSnackBuild
|
inferSnackBuild
|
||||||
inferSnackGhci
|
inferSnackGhci
|
||||||
inferHPackBuild
|
inferHPackBuild
|
||||||
@ -160,7 +194,7 @@ in
|
|||||||
buildAsExecutable
|
buildAsExecutable
|
||||||
buildAsLibrary
|
buildAsLibrary
|
||||||
snackSpec
|
snackSpec
|
||||||
hpackSpec
|
hpackSpecs
|
||||||
mkPackage
|
mkPackage
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ test() {
|
|||||||
$SNACK run
|
$SNACK run
|
||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack -j4" test
|
SNACK="snack -j4 --package-file ./package.nix" test
|
||||||
SNACK="snack -j4 -s ./package.nix" test
|
SNACK="snack -j4 --package-file ./package.nix -l ../../snack-lib" test
|
||||||
SNACK="snack -j4 -s ./package.nix -l ../../snack-lib" test
|
SNACK="snack -j4 --package-file ./package.yaml" test
|
||||||
SNACK="snack -j4 --package-yaml ./package.yaml" test
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
{ main = "Foo";
|
|
||||||
src = ./src;
|
|
||||||
dependencies = [
|
|
||||||
"conduit"
|
|
||||||
"something-that-doesnt-exist"
|
|
||||||
];
|
|
||||||
}
|
|
@ -16,6 +16,5 @@ test() {
|
|||||||
rm $TMP_FILE
|
rm $TMP_FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack -j4 --snack-nix snack.nix --package-nix package.nix" test
|
SNACK="snack -j4 --snack-nix snack.nix --package-file package.yaml" test
|
||||||
SNACK="snack -j4 --snack-nix snack.nix" test
|
SNACK="snack -j4" test
|
||||||
SNACK="snack -j4 --snack-nix snack.nix --package-yaml package.yaml" test
|
|
||||||
|
@ -15,7 +15,6 @@ test() {
|
|||||||
rm $TMP_FILE
|
rm $TMP_FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack -j4" test
|
SNACK="snack -j4 --package-file ./package.nix" test
|
||||||
SNACK="snack -j4 -s ./package.nix" test
|
SNACK="snack -j4 --package-file ./package.nix -l ../../snack-lib" test
|
||||||
SNACK="snack -j4 -s ./package.nix -l ../../snack-lib" test
|
SNACK="snack -j4 --package-file ./package.yaml" test
|
||||||
SNACK="snack -j4 --package-yaml ./package.yaml" test
|
|
||||||
|
@ -8,6 +8,8 @@ TMP_DIR=$(mktemp -d)
|
|||||||
git clone http://github.com/nmattia/pboy.git $TMP_DIR
|
git clone http://github.com/nmattia/pboy.git $TMP_DIR
|
||||||
git -C $TMP_DIR reset --hard a2458d6984930a33a3b1972cb6d5c167d2511b06
|
git -C $TMP_DIR reset --hard a2458d6984930a33a3b1972cb6d5c167d2511b06
|
||||||
|
|
||||||
snack -j4 build --package-yaml $TMP_DIR/package.yaml
|
pushd $TMP_DIR
|
||||||
|
snack -j4 build
|
||||||
|
popd
|
||||||
|
|
||||||
rm -rf $TMP_DIR
|
rm -rf $TMP_DIR
|
||||||
|
@ -16,6 +16,6 @@ test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack -j4" test
|
SNACK="snack -j4" test
|
||||||
SNACK="snack -j4 -s ./package.nix" test
|
SNACK="snack -j4 --package-file ./package.nix" test
|
||||||
SNACK="snack -j4 -s ./package.nix -l ../../snack-lib" test
|
SNACK="snack -j4 --package-file ./package.nix -l ../../snack-lib" test
|
||||||
# Note: no HPack test, because HPack doesn't support multi library
|
# Note: no HPack test, because HPack doesn't support multi library
|
||||||
|
@ -16,6 +16,6 @@ test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack" test
|
SNACK="snack" test
|
||||||
SNACK="snack -s ./package.nix" test
|
SNACK="snack --package-file ./package.nix" test
|
||||||
SNACK="snack -j4 -s ./package.nix -l ../../snack-lib" test
|
SNACK="snack -j4 --package-file ./package.nix -l ../../snack-lib" test
|
||||||
# Note: no HPack test, because HPack doesn't support multi library
|
# Note: no HPack test, because HPack doesn't support multi library
|
||||||
|
@ -15,6 +15,5 @@ test() {
|
|||||||
rm $TMP_FILE
|
rm $TMP_FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack -j4" test
|
SNACK="snack -j4 --package-file ./package.nix" test
|
||||||
SNACK="snack -j4 -s ./package.nix" test
|
SNACK="snack -j4 --package-file ./package.yaml" test
|
||||||
SNACK="snack -j4 --package-yaml ./package.yaml" test
|
|
||||||
|
@ -15,6 +15,5 @@ test() {
|
|||||||
rm $TMP_FILE
|
rm $TMP_FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack -j4" test
|
SNACK="snack -j4 --package-file ./package.nix" test
|
||||||
SNACK="snack -j4 -s ./package.nix" test
|
SNACK="snack -j4 --package-file ./package.yaml" test
|
||||||
SNACK="snack -j4 --package-yaml ./package.yaml" test
|
|
||||||
|
@ -16,6 +16,5 @@ test() {
|
|||||||
rm $TMP_FILE
|
rm $TMP_FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack -j4" test
|
SNACK="snack -j4 --package-file ./package.nix" test
|
||||||
SNACK="snack -j4 -s ./package.nix" test
|
SNACK="snack -j4 --package-file ./package.yaml" test
|
||||||
SNACK="snack -j4 --package-yaml ./package.yaml" test
|
|
||||||
|
@ -16,6 +16,5 @@ test() {
|
|||||||
rm $TMP_FILE
|
rm $TMP_FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack -j4" test
|
SNACK="snack -j4 --package-file ./package.nix" test
|
||||||
SNACK="snack -j4 -s ./package.nix" test
|
SNACK="snack -j4 --package-file ./package.yaml" test
|
||||||
SNACK="snack -j4 --package-yaml ./package.yaml" test
|
|
||||||
|
@ -8,7 +8,6 @@ test() {
|
|||||||
$SNACK run
|
$SNACK run
|
||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack -j4" test
|
SNACK="snack -j4 --package-file ./package.nix" test
|
||||||
SNACK="snack -j4 -s ./package.nix" test
|
SNACK="snack -j4 --package-file ./package.nix -l ../../snack-lib" test
|
||||||
SNACK="snack -j4 -s ./package.nix -l ../../snack-lib" test
|
SNACK="snack -j4 --package-file ./package.yaml" test
|
||||||
SNACK="snack -j4 --package-yaml ./package.yaml" test
|
|
||||||
|
@ -8,4 +8,4 @@ test() {
|
|||||||
$SNACK run
|
$SNACK run
|
||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack -j4 --package-yaml ./package.yaml" test
|
SNACK="snack -j4" test
|
||||||
|
@ -16,10 +16,5 @@ test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SNACK="snack -j4" test
|
SNACK="snack -j4 -p ./package.nix" test
|
||||||
|
SNACK="snack -j4 -p ./package.yaml" test
|
||||||
# TODO: Fix cannot coerce a list to a string, at /...-snack-lib/files.nix:66:12
|
|
||||||
SNACK="snack -j4 -s ./package.nix" test
|
|
||||||
|
|
||||||
# TODO: Fix cannot coerce a list to a string, at /...-snack-lib/hpack.nix:60:37
|
|
||||||
SNACK="snack -j4 --package-yaml ./package.yaml" test
|
|
||||||
|
@ -15,6 +15,5 @@ test() {
|
|||||||
rm $TMP_FILE
|
rm $TMP_FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack -j4" test
|
SNACK="snack -j4 --package-file ./package.nix" test
|
||||||
SNACK="snack -j4 -s ./package.nix" test
|
SNACK="snack -j4 --package-file ./package.yaml" test
|
||||||
SNACK="snack -j4 --package-yaml ./package.yaml" test
|
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
snack -j4 build -s code/package.nix
|
snack -j4 build --package-file code/package.nix
|
||||||
snack -j4 run -s code/package.nix | diff golden -
|
snack -j4 run --package-file code/package.nix | diff golden -
|
||||||
|
|
||||||
TMP_FILE=$(mktemp)
|
TMP_FILE=$(mktemp)
|
||||||
|
|
||||||
capture_io "$TMP_FILE" main | snack -j4 -s code/package.nix ghci
|
capture_io "$TMP_FILE" main | snack -j4 --package-file code/package.nix ghci
|
||||||
|
|
||||||
diff golden $TMP_FILE
|
diff golden $TMP_FILE
|
||||||
rm $TMP_FILE
|
rm $TMP_FILE
|
||||||
|
@ -16,5 +16,5 @@ test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack -j4" test
|
SNACK="snack -j4" test
|
||||||
SNACK="snack -j4 -s ./package.nix" test
|
SNACK="snack -j4 --package-file ./package.nix" test
|
||||||
# Note: no HPack test, because HPack doesn't support multi library
|
# Note: no HPack test, because HPack doesn't support multi library
|
||||||
|
@ -15,6 +15,5 @@ test() {
|
|||||||
rm $TMP_FILE
|
rm $TMP_FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack" test
|
SNACK="snack --package-file ./package.nix" test
|
||||||
SNACK="snack -s ./package.nix" test
|
SNACK="snack --package-file ./package.yaml" test
|
||||||
SNACK="snack --package-yaml ./package.yaml" test
|
|
||||||
|
@ -15,6 +15,5 @@ test() {
|
|||||||
rm $TMP_FILE
|
rm $TMP_FILE
|
||||||
}
|
}
|
||||||
|
|
||||||
SNACK="snack" test
|
SNACK="snack --package-file ./package.nix" test
|
||||||
SNACK="snack -s ./package.nix" test
|
SNACK="snack --package-file ./package.yaml" test
|
||||||
SNACK="snack --package-yaml ./package.yaml" test
|
|
||||||
|
Loading…
Reference in New Issue
Block a user