cmd function params: How to directly concat string and symbol?

14 views
Skip to first unread message

alex.d...@gmail.com

unread,
Apr 24, 2015, 11:59:24 AM4/24/15
to shake-bui...@googlegroups.com
Here's my cmd line:

mainModule = "MyModule"
cmd "psc --output" out "--main=" mainModule pursFiles

This produces the following command line:

psc --output dist/test.js --main= MyModule src/Test.purs src/Test2.purs

The build fails, as the psc compiler can't figure out that MyModule belongs to the --main argument.

How can I combine `"--main=" mainModule` such that they don't produce a space between them?


If possible, can you help me find the answer myself? I'm new to reading type signatures to find compatible functions. Looking at

http://hackage.haskell.org/package/shake-0.15/docs/Development-Shake.html#v:cmd

, I see CmdArguments, but I don't know what functions I can use with them.

Reading

http://hackage.haskell.org/package/shake-0.15/docs/Development-Shake-Command.html#t:CmdArguments

, it looks like CmdArguments is an instance of IO, Action, and something else, but I don't know where to go from there.

Neil Mitchell

unread,
Apr 24, 2015, 12:20:36 PM4/24/15
to alex.d...@gmail.com, shake-bui...@googlegroups.com
Hi Alex,

The function 'cmd' is highly overloaded, since it takes a variable
number of arguments, and has multiple return types. As such, unlike
most other functions in Haskell, it's type isn't very meaningful.
Tracking it down going via CmdArguments is unlikely to help. The docs
say:

* String arguments are treated as whitespace separated arguments.
* [String] arguments are treated as literal arguments.

So:

"--main=" mainModule

Is treated as two separated arguments. To get it treated as one, you
can join the strings first:

cmd "psc --output" out ("--main=" ++ mainModule) pursFiles

However, even though they are a string, if mainModule has any spaces
in it (which I suspect is unlikely), it would still get separated. You
can fix that by doing:

cmd "psc --output" out ["--main=" ++ mainModule] pursFiles

Generally, if it's not direct string literals, I put the arguments in
[square brackets] to ensure that they don't accidentally get split.

There is also a function 'command' which is the simpler version, which
doesn't have crazy type magic. With that, it should be possible to
figure it out from the types. there it directly takes a list of
strings.

Thanks, Neil

alex.d...@gmail.com

unread,
Apr 24, 2015, 1:04:21 PM4/24/15
to shake-bui...@googlegroups.com, alex.d...@gmail.com
Ah! This is what I didn't try! Wrapping it in parens! I tried

cmd "psc --output" out "--main=" ++ mainModule pursFiles

which gave a type error, of course.

> Is treated as two separated arguments. To get it treated as one, you
> can join the strings first:
>
> cmd "psc --output" out ("--main=" ++ mainModule) pursFiles
>
> However, even though they are a string, if mainModule has any spaces
> in it (which I suspect is unlikely), it would still get separated. You
> can fix that by doing:
>
> cmd "psc --output" out ["--main=" ++ mainModule] pursFiles

Yeah, I read the docs which explains the use of [] in the cmd function, but I somehow couldn't understand the motivation of offering the [] option. Having some examples there would make it clear, for sure. cmd is a pretty essential piece of Shake, so additional examples wouldn't be a nuisance, for sure.

Are the following examples correct?

* String arguments are treated as whitespace separated arguments.
* [String] arguments are treated as literal arguments.

Examples:
`cmd "git log --pretty=" "oneline"` -> "git log --pretty= oneline"
`cmd "git log --pretty=" ["oneline"]` -> "git log --pretty= oneline"
`cmd "git log" ("--pretty=" ++ "oneline")` -> "git log --pretty=oneline"
`cmd "git log" ("--pretty=" ++ "one line")` -> "git log --pretty=one line"
`cmd "git log" ["--pretty=" ++ "one line"]` -> "git log --pretty=one\ line"

I am away from my linux machine, which has my Shake project, so I can't test my understanding above.

If you'd like, I can try to make a PR to add a similar bit as above. Or you can add it if you have a better idea.

Neil Mitchell

unread,
Apr 24, 2015, 2:09:22 PM4/24/15
to alex.d...@gmail.com, shake-bui...@googlegroups.com
> Are the following examples correct?
>
> * String arguments are treated as whitespace separated arguments.
> * [String] arguments are treated as literal arguments.
>
> Examples:
> `cmd "git log --pretty=" "oneline"` -> "git log --pretty= oneline"
> `cmd "git log --pretty=" ["oneline"]` -> "git log --pretty= oneline"
> `cmd "git log" ("--pretty=" ++ "oneline")` -> "git log --pretty=oneline"
> `cmd "git log" ("--pretty=" ++ "one line")` -> "git log --pretty=one line"
> `cmd "git log" ["--pretty=" ++ "one line"]` -> "git log --pretty=one\ line"

Yes, they are all correct. However, I'd have written the one with a
space as git log "--pretty=one line" since that works on all shells,
while the \<space> only tends to work on non-Windows shells.

> If you'd like, I can try to make a PR to add a similar bit as above. Or you can add it if you have a better idea.

A PR would be great. It's hard writing docs based on what I think
others want to know, since I can miss the stuff that's obvious if you
implemented the function :)

Thanks, Neil
Reply all
Reply to author
Forward
0 new messages