fsprojects / FAKE

FAKE - F# Make
https://fake.build
Other
1.28k stars 581 forks source link

Trying to make sense of fake-cli syntax #2666

Closed mlaily closed 1 year ago

mlaily commented 2 years ago

Hello,

I'm new to FAKE, and I'm having a hard time trying to make sense of the FAKE CLI.
After actually spending a few hours on this, I decided to open an issue here so maybe this can be improved. (And I can get answers :))

I don't find the --help very helpful on its own, maybe even convoluted to the point of being misleading, and https://fake.build/fake-commandline.html does not really answer my questions.

Here are a few things I would really appreciate to be explained better:

The help web page states that run and build are "basically equivalent", but the commands I'm trying to execute sometime succeed with one but fail with the other.
e.g. dotnet fake build --list lists my targets, but dotnet fake run --list fails with a useless error message.

The Usage: section of the --help indicates that both run or build are basically identical, with everything following them being optional, but as per my previous example, it seems that's actually not true! (at least some of the time)

I know that -- is somewhat standard in many CLI tools, but neither the --help nor the docs explain what it does and when it is supposed to be used. My understanding is that it's to disambiguate that something is supposed to be a scriptargs, but can be omitted when the scriptargs does not conflict with a fake-cli existing option or command.

Maybe some basic examples of everyday commands would be useful in the --help?
(instead of the current example of fake -v build -- --list — I can feel that it's trying to demonstrate an important point, but I'm not completely sure I get it, so it's actually more scary than useful...)

Thank you for your time.

github-actions[bot] commented 2 years ago

Welcome to the FAKE community! Thank you so much for creating your first issue and therefore improving the project!

matthid commented 2 years ago

Yes the UX is not optimal and it is entirely my fault (I couldn't come up with something better). Rather than going full out technical let me try to motivate why it was implemented this way (we can decide to change that here and start a discussion). Some relevant discussions (just if someone is interested in the archives):

Basically since v5 we have two separate parts of fake, the runtime and the Build-APIs, the runtime is a general purpose F# running and dependency resolving machine (kind of like standalone fsi if you will). Therefore it made sense to split up the command line into a "runtime" and a "targets" part - in order to not inherit 'api'-specific stuff into the 'runtime'-cli. Note that today you can write your own "Fake.Core.Targets" and even replace that part of the command line, for example you could have "BuildSteps" instead of "Targets" or simple script with a different CLI (which is something I used from time to time, see these docs). (Sidenote) This would even allow us to create a new API and obsoleting the old NuGet-Package without breaking change.

The rest is due to the technical implementation and leaky abstraction :)

Regarding

Like said above fake build is convenience for the most common use case having a script called build.fsx

Well the Script arguments are what is put in <scriptargs> from the first section, and fake-run is basically your runtime CLI you used (again from the first section). Here are two examples:

Does this help? I'm now stepping aside and I'm more than happy to see improvements :)

mlaily commented 2 years ago

Thank you for this thorough reply! I'm still processing it and reading all your links, while reading the code of fake-cli (the ultimate source of truth!).
I don't have enough free time right now but I will come back to this thread in a few days...

mlaily commented 2 years ago

After digging more, it's kinda funny that I find the --help misleading while the command line is actually generated from it!

Docopt seems like the ultimate command line parser at first, but the more I play with it, the less I'm a fan of it.

I suspect one of the reasons I find the fake-cli hard to grok is that I find its parsing unintuitive.
To improve on that, I tried to add a verbose output of the parsed tokens as a way to display what fake "understands", hoping that it could help clarify things when a command does not work as expected, but the two last bullet points above make it impossible to do so in a user-friendly way. :/

I haven't given up just yet, and I don't want to seem disrespectful or anything about your hard work, but I feel like maybe it would be better to reimplement the fake-cli using https://github.com/dotnet/command-line-api ...
Would you be open to experimentation about this?


Another thing:
I find the way --fsiargs is handled a bit strange. If my understanding is correct, it's only possible to define a single arg after it? So if I want to define a compilation symbol and a script I have to use fake build --fsiargs --define:X --fsiargs build.fsx?

BTW, fake build --fsiargs --define:X with a build.fsx file in the working directory does not work. (The current implementation expects the script to be provided explicitly as a --fsiargs script.fsx or run [<script.fsx>])
Should I open an issue or is it by design? (I have 80% of a PR ready if this is indeed a bug)

yazeedobaid commented 1 year ago

Is there anything left in this issue now after merging #2667 PR?

mlaily commented 1 year ago

I think most of the issues are still present, though hopefully better documented, but I understand if you want to close this issue as there is nothing easily actionable.

As I mentioned in my previous comment, I feel like the whole CLI would benefit from being rewritten using https://github.com/dotnet/command-line-api
I think it would solve most of the "feels unfamiliar an surprising to use" UX thing. But I know this is easier said than done.

I actually started experimenting with this a few months ago, but I stopped for lack of feedback, and also because I'm still not sure this is the right thing to do. Backward compatibility is important too.

( I might get back to it at some point, we'll see... :) )

yazeedobaid commented 1 year ago

I think the current version is acceptable and convey the underlying functionality. Until we get to the runner and modify it we can consider changing the help message. Please feel free to experiment with it and PR your results at any time. I'm going to close this issue because as you said, there is nothing actionable at the current moment.