twpayne / chezmoi

Manage your dotfiles across multiple diverse machines, securely.
https://www.chezmoi.io/
MIT License
12.85k stars 477 forks source link

Allow to use templates to process modify_ files #2526

Closed felipecrs closed 1 year ago

felipecrs commented 1 year ago

Is your feature request related to a problem? Please describe.

Chezmoi's template functions are quite powerful, which includes the likes of fromYaml, toYaml, fromJson, toJson and so on. I believe these functions are powerful enough to replace jq for example in my modify_ files, and if I could stop using interpreters as well (like Bash or Python) it would be even better for portability.

Describe the solution you'd like

Somehow to instruct chezmoi that it should use go-template to process the data, by providing the original source file as a top level key, like:

# Note that the file does not end with `.tmpl`
$ cat dot_docker/modify_config.json
{{- /* chezmoi:modify-with-template=true */ -}}
{{- $input := fromJson .input -}}
{{- $_ := set $input "myFlag" true -}}
{{- toJson $input -}}

Describe alternatives you've considered

I was thinking about using chezmoi execute-template as the shebang, but I then I thought: how would I handle the unpresence of chezmoi in PATH? Which may happen, like in the first installation.

I could probably use {{ .chezmoi.executable }}, but then I would have to mark the file as a template because of this, thus having to escape all other template instructions inside of the file as well.

Additional context

None.

bradenhilton commented 1 year ago

@felipecrs I don't have any thoughts on this issue at the moment. I just wanted to say I linked to this issue in https://github.com/twpayne/chezmoi/pull/2527 by mistake, though you might have assumed as much. Regardless, you can ignore it :)

bradenhilton commented 1 year ago

Actually, +1 now that I'm reading through this.

It's especially painful with PowerShell, where it can take several hundred milliseconds just to launch, which is about 3-4 times slower than just running a simple chezmoi execute-template ...:

(based on https://devblogs.microsoft.com/powershell/optimizing-your-profile/#getting-a-baseline-for-pwsh)

benchmark.ps1:

@(
    'powershell -noninteractive -noprofile -command "1"',
    'pwsh -noninteractive -noprofile -command "1"',
    'chezmoi execute-template ''{{1}}'''
) | ForEach-Object {
    $command = ($_ -split ' ')[0]
    $arg = ($_ -split ' ') | Select-Object -Skip 1

    $average = 0

    1..100 | ForEach-Object {
        Write-Progress -Id 1 -Activity $command -PercentComplete $_
        $average += (Measure-Command {
                & $command $arg
            }).TotalMilliseconds 
    }
    Write-Progress -id 1 -Activity 'profile' -Completed

    $average = $average / 100
    "{0,10} average: {1,10:n3}ms" -f $command, $average
}
❯ .\benchmark.ps1
powershell average:    315.225ms
      pwsh average:    456.244ms
   chezmoi average:     99.217ms

chezmoi is more than capable of basic CRUD in config files with from* and to*.

twpayne commented 1 year ago

+1 this is a great idea @felipecrs. PR coming up...

twpayne commented 1 year ago

Fixed with #2529.

felipecrs commented 1 year ago

Thanks a lot. This is going to be much nicer!