-
Notifications
You must be signed in to change notification settings - Fork 902
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement: Install helpers - Parse-Args PS function for parsing Package Parameters #312
Comments
What would you suggest as an alternative? |
Not to throw this off too much, but you should be using -params (Package Parameters), not Install Args. Install Args are meant for the native installer, where Package Parameters have a more general purpose use. |
hm, ok - i will try |
You run into the same thing, it's just that package params do not get passed automatically through to any native installers. |
This is the article we have right now on how to parse package parameters - https://github.com/chocolatey/choco/wiki/How-To-Parse-PackageParameters-Argument And agreed the process of parsing should become helpers. |
got it - thanks for info, i will fix it in my scripts |
yeah, i saw the article - the point i denied to use this method - there is no '/"" escaping inside values. + /key:value is too different from what i used to with unix tools, even PS have different syntax |
|
ok. i just found that c-style parser is a little bit more convenient here, coz regex for " "" " requires look ahead feature and it makes this regexp too complex to easy understand. thats why, i did my own thing :;): |
@ferventcoder - I would like to grab this one. I was hoping to do the following as well:
|
@DarwinJS I await your proposal. :) |
OK - no known problems with "=" as far as you know? Proposal = Pull Request? Psuedo code for ChocolateyInstall.ps1:
|
There are known problems with "=" :) Proposal is what you just sent. I'm thinking maybe simpler?
|
Well, if you didn't need to set defaults, then what I am proposing would be this simple:
Any variables in -Params are now variables in the script - not even any fusing with a hash table. If someone wants to manipulate settings or do checking on them, then they could make the names on the -Params parameter something other than what they use in their script. This is also a little more like the powershell parameter patterns in that parameters defined for a script simply become variables available in your code. |
The problem is in understanding Chocolatey, you almost always need to set the defaults. |
The difference is that when you have a script you know about, you get to define those variables for use. When it is automatically created for you, you are trusting in documentation and magic. I'm not sure we want something magical. It needs to be straightforward and easily understandable. Simplicity is the essence of Chocolatey. And to quote this again, "Simple ain't easy." Simple requires much more thought. It's super easy to come up with a solution to a problem. It is generally much more difficult to come up with a simple, elegant solution. It is usually one that requires much more thought. |
With RoundhousE, it took us months to come up with how database versioning should be done. We have it in there now and it is simple and makes complete sense, we use the same versioning concept as DLLs and code. But we spent a couple of months thinking about it prior to the light bulb going off and us saying "Duh!". So long story short, I want you to find the simple, elegant solution to the problem. Which may not necessarily be the first one that comes to mind. |
Sure, I always say "Getting to simple is complex." On one contract the client seemed to have the persistent though that keeping it simple meant that the process of simplifying should also be simple - nada. Well, whether something is "first to mind" versus not is also a function of how many times one has grappled with the problem and created solutions for the problem (or a similar one) in the past and whether there are significant patterns to key off. Before VB Script supported named parameters I had created an argument processing engine that was almost identical. Following the powershell pattern would also be familiar to powershell coders. I think I told you in another thread how repeatedly dealing with the versioned resources problem caused me to eventually create "Get-Versionstring" which could pull a version string from any of an EXE, a DLL, an MSI GUID or a Programs and Features friendly name. Returns 0.0.0.0 for does not exist and 0.0.0.1 for "exists with no version resource" and of course the actual version number for versioned resources. Was enhanced to strip text crap from the end (check the iexplore.exe version). Ended up being much more flexible than I originally intended. I would suggest that any mysteries of something like "Import-ChocolateyPackagePararms" be combated by:
Get-ChocoPackageParamsToVariables found -Params and is converting it to variables... |
Yeah, naming is also hard. :) |
Get-VersionString sounds kind of interesting. :) |
Late edit to the above: ConvertFrom-ChocoPackageParamsToVariables -String $env:chocolateyPackageParameters |
Yes - it really rocks. Was part of an idempotent, DSC like engine for Desktop software deployment automation that had to handle many more complex issues than we typically do in server. |
Get-VersionString automatically figures out what type of resource you have given it as well - I like to do the hard thinking when I build the code - not everytime I go to use it ;) |
Maybe it's possible to just let PowerShell / .NET do the dirty work:
Wasn't having much luck passing this in to Choco's built-in support. |
I have been playing with prototyping this and I can't read nor write variables in the scope of ChocolateyInstall.ps1. (even when using "Get-Variable -scope") Are helper functions sandboxed in some way? |
They are sandboxed, but only in the way that the module that loads them is not in the module path and only loaded by Chocolatey. |
Ok - so then my variable scoping in a helper function is very different than the regular CMDLet / Module implementation? I guess, my helper does not even have a shared scope with ChocolateyInstall.ps1 then? |
I would also like to add all the special characters that are valid password characters to the values that can match the value data. AWS EC2 assigned passwords seem to try to use the whole list of special chars. |
Maybe?
The chocolateyInstall can call the helpers, so there is some sharing of scope. The functions are available like they would be for a regular powershell module. |
I'd love to see this feature implemented, but I'd suggest a different approach to the chocolateyInstall.ps1 side of this. PowerShell already has a rich, robust, well-understood mechanism of passing arguments to scripts - why not use it? Example chocolateyInstall.ps1 (which could be used for Visual Studio 2013): # declare parameters using standard PowerShell syntax and facilities, such as default values, data types and validation
Param (
[Parameter(HelpMessage = 'The optional features to be installed')]
[ValidateSet('Blend', 'LightSwitch', 'VC_MFC_Libraries', 'SQL', 'WebTools')]
[string[]] $Features = @('WebTools', 'SQL'),
[Parameter(HelpMessage = 'The product key - if not provided, a 90-day trial version will be installed')]
[ValidatePattern('^([a-zA-Z0-9]{5}-){4}([a-zA-Z0-9]){5}$')] # ABCDE-FG123-H4567-QWERT-09876
[string] $ProductKey
)
# use the parameters
. $PSScriptRoot\VisualStudioInstallHelpers.ps1
Install-VisualStudio -Features $Features -ProductKey $ProductKey The parameter declaration syntax is declarative and rich in metadata, enabling scenarios such as:
The syntax is also terse - there is no imperative boilerplate code and nearly all text is actually meaningful. The parameter declarations are quite readable, so chocolateyInstall.ps1 becomes very much self-documenting, perhaps even eliminating the need for the package author to write separate package parameter documentation in the package description. Implementation considerations: One last point - unlike adding a new helper (which is a breaking change), this approach would allow packages to function even on legacy versions of Chocolatey, with graceful degradation of functionality (package parameters always set to default values) instead of hard installation errors due to missing helpers. |
I would love nothing more than to use PowerShell's native parameters - but I'm not understanding how this would have backward compatibility - wouldn't chocolatey need to take the current -params and pass it along properly formatted -which means a future version of Chocolatey? I also don't understand how a new helper is a breaking change - if someone isn't using it, they just keep using the older template code that has been provided.
|
Taking full advantage of this feature would certainly require support from Chocolatey, so it does mean a new version, yes. Let me describe the compatibility scenarios: 1. Future Chocolatey, future package with parameter declarations Chocolatey parses the parameters and passes them to the package. No surprise there. 2. Future Chocolatey, unmodified existing package (which does not declare parameters) with custom $Env:chocolateyInstallArguments parsing logic Chocolatey recognizes the package as a legacy one and does not parse packageParameters, but passes the string unmodified to the package via $Env:chocolateyInstallArguments, like current Chocolatey does. 3. Future Chocolatey, future package which declares a Chocolatey recognizes the package as one that takes parameter parsing responsibility upon itself. Chocolatey does not parse packageParameters, but passes the string unmodified to the package as the value of the $ChocolateyRawPackageParameters parameter. This provides an easy upgrade path for existing packages with custom parsing logic. 4. Current/earlier Chocolatey, unmodified existing package with custom packageParameters parsing logic No change from current behavior (obviously). Chocolatey passes the parameter string unmodified to the package. 5. Current/earlier Chocolatey, future package with parameter declarations and no code looking at $Env:chocolateyInstallArguments Chocolatey passes packageParameters as $Env:chocolateyInstallArguments. The package installs using default parameter values. 6. Current/earlier Chocolatey, future package with parameter declarations and additional backward compatiblity code parsing $Env:chocolateyInstallArguments Chocolatey passes packageParameters as $Env:chocolateyInstallArguments. The package recognizes it is being installed by a legacy Chocolatey and parses the parameter values out of $Env:chocolateyInstallArguments. This only makes sense if the parsing code in the package is fully compatible with the logic used by future Chocolatey. Under that condition, it would be possible to create parameterized packages supporting both current/legacy and future parameter passing models, which might be useful in some private scenarios (however, I think most folks would be okay with simply upgrading Chocolatey).
True, however, that's not what I meant (I've been really unclear). When a package does use a new helper, it ceases to be compatible with earlier versions of Chocolatey - the missing helper will cause the package installation to fail. On the other hand, with parameter declarations, as stated in 5. above, the package will install under earlier Chocolatey (using default parameter values), making it a graceful reduction of functionality instead of a complete breakage.
They only cause a syntax error if the script is decorated with
Right, a.k.a. $PSBoundParameters and $args, respectively. |
Hey Guys, I see this hasn't been updated in a while, but I'd like to weigh in on this, since I feel that package parameters are an area where Chocolatey could make things a lot easier on package authors. I think the --params option already is a nice foundation provided by Chocolatey, but it would be nice if there was a "happy path". :) First, I'd like to point out that it isn't completely necessary that a parameter parsing helper be included in Chocolatey out of the box.
Personally I vote for working on an extension package or packages, at least initially until some level of consensus develops. We can experiment with formats and approaches, and theoretically the best approach(es) will bubble up to the top via real-world usage. But, I also think it would be useful if the conversation about the way the params are parsed could continue rather than just dissipating into the void, i.e. there are factors that someone like Rob can provide insight and guidance on, especially if the goal would be to put something in choco at some point... I really like the idea from @jberezanski about supported PowerShell script parameters in chocolateyInstall.ps1 (and I'd love to hear Rob's take on it). However, I suspect it would be best to treat this as separate from the '--params' argument. Here's one idea... It isn't all that uncommon for a command-line tool that will call other tools or scripts to have to deal with passing through arguments. One approach out there is the linux form of using -- to designate that the remaining arguments should be passed directly to an inner command.
In addition to the benefits already laid out:
This would have to be something that chocolatey supported, but wouldn't involve the --params argument at all. Also, theoretically non-PS based packages could accept different format of args and/or parse them in a different way (just thinking out loud). In conclusion, it would be nice if both approaches, --params and PS script params, could be supported. Thoughts? -Bryan |
I have not forgotten about this - I'm just focused on 0.9.10.0 and getting it out the door. This will come after that, so I will be back to discuss then. 👍 |
I have been using a settings.psd1 file to store all my defaults parameter settings, then overriding the defaults with the --params. But if we define the "expected" settings or parameters couldn't you just parse the choco install {{packagename}} command string to grab the values defined? That way we don't have to change the existing convention, we just need to store the choco install command into an $env variable then parse it using a helper and providing a settings.psd1 file.. And if that file doesn't exist, you just don't go looking.. settings.psd1 file choco install mypackage -InstallPath "C:\mypackage" -AddDesktopShortcut false so that we would just parse the "choco install mypackage -InstallPath "C:\mypackage" -AddDesktopShortcut false" string looking for key values from settings.psd1 and a regular expression that supported -key "value" | -key 'value' | key value or any other desired formatting. |
Hello, just a proposition if method from here https://github.com/chocolatey/choco/wiki/How-To-Parse-PackageParameters-Argument will stay for a long time.
This should allow to have more than one variable with the same name, for example consul -config-dir option. (https://www.consul.io/docs/agent/options.html#_config_dir) |
It seems like a lot of complexity would be removed if $packageParameters wasn't cast as a string; allowing for structured data - which seems like what everyone is trying to work with as an end result. |
@onyxhat agreed. it's the technical details that get you though. Part of what this is doing is taking that string passed to a CLI application (choco.exe) and providing it in the same format, so that folks can decide what to do with it in packaging. We are looking to add a helper to take that string and convert it to structured data for folks. One of the other aspects is passing the parameter in as structured data as a script parameter. |
Ended up implementing the following. Didn't want to be opinionated about the style of switching - so just reduced the parser to take the string apart into k/v pairs that create locally scoped variables. That way you can pass it around however you like however your installer or process needs to use them.
|
@onyxhat very similar to https://github.com/chocolatey/choco/wiki/How-To-Parse-PackageParameters-Argument, except you are doing this with "=" as the delimiter. 👍 |
Although, you are creating variables with yours... hmmm interesting. |
@ferventcoder Yeah, that's precisely what I started from as a template; just trimmed it down to the bare essentials and modified just to spin up variables. On the off chance someone prefers to pad declarations with spaces I allowed for that as well. |
Definitely finding this discussion interesting as I look at modifying a package installer to handle parameters that modify how it installs. Is PowerShell's Just curious because in that case you could simply set the values in a |
Just an update to this discussion:
|
There is also a bug in the way that the Chocolatey core extension module loads up, in that it unconditionally overrides the built-in one. chocolatey-community/chocolatey-packages#898 |
@jberezanski as this conversation went all kinds of ways - the core of what this issue was about has been covered and this can be closed. I would like to capture what you are hoping for - PowerShell parameters for Chocolatey automation scripts into another issue. Would you be able to split that out and reference the points here (@mattheyan and @DarwinJS had some really good thoughts in here as well to expand on your notes). |
I am heavily using
-ia
parser for a bunch of packages i've developed.Use cases:
chocolateyInstall.ps1
script wants some advanced control options to be passes with predefined default values. Actually, it is sad thatchoco
requires additional flag to pass anything inside, but ok.What i have:
Parse-Args -Arg $env:ChocolateyAdvanceArgs -Default @{ option = "default value" }
-> [hashtable]Merge-Args -To $A -From $B
Args format:
Example:
choco install package -y -ia '-flag -key=value -key2="value 123 -key3=1 -key3=2"'
The text was updated successfully, but these errors were encountered: