Development/Tools/Using kconf update: Difference between revisions

    From KDE TechBase
    m (cosmetic changes)
    (→‎Debugging and testing: Explain how to manually test update files)
    (13 intermediate revisions by 6 users not shown)
    Line 1: Line 1:
    {{Review|
    * Update to KF5
    * Double check info and paths
    }}
    {{Note|
    {{Note|
    The text for this document was lifted from the source file kdelibs/kconf_update/README.kconf_update. It is reprinted here so that we have a description outside of the source code, and so we can add more example update scripts.}}
    The text for this document was lifted from the source file kdelibs/kconf_update/README.kconf_update. It is reprinted here so that we have a description outside of the source code, and so we can add more example update scripts.}}
    Line 13: Line 18:
       
       
    ==How it works==
    ==How it works==
    Applications can install so called "update files" under {{path|$KDEDIR/share/apps/kconf_update}}. An update file has ".upd" as extension and contains instructions for transferring/converting configuration information from one place to another.
    Applications can install so called ''update files'' under {{path|$KDEDIR/share/apps/kconf_update}}. An update file has ''.upd'' as extension and contains instructions for transferring and converting configuration information from one place to another.
       
       
    Updating the configuration happens automatically, either when KDE gets started or when <tt>kded</tt> detects a new update file in the above mentioned location.
    Updating the configuration happens automatically, either when KDE gets started or when <tt>kded</tt> detects a new update file in the above mentioned location.
       
       
    Update files are separated into sections. Each section has an Id. When a section describing a configuration change has been applied, the Id will be stored in the file "kconf_updaterc". This information is used to make sure that a configuration update is only performed once.
    Update files are separated into sections. Each section has an unique ID. When a section describing a configuration change has been applied, the ID will be stored in the file {{path|$KDEHOME/share/config/kconf_updaterc}}. This information is used to make sure that a configuration update is only performed once.
    If you overwrite an existing update file with a new version that contains a new section, only the update instructions from this extra section will be performed.  
       
       
    If you overwrite an existing update file with a new version that contains a new section, only the update instructions from this extra section will be performed.
    ==File format of the update file==
    ==File format of the update file==
    Empty lines or lines that start with '#' are considered comments. Commas (,) are used to seperate fields and may not occur as part of any field and all of the keywords are case-sensitive, i.e. you cannot say "key" instead of "Key" for example.
    Empty lines or lines that start with '#' are considered comments.
    Commas are used to seperate fields and may not occur as part of any field.
    All of the keywords are case-sensitive.
       
       
    The remainder of the file is parsed and executed sequentially from top to bottom. Each line can contain one entry. The following entries are recognized:
    The remainder of the file is parsed and executed sequentially from top to bottom. Each line can contain one entry. The following entries are recognized:
        
        
    Id=<id>  
    * Version=5
     
    :Specifies which KDE Frameworks version this update file targets. At the time of writing the only valid value is 5, meaning modern (KDE Frameworks 5) kconf_update binaries will process the file. A file without Version value is skipped by kconf_update. A file with Version=5 may still be run on older kconf_updates!
     
    * Id=<id>  


    With <id> identifying the group of update entries that follows. Once a group of entries have been applied, their <id> is stored and this group of entries will not be applied again.
    :With <id> identifying the group of update entries that follows. Once a group of entries have been applied, their ID is stored and this group of entries will not be applied again. This ID has to be unique.
       
       
    File=<oldfile>,<newfile>  
    * File=<oldfile>,<newfile>  
    File=<oldfile>  
    * File=<oldfile>  
     
    :Specifies that configuration information is read from <oldfile> and written to <newfile>.


    Specifies that configuration information is read from <oldfile> and written to <newfile>. If you only specify <oldfile>, the information is read from as well as written to <oldfile>.
    :If you only specify <oldfile>, the information is read from as well as written to <oldfile>.
    :Note that if the file does not exist at the time kconf_update first checks, no related update will be performed.
       
       
      Script=<_script>[,<interpreter>]  
    * Script=<_script>[,<interpreter>]
     
    :All entries from <oldfile> are piped into <_script>.


    All entries from <oldfile> are piped into <_script>. The output of script is used as new entries for <newfile>. Existing entries can be deleted by adding lines with "# DELETE [group]key" in the output of the script. To delete a whole group use "# DELETEGROUP [group]".
    :The output of <_script> is used as new entries for <newfile>. Existing entries can be deleted by adding lines with  
    # DELETE [group]key
    :in the output of the script. To delete a whole group use  
    # DELETEGROUP [group]
       
       
    <_script> should be installed into {{path|$(kde_datadir)/kconf_update}}, or kconf_update will not be able to find it. It is not portable to install binary applications in {{path|$kde_datadir}}, so you have to stick with interpreted scripts like shell or perl scripts.  
    :<_script> should be installed into {{path|$(kde_datadir)/kconf_update}}, or kconf_update will not be able to find it.  


    It is also possible to install kconf_update applications in {{path|$(kde_bindir)/kconf_update_bin}}, which opens the door to kconf_update applications that are written in C++ and use Qt's powerful string API instead.
    :It is not portable to install binary applications in {{path|$kde_datadir}}, so you have to stick with interpreted scripts like shell or perl. To make your scripts compatible with Windows, you should not use shell scripts.


    If Script was issued after a "Group" command the behavior is slightly different: all entries from <oldfile>/<oldgroup> are piped into <_script>. The output of script is used as new entries for <newfile>/<newgroup>, unless a different group is specified with "[group]". Existing entries can be deleted from <oldgroup> by adding lines with "# DELETE key" in the output of the script. To delete <oldgroup> use "# DELETEGROUP".
    :It is also possible to install kconf_update applications in {{path|$(kde_bindir)/kconf_update_bin}}, which opens the door to kconf_update applications that are written in C++ and use Qt's powerful string API instead.
     
    :If the ''Script'' command was issued after a ''Group'' command the behavior is slightly different: All entries from <oldfile>/<oldgroup> are piped into <_script>. The output of script is used as new entries for <newfile>/<newgroup>, unless a different group is specified with ''[group]''. Existing entries can be deleted from <oldgroup> by adding lines with
    # DELETE key
    :in the output of the script. To delete <oldgroup> use  
    # DELETEGROUP
       
       
    <interpreter> can be something like "perl".
    :<interpreter> can be something like "perl".
       
       
    It is also possible to have a script without specifying <oldfile> or <newfile>. In that case the script is run but it will not be fed any input and its output will simply be discarded.
    :It is also possible to have a script without specifying <oldfile> or <newfile>. In that case the script is run but it will not be fed any input and its output will simply be discarded.
        
        
    ScriptArguments=<arguments>  
    *ScriptArguments=<arguments>  


    If specified, the arguments will be passed to <_script>. IMPORTANT: Specify the ScriptArguments '''before''' the script.
    :If specified, the arguments will be passed to <_script>. IMPORTANT: Specify the ScriptArguments '''before''' the ''Script'' command.
        
        
    Group=<oldgroup>,<newgroup>  
    * Group=<oldgroup>,<newgroup>  
    Group=<oldgroup>  
    * Group=<oldgroup>  


    Specifies that configuration information is read from the group <oldgroup> and written to <newgroup>. If you only specify <oldgroup>, the information is read from as well as written to <oldgroup>. You can use <default> to specify keys that are not under any group.
    :Specifies that configuration information is read from the group <oldgroup> and written to <newgroup>. If you only specify <oldgroup>, the information is read from as well as written to <oldgroup>. You can use <default> to specify keys that are not under any group.
        
        
    RemoveGroup=<oldgroup>  
    * RemoveGroup=<oldgroup>  


    Specifies that <oldgroup> is removed entirely. This can be used to remove obsolete entries or to force a revert to default values.
    :Specifies that <oldgroup> is removed entirely. This can be used to remove obsolete entries or to force a revert to default values.
        
        
    Options=<option1>, <option2>, ....  
    * Options=<option1>, <option2>, ....  


    With this entry you can specify options that apply to the next "Script", "Key" or "AllKeys" entry (only to the first!). Possible options are:
    :With this entry you can specify options that apply to the next ''Script'' command, ''Key'' or ''AllKeys'' entry (only to the first!). Possible options are:
       
       
    :* "copy" Copy the configuration item instead of moving it. This means that the configuration item will not be deleted from <oldfile>/<oldgroup>.
    ::- "copy" Copy the configuration item instead of moving it. This means that the configuration item will not be deleted from <oldfile>/<oldgroup>.
       
       
    :* "overwrite" Normally, a configuration item is not moved if an item with the new name already exists. When this option is specified the old configuration item will overwrite any existing item.
    ::- "overwrite" Normally, a configuration item is not moved if an item with the new name already exists. When this option is specified the old configuration item will overwrite any existing item.
        
        
    Key=<oldkey>,<newkey>  
    * Key=<oldkey>,<newkey>  
    Key=<oldkey>  
    * Key=<oldkey>  


    Specifies that configuration information is read from the key <oldkey> and written to <newkey>. If you only specify <oldkey>, the information is read from as well as written to <oldkey>.
    :Specifies that configuration information is read from the key <oldkey> and written to <newkey>. If you only specify <oldkey>, the information is read from as well as written to <oldkey>.
        
        
    AllKeys  
    * AllKeys  


    Specifies that all configuration information in the selected group should be moved (All keys).
    :Specifies that all configuration information in the selected group should be moved (All keys).
        
        
    AllGroups  
    * AllGroups  


    Specifies that all configuration information from all keys in ALL groups should be moved.  
    :Specifies that all configuration information from all keys in '''all''' groups should be moved.  
       
       
    RemoveKey=<oldkey>  
    * RemoveKey=<oldkey>  


    Specifies that <oldkey> is removed from the selected group. This can be used to remove obsolete entries or to force a revert to default values.
    :Specifies that <oldkey> is removed from the selected group. This can be used to remove obsolete entries or to force a revert to default values.


    <code ini>
    == Example update file ==
    # Example update file
     
    <syntaxhighlight lang="ini">
    # This is comment
    # This is comment
    Version=5
    Id=kde2.2
    Id=kde2.2
    File=kioslaverc,kio_httprc
    File=kioslaverc,kio_httprc
    Line 103: Line 130:
    RemoveGroup=KDE
    RemoveGroup=KDE
    # End of file
    # End of file
    </code>
    </syntaxhighlight>


    The above update file extracts config information from the file {{path||kioslaverc}} and stores it into the file {{path||kio_httprc}}.
    The above update file extracts config information from the file {{path|kioslaverc}} and stores it into the file {{path|kio_httprc}}.
       
       
    It reads the keys "NoProxyFor", "UseProxy" and "httpProxy" from the group "Proxy Settings" in the {{path|kioslaverc}} file. If any of these options are present they are written to the keys "NoProxyFor", "UseProxy" and "Proxy" (!) in the group "Proxy Settings" in the {{path|kio_httprc}} file.
    It reads the keys "NoProxyFor", "UseProxy" and "httpProxy" from the group "Proxy Settings" in the {{path|kioslaverc}} file. If any of these options are present they are written to the keys "NoProxyFor", "UseProxy" and "Proxy" (!) in the group "Proxy Settings" in the {{path|kio_httprc}} file.
    Line 114: Line 141:
       
       
    Finally it removes the entire "KDE" group in the {{path|kioslaverc}} file.
    Finally it removes the entire "KDE" group in the {{path|kioslaverc}} file.
     
     
    == Further Examples ==
     
    The best way to learn how to write scripts and update files is to look at existing ones, for example the ones of [http://websvn.kde.org/trunk/KDE/kdepim/kmail/kconf_update/ KMail].
     
    ==Debugging and testing==
    ==Debugging and testing==
    ===Testing update entries===
    To test an <code>*.upd</code> file it may be convenient to manually run kconf_update, usually located at <code>/usr/lib/kf5/kconf_update</code>. This is particularly relevant if you are testing an update file for a program installed in a custom prefix that is not the same as the one of kded, because kde will not run kconf_update automatically.
    For example if you want to test the Okular update file okular.upd
    {{Output|1=<nowiki>
    #Configuration update for Okular
    Version=5
    #Convert user-defined annotation tools to quick annotation tools
    Id=annotation-toolbar
    File=okularpartrc
    Group=Reviews
    Key=AnnotationTools,QuickAnnotationTools
    </nowiki>}}
    you can first make a copy of the config file you want to target to the test path {{Path | .qttest/}}
    {{Input|1=<nowiki>
    mkdir -p .qttest/config/
    cp ~/.config/okularpartrc ~/.qttest/config/
    </nowiki>}}
    then you can manually run kconf_update from the folder where okular.upd is located
    {{Input|1=<nowiki>
    /usr/lib/kf5/kconf_update ./okular.upd --debug --testmode
    </nowiki>}}
    The <code>--testmode</code> flag allows you to use test directories under {{Path | ~/.qttest }} to stay away the user's real files, while the <code>--debug</code> flag enables useful debugging messages displaying what kconf_update is doing.
    If the rule is applied correctly, the command displays the following output
    {{Output|1=<nowiki>
    Automatically enabled the debug logging category kf5.kconfig.update
    kf5.kconfig.update: Checking update-file "/opt/install_prefix/share/kconf_update/okular.upd" for new updates
    kf5.kconfig.update: "okular.upd" : Found new update "annotation-toolbar"
    kf5.kconfig.update: "okular.upd" : Updating "okularpartrc" : "Reviews" : "QuickAnnotationTools" to "<tool type=\"note-linked\" id=\"1\">..."
    kf5.kconfig.update: "okular.upd" : Removing "okularpartrc" : "Reviews" : "AnnotationTools" , moved.
    </nowiki>}}
    The configuration file {{Path | ~/.qttest/config/okularpartrc}} should now have the following key indicating that it has been updated using the update rule okular.upd:annotation-toolbar
    {{Output|1=<nowiki>
    [$Version]
    update_info=okular.upd:annotation-toolbar
    </nowiki>}}
    If you now run kconf_update, the update rule will not be applied again because kconf_update registered that it has already been applied. To test the update rule again you have to:
    # copy the old configuration file {{Path |~/.config/okularpartrc}} over the updated one {{Path |~/.qttest/config/okularpartrc}}
    # remove the <code>[$Version]</code> settings group from the configuration file
    # remove the okular:annotation-toolbar entry from {{Path | ~/.config/kconf_updater}}
    ===Debugging update scripts===
    If you are developing a kconf_update script and want to test or debug it you need to make sure kconf_update runs again after each of your changes. There are a number of ways to achieve this.
    If you are developing a kconf_update script and want to test or debug it you need to make sure kconf_update runs again after each of your changes. There are a number of ways to achieve this.
       
       
    The easiest is to not install the kconf_update script in the first place, but manually call it through a pipe. If you want to test the update script for your application KHello's config file {{path|khellorc}}, you can test by using
    The easiest is to not install the kconf_update script in the first place, but manually call it through a pipe. If you want to test the update script for your application KHello's config file {{path|khellorc}}, you can test by using


    <code bash>  
    <syntaxhighlight lang="bash">
    cat ~/.kde/share/config/khellorc | khello_conf_update.sh
    cat ~/.local/share/config/khellorc | khello_conf_update.sh
    </code>
    </syntaxhighlight>
       
       
    (assuming {{path|khello_conf_update.sh}} is the kconf_update script and {{path|~/.kde}} is your $KDEHOME). This is easier than making install every time, but has the obvious downside that you need to 'parse' your script's output yourself instead of letting kconf_update do it and check the resulting output file.
    (assuming {{path|khello_conf_update.sh}} is the kconf_update script and {{path|~/.local/share}} is your $XDG_DATA_HOME). This is easier than installing every time, but has the obvious downside that you need to 'parse' your script's output yourself instead of letting kconf_update do it and check the resulting output file.
       
       
    After 'make install' the kconf_update script is run by kded, but it does so only once. This is of course the idea behind it, but while developing it can be a problem. You can increase the revision number for each subsequent run of 'make install' to force a new kconf_update run, but there's a better approach that doesn't skyrocket the version number for a mediocre debug session.
    After 'make install' the kconf_update script is run by kded, but it does so only once. This is of course the idea behind it, but while developing it can be a problem. You can increase the revision number for each subsequent run of 'make install' to force a new kconf_update run, but there's a better approach that doesn't skyrocket the version number for a mediocre debug session.
    Line 130: Line 215:
    kded doesn't really ignore scripts that it has already run right away. Instead it checks the affected config file every time a .upd file is added or changed. The reason it still doesn't run again on your config file lies in the traces kconf_update leaves behind: it adds a special config group '[$Version]' with a key 'update_info'. This key lists all kconf_update scripts that have already been run on this config file. Just remove your file's entry, 'make install', and kconf_update will happily run your script again, without you having to increase the version number.
    kded doesn't really ignore scripts that it has already run right away. Instead it checks the affected config file every time a .upd file is added or changed. The reason it still doesn't run again on your config file lies in the traces kconf_update leaves behind: it adds a special config group '[$Version]' with a key 'update_info'. This key lists all kconf_update scripts that have already been run on this config file. Just remove your file's entry, 'make install', and kconf_update will happily run your script again, without you having to increase the version number.
       
       
    If you want to know what kconf_update has been up to lately, have a look at {{path|$KDEHOME/share/apps/kconf_update/log/update.log}}
    After KDE Frameworks 5.57 status updates of kconf_update are run through QDebug and may be controlled in any way other QDebugs may be controlled. Notably, by default, debug output is not generated unless the category <code>kf5.kconfig.update</code> is explicitly enabled and will be printed to stderr and consequently end up in {{path|xsession-errors}} or {{path|wayland-errors}}. If Qt was built with support for logging to system log facilities (such as  systemd-journald) the output may be found there instead.
    Before 5.57 the output was always sent to stderr and may be found in the aforementioned errors files.
     
    ==Common Problems==
    ==Common Problems==



    Revision as of 10:37, 26 July 2020

    Warning
    This page needs a review and probably holds information that needs to be fixed.

    Parts to be reviewed:

    • Update to KF5
    • Double check info and paths
    Note
    The text for this document was lifted from the source file kdelibs/kconf_update/README.kconf_update. It is reprinted here so that we have a description outside of the source code, and so we can add more example update scripts.


    What it does

    kconf_update is a tool designed to update configuration files. Over time applications sometimes need to rearrange the way configuration options are stored. Since such an update shouldn't influence the configuration options that the user has selected, the application must take care that the options stored in the old way will still be honored.

    What used to happen is that the application looks up both the old and the new configuration option and then decides which one to use. This method has several drawbacks:

    • The application may need to read more configuration files than strictly needed, resulting in a slower startup
    • The application becomes bigger with code that will only be used once

    kconf_update addresses these problems by offering a framework to update configuration files without adding code to the application itself.

    How it works

    Applications can install so called update files under $KDEDIR/share/apps/kconf_update. An update file has .upd as extension and contains instructions for transferring and converting configuration information from one place to another.

    Updating the configuration happens automatically, either when KDE gets started or when kded detects a new update file in the above mentioned location.

    Update files are separated into sections. Each section has an unique ID. When a section describing a configuration change has been applied, the ID will be stored in the file $KDEHOME/share/config/kconf_updaterc. This information is used to make sure that a configuration update is only performed once.

    If you overwrite an existing update file with a new version that contains a new section, only the update instructions from this extra section will be performed.

    File format of the update file

    Empty lines or lines that start with '#' are considered comments. Commas are used to seperate fields and may not occur as part of any field. All of the keywords are case-sensitive.

    The remainder of the file is parsed and executed sequentially from top to bottom. Each line can contain one entry. The following entries are recognized:

    • Version=5
    Specifies which KDE Frameworks version this update file targets. At the time of writing the only valid value is 5, meaning modern (KDE Frameworks 5) kconf_update binaries will process the file. A file without Version value is skipped by kconf_update. A file with Version=5 may still be run on older kconf_updates!
    • Id=<id>
    With <id> identifying the group of update entries that follows. Once a group of entries have been applied, their ID is stored and this group of entries will not be applied again. This ID has to be unique.
    • File=<oldfile>,<newfile>
    • File=<oldfile>
    Specifies that configuration information is read from <oldfile> and written to <newfile>.
    If you only specify <oldfile>, the information is read from as well as written to <oldfile>.
    Note that if the file does not exist at the time kconf_update first checks, no related update will be performed.
    • Script=<_script>[,<interpreter>]
    All entries from <oldfile> are piped into <_script>.
    The output of <_script> is used as new entries for <newfile>. Existing entries can be deleted by adding lines with
    # DELETE [group]key
    
    in the output of the script. To delete a whole group use
    # DELETEGROUP [group]
    
    
    <_script> should be installed into $(kde_datadir)/kconf_update, or kconf_update will not be able to find it.
    It is not portable to install binary applications in $kde_datadir, so you have to stick with interpreted scripts like shell or perl. To make your scripts compatible with Windows, you should not use shell scripts.
    It is also possible to install kconf_update applications in $(kde_bindir)/kconf_update_bin, which opens the door to kconf_update applications that are written in C++ and use Qt's powerful string API instead.
    If the Script command was issued after a Group command the behavior is slightly different: All entries from <oldfile>/<oldgroup> are piped into <_script>. The output of script is used as new entries for <newfile>/<newgroup>, unless a different group is specified with [group]. Existing entries can be deleted from <oldgroup> by adding lines with
    # DELETE key
    
    in the output of the script. To delete <oldgroup> use
    # DELETEGROUP
    
    
    <interpreter> can be something like "perl".
    It is also possible to have a script without specifying <oldfile> or <newfile>. In that case the script is run but it will not be fed any input and its output will simply be discarded.
    • ScriptArguments=<arguments>
    If specified, the arguments will be passed to <_script>. IMPORTANT: Specify the ScriptArguments before the Script command.
    • Group=<oldgroup>,<newgroup>
    • Group=<oldgroup>
    Specifies that configuration information is read from the group <oldgroup> and written to <newgroup>. If you only specify <oldgroup>, the information is read from as well as written to <oldgroup>. You can use <default> to specify keys that are not under any group.
    • RemoveGroup=<oldgroup>
    Specifies that <oldgroup> is removed entirely. This can be used to remove obsolete entries or to force a revert to default values.
    • Options=<option1>, <option2>, ....
    With this entry you can specify options that apply to the next Script command, Key or AllKeys entry (only to the first!). Possible options are:
    - "copy" Copy the configuration item instead of moving it. This means that the configuration item will not be deleted from <oldfile>/<oldgroup>.
    - "overwrite" Normally, a configuration item is not moved if an item with the new name already exists. When this option is specified the old configuration item will overwrite any existing item.
    • Key=<oldkey>,<newkey>
    • Key=<oldkey>
    Specifies that configuration information is read from the key <oldkey> and written to <newkey>. If you only specify <oldkey>, the information is read from as well as written to <oldkey>.
    • AllKeys
    Specifies that all configuration information in the selected group should be moved (All keys).
    • AllGroups
    Specifies that all configuration information from all keys in all groups should be moved.
    • RemoveKey=<oldkey>
    Specifies that <oldkey> is removed from the selected group. This can be used to remove obsolete entries or to force a revert to default values.

    Example update file

    # This is comment
    
    Version=5
    Id=kde2.2
    File=kioslaverc,kio_httprc
    Group=Proxy Settings
    Key=NoProxyFor
    Key=UseProxy
    Key=httpProxy,Proxy
    Group=Cache Settings,Cache
    Key=MaxCacheSize
    Key=UseCache
    Group=UserAgent
    AllKeys
    RemoveGroup=KDE
    # End of file
    

    The above update file extracts config information from the file kioslaverc and stores it into the file kio_httprc.

    It reads the keys "NoProxyFor", "UseProxy" and "httpProxy" from the group "Proxy Settings" in the kioslaverc file. If any of these options are present they are written to the keys "NoProxyFor", "UseProxy" and "Proxy" (!) in the group "Proxy Settings" in the kio_httprc file.

    It also reads the keys "MaxCacheSize" and "UseCache" from the group "Cache Settings" in the kioslaverc file and writes this information to the keys "MaxCacheSize" and "UseCache" in the group "Cache" (!) in the kio_httprc file.

    Then it takes all keys in the "UserAgent" group of the file "kioslaverc" and moves then to the "UserAgent" group in the kio_httprc file.

    Finally it removes the entire "KDE" group in the kioslaverc file.

    Further Examples

    The best way to learn how to write scripts and update files is to look at existing ones, for example the ones of KMail.

    Debugging and testing

    Testing update entries

    To test an *.upd file it may be convenient to manually run kconf_update, usually located at /usr/lib/kf5/kconf_update. This is particularly relevant if you are testing an update file for a program installed in a custom prefix that is not the same as the one of kded, because kde will not run kconf_update automatically.

    For example if you want to test the Okular update file okular.upd

    #Configuration update for Okular
    Version=5
    
    #Convert user-defined annotation tools to quick annotation tools
    Id=annotation-toolbar
    File=okularpartrc
    Group=Reviews
    Key=AnnotationTools,QuickAnnotationTools
    

    you can first make a copy of the config file you want to target to the test path .qttest/

    mkdir -p .qttest/config/
    cp ~/.config/okularpartrc ~/.qttest/config/
    

    then you can manually run kconf_update from the folder where okular.upd is located

    /usr/lib/kf5/kconf_update ./okular.upd --debug --testmode
    

    The --testmode flag allows you to use test directories under ~/.qttest to stay away the user's real files, while the --debug flag enables useful debugging messages displaying what kconf_update is doing.

    If the rule is applied correctly, the command displays the following output

    Automatically enabled the debug logging category kf5.kconfig.update
    kf5.kconfig.update: Checking update-file "/opt/install_prefix/share/kconf_update/okular.upd" for new updates
    kf5.kconfig.update: "okular.upd" : Found new update "annotation-toolbar"
    kf5.kconfig.update: "okular.upd" : Updating "okularpartrc" : "Reviews" : "QuickAnnotationTools" to "<tool type=\"note-linked\" id=\"1\">..."
    kf5.kconfig.update: "okular.upd" : Removing "okularpartrc" : "Reviews" : "AnnotationTools" , moved.
    

    The configuration file ~/.qttest/config/okularpartrc should now have the following key indicating that it has been updated using the update rule okular.upd:annotation-toolbar

    [$Version]
    update_info=okular.upd:annotation-toolbar
    

    If you now run kconf_update, the update rule will not be applied again because kconf_update registered that it has already been applied. To test the update rule again you have to:

    1. copy the old configuration file ~/.config/okularpartrc over the updated one ~/.qttest/config/okularpartrc
    2. remove the [$Version] settings group from the configuration file
    3. remove the okular:annotation-toolbar entry from ~/.config/kconf_updater


    Debugging update scripts

    If you are developing a kconf_update script and want to test or debug it you need to make sure kconf_update runs again after each of your changes. There are a number of ways to achieve this.

    The easiest is to not install the kconf_update script in the first place, but manually call it through a pipe. If you want to test the update script for your application KHello's config file khellorc, you can test by using

    cat ~/.local/share/config/khellorc | khello_conf_update.sh
    

    (assuming khello_conf_update.sh is the kconf_update script and ~/.local/share is your $XDG_DATA_HOME). This is easier than installing every time, but has the obvious downside that you need to 'parse' your script's output yourself instead of letting kconf_update do it and check the resulting output file.

    After 'make install' the kconf_update script is run by kded, but it does so only once. This is of course the idea behind it, but while developing it can be a problem. You can increase the revision number for each subsequent run of 'make install' to force a new kconf_update run, but there's a better approach that doesn't skyrocket the version number for a mediocre debug session.

    kded doesn't really ignore scripts that it has already run right away. Instead it checks the affected config file every time a .upd file is added or changed. The reason it still doesn't run again on your config file lies in the traces kconf_update leaves behind: it adds a special config group '[$Version]' with a key 'update_info'. This key lists all kconf_update scripts that have already been run on this config file. Just remove your file's entry, 'make install', and kconf_update will happily run your script again, without you having to increase the version number.

    After KDE Frameworks 5.57 status updates of kconf_update are run through QDebug and may be controlled in any way other QDebugs may be controlled. Notably, by default, debug output is not generated unless the category kf5.kconfig.update is explicitly enabled and will be printed to stderr and consequently end up in xsession-errors or wayland-errors. If Qt was built with support for logging to system log facilities (such as systemd-journald) the output may be found there instead. Before 5.57 the output was always sent to stderr and may be found in the aforementioned errors files.

    Common Problems

    kconf_update refuses to update an entry

    If you change the value of an entry without changing the key or file, make sure to tell kconf_update that it should overwrite the old entry by adding "Options=overwrite".