cmd/cue: `fix --exp=X` should add the per-file `@experiment(X)` attribute unconditionally
Is your feature request related to a problem? Please describe.
As a user, when I'm updating my CUE to use a specific experiment, I don't implicitly know if the experiment's syntax changes require modification in any given CUE file.
Therefore when I run cue fix --exp=X for a given module, package, set of files, or single file, I expect that those files have been properly fixed, regardless of their content. I expect that they're in a good state, ready for me to edit in line with having been set up correctly for the experiment.
Annoyingly, as a user, cue fix --exp=X only adds the @experiment(X) line when it discovered and updated some CUE that needed to be changed for experiment X.
This means that when I run cue fix --exp=X *.cue, I can't assume that *.cue are ready for me to edit with the "experiment X is enabled" switch flipped in my head.
Describe the solution you'd like
I'd like a per-file experiment to be enabled unconditionally, with the correct attribute in place, on each file that's in scope of cue fix --exp=....
I don't have an opinion on the behaviour of cue fix --exp=all.
Describe alternatives you've considered
Currently, to enable the experiment globally (or for a specific set of files), I must first run cue fix --exp=X to update any CUE needing an update; and then I need to check the preamble of each file.
Additional context
This change would also help the clarity of the "Trying experiment X" documentation currently being prepared for cuelang.org.
I think the point is to not litter every single CUE file with the experiment; it's only added to those that need it. In terms of a "fix" for existing code, I think this is the behavior that we want.
However, you want to use the experiment throughout a module and not have to need to add @experiment lines to each file that's not needed it yet. That's also a valid use case, which follows up from an initial "fix" of the module.
Perhaps the answer is that we should support setting language experiments in cue.mod/module.cue, so that they apply to all packages and files in the module, avoiding the repetition of @experiment. Then, cue fix --exp=foo for an entire module would edit the module file rather than separate CUE files, which is also less repetitive in many cases.
I should note that I'm borrowing this idea from Go, where its "godebug knobs" can be set in go.mod for all packages in the module: https://go.dev/doc/modules/gomod-ref#godebug
I think the point is to not litter every single CUE file with the experiment; it's only added to those that need it. In terms of a "fix" for existing code, I think this is the behavior that we want.
However, you want to use the experiment throughout a module and not have to need to add
@experimentlines to each file that's not needed it yet. That's also a valid use case, which follows up from an initial "fix" of the module.Perhaps the answer is that we should support setting language experiments in
cue.mod/module.cue, so that they apply to all packages and files in the module, avoiding the repetition of@experiment. Then,cue fix --exp=foofor an entire module would edit the module file rather than separate CUE files, which is also less repetitive in many cases.
Some random thoughts:
That is an interesting idea. Obviously, this won't work for files where we don't consult the module file, but under normal circumstances, we need to look up the language version in the module file anyway to interpret the experiment flags.
I do think, though, that having the experiment attribute makes it a bit clearer to the reader that the CUE in the file is different. We also need to consider if there are cases where we need to fall back on default behavior for a file when the module file is not available. In such cases having the attribute is a bit more robust.
I would not be opposed to forcibly mark all files with the experiment flag. An advantage of putting it in the module file is that we can enforce all files henceforth adopt the new approach. If that is the goal, we could also add a module option to enforce the experiment is enabled for all files.
At first glance, I would be fine with any combination of these additions.
I lean towards a cue.mod/module.cue directive to enable a language experiment for a whole module over "add the experiment attribute to all module files" precisely because then I can add new CUE files without needing to remember to add the right attributes :)
The per-file attributes would still be an option, when their module does not have the directive. They will be useful for standalone (module-less) files, or when one wants to slowly transition a module piece by piece. I'd argue that cue fix could remove redundant attributes which are already satisfied by the module defaults, set by the language version plus experiment directives.