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

Manage only part of config file via chezmoi to exclude ovewriting program temporary state settings #847

Closed
MurzNN opened this issue Aug 11, 2020 · 10 comments · Fixed by #1027
Labels
enhancement New feature or request

Comments

@MurzNN
Copy link

MurzNN commented Aug 11, 2020

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

Many programs store config settings (permanent configuration options) and program state settings (temporary settings like window size and position, list of opened files, etc) in one config file, so on each program start and on usage time file is changed very frequently. And each chezmoi update rewrite this file to original content, that's bad for UX.

Describe the solution you'd like

To solve this problem will be good to have ability to store and apply only part of config file via chezmoi.

Maybe this can be solved via some pre-formatted comment lines like:

{text lines before, not managed via chezmoi}
# chezmoi managed part start #
{text lines with settings, managed via chezmoi}
# chezmoi managed part end #
{text lines after, not managed via chezmoi}

Or maybe anybody can provide some better solution?

Describe alternatives you've considered

Alternative solution to described problem, limited only to ini-style config files, can be creating chezmoi function to force set of ini option to needed value, like in SaltStack or other big global configuration management systems.

Additional context

Popular example of this problem is KDE Konsole program, that save window size in his ini-formatted config file .config/konsolerc, here is example:

[Desktop Entry]
DefaultProfile=Profile 1.profile

[DownloadDialog Settings]
Height 1080=494
Width 1920=700

[Favorite Profiles]
Favorites=

[MainWindow]
Height 1080=1011
Height 768=705
State=AAAA/wAAAAD9AAAAAAAAB4AAAAPVAAAABAAAAAQAAAAIAAAACPwAAAAA
ToolBarsMovable=Disabled
Width 1366=1366
Width 1920=1920
Window-Maximized 1080x1920=true
Window-Maximized 768x1366=true

[TabBar]
Favorite Profiles=~/.local/share/konsole/Murz.profile
NewTabBehavior=PutNewTabAfterCurrentTab
NewTabButton=true
ShowQuickButtons=true
TabBarPosition=Top
xNewTabBehavior=PutNewTabAfterCurrentTab
xShowQuickButtons=true
xTabBarPosition=Top
xTabBarVisibility=AlwaysShowTabBar

[TabBar2]
NewTabBehavior=PutNewTabAfterCurrentTab

So I want to manage and apply via chezmoi only [Desktop Entry], [TabBar] and [TabBar2] groups of settings, and don't touch (and always overwrite) other groups.

@MurzNN MurzNN added the enhancement New feature or request label Aug 11, 2020
@MurzNN
Copy link
Author

MurzNN commented Aug 11, 2020

The source of described problem is KDE software principes, so I fill feature request to fix this in their thread, but they will not fix this quicker in all programs, so solution from chezmoi side will be very useful!

@Singond
Copy link

Singond commented Jan 26, 2021

I am also in favour of such feature. In my use case, I want to control a few specific lines (which can be selected by regex, regardless of whether it is before or after modification) in a configuration file and I don't care about the rest of the file. I do not want to put the whole file under version control because it changes frequently, and updating the repository every time the file changes (which is every time the application is opened) would be very tedious.

In the current version, the solution would probably be to use scripts to be run with chezmoi apply (in my case, a simple sed invocation would do), but the documentation advises against their widespread use, probably because the scripts can do arbitrary things and Chezmoi cannot control which files would be modified. I also suspect Chezmoi does not show the modifications in chezmoi diff.

I imagine this could be solved, for example, by being able to define a shell script which takes the current version of the file in stdin and outputs the file with the desired modifications to stdout. This way, Chezmoi would know which file is modified by the script and would be able to show the modifications in chezmoi diff before applying them.

Are there any plans on supporting this? Thanks in advance.

@twpayne
Copy link
Owner

twpayne commented Jan 26, 2021

I imagine this could be solved, for example, by being able to define a shell script which takes the current version of the file in stdin and outputs the file with the desired modifications to stdout. This way, Chezmoi would know which file is modified by the script and would be able to show the modifications in chezmoi diff before applying them.

This is a really interesting proposal. How does something like the following sound in practice?

If a file in the source state has the name modify_<target> then it is treated as an executable which reads the current contents of <target> on stdin and writes the desired target state of <target> to stdout. Such modify_ scripts must be idempotent and cannot modify file permission or change entry types (e.g they cannot convert a file to a symlink).

An example modify_ script might be called dot_config/modify_consolerc in @MurzNN's example above.

@twpayne
Copy link
Owner

twpayne commented Jan 26, 2021

Are there any plans on supporting this? Thanks in advance.

For what it's worth, I'd love for chezmoi to support this - it just needed a good mechanism.

@Singond
Copy link

Singond commented Jan 26, 2021

If a file in the source state has the name modify_<target> then it is treated as an executable which reads the current contents of <target> on stdin and writes the desired target state of <target> to stdout. Such modify_ scripts must be idempotent and cannot modify file permission or change entry types (e.g they cannot convert a file to a symlink).

This is exactly what I had in mind. I would also consider placing an additional restriction on the script, that is to disallow any side-effects like creating additional files. The script should act as a simple filter to ensure that Chezmoi knows what will be modified.

For what it's worth, I'd love for chezmoi to support this - it just needed a good mechanism.

That would be great. Unfortunately, I don't know anything about the inner workings of Chezmoi to suggest a good mechanism to do this, nor am I a Go developer to offer any help.

Thanks for considering this feature.

@twpayne
Copy link
Owner

twpayne commented Jan 26, 2021

OK, I'll try to come up with an implementation of this. It will be in chezmoi2 (see #987) as chezmoi2's architecture makes it much easier to add functionality like this.

I would also consider placing an additional restriction on the script, that is to disallow any side-effects like creating additional files.

In practice, this is really hard to implement. chezmoi could spin up an isolated environment (e.g. a Docker container) to run the script, but in the short term I'll just trust the user to make sure that their modify_ scripts are idempotent (just like their run_ scripts should be).

@twpayne twpayne added this to the v2.0.0 milestone Jan 26, 2021
@Singond
Copy link

Singond commented Jan 26, 2021

In practice, this is really hard to implement. chezmoi could spin up an isolated environment (e.g. a Docker container) to run the script, but in the short term I'll just trust the user to make sure that their modify_ scripts are idempotent (just like their run_ scripts should be).

Yes, this is what I meant. The no-side-effects requirement, just as the idempotence, is left solely to the user's responsibility. I don't think this is a problem, because it is stated clearly in the documentation. Running a Docker container to check that all these requirements are met seems like an overkill to me.

@MurzNN
Copy link
Author

MurzNN commented Apr 25, 2021

@twpayne great thanks for implementing! But I can't find right documentation how to make new modify_ file via chezmoi command line arguments - can you explain this more detailed in docs?
Or this file must be created manually in git repo?

And will be cool to see some example in docs, eg script for enforcing the Meta+D hotkey to show desktop into .config/kglobalshortcutsrc (ini-formatted) file with lines:

[kwin]
...[some other strings]...
Show Desktop=none,Meta+D,Show Desktop
...[some other strings]...

@twpayne
Copy link
Owner

twpayne commented Apr 25, 2021

Currently you have to manually create modify_ scripts in the source directory.

This is a new feature, and it's clearly not easy to use (see the comments in #1046 for examples), so it's deliberately not documented in detail as we (the chezmoi users) still need to work out how to use it effectively.

I think that once we have a few solid examples we can add those to the "how to" documentation.

@eugenesvk
Copy link
Contributor

eugenesvk commented Aug 27, 2021

And will be cool to see some example in docs, eg script for enforcing the Meta+D hotkey to show desktop into .config/kglobalshortcutsrc (ini-formatted) file with lines

@MurzNN FYI I've added a Python script example that would do exactly this — pass all lines of a config file as is except for a single line with an option that matches our regex ("font_size" in my example), which should be tracked vs. our value in a template
(this assumes, though, that the option exists, not sure it applies to your example, which in that case would need to have another check when no option is found)

#1046 (comment)

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants