packages feed

buffet 0.3.0 → 0.4.0

raw patch · 7 files changed

+108/−23 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

README.md view
@@ -4,22 +4,52 @@ [![License](https://img.shields.io/github/license/evolutics/buffet)](LICENSE) [![Package](https://img.shields.io/hackage/v/buffet)](https://hackage.haskell.org/package/buffet) -Assemble many Dockerfiles in a single Dockerfile. This gives you the convenience of one Docker image with your favorite tools while keeping the modularity of a separate Dockerfile per tool.+Assemble many Dockerfiles in a single Dockerfile. This gives you the convenience of one Docker image with your favorite tools while keeping a separate Dockerfile per tool. -See [Code Cleaner Buffet](https://github.com/evolutics/code-cleaner-buffet) for an application of this.+<details>+<summary>Demo example</summary> -## Installation+A Dockerfile for Prettier -Run+```dockerfile+FROM alpine:3.11.5+RUN apk add --no-cache yarn~=1.19 && yarn global add prettier@2.0.2+WORKDIR /workdir+``` +plus a Dockerfile for HTML Tidy++```dockerfile+FROM alpine:3.11.5+RUN apk add --no-cache tidyhtml~=5.6+WORKDIR /workdir+```++are automatically assembled in a single Dockerfile++```dockerfile+FROM alpine:3.11.5+RUN apk add --no-cache yarn~=1.19 && yarn global add prettier@2.0.2 \+  && apk add --no-cache tidyhtml~=5.6+WORKDIR /workdir+```++You can try this yourself by running+ ```bash-stack install buffet+buffet assemble examples/minimal_demonstration ``` -or+</details> +See [Code Cleaner Buffet](https://github.com/evolutics/code-cleaner-buffet) for an application of this.++## Installation++For a **quick start,** use the Docker image [`evolutics/buffet`](https://hub.docker.com/r/evolutics/buffet). I recommend a Bash alias like+ ```bash-cabal install buffet+alias buffet='docker run --rm --volume "$(pwd)":/workdir evolutics/buffet' ```  You are ready when@@ -30,6 +60,8 @@  works. +Alternatively, you can do a **native** installation with `stack install buffet` or `cabal install buffet`.+ ## Usage example  Say we work on a simple website with HTML code that we would like to format, clean up, and validate. For this purpose, we choose the tools Prettier and HTML Tidy, which we plan use in continuous integration via a Docker image.@@ -41,22 +73,23 @@ cd buffet ``` +The source code for this and other examples is in the **[`examples`](examples) folder.**+ ### Assembling -In the subfolders of [`examples/quick_start`](examples/quick_start), you see a [Dockerfile for Prettier](examples/quick_start/prettier/Dockerfile) and another [Dockerfile for HTML Tidy](examples/quick_start/tidy/Dockerfile). These Dockerfiles (called "dishes") are the modular toy blocks, which we now automatically combine to one Dockerfile (called "buffet") by running+In the subfolders of [`examples/quick_start`](examples/quick_start), you see a [Dockerfile for Prettier](examples/quick_start/prettier/Dockerfile) and another [Dockerfile for HTML Tidy](examples/quick_start/tidy/Dockerfile). These Dockerfiles (called "dishes") are the modular toy blocks, which we now **automatically combine** to one Dockerfile (called "buffet") by running  ```bash buffet assemble examples/quick_start ``` -This prints a Dockerfile based on the subfolders of `examples/quick_start`. From this, we can then build a Docker image `mona_linta` with+This prints a Dockerfile based on the subfolders of `examples/quick_start` to stdout. From this, we can then build a Docker image `mona_linta` with  ```bash-buffet assemble examples/quick_start | \-  docker build --build-arg prettier=1.19.1 --tag mona_linta -+buffet assemble examples/quick_start | docker build --tag mona_linta - ``` -Note how in case of Prettier, we pass a `--build-arg` to parameterize the tool version.+Note the hyphen `-` at the end that makes Docker read the Dockerfile from stdin.  ### Testing @@ -68,15 +101,17 @@ tidy --version ``` -To integrate a check like `prettier --version` as a test of the tool installation, add a `HEALTHCHECK` instruction as you see in the [Dockerfile for Prettier](examples/quick_start/prettier/Dockerfile). The exit status of such a command is then reported when you run our example test suite with+To integrate a check like `prettier --version` as a test of the tool installation, add a `HEALTHCHECK` instruction as you see in the [Dockerfile for Prettier](examples/quick_start/prettier/Dockerfile). The exit status of such a command is then reported when you run our example **test suite** with  ```bash buffet test --arguments examples/quick_start/test_arguments.yaml \   examples/quick_start ``` -This builds a Docker image to then run the tests. The file [`test_arguments.yaml`](examples/quick_start/test_arguments.yaml) provides a map that is used for two things: firstly, its entries are used as `--build-arg` options when building the image, and secondly, only tests of dishes referred in this map are run.+This builds a Docker image to then run the tests. Only the dishes referred in the file [`test_arguments.yaml`](examples/quick_start/test_arguments.yaml) are tested. +**Note:** As `buffet test …` executes Docker commands, a [native installation](#installation) is required here.+ If you like, try adding a test for HTML Tidy.  ### Documenting@@ -88,13 +123,21 @@   examples/quick_start ``` -This renders the template [`document_template.md.mustache`](examples/quick_start/document_template.md.mustache). To print the raw template context, omit this option as in+This renders the template [`document_template.md.mustache`](examples/quick_start/document_template.md.mustache). To print the raw **template context,** omit this option as in  ```bash buffet document examples/quick_start ```  Among others, data from `LABEL` instructions is integrated in the template context.++### API usage++You may like to programmatically process the parsed source Dockerfiles. To print an intermediate representation in JSON, run++```bash+buffet parse examples/quick_start+```  ## Terminology 
buffet.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 5c90f2e0ec4124cff2061142d852633fd18e964bd4a7e694cdc1dcf169ae55af+-- hash: 5aa136a496cd4e9ffdb1c3708111acaa4831e2aa5f2eb24ab55e68193bbad52e  name:           buffet-version:        0.3.0+version:        0.4.0 synopsis:       Assembles many Dockerfiles in one. description:    See https://github.com/evolutics/buffet category:       Development@@ -79,7 +79,7 @@       Paths_buffet   hs-source-dirs:       src-  ghc-options: -Weverything -Wno-unsafe -Wno-safe -Wno-missing-local-signatures+  ghc-options: -Weverything -Wno-unsafe -Wno-safe -Wno-missing-deriving-strategies -Wno-missing-local-signatures   build-depends:       aeson     , aeson-pretty@@ -110,7 +110,7 @@       Paths_buffet   hs-source-dirs:       app-  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Weverything -Wno-unsafe -Wno-safe -Wno-missing-local-signatures+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Weverything -Wno-unsafe -Wno-safe -Wno-missing-deriving-strategies -Wno-missing-local-signatures   build-depends:       base >=4.7 && <5     , buffet-internal@@ -120,6 +120,7 @@   type: exitcode-stdio-1.0   main-is: Spec.hs   other-modules:+      Buffet.ReadmeTests       Buffet.Toolbox.TestHelp       Buffet.Toolbox.TestTools       Buffet.Toolbox.TestUtility@@ -129,7 +130,7 @@       Paths_buffet   hs-source-dirs:       test-  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Weverything -Wno-unsafe -Wno-safe -Wno-missing-local-signatures+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Weverything -Wno-unsafe -Wno-safe -Wno-missing-deriving-strategies -Wno-missing-local-signatures   build-depends:       aeson     , base >=4.7 && <5
src/Buffet.hs view
@@ -42,7 +42,7 @@  versionOption :: Options.Parser (a -> a) versionOption =-  Options.infoOption "Buffet 0.3.0" $+  Options.infoOption "Buffet 0.4.0" $   mconcat     [Options.long "version", Options.helpDoc $ Just versionHelp, Options.hidden]   where
src/Buffet/Assemble/ScheduleParallelInstructions.hs view
@@ -61,6 +61,7 @@       , scheduleEnvInstructions       , scheduleRunInstructions       , scheduleWorkdirInstructions+      , scheduleCommentInstructions       , scheduleNextInstructionEach       ] @@ -125,6 +126,12 @@   where     isWorkdir (Docker.Workdir _) = True     isWorkdir _ = False++scheduleCommentInstructions :: ScheduleStep+scheduleCommentInstructions = unifyInstructions isComment+  where+    isComment (Docker.Comment _) = True+    isComment _ = False  scheduleNextInstructionEach :: ScheduleStep scheduleNextInstructionEach queues = (mconcat nexts, queues')
+ test/Buffet/ReadmeTests.hs view
@@ -0,0 +1,24 @@+module Buffet.ReadmeTests+  ( get+  ) where++import qualified Buffet.Toolbox.TestTools as TestTools+import Prelude (FilePath, ($), fmap)+import qualified Test.Tasty as Tasty+import qualified Test.Tasty.HUnit as HUnit++get :: FilePath -> Tasty.TestTree+get readme = Tasty.testGroup readme [filePartsTests readme]++filePartsTests :: FilePath -> Tasty.TestTree+filePartsTests readme =+  Tasty.testGroup "Files that are part of readme" $+  fmap+    inReadme+    [ "examples/minimal_demonstration/prettier/Dockerfile"+    , "examples/minimal_demonstration/tidy/Dockerfile"+    , "test/data/examples/minimal_demonstration/assemble_works/stdout.Dockerfile"+    ]+  where+    inReadme file =+      HUnit.testCase file $ TestTools.assertIsContainedIn file readme
test/Buffet/Toolbox/TestTools.hs view
@@ -1,11 +1,13 @@ module Buffet.Toolbox.TestTools-  ( assertJsonIsSubstructure+  ( assertIsContainedIn+  , assertJsonIsSubstructure   , folderBasedTests   ) where  import qualified Buffet.Toolbox.TextTools as TextTools import qualified Control.Monad as Monad import qualified Data.Aeson as Aeson+import qualified Data.ByteString as ByteString import qualified Data.Function as Function import qualified Data.HashMap.Strict as HashMap import qualified Data.HashSet as Set@@ -37,6 +39,12 @@ import qualified System.FilePath as FilePath import qualified Test.Tasty as Tasty import qualified Test.Tasty.HUnit as HUnit++assertIsContainedIn :: FilePath -> FilePath -> HUnit.Assertion+assertIsContainedIn needlePath haystackPath = do+  needle <- ByteString.readFile needlePath+  haystack <- ByteString.readFile haystackPath+  HUnit.assertBool "" $ ByteString.isInfixOf needle haystack  assertJsonIsSubstructure :: T.Text -> T.Text -> HUnit.Assertion assertJsonIsSubstructure = Function.on (assert []) getJson
test/Spec.hs view
@@ -1,8 +1,9 @@+import qualified Buffet.ReadmeTests as ReadmeTests import qualified Buffet.Toolbox.TestHelp as TestHelp import qualified Buffet.Toolbox.TestTools as TestTools import qualified Buffet.Toolbox.TestUtility as TestUtility import qualified Buffet.Toolbox.TestVersion as TestVersion-import Prelude (FilePath, IO, ($), (.), (<$>), (>>=), flip, sequenceA)+import Prelude (FilePath, IO, ($), (.), (<$>), (>>=), flip, pure, sequenceA) import qualified System.FilePath as FilePath import qualified Test.Tasty as Tasty import qualified Test.Tasty.HUnit as HUnit@@ -20,6 +21,7 @@     , documentTests "test/data/document"     , parseTests "test/data/parse"     , testTests "test/data/test"+    , pure $ ReadmeTests.get "README.md"     , examplesTests "test/data/examples"     ]