Skip to content
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

Dynamic args and params #42

Open
jayvdb opened this issue Jun 5, 2019 · 9 comments
Open

Dynamic args and params #42

jayvdb opened this issue Jun 5, 2019 · 9 comments

Comments

@jayvdb
Copy link
Contributor

jayvdb commented Jun 5, 2019

Composer needs to know where php is located, so it would look something like this:

        {
            "name": "php",
            "version": "7.3.6",
            "params": "/InstallDir:C:\\tools\\php"
        },
        {
            "name": "composer",
            "args": "/PHP=C:\\tools\\php\\php.exe"
        },

But it would be much nicer if there were not hard-coded directories could be something like

        {
            "name": "php",
            "version": "7.3.6",
        },
        {
            "name": "composer",
            "args": "/PHP=$(fudge which php)"
        },

or perhaps

        {
            "name": "composer",
            "dynamic-args": "name-of-script-returning-args-as-string"
        },

There is already a dependency between the composer and php packages, so the dynamic scriptlet only needs to be run just before composer is ready to be installed.

@jayvdb
Copy link
Contributor Author

jayvdb commented Jun 5, 2019

Or even better would be to have a hook system like @pnpm , so a custom chunk of ps1 can re-process the dependency entry and fiddle with it before fudge processes it.

@jayvdb
Copy link
Contributor Author

jayvdb commented Jun 6, 2019

Another important use of this would be loading the version dynamically from .nvmrc and similar.

@jayvdb
Copy link
Contributor Author

jayvdb commented Jun 14, 2019

Hooks in choco itself is chocolatey/choco#1185

@Badgerati
Copy link
Owner

This could actually be really easily achieved using the "args": "/PHP=$(fudge which php)" syntax, as embedded PowerShell (or other script calls). There's currently something very similar over in Pode.

Idea is to basically take the string, convert it to a scriptblock, and invoke it like PowerShell:

# take the args from the fudgefile
$args = "path=$(where.exe choco)"
$args = (. ([scriptblock]::Create('return "$($args)"')))

# args is now
"path=C:\ProgramData\chocolatey\bin\choco.exe"

This also raises a point for fudge which, as it doesn't just return the path - maybe something that could be changed in #45?

For the hooks, I really like the idea; be good as a new feature request! You could have both this and the hooks. Right now there's pre/post hooks for before/after all packages, but we could have pre/post-package hooks that run before/after each package. Then maybe let each package have it's own individual pre/post hooks?

@jayvdb
Copy link
Contributor Author

jayvdb commented Jun 20, 2019

Embedding PS into JSON? :P Hence #59 , as YAML is better for writing code snippets inside config.

Another approach for some dynamic uses of "args" and "params", slightly less pretty but less convoluted and more consistent, is to use CMD syntax, "/PHP=%PHP_ROOT%" . The users might set those envvars before calling Fudge, or Fudge could have a "environment" section which adds defaults. Then it becomes the responsibility of per-package hooks to define any new envvars which can only be known after one package is installed and needed by the args/params of a subsequent package.

This doesnt provide a nice approach for dynamically choosing whether to --forcex86 depending on an envvar, unless a more complete CMD.exe batch script parser is introduced ;-)

(It would be very useful to have a PS implementation of .CMD file parser.)

@Badgerati
Copy link
Owner

Haha, yeeeeah it's not great, but for simple inline stuff like /PHP=$(where.exe php) it's not too bad!

In which case, we could have:

  • args: which is for raw arguments and %VAR% environment variable placeholders - with the possibility of supporting simple inline $(...) commands.
  • script-args: which takes a path to a .ps1 script that returns dynamic arguments.

@jayvdb
Copy link
Contributor Author

jayvdb commented Jun 22, 2019

Another option is to allow Fudgefile.psd1 as an alternative to Fudgefile, which allows basic PS1 to be embedded easily/naturally.

This is like Gemfile which is ruby-ish syntax. But one of the strengths of npm and pip is that their requirements formats are not language specific, so parsing is easy to do in other languages.

@Badgerati
Copy link
Owner

I was just thinking about changing the JSON file to a Hashtable format last night - possibly better than #59?

Since changing the file format is a v2.0 change - maybe having the args/script-args change here for v1.4?

@jayvdb
Copy link
Contributor Author

jayvdb commented Jun 23, 2019

Why not support both JSON and .psd1 ? That avoids a breaking change , avoids needing to rewrite all the documentation, and lets the .psd1 support be 'beta' and allowed to change over the next few versions until we're confident it is ready to be stable.

For my part, my next iteration will be importing Fudge.ps1 and FudgeTools into the coala central mobans repo, so you cant break us - you can only prevent us from upgrading fudge.

With my learnings at #58 (comment) , I think $(..) and script-args are unnecessary hacks, and are still limited by the fact that args/script-args are a single snippet, and will not be suitable for all choco actions (install/uninstall/etc). Providing a pre-install per-package hook would allow for args and params etc to be dynamic, or if $action is in the scope only pre per-package hook is needed (and the hook logic can check if it is install/uninstall/etc).

e.g. the original problem can be solved by hook

$package.args = ("/PHP=" + (fudge which php))

And if that args breaks the choco uninstall, the hook script can be easily enhanced to

if ($action -eq 'install') {
    $package.args = ("/PHP=" + (fudge which php))
}

And %foo% style syntax can be implemented easily with a pre-install hook, if the Fudge writer feels that is more user-friendly.

if ($action -eq 'install') {
    $package.args = $package.args -replace '%PHP_ROOT%',(fudge which php)
}
else {
    $package.args = $null
}

script-args is implicitly a pre-something per-package hook, but it is limited in what it can change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants