cue-lang / cue

The home of the CUE language! Validate and define text-based and dynamic configuration
https://cuelang.org
Apache License 2.0
5.14k stars 294 forks source link

user feedback: tool/exec and tool/cli #361

Open cueckoo opened 3 years ago

cueckoo commented 3 years ago

Originally opened by @errordeveloper in https://github.com/cuelang/cue/issues/361

To be honest, I was a somewhat surprised to discover tool/exec and tool/cli in CUE. Are these considered fundamental to the design? I would have thought that ability of writing data to files and to stdout (perhaps with some filtering capabilities) would have given most users all they need. Is there a desire to make scripting on top of cue unnecessary? I am just a little unsure about the viability, especially considering familiarity factors of scripting languages. For example, is how should user define error handling logic and is CUE going to implement a flag parser?

cueckoo commented 3 years ago

Original reply by @errordeveloper in https://github.com/cuelang/cue/issues/361#issuecomment-618898527

I think FeatureRequest label should be removed, just wasn't sure what category to pick...

cueckoo commented 3 years ago

Original reply by @mpvl in https://github.com/cuelang/cue/issues/361#issuecomment-619050921

I agree it seems gratuitous at first to have a tooling layer in CUE. It does aim to solve several core issues and shortcomings of other configuration languages:

Work around the limits of hermetic configuration It is generally considered a good property for configurations to be hermitic (or pure, if you will). That is, their values should not depend on anything defined outside the configuration. In practice this is quite a limitation and many configuration languages allow injecting values one way or the other. Unfortunately, this is often done in a way that then reduces the ability to analyze or automate such configurations.

The tooling layer in CUE serves to inject non-hermitic input. Arguably this could be done outside of CUE. However, having it inside gives more information about the intent of a configuration and allows for more continuity.

Code or data? Ideally, all configuration is expressed in terms of data and some simple logic to allow some reuse and boilerplate reduction. In practice, this doesn't work. Sooner or later one hits a wall where the complexity needs to be pulled in the configuration layer. What we have seen is that languages like GCL and Jsonnet become full programming languages, far removed from the original intent.

Some will argue that given this, why not represent all configuration as code? This is the stance Pulimi takes.

CUE takes a different stance. Instead of wrapping configuration with code, the idea is to wrap code with configuration (or rather interleave it). CUEs compositional model makes it easy to combine data from different sources. Partial CUE evaluations can be shelled out to code and the result can be injected back into CUE. By splitting out this interaction in the tooling layer, we keep fully analyzability at the configuration layer. Defining this interaction in CUE itself has various benefits, if nothing else for continuity.

Tooling proliferation When you say that scripting isn't necessary, you are probably alluding to the fact that if cue just does conversions, one can just script around it. True. The problem is that scripts are hard to share. What one sees in practice is that, instead, tools are written around a generic configlang tool or library to deal with this. I've written many! But such tools are inevitably closed. So to address shortcomings of those tools, people write more tools, etc. Some prefer to refer to this tooling proliferation as a "rich ecosystem", but I generally consider it problematic.

To use CUE, people already need to install CUE tooling. In addition, the model of composition of CUE makes it very suitable for defining reusable. workflows. So if CUE is a given, one might as well use it for defining tools. This eliminates the need to distribute more binaries or install runtimes and allows for a consistent CLI generation. But most importantly, it opens up the ability to create composable tools.

CUE is also an efficient way to write tools. I've analyzed a myriad of command line tools and micro services and in many cases a CUE implementation could be written in a fraction of the code of the original.

Conclusion

Anyway, all in all it seems that the benefits outweighed the drawbacks. It has a lot of potential, even if it is a bit undeveloped at this point. Even so, there are many fans already.

Answers to direct questions:

how should user define error handling logic?

Right now a task error fails all following tasks and ultimately the process. The idea is indeed to allow error gobbling.

familiarity factors of scripting languages.

Scripting languages do not adequately address the concerns mentioned above.

CUE going to implement a flag parser?

There currently is a general injection mechanism. See cue help injection. A flag mechanism specifically for tools may be considered.

HTH :)

cueckoo commented 3 years ago

Original reply by @errordeveloper in https://github.com/cuelang/cue/issues/361#issuecomment-620743380

@mpvl thanks a lot for the insight, I can understand the reasoning, I guess I still stand as surprised user :)

Also, I have to say, I found the Go library very easy to use, and started an experimental project, the idea is to add some simple conventions/opinions on top of CUE that make it a bit easier to consume for someone who doesn't have all the time to invest in learning all features of CUE and just wants to do a few simple things to start with. But also, aside from that, I believe that simple conventions often work very well.