As my weekend's fun project I added an experimental new configuration system to the compiler. Unfortunately I had no time to document it, PRs welcome. So this is how it works:
Instead of foo.nim.cfg you can use foo.nims to provide a configuration file that uses Nim's VM. Within foo.nims the full power of Nim is available and system.nim provides additional tools for you like cd, mvFile and even task. Example:
# don't really execute 'gcc -v'
mode = ScriptMode.Whatif
exec "gcc -v"
--forceBuild
task listDirs, "lists every subdirectory":
for x in listDirs("."):
echo "DIR ", x
task default, "default target":
# 'nim default foo.nim' is an alias for 'nim c foo.nim'
setCommand "c"
I'm quite proud of how few lines it took to get there, so study this piece of art :-)
The extension to system.nim is here:
https://github.com/nim-lang/Nim/blob/devel/lib/system/nimscript.nim
The support in the compiler is here:
https://github.com/nim-lang/Nim/blob/devel/compiler/scriptconfig.nim
An example here:
https://github.com/nim-lang/Nim/blob/devel/tests/newconfig/tfoo.nims https://github.com/nim-lang/Nim/blob/devel/tests/newconfig/tfoo.nim
NimScript has been inspired by nake, but doesn't compile your build script, instead it runs it via Nim's virtual machine. It's my hope that we can deprecate the old configuration system soon.
Cheers!
PS: I'm not sure what this means for the Nimble - Nim interaction.
I tried this:
import os
echo paramStr(1)
But i get the following:
winlean.nim(468, 3) Error: cannot 'importc' variable at compile time
Which is a bad thing, because then it hardly can be used as a windows scripting language. Otherwise, i'd say this is a big achievement. It could kick python as a scripting lang.
Maybe .ns as an alternative ext?
On a practical note, I'd suggest a different extension instead of .nims. I'm not particularly picky about which one, but it should be easy to tell apart from .nim and easy to pick out of a directory listings.
Meh, alright, will call it .nimscript then.
It seems interesting, but I am not sure how to actually run it. I tried to download the example, and in fact when I compile tfoo with nim c tfoo I see that tfoo.nims is being processed - in fact [NimScript] exec: gcc -v is printed, and if I remove the speculative mode, gcc -v is run.
I am not sure, though, how to execute the tasks defined below
task build:
mkDir("target/lib")
exec "nim c src/main.nim"
setCommand "nop"
@r-ku That is a problem because the configuration system doesn't perform a fixpoint iteration, so by the time -d:release is picked up, the default config already set the other switches and it's too late. This issue has nothing to do with nimscript, the old configuration files have exactly this problem too.
EDIT: My own nimscript files use mkDir. Works for me.
task build:
mkDir("target/lib")
setCommand "c", "src/main.nim"
Thank you. The problem was that, inside the same folder my script was i had a nim.cfg. There i have some hints off, one --import, one --path and one warnning off. I changed the location of this cfg and now everything works as expected.
By the way, my project is actually two (client and server) and my task script is defined for both. I had to make a dummy build.nim to make it work. Maybe you could change it to make task build as standalone scripts.
I'm interested in NimScript as a portable "make-like", but I have some questions.
What's the purpose of the string in the task expression ? What's exactly the purpose of setCommand since you can control the compiler and the O.S using exec ? What is the problem encountered if we don't use setCommand "nop" ?
The string in a task describes the task. See this example: https://github.com/nim-lang/nimble/blob/master/nimble.nimble#L32
setCommand is meant to make the execution of a different command by the compiler more efficient. And setCommand "nop" is no longer needed AFAIK (definitely not needed in Nimble which also implements nimscript).