Add cabal check to ci, build strictly (once)

This commit is contained in:
Robert Hensing 2019-10-04 19:09:29 +02:00
parent 41d4fefd64
commit 7749eb2ef9
11 changed files with 49 additions and 73 deletions

View file

@ -1,9 +1,9 @@
cabal-version: 2.4
name: arion-compose
version: 0.1.0.0
version: 0.1.0.0
synopsis: Run docker-compose with help from Nix/NixOS
-- description:
description: Arion is a tool for building and running applications that consist of multiple docker containers using NixOS modules. It has special support for docker images that are built with Nix, for a smooth development experience and improved performance.
homepage: https://github.com/hercules-ci/arion#readme
-- bug-reports:
license: Apache-2.0
@ -11,10 +11,10 @@ license-file: LICENSE
author: Robert Hensing
maintainer: robert@hercules-ci.com
-- copyright:
-- category:
extra-source-files: CHANGELOG.md, README.asciidoc
write-ghc-enviroment-files:
never
category: Distribution, Network, Cloud, Distributed Computing
extra-source-files: CHANGELOG.md, README.asciidoc,
src/haskell/testdata/**/*.nix
src/haskell/testdata/**/*.json
data-files: nix/*.nix
, nix/modules/composition/*.nix
, nix/modules/nixos/*.nix
@ -24,7 +24,7 @@ data-files: nix/*.nix
-- all data is verbatim from some sources
data-dir: src
common deps
common common
build-depends: base ^>=4.12.0.0
, aeson
, aeson-pretty
@ -38,25 +38,27 @@ common deps
, text
, protolude
, unix
ghc-options: -Wall
flag ghci
default: False
manual: True
library
import: deps
import: common
exposed-modules: Arion.Nix
Arion.Aeson
Arion.DockerCompose
Arion.Images
Arion.Services
other-modules: Paths_arion_compose
autogen-modules: Paths_arion_compose
-- other-extensions:
hs-source-dirs: src/haskell/lib
default-language: Haskell2010
executable arion
import: deps
import: common
main-is: Main.hs
-- other-modules:
-- other-extensions:
@ -66,7 +68,7 @@ executable arion
default-language: Haskell2010
test-suite arion-unit-tests
import: deps
import: common
if flag(ghci)
hs-source-dirs: src/haskell/lib
ghc-options: -Wno-missing-home-modules

View file

@ -7,6 +7,7 @@ in
dimension "Nixpkgs version" {
"nixos-19_03" = {
nixpkgsSource = "nixpkgs";
isReferenceNixpkgs = true;
};
"nixos-unstable" = {
nixpkgsSource = "nixos-unstable";
@ -16,15 +17,15 @@ dimension "Nixpkgs version" {
enableDoc = false;
};
} (
_name: { nixpkgsSource, enableDoc ? true }:
_name: { nixpkgsSource, isReferenceNixpkgs ? false, enableDoc ? true }:
dimension "System" {
"x86_64-linux" = {};
"x86_64-linux" = { isReferenceTarget = isReferenceNixpkgs; };
# TODO: darwin
# "x86_64-darwin" = { enableNixOSTests = false; };
} (
system: {}:
system: { isReferenceTarget ? false }:
let
pkgs = import ./. { inherit system; nixpkgsSrc = sources.${nixpkgsSource}; };
in
@ -32,6 +33,8 @@ dimension "Nixpkgs version" {
inherit (pkgs) arion tests;
} // lib.optionalAttrs enableDoc {
doc = pkgs.recurseIntoAttrs (import ../doc { inherit pkgs; });
} // lib.optionalAttrs isReferenceTarget {
inherit (pkgs.arion-project.haskellPkgs) arion-compose-checked;
}
)
)

View file

@ -1,4 +1,16 @@
self: super: hself: hsuper:
{
arion-compose = import ./haskell-arion-compose.nix { pkgs = self; haskellPackages = hself; };
arion-compose-checked =
let pkg = super.haskell.lib.buildStrictly hself.arion-compose;
checked = super.haskell.lib.overrideCabal pkg (o: {
postConfigure = ''${o.postConfigure or ""}
if ! ${hsuper.cabal-install}/bin/cabal check;
then
echo 1>&2 ERROR: cabal file is invalid. Above warnings were errors.
exit 1
fi
'';
});
in checked;
}

View file

@ -12,20 +12,13 @@ import qualified Arion.DockerCompose as DockerCompose
import Arion.Services (getDefaultExec)
import Options.Applicative
import Control.Applicative
import Control.Monad.Fail
import qualified Data.Aeson.Encode.Pretty
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Builder as TB
import qualified Data.List.NonEmpty as NE
import Data.List.NonEmpty (NonEmpty(..))
import Control.Arrow ((>>>))
import System.Posix.User (getRealUserID)
data CommonOptions =
@ -69,6 +62,7 @@ parseOptions = do
let nixArgs = userNixArgs <|> "--show-trace" <$ guard showTrace
in CommonOptions{..}
textArgument :: Mod ArgumentFields [Char] -> Parser Text
textArgument = fmap T.pack . strArgument
parseCommand :: Parser (CommonOptions -> IO ())
@ -124,18 +118,18 @@ commandDC
-> Text
-> Text
-> Mod CommandFields (CommonOptions -> IO ())
commandDC run cmdStr help =
commandDC run cmdStr helpText =
command
(T.unpack cmdStr)
(info
(run cmdStr <$> parseDockerComposeArgs)
(progDesc (T.unpack help) <> fullDesc <> forwardOptions))
(progDesc (T.unpack helpText) <> fullDesc <> forwardOptions))
--------------------------------------------------------------------------------
runDC :: Text -> DockerComposeArgs -> CommonOptions -> IO ()
runDC cmd (DockerComposeArgs args) opts = do
runDC cmd (DockerComposeArgs args) _opts = do
DockerCompose.run DockerCompose.Args
{ files = []
, otherArgs = [cmd] ++ args
@ -265,7 +259,7 @@ runExec detach privileged user noTTY index envs workDir service commandAndArgs o
main :: IO ()
main =
(join . execParser) (info (parseAll <**> helper) fullDesc)
(join . arionExecParser) (info (parseAll <**> helper) fullDesc)
where
execParser = customExecParser (prefs showHelpOnEmpty)
arionExecParser = customExecParser (prefs showHelpOnEmpty)

View file

@ -4,11 +4,9 @@ import Prelude ()
import Data.Aeson
import qualified Data.ByteString.Lazy as BL
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.IO as TL
import qualified Data.Text.Lazy.Builder as TB
import qualified Data.Aeson.Encode.Pretty
import Data.Aeson.Encode.Pretty ( defConfig
, keyOrder
, confCompare
, confTrailingNewline
)

View file

@ -3,24 +3,7 @@ module Arion.DockerCompose where
import Prelude ( )
import Protolude
import Arion.Aeson ( pretty )
import Data.Aeson
import qualified Data.String
import System.Process
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
import Paths_arion_compose
import Control.Applicative
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.List.NonEmpty as NE
import Data.List.NonEmpty ( NonEmpty(..) )
import Control.Arrow ( (>>>) )
import System.IO.Temp ( withTempFile )
import System.IO ( hClose )
data Args = Args
{ files :: [FilePath]
@ -43,6 +26,5 @@ run args = do
case exitCode of
ExitSuccess -> pass
ExitFailure 1 -> exitFailure
e@ExitFailure {} -> do
ExitFailure {} -> do
throwIO $ FatalError $ "docker-compose failed with " <> show exitCode
exitWith e

View file

@ -10,7 +10,6 @@ import Protolude hiding (to)
import qualified Data.Aeson as Aeson
import Arion.Aeson (decodeFile)
import qualified Data.ByteString as BS
import qualified System.Process as Process
import Control.Lens

View file

@ -16,12 +16,9 @@ import Data.Aeson
import qualified Data.String
import qualified System.Directory as Directory
import System.Process
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
import Paths_arion_compose
import Control.Applicative
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.List.NonEmpty as NE
@ -76,21 +73,20 @@ evaluateComposition ea = do
case exitCode of
ExitSuccess -> pass
ExitFailure 1 -> exitFailure
e@ExitFailure {} -> do
ExitFailure {} -> do
throwIO $ FatalError $ "evaluation failed with " <> show exitCode
exitWith e
case v of
Right r -> pure r
Left e -> throwIO $ FatalError "Couldn't parse nix-instantiate output"
Left e -> throwIO $ FatalError ("Couldn't parse nix-instantiate output" <> show e)
-- | Run with docker-compose.yaml tmpfile
withEvaluatedComposition :: EvaluationArgs -> (FilePath -> IO r) -> IO r
withEvaluatedComposition ea f = do
v <- evaluateComposition ea
withTempFile "." ".tmp-arion-docker-compose.yaml" $ \path handle -> do
T.hPutStrLn handle (pretty v)
hClose handle
withTempFile "." ".tmp-arion-docker-compose.yaml" $ \path yamlHandle -> do
T.hPutStrLn yamlHandle (pretty v)
hClose yamlHandle
f path
@ -117,15 +113,14 @@ buildComposition outLink ea = do
case exitCode of
ExitSuccess -> pass
ExitFailure 1 -> exitFailure
e@ExitFailure {} -> do
ExitFailure {} -> do
throwIO $ FatalError $ "nix-build failed with " <> show exitCode
exitWith e
-- | Do something with a docker-compose.yaml.
withBuiltComposition :: EvaluationArgs -> (FilePath -> IO r) -> IO r
withBuiltComposition ea f = do
withTempFile "." ".tmp-arion-docker-compose.yaml" $ \path handle -> do
hClose handle
withTempFile "." ".tmp-arion-docker-compose.yaml" $ \path emptyYamlHandle -> do
hClose emptyYamlHandle
-- Known problem: kills atomicity of withTempFile; won't fix because we should manage gc roots,
-- impl of which will probably avoid this "problem". It seems unlikely to cause issues.
Directory.removeFile path
@ -149,9 +144,8 @@ replForComposition ea = do
case exitCode of
ExitSuccess -> pass
ExitFailure 1 -> exitFailure
e@ExitFailure {} -> do
ExitFailure {} -> do
throwIO $ FatalError $ "nix repl failed with " <> show exitCode
exitWith e
argArgs :: EvaluationArgs -> [[Char]]
argArgs ea =

View file

@ -10,13 +10,9 @@ import Protolude hiding (to)
import qualified Data.Aeson as Aeson
import Arion.Aeson (decodeFile)
import qualified Data.ByteString as BS
import qualified System.Process as Process
import Control.Lens
import Data.Aeson.Lens
import Data.String
import System.IO (withFile, IOMode(ReadMode))
-- | Subject to change
getDefaultExec :: FilePath -> Text -> IO [Text]

View file

@ -6,16 +6,11 @@ where
import Protolude
import Test.Hspec
import Test.QuickCheck
import qualified Data.List.NonEmpty as NEL
import Arion.Aeson
import Arion.Nix
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.Text.Lazy.IO as TL
import qualified Data.Text.Lazy.Builder as TB
import qualified Data.Aeson.Encode.Pretty
import Data.Char (isSpace)
spec :: Spec
spec = describe "evaluateComposition" $ it "matches an example" $ do
@ -32,8 +27,8 @@ spec = describe "evaluateComposition" $ it "matches an example" $ do
expected <- T.readFile "src/haskell/testdata/Arion/NixSpec/arion-compose.json"
censorPaths actual `shouldBe` censorPaths expected
censorPaths :: Text -> Text
censorPaths = censorImages . censorStorePaths
--censorPaths = censorStorePaths
censorStorePaths :: Text -> Text
censorStorePaths x = case T.breakOn "/nix/store/" x of
@ -61,4 +56,4 @@ isNixNameChar c | c >= 'A' && c <= 'Z' = True
isNixNameChar c | c == '-' = True
isNixNameChar c | c == '.' = True
isNixNameChar c | c == '_' = True -- WRONG?
isNixNameChar c = False -- WRONG?
isNixNameChar _ = False -- WRONG?

View file

@ -1,5 +1,6 @@
module Main where
import Prelude()
import Protolude
import Test.Hspec.Runner
import qualified Spec