4 ms·
If you’ve ever had to wrangle yaml configuration files… do yourself a favor and learn Cue. It’s still young and the website can seem intimidating; but it’s simp
by shykes 5y ago
If you’ve ever had to wrangle yaml configuration files… do yourself a favor and learn Cue. It’s still young and the website can seem intimidating; but it’s simpler than it looks, and the language is unbelievably powerful. There simply isn’t anything else like it. In my opinion it’s in a league of its own compared to other configuration languages like HCL, Jsonnet, Dhall, Starlark etc. Marcel, the creator of Cue, is basically the godfather of configuration languages - most of the state of the art can be traced back to his work at Google. Despite his deep knowledge of the subject and unparalleled experience, he is modest, pragmatic and responsive to questions and feedback. The momentum behind Cue reminds me of Go in its early days.
I’ve been using Cue for over a year now, using it as the foundation for a new projet; and will gladly answer questions about our experience.
- throwaway894345 5y agoI tried dabbling with Cue, but it doesn't seem to solve the problem that I care about, which is that I have a whole bunch of configs that vary only slightly and I want to DRY them up. For example, for any given application we have several fixed environments--dev, staging, prod--as well as "on demand" environments for things like pull requests or individual developer environments. The configs for these environments are almost the same, but they vary based on a handful of parameters. I want to be able to write a "generic environment" module for each application and then parameterize it accordingly for each environment. Cue doesn't seem to care much about this problem, but rather it's just trying to make sure your data is type checked. It seems more like an advanced JSONSchema rather than a typed Starlark. I think the latter would be more powerful (albeit Cue's type system is more powerful than an ordinary generic type system with things like range types). Cue almost has an answer to the DRY problem, but you can't quite emulate functions as far as I can tell (due, I think, to shadowing problems). I wonder what people who are convinced that Cue is the future would say to this? Am I just thinking about the problem wrong?
- deleted 5y ago[deleted]
- Kinrany 5y ago> I want to be able to write a "generic environment" module for each application and then parameterize it accordingly for each environment. This specifically looks like you want inheritance, which Cue eschews. You can set up a generic config with default values for everything, and then have more specific configs that override the defaults. A concrete example would help figure out if Cue can do what you want.
- GordonS 5y ago> You can set up a generic config with default values for everything, and then have more specific configs that override the defaults. I was going to say the same thing - this pattern of having an "override" file in add to defaults, is something I've seen in multiple systems and liked. For example, it's used for JSON configuration in .NET, and with Docker Compose's YAML service configuration files.
- throwaway894345 5y agoHere's a simplified example for configuring GitHub Actions workflows: https://github.com/cuelang/cue/discussions/967 https://github.com/cuelang/cue/discussions/967 FWIW, I'm not looking for "inheritance".
- sdboyer 5y agoI'd say all of these problems have answers in CUE. > I want to be able to write a "generic environment" module for each application and then parameterize it accordingly for each environment. This is pretty solidly in the target use case range, i'd say - managing variations of the same "object type" over some dimension is a lot of what's targeted by the way that CUE treats directory hierarchies when loading files: https://cuelang.org/docs/concepts/packages/#instances https://cuelang.org/docs/concepts/packages/#instances The main thing you have to consider in designing a layout is that you have to take a compositional approach to how you define individual config instances. That is, you can't start from prod's config, then override a value or two for staging. If i were to do it - i have not, this is not how i currently use CUE - my first approach would probably be by defining defaults at the "policy" level (per the above link), which effectively allows you to get exactly one "override"-ish behavior. Lots of possible approaches to this, though. > but you can't quite emulate functions as far as I can tell Function-like capability is present, just in a form that's less familiar. I think of them as "function structs." This post has a bunch of examples https://github.com/cuelang/cue/issues/139#issuecomment-556770516 https://github.com/cuelang/cue/issues/139#issuecomment-55677.... It seems there's a plan to add a more comfortable notation (https://github.com/cuelang/cue/issues/943 https://github.com/cuelang/cue/issues/943), but it's fundamentally possible now.
- throwaway894345 5y agoConsider this example: https://github.com/cuelang/cue/discussions/967 https://github.com/cuelang/cue/discussions/967 How would you solve this with directory structure and "function structs" respectively? I'm having trouble wrapping my head around the former and ran into shadowing problems with the latter.
- dqpb 5y agoI would do it like this: test.cue: #Job: { command: string args: string cli: "\(command) \(args)" } #GoJob: #Job & { command: "go" } #GoJobV: #GoJob & { args: "-v ./..." } job: #GoJobV.cli Results in: $ cue export test.cue { "job": "go -v ./..." }
- dqpb 5y agoCue solves the DRY problem using a lattice data structure instead of inheritance. This is precisely why cue is better than everything else.