Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This reverts commit ba7af70. We migrated the cat_hs example from using Hazel to using `haskell_cabal_library` and `stack_snapshot`. This is an example of a non-trivial application, with system dependencies and Hackage-downloaded depnedencies. Closes #732
- Loading branch information
Showing
13 changed files
with
476 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
load( | ||
"@rules_haskell//haskell:defs.bzl", | ||
"haskell_doc", | ||
) | ||
|
||
haskell_doc( | ||
name = "api-doc", | ||
deps = [ | ||
"//cat_hs/lib/args", | ||
"//cat_hs/lib/cat", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# cat_hs - A rules_haskell Example Project | ||
|
||
This project re-implements a subset of the `cat` command-line tool in | ||
Haskell. It serves as an example of a project built using | ||
the [Bazel][bazel] build system, using [rules_haskell][rules_haskell] | ||
to define the Haskell build, including rules that wrap Cabal to build | ||
third-party dependencies downloadable from Hackage, and | ||
using [rules_nixpkgs][rules_nixpkgs] and [Nix][nix] to manage system | ||
dependencies. | ||
|
||
[bazel]: https://bazel.build/ | ||
[rules_haskell]: https://haskell.build/ | ||
[rules_nixpkgs]: https://github.com/tweag/rules_nixpkgs | ||
[nix]: https://nixos.org/nix/ | ||
|
||
## Prerequisites | ||
|
||
You need to install the [Nix package manager][nix]. All further dependencies | ||
will be managed using Nix. | ||
|
||
## Instructions | ||
|
||
To build the package execute the following command in the checked out source | ||
repository. | ||
|
||
``` | ||
$ nix-shell --pure --run "bazel build //..." | ||
``` | ||
|
||
To run the tests execute the following command. | ||
|
||
``` | ||
$ nix-shell --pure --run "bazel test //..." | ||
``` | ||
|
||
To run the executable enter the following commands. | ||
|
||
``` | ||
$ nix-shell --pure --run "bazel run //exec/cat_hs -- -h" | ||
$ nix-shell --pure --run "bazel run //exec/cat_hs -- $PWD/README.md" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
load( | ||
"@rules_haskell//haskell:defs.bzl", | ||
"haskell_binary", | ||
) | ||
load( | ||
"@rules_haskell//haskell:cabal.bzl", | ||
"haskell_cabal_library", | ||
) | ||
|
||
haskell_binary( | ||
name = "cat_hs", | ||
srcs = glob(["src/**/*.hs"]), | ||
deps = [ | ||
"//cat_hs/lib/args", | ||
"//cat_hs/lib/cat", | ||
"@stackage//:base", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
module Main | ||
( main | ||
) where | ||
|
||
import qualified Args | ||
import Cat (runCat) | ||
|
||
|
||
main :: IO () | ||
main = Args.parse >>= runCat |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
load( | ||
"@rules_haskell//haskell:defs.bzl", | ||
"haskell_library", | ||
"haskell_test", | ||
) | ||
load( | ||
"@rules_haskell//haskell:cabal.bzl", | ||
"haskell_cabal_library", | ||
) | ||
|
||
haskell_library( | ||
name = "args", | ||
srcs = glob(["src/**/*.hs"]), | ||
visibility = ["//visibility:public"], | ||
deps = [ | ||
"@stackage//:base", | ||
"@stackage//:optparse-applicative", | ||
], | ||
) | ||
|
||
haskell_test( | ||
name = "unit", | ||
srcs = glob(["test/**/*.hs"]), | ||
deps = [ | ||
":args", | ||
"@stackage//:base", | ||
"@stackage//:hspec", | ||
"@stackage//:optparse-applicative", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
{-# LANGUAGE LambdaCase #-} | ||
|
||
module Args | ||
( -- * Configuration Types | ||
Args (..) | ||
, FileArg (..) | ||
-- * I/O Interface | ||
, parse | ||
-- * Command-Line Parser | ||
, parser | ||
) where | ||
|
||
import Options.Applicative | ||
|
||
|
||
-- | A file argument. | ||
data FileArg | ||
= StdIn | ||
-- ^ Read from standard input. | ||
| File FilePath | ||
-- ^ Read from the given file. | ||
deriving (Eq, Show) | ||
|
||
|
||
-- | Parsed command-line arguments. | ||
data Args = Args | ||
{ number :: Bool | ||
-- ^ Number output lines flag. | ||
, files :: [FileArg] | ||
-- ^ The list of input files. | ||
} deriving (Eq, Show) | ||
|
||
|
||
-- | Parse the command-line arguments. | ||
parse :: IO Args | ||
parse = execParser parser | ||
|
||
|
||
-- | Command-line parser. | ||
parser :: ParserInfo Args | ||
parser = | ||
info (argsParser <**> helper) | ||
( fullDesc | ||
<> progDesc "Concatenate files to standard output." | ||
<> header "cat_hs - A Haskell implementation of cat." ) | ||
|
||
|
||
argsParser :: Parser Args | ||
argsParser = Args | ||
<$> switch | ||
( long "number" | ||
<> short 'n' | ||
<> help "Number all output lines." ) | ||
<*> many fileArgParser | ||
|
||
|
||
fileArgParser :: Parser FileArg | ||
fileArgParser = | ||
argument readFileArg | ||
( metavar "FILES..." | ||
<> help | ||
"Read from the given file, or from standard input if '-'.\ | ||
\ Use './-' to read from a file named '-'." ) | ||
|
||
|
||
-- | Read a 'FileArg' from a 'String'. | ||
readFileArg :: ReadM FileArg | ||
readFileArg = | ||
maybeReader $ \case | ||
"-" -> Just StdIn | ||
fname -> Just $ File fname |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
module Main | ||
( main | ||
) where | ||
|
||
import Args (Args (Args)) | ||
import qualified Args | ||
import Options.Applicative | ||
import Test.Hspec | ||
|
||
|
||
main :: IO () | ||
main = hspec $ do | ||
describe "Args.parser" $ do | ||
it "parses no arguments" $ do | ||
parse [] | ||
`shouldBe` | ||
Just Args { Args.files = [], Args.number = False } | ||
it "parses one stdin" $ do | ||
parse ["-"] | ||
`shouldBe` | ||
Just Args { Args.files = [Args.StdIn], Args.number = False } | ||
it "parses two stdin" $ do | ||
parse ["-", "-"] | ||
`shouldBe` | ||
Just Args | ||
{ Args.files = [Args.StdIn, Args.StdIn], Args.number = False } | ||
it "parses numbered stdin" $ do | ||
parse ["-n", "-"] | ||
`shouldBe` | ||
Just Args { Args.files = [Args.StdIn], Args.number = True } | ||
it "parses numbered stdin reversed" $ do | ||
parse ["-", "-n"] | ||
`shouldBe` | ||
Just Args { Args.files = [Args.StdIn], Args.number = True } | ||
it "parses file -n" $ do | ||
parse ["--", "-n"] | ||
`shouldBe` | ||
Just Args { Args.files = [Args.File "-n"], Args.number = False } | ||
it "parses file -" $ do | ||
parse ["./-"] | ||
`shouldBe` | ||
Just Args { Args.files = [Args.File "./-"], Args.number = False } | ||
it "parses stdin and file" $ do | ||
parse ["-", "file"] | ||
`shouldBe` | ||
Just Args | ||
{ Args.files = [Args.StdIn, Args.File "file"], Args.number = False } | ||
it "recognizes -h" $ do | ||
parse ["-h"] | ||
`shouldBe` | ||
Nothing | ||
it "recognizes --help" $ do | ||
parse ["-h"] | ||
`shouldBe` | ||
Nothing | ||
it "parses file -h" $ do | ||
parse ["--", "-h"] | ||
`shouldBe` | ||
Just Args { Args.files = [Args.File "-h"], Args.number = False } | ||
|
||
|
||
-- | Execute the command-line parser on the given arguments. | ||
-- Returns 'Nothing' if the parser failed, or @--help@ was passed. | ||
parse :: [String] -> Maybe Args | ||
parse args = | ||
getParseResult $ | ||
execParserPure defaultPrefs Args.parser args |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
load( | ||
"@rules_haskell//haskell:defs.bzl", | ||
"haskell_library", | ||
"haskell_test", | ||
) | ||
load( | ||
"@rules_haskell//haskell:cabal.bzl", | ||
"haskell_cabal_library", | ||
) | ||
|
||
haskell_library( | ||
name = "cat", | ||
srcs = glob(["src/**/*.hs"]), | ||
visibility = ["//visibility:public"], | ||
deps = [ | ||
"//cat_hs/lib/args", | ||
"@stackage//:base", | ||
"@stackage//:bytestring", | ||
"@stackage//:conduit", | ||
"@stackage//:conduit-extra", | ||
"@stackage//:text", | ||
"@stackage//:text-show", | ||
], | ||
) | ||
|
||
haskell_test( | ||
name = "unit", | ||
srcs = glob(["test/**/*.hs"]), | ||
deps = [ | ||
":cat", | ||
"//cat_hs/lib/args", | ||
"@stackage//:base", | ||
"@stackage//:conduit", | ||
"@stackage//:hspec", | ||
"@stackage//:text", | ||
], | ||
) |
Oops, something went wrong.