UpdateSettings
From GoboLinux Knowledge Base
The UpdateSettings tool is most commonly called by InstallPackage and Compile to ensure that any configuration files necessary for a program to function properly are placed in /Programs/*/Settings, where they belong. The default behavior is to show all of the changes to the user and ask the user what to do, but less-interactive 'quick' and 'auto' modes are also available, which try to guess at what the user wants based on settings in UpdateSettings.conf and any Hints provided by the recipe/package author.
Contents |
[edit] Usage
UpdateSettings [<options>] [<mode>] <program> [<version>]
[edit] Options
- -h, --help
Shows a page of help similar to this one, but with slightly less explanation. The help page you get will correctly show what the default update mode is on your configuration. - -v, --version
Show program version - -V, --verbose
Enable verbose mode. - -d, --diffs
When a file has been modified, show differences. Whenever UpdateSettings prompts a user for instructions when this option is on, before asking what to do, it'll show a diff in unified format between the currently-installed settings file, and the new default settings file. - -c, --check
Only check whether current settings differ from the defaults. Returns a nonzero value if they do. - -r, --report
Only report whether current settings and defaults differ. Logs a one-line message, and returns a nonzero value if the settings are indeed different. - -l, --list
List files that differ between current settings and defaults. This will generate a report similar to this:
-
1 mod: Settings/a 2 new: Current/Resources/Defaults/Settings/b 3 del: Settings/d
- showing files that (1) differ from the new default, (2) only exist in the new default, not the installed settings and (3) exist in the installed settings, but not the default. This list is also displayed when actually updating.
- -u, --update
Actually tries to update the settings
[edit] Update Modes
- -a, --auto
Update automatically, without prompting the user at any point. For each file, this mode tries the various update commands at its disposal until it either successfully updates the file, or has to give up and move on to the next one. All permissible commands listed in the hints file and update order are attempted in turn, with the exception of prompt_user. - -i, --interactive
Update interactively, prompting the user before each change. This option completely ignores both hints and update order, and promts the user for every operation. Unless a different defaultMode set in UpdateSettings.conf, this option is the default. - -q, --quick
Quickly update, prompting only when there are conflicts. The only difference between --quick and --auto modes is that --quick mode will honour any prompt_user instructions that occur.
[edit] Configuring UpdateSettings
In order to maintain compatiblity with versions of UpdateSettings that existed before the days of auto_merge, UpdateSettings without any configuration doesn't use any of its more powerful features. Hints will be ignored entirely, and unless you specify --quick or --auto on the command line, you'll have to answer a question for every file. If you want to take advantage of some of the new behavior that's been added, you'll need to configure things a bit.
[edit] Update Commands
The --auto and --quick modes work by collecting a list of commands to attempt for each modified file, then trying them one at a time until one succeeds. Most of the configuration involves specifying which of these commands are acceptible, and the order in which to try them.
[edit] Basic Commands
- prompt_user
- Displays a classic-UpdateSettings-style prompt, showing which file is currently being considered, a diff (if the caller specified -d), and a list of available options, then tries to do whatever the user says to do. This command always succeeds (moving UpdateSettings on to the next file), and is the only command available for --interactive mode, regardless of settings.
- skip
- Does absolutely nothing and moves on to the next file. This will ususally Log a message indicating what it's not doing.
- fail
- Does nothing to the current file and moves on. This command is effectively the same as skip, the only difference being that fail will always Log an error (red text in your console) indicating that something went wrong.
[edit] Commands for New Files
These commands are only availabe for files that exist in Defaults, but not in the Settings tree of the currently symlinked version.
- create
- Creates a copy of the default file in the Settings tree.
- dont_create
- Should be farily obvious. Effectively identical to skip, except for in when it's available.
- check_delete
- Checks whether this file has existed before (in the defaults of the previously-symlinked version). If it's a brand new file, UpdateSettings creates a copy of it. If the user has explicitly deleted it once before, UpdateSettings doesn't create a new one.
[edit] Commands for Deleted Files
These commands are only available for files that exist in the currently symlinked Settings tree, but not in Defaults.
- delete
- Deletes the file in the Settings tree
- dont_delete
- Another alias for skip, only available for deleted files
- check_create
- Compares this file with the previous Defaults. If it's something the user has created or modified, the check_create command fails, and UpdateSettings moves on to the next command. If it's something UpdateSettings put there, it'll be deleted.
[edit] Commands for Modified Files
These commands pertain to files that exist both in the symlinked Settings and in the new Defaults.
- overwrite
- Deletes the file in the Settings tree and replaces it with a copy of the file from the Defaults tree.
- dont_change
- Another skip alias
- auto_merge
- Auto-merge is both the most powerful and most difficult to explain command. Basically, it tries to combine any changes made to the Defaults by the recipe/package authors with any changes made to the Settings tree by the user. For more details, there is a separate section on how auto_merge works.
[edit] UpdateSettings.conf
This is the configuration file for UpdateSettings. Like most of the Scripts configuration files, this file is really just a shell script where you're supposed to set some variables. This doesn't mean you should put any shell code in this file, but it does mean that you have to follow the normal shell scripting variable assignment syntax, which is case- and spacing-sensitive. For example, this will work:
hintsEnabled=yes
but this will not:
hintsEnabled = Yes
And so, without further ado, here are the various options supported by UpdateSettings.conf
[edit] defaultMode=<interactive|quick|auto>"
default: interactive
If no Update Mode is explicitly specified on the command line, UpdateSettings will use whichever mode is specified by this option. See the section on update modes for more information.
[edit] hintsEnabled=<yes|no>
default: no
This setting determines whether or not UpdateSettings will honour the hints provided by the recipe author.
[edit] hintsAllowed=(<array>)
default: unset
When this option is set, and when hintsEnabled=yes, UpdateSettings will only honour hinted commands that occur in this list. If you're worried that a recipe or package author might have a *:delete line in their hints file, you can use this option to limit the Hints feature to operations you've explicitly approved. The order in which stuff occurs in this array doesn't matter.
If you only want to allow hints to commands you have in your update order, you can do so with a line like this:
hintsAllowed=( "${updateOrder[@]}" )
Which, of course, will only work if it occurs in the .conf file after updateOrder.
[edit] mergeChecker=<program>|disable
default: MergeSucceeded.rb This refers to a program to run to check whether the auto_merge operation succeeded. The program will be called with the following arguments:
MergeSucceeded.rb <old_file> <user_file> <default_file> <new_file> "$mergeFuzz"
This program is expected to exit successfully (with a 0) if there is no discrepancy, or 1 if auto_merge should try something else. This check is above and beyond the checks that /Programs/Patch does to make sure that merging settings succeeded. MergeSucceeded.rb basically does an index of the file. It was written on the undertaking that most config files are in a line-by-line syntax, and generally are in the form nameOfSetting[:= ]valueOfSetting, and uses this assumption to look for duplicated sections in the configuration files it checks, in an effort to detect the case where the recipe maintainer added a line, the user added the same line in a different place, and both made it into the patched output.
[edit] mergeFuzz=<number>
default: 1 Sets how much 'fuzz' the merge checker is supposed to tolerate. More 'fuzz' means more merges will be considered a success, but it also increases the chance of a false positive.
[edit] updateOrder=(<array>)
default: ( create dont_delete prompt_user auto_merge fail )
This array determines which commands you would like UpdateSettings to try, and the order in which you want it to try them. If hints are enabled, hinted commands will be attempted before the commands in this list. As soon as one of these commands succeeds, UpdateSettings will move on to the next file.
[edit] versionCheckingMethod=<ctime|mtime|atime|GuessLatest>"
default: mtime
Auto-Merge and the check_* commands (which are actually a side-effect of Auto-Merge) depend on knowing what version of the Program being updated was installed previously. UpdateSettings tries to guess which version to use, based on whichever option versionCheckingMethod is set to.
- ctime
- When the folder containing each version was created. Note that on my /Programs partition (ReiserFS), this field does not exist, so the results are complete garbage.
- mtime
- When the folder containing each version was last modified.
- atime
- When the folder containing each version was last accessed. Unfortunately 'accessed' to a computer includes things like
updatedband the like, so I wouldn't recommend this one. - GuessLatest
- Gobo's own version number comparing script. This generally produces good results, but there are some cases when projects change their version numbering scheme in such a way that breaks it.
I don't recommend changing this setting. mtime worked quite well for me in testing, but your mileage may vary depending on your filesystem. A good way to tell whether something is going to work well is to check a few folders with ls, using its various sorting options (see man ls for more information) to see whether the version numbers get sorted in a more-or-less sane way.
[edit] Hints
In the --auto and --quick modes of operation, UpdateSettings by default, will try to follow any valid operation instructions instructions specified in the Hints File in the order that they occur. In the event that those fail, it'll proceed with the normal list of things to try, unless the hints file explicitly requests a skip or fail operation.
[edit] How Auto-Merge Works
Somewhere in the darkest, most obscure corner of the basement Gobo's lair, there lurks a magical furry creature that emerges, tweaks your settings, then retreats into the darkness, happy that your settings work. This is, of course, false, and there really is some logic to what happens instead.
The auto_merge function uses the provided versionCheckingMethod to determine which version of the program was installed most recently. It then does a three-way comparison among the old version default, current version default, and the file in the currently-active Settings tree.
Before attempting anything complicated, auto_merge will check for a couple of simple conditions:
- If the user hasn't changed their settings from the old defaults, their settings are automatically updated to the new defaults.
- If the defaults haven't changed between versions, then the active settings are left untouched.
- If the file doesn't exist in the new defaults, and the user hasn't changed that file in their active configuration, then the active settings are deleted.
If none of those conditions is true, then auto_merge will attempt to create a patched file where the differences between the new defaults and the old defaults, and the differences between the active settings and the old defaults are combined. In order to prevent the configuration from being corrupted, if the patch binary returns a nonzero status, or if the patches created have any failed hunks, the results are discarded entirely.
Until it arrives at a perfect combination of changes, auto_merge will try the same process up to three times using different command line options for the 'diff' tool each time. If all three attempts fail, then the auto_merge operation is considered a failure, auto_merge will delete all its temporary files, and UpdateSettings will try the next operation in its list of instructions.
[edit] Limitations of Auto-Merge
Nothing is really perfect. Mystical basement squirrels are not perfect, and neither is auto_merge.
- The fact that it computes 9 diffs and attempts 9 patches before giving up may take quite a while if it's working on a large file. It tries the options that worked most often for me in testing first, but your mileage may vary, and auto_merge is not an AI.
- If the same line was changed both in the active settings and the new defaults, auto-merge will fail, since it's unclear which setting is 'correct,' and auto_merge is not clarvoyant.
- If ajacent lines are changed in the active settings and the new defaults (say, for example, the user changed line 12 and the recipe maintainer changed line 13), auto-merge might succeed, but probably will fail. If the diffs generated by comparing files overlap, patch will probably reject them, and auto_merge is not its own patching program.
- If you add a section to your configuration, and the recipe maintainer adds the same section in a different place, both versions of that configuration might end up in auto-merge's output, and auto-merge may not notice. There is a special check for this, but it may miss something depending on the syntax of your configuration file. auto_merge is not perfect.
- Keep in mind that auto-merge can't actually parse settings. Everything it's doing is based on comparing lines of text.


