Closed turion closed 6 months ago
Workaround on linux is:
find . -name *.cabal -exec cabal-gild --input {} --output {} \;
Thanks for opening this issue! I think there are actually two related feature requests here:
cabal-gild --inplace example.cabal
.Alternatively, I could see adding something like --auto
that discovers package descriptions and formats them in-place. Perhaps that's a little too magical though.
For this particular example, you can use the shell directly rather than find
:
$ sh -exc 'for f in */*.cabal; do cabal-gild -i $f -o $f; done'
Gild could add a new --io=FILE
option for specifying both --input=FILE
and --output=FILE
at the same time. That would effectively be in-place. However it's still limited to one file, so you'd still have to script it somehow.
I'm trying to think of how to support this without dramatically changing the command line interface. I could add a new --inplace=FILES
option, but it would be mutually incompatible with all the current options. And maybe people want to check multiple files instead of formatting them, in which case the --inplace
option wouldn't be useful to them.
On the other hand, I tried to make Gild easy to use in shell scripts. Formatting (or checking) multiple package descriptions is a relatively advanced workflow, so perhaps requiring a shell script isn't outrageous.
Ormolu for example has --mode=inplace
. But that would make no big difference, since there would still have to be a separate way to specify multiple files. E.g.
gild --mode=inplace */*.cabal
This would be a bigger change to the CLI.
requiring a shell script isn't outrageous.
Not outrageous, it's just an extra hurdle to overcome. Maybe it's just me, but when I write Haskell, I want to write only Haskell, and not script my way around other things.
And maybe people want to check multiple files instead of formatting them
So why not a usage like
gild --mode=check --input file1.cabal file2.cabal
You might even allow lists for --input
and --output
, but then requiring them to be of the same length? E.g.:
gild --input */*.cabal --output */*.cabal
Formatting (or checking) multiple package descriptions is a relatively advanced workflow, so perhaps requiring a shell script isn't outrageous.
I guess you have a good point here. I just required gild for one of my projects (https://github.com/turion/rhine/pull/292) and my CI even turned out already to have a script that calls cabal check
already, and it wasn't too hard to modify it to also call cabal-gild
. (Although one might argue that cabal check
should work for such a setup as well.)
Now that I think about it even more, maybe a possibility would be to call it for a cabal.project
? It could extract several cabal files from there. Although one would need to add functionality to only take all local cabal files, as a cabal.project
can contain references to arbitrary paths, even remote git repos.
Yeah, I could allow both --input
and --output
to be specified multiple times, then zip them together pairwise. That would be clunky though. And I don't think it would solve your problem; even though you can say --input=*/*.cabal --output=*/*.cabal
, I don't think the expansion order of globs is specified so in theory they could be mismatched.
Reading the cabal.project
file to discover *.cabal
files could work. That's what I meant to suggest with my --auto
idea earlier. One problem with that approach is that Gild can also be used to format cabal.project
files themselves. So there would need to be some way to distinguish between using a project file for discovery versus using it for formatting.
I see, tricky. Maybe adding a pragma comment in cabal.project
itself to specify those cabal files that should be matched and processed in the same way as the cabal.project
is processed?
I'm still not sure if I want to support this or not. However if I do, I think it will be like this:
Change the CLI to accept input as positional arguments. If there are no input files, read from STDIN. Remove the --input
and --output
options. Add a new mode called in-place
that formats the input files in-place. For the regular format
mode, output will be sent to STDOUT. Then you could do:
$ cabal-gild --mode=in-place */*.cabal
That approach feels like the most flexible and also is similar to other source code formatters like Ormolu. It would be a breaking change of course, but it's hard to imagine a solution here that wouldn't be breaking.
The --io=FILE
option I mentioned was added in version 1.1.2.0. I know that doesn't help you original use case, but it should make it easier to modify single files in-place.
Awesome, thanks! Will use it!
For the time being, I don't think I'll change Gild's command line interface. I think formatting multiple package descriptions is a somewhat advanced situation. (Compared to, say, formatting multiple Haskell files.) As such, I think it's reasonable to handle it with a little bit of shell scripting. Or perhaps someone might be interested in writing a little wrapper script that parses a cabal.project
file and then calls Gild on all the local packages defined in there.
To modify a cabal file in place, one currently needs to supply it as
--input
and--output
. It would be easier if there was an option where one has to supply the file name only once. For example, this would allow usage like this:This is currently not directly possible, and one needs to resort to for loops or
find
.