Comments (18)
@parsonsmatt I'd like to take a stab at this since I'm not really sure what this project's purpose is and I figure writing the docs would be a good way to find out. :) Perhaps you could describe the purpose in a little more detail and/or provide an example use case.
Looking at the code it seems to me that this app will generate Haskell source code for user-provided "Tasks" in a particular location that are not known to kale at compile time. These tasks would do . . . what? Anything? This seems to be in the spirit of other command line tools like git, for example, that have sub-commands (git branch
, git checkout
, etc.). In this case it would be kale runMySpecialCommand
or kale runThisOtherSpecialCommand
. Am I close?
from kale.
That's the idea!
There's a decent amount of boilerplate associated with writing a command line parsing utility, and most of it can be discovered and automated away. Stuff like optparse-generic
goes a really long way to making it declarative and gets rid of 99% of the boilerplate, but we can do better :)
The "big idea" is to discover all the modules with a form:
module Lib.FooTask where
data Args = Args { i am command line arguments for the program }
task :: Args -> IO ()
task args = ...
And create a nice command line interface for calling them. What the users end up doing is totally up to them, this library's purpose is to eliminate the boilerplate of:
module Task where
import qualified Lib.FooTask as FooTask
import qualified Lib.BarTask as BarTask
-- ...
data Command = Foo { fooArgs ... } | Bar { barArgs ... } | ...
deriving (Generic, ParseRecord)
main :: IO ()
main = do
cmd <- getRecord "the program"
case cmd of
Foo {..} -> FooTask.task FooTask.Args {..}
Bar {..} -> BarTask.task BarTask.Args {..}
...
from kale.
Thanks for the speedy response! This is great and is enough to get me started. PR coming your way soon.
from kale.
I seem to be having a little trouble with Haddock (I've never used it before). I added several docs to functions in Kale.hs
and when I run
$ cabal haddock
I see this output:
Running Haddock for kale-0.1.0.0...
Preprocessing library kale-0.1.0.0...
Warning: The documentation for the following packages are not installed. No
links will be generated to these packages: Only-0.1, ansi-terminal-0.7.1.1,
ansi-wl-pprint-0.6.8.1, colour-2.3.3, optparse-applicative-0.14.0.0,
optparse-generic-1.2.3, semigroups-0.18.3, system-filepath-0.4.13.4,
text-1.2.2.2, transformers-compat-0.5.1.4, void-0.7.2
target ‘command’ is not a module name or a source file
And no documentation is generated. Any ideas?
from kale.
I'd suggest using stack
for building documentation. stack haddock
works for me on the master branch.
If you want to open a PR, I can take a look at it :)
from kale.
I have a couple of questions regarding Kale's command line arguments. First, this line takes the first and third command line arguments and ignore the second and fourth. Why is that? What are the second and fourth arguments supposed to be?
On this line it says that Kale doesn't take command line arguments. It seems that this is a misstatement, correct?
from kale.
Good questions!
The GHC preprocesser step provides some arguments to the executable that's used to process the source file. I don't know what the arguments do exactly -- I copied the structure from hspec-discover
.
The arguments that Kale takes are provided by GHC. It doesn't accept any user arguments.
from kale.
OK. That leads to a question I've had about the intended workflow of Kale. Is Kale expected to be executed as part the client project's build? How exactly? It sounds like you intend for it to be run by hspec
, correct?
from kale.
GHC has a textual preprocessor step that allows you to provide your own way to manipulate the source files. It calls the executable and that executable writes a Haskell source file to disk, which GHC then compiles as usual.
So kale
gets called in this step, discovers all the task modules, and then writes a Haskell file that GHC compiles and runs.
from kale.
@parsonsmatt Thanks for the info. I did not know that GHC had such a textual preprocessing step and some quick googling only seems to lead me to CPP-related stuff but I suspect that is not what's at play here. Can you give more information about this or perhaps a link? In particular, I'm interested to know how you "provide your own way to manipulate the source files." Where do you tell GHC to call Kale's main
function?
from kale.
This file in the example
is where it is called. I found the pgmF
flag thanks to hspec
and it's discovery feature.
from kale.
I've created test client application for Kale here but when I run stack build
, I get the following error:
$ stack build
kaletest-0.1.0.0: configure (lib + exe)
colour-2.3.4: download
kaletest-0.1.0.0: build (lib + exe)
Only-0.1: configure
Only-0.1: build
semigroups-0.18.3: configure
semigroups-0.18.3: build
colour-2.3.4: configure
colour-2.3.4: build
semigroups-0.18.3: copy/register
Only-0.1: copy/register
colour-2.3.4: copy/register
Log files have been written to: /home/tim/workspace/haskell/kaletest/.stack-work/logs/
Progress: 4/13
-- While building custom Setup.hs for package kaletest-0.1.0.0 using:
/home/tim/.stack/setup-exe-cache/x86_64-linux/Cabal-simple_mPHDZzAJ_2.0.1.0_ghc-8.2.2 --builddir=.stack-work/dist/x86_64-linux/Cabal-2.0.1.0 build lib:kaletest exe:kaletest-exe --ghc-options " -ddump-hi -ddump-to-file -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
Logs have been written to: /home/tim/workspace/haskell/kaletest/.stack-work/logs/kaletest-0.1.0.0.log
Configuring kaletest-0.1.0.0...
Preprocessing library for kaletest-0.1.0.0..
Building library for kaletest-0.1.0.0..
["src/Lib.hs","src/Lib.hs","/tmp/ghc456_0/ghc_1.hspp"]
[2 of 3] Compiling Lib ( src/Lib.hs, .stack-work/dist/x86_64-linux/Cabal-2.0.1.0/build/Lib.o )
/home/tim/workspace/haskell/kaletest/src/Lib.hs:10:1: error:
Could not find module ‘Kale.Discover’
Use -v to see a list of the files searched for.
It seems that GHC is looking for a Haskell module and not an executable named kale-discover
as I'm expecting. Any idea what I'm doing wrong?
from kale.
from kale.
I see. I added kale
as a dep to package.yaml
and it builds without error now. I was under the impression that the preprocessor specified in {-# OPTIONS_GHC -F -pgmF my-pre-processor #-}
could be any old executable on the path in which case the kaletest
project would not need to depend on kale at all. Can you tell me why I need to set kale
as a dependency?
Also, when stack build
completed I expected to see a new file generated by the preprocessor. Is this not a correct expectation? Is that generated file ephemeral?
from kale.
I don't understand the pgmF
flag or how exactly it works. I coped code from hspec
🙂
Yes, the generated file only exists temporarily while GHC compiles and builds it into the executable.
from kale.
I'm starting to understand this pgmF
business a bit better. One thing I tried in an effort to understand things better was to specify these GHC options on the command line instead of in a Lib.hs
file like so:
$ stack build --ghc-options="-F -pgmF kale-discover"
but it gives this error:
/home/tim/workspace/haskell/kaletest/src/Lib/Task.hs:8:8: error:
File name does not match module name:
Saw: ‘Task’
Expected: ‘Lib.Task’
This seems to ultimately be due to the way kale
generates the module name for the generated Haskell (in the pathToModule
function) which only takes the final segment of the path as the module name. This seems to work since the current method of preprocessing is done at the same level as the Lib
directory so the generated module is directly under src
. (The above method apparently does the preprocessing in the same directory as the module, which makes sense.)
So I wonder if you have a preference for how users might specify the GHC options. You could leave things as is and just tell the user how to specify the options or change things so that the options could be specified in other ways.
from kale.
Interesting. The -pgmF
flag when used liket hat is likely going to apply the preprocessor to all of the files in the project, which isn't what we want.
I would definitely prefer folks to write the GHC options in the file that is going to become the module containing the task executable stuff -- in the same way that hspec-discover
only is ever used like
-- test/Spec.hs
{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
from kale.
Good enough! Yes, I had thought about how that command would run the preprocessor on all the files but forgot to mention it. For that reason I agree that it's a good idea to specify the options as you are doing.
from kale.
Related Issues (11)
- Command Line Arguments HOT 2
- Write more tests! HOT 5
- Write more types! HOT 3
- Continuous Integration, Code Health
- Use a Syntax data type instead of smashing strings together HOT 2
- Instead of hardcoding values, use a Config type HOT 2
- Load configuration HOT 1
- Search for and import an Import module
- Command line arguments should work for positional arguments, too.
- Make doesn't work properly on Ubuntu Linux HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from kale.