I'd like UCI to add only those options which don't exist and sort all options within each section.
Every time UCI settings are changed they seem to occur in random order. This makes it impossible to do a simple file compare to find the differences. UCI also adds duplicates of settings.
Many years ago win3 used ini files (which are essentially the same thing) and ini editors were much smarter.
Maybe I need to write changes to a file then use the -m option to merge the file.
Yes, I could believe it's hard to read/write UCI config files. But there's hope. You can use the UCI command line to make changes only to the lines you want. There's a brief outline of using UCI to do this in OpenWRT SSID Creation
I agree, that sorting is often convenient.
But the problem is more complicated than it seems.
Some configuration could depend on options order.
Some other could depend on sections order.
So it's impossible to apply sorting by default, otherwise it would break things.
Possible solution is providing a command uci sort [<config>].
Adding duplicates could also be useful.
May be not by default, but with some option like -D, --allow-duplicates.
Diff is actually missing.
And that's especially frustrating when you want to compare modified configuration with default one including custom formatting and comments.
It not only requires diffutils but also additional work to unify the formatting.
A bit OT but I have used augeas, it can handle a plethora of unix/linux config files, and it would probably be easy to add UCI files to it. It does not reorder stuff, handles comments etc. But the footprint is (without really knowing) probably too large for a router. But for a larger system it's a nice tool to update config files from shell scripts etc.
I find uci useful only for manual control or simple scrips.
Quite a few times I've had to have a script go and parse uci files in /etc/config/ directly with sed and awk (it's pretty easy, due to their syntax) and then run uci commit && reload_config to have the system load the changed configs.
You did it wrong then There's no single sane reason I can think of why that would be preferable over the shell API.
I agree that a sed/awk substitution approach would retain comments but since you mentioned uci commit (which rewrites and reformats the files) that couldn't have been the motivation.
Can you elaborate on that? Do you mean that you do not want a uci set foo.bar.baz=qrx to end up in the changes list of that option already was set to qrx?
This sounds like something that can be addressed by introducing a specialized uci diff command.
Can you try to better explain what you mean with this?
If it already exists it adds it again, ie duplicates it.
Maybe - A consistent order (unless changed for a reason) is important to me to allow comparing files from two configurations outside the modem with np++.
Can you provide a specific example on what you mean exactly? It is not possible to create duplicate options through the uci set command, I'm sure you're referring to something else.
Ah okay, so your problem is with add_list and not set. I guess it boils down to the way how add_list is defined as operation. It is supposed to merely append its value as item to a collection.
To make the example above idempotent, you'd need something like:
This is actually quite like e.g. iptables works. Invoking iptables -I ... or iptables -A ... multiple times will also results in duplicate rules unless each -A or -I is preceeded by a matching -D.
So what is needed to address your particular problem here is a new cli operation, e.g. replace_list conf.sect.opt=val (or maybe set_list is a better fitting name), which is defined as "append val to the list at conf.sect.opt unless the list already contains an item val".