microsoft / winget-cli

WinGet is the Windows Package Manager. This project includes a CLI (Command Line Interface), PowerShell modules, and a COM (Component Object Model) API (Application Programming Interface).
https://learn.microsoft.com/windows/package-manager/
MIT License
23.15k stars 1.44k forks source link

Support file composition for WinGet Configure #3797

Open PhilipRieck opened 1 year ago

PhilipRieck commented 1 year ago

Description of the new feature / enhancement

I'd like to be able to reference one file from another to use with winget configure. When WinGet's configure command processes a file with one or more references, it applies the union of all configurations described.

This would become even more powerful with #3554

This would support the following scenarios and possibly more:

  1. I want to break up my files for readability. For example, I have nodejs and several web tools in one file for the frontend, and the dotnet sdk and tools in another. This makes finding specific resources easier.
  2. I have a project based on a different project with additional requirements. For example, I have a project that uses electron - I can reference the electron project DSC and then add my additional requirements to my own repository without having to duplicate and maintain the base file. When the electron project changes its requirements, my configuration does not need to be updated.
  3. I have a multi-repository project and want to compartmentalize the configuration files but use a common core that can be updated independently.
  4. I can share configurations with people for specific scenarios and they can compose those into full machine setups (DevBox) or project setups without having to do partial compares if I publish changes. For example, I provide a config that will set up OhMyPosh and some related tools for great kubernetes visibility. Another person can download that and reference it rather than

Proposed technical implementation details

No response

PhilipRieck commented 1 year ago

I may already be able to implement this somewhat in a hacky way with a script resource that calls winget configure, and has test always return false. There's a few downsides with that - initial display of configurations to apply is not accurate, output is odd, and perf problems along with the fact that it's not actually able to determine if the config is applied as described. It's sort of an imperative hack inside my DSC.

Given that, I can see two "obvious" mechanisms:

The first would be to have a special resource type and simply use the current config schema. There would need to be special handling for it to cure the problems listed above with the hack approach. It would really need to merge the file contents before actually processing the resources. This magic resource type being handled differently could be confusing, especially for anyone trying to implement a third-party parser/editor. An upside there would be that id: xxx and dependsOn: xxx could continue to work as is.

The second would be to have a separate section (like imports) alongside resources and assertions. This would make it clear that there is special handling to roll the files together and would remove the confusion of there being a type of magic resource that is handled in a completely different way, at the cost of slightly higher schema complexity. I do prefer this approch though, as it makes the semantic differences clear and surfaces clearly that there is more to this configuration than a single file. It would also better lend itself to an option like --allowImports or --noImports, for example.

For id/dependencies: I don't see a lot of value in hoisting ids so that dependsOn can work across files. That would break composability and add complexity to handle id collisions via namespacing or mangling. I think a simple test to require the included file was configured would be enough

denelon commented 1 year ago

@PhilipRieck thanks for submitting this Issue!

We're looking at several different scenarios where multiple configuration files represent the single "logical" configuration we want to apply. Part of the challenge is the visibility into the actual configuration. We are looking at the proposed powershell/DSC v3 implementation and some of that work is in progress.

It was an intentional decision to initially limit our current use case to a single configuration file (on the local file system) while we iterate on the designs to support these more sophisticated scenarios.

The best case scenario in my mind is some kind of mechanism to support what you want and it includes the ability to present a single merged view of everything to be configured. I don't want someone to run a configuration thinking it's only a few things they need to evaluate and then find out after the fact that any number of arbitrary configurations are also applied.

This is certainly a "high-order" problem on the WinGet side rather than just on the PowerShell DSC side, but I want to keep scenarios like this visible.

Mentioning @SteveL-MSFT for visibility.