mirror of
https://github.com/hercules-ci/arion.git
synced 2024-09-11 10:45:38 +03:00
Add cabal check to ci, build strictly (once)
This commit is contained in:
parent
41d4fefd64
commit
7749eb2ef9
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
)
|
||||
)
|
||||
|
@ -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;
|
||||
}
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 =
|
||||
|
@ -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]
|
||||
|
@ -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?
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Main where
|
||||
|
||||
import Prelude()
|
||||
import Protolude
|
||||
import Test.Hspec.Runner
|
||||
import qualified Spec
|
||||
|
Loading…
Reference in New Issue
Block a user