On Thu, 2002-04-25 at 07:47, Geoffrey Talvola wrote: > Already partially done. Look at WebKit/Docs/Application.configlist and > WebKit/Docs/AppServer.configlist. These files are used to auto-generate the > documentation sections of the user's guide using > WebKit/DocSupport/config.py.
OnceAndOnlyOnce suggests that the foo.configlist should come from the same place as defaultConfig.
class ConfigurationOption: def __init__(self,name,default,help): ... class ConfigurationSchema: def __init__(self,namespace,version,options): ... def default(self,key): return self._optionMap[key].default def defaults(self): config = {} for opt in self._options: config[opt.name] = opt.default ... class Configureable: #configSchema() supercedes defaultConfig() #config() uses the schema #setting() can (optionally) warn if a key is requested that #is not in the schema def loadConfig(self,file): # factor out from userConfig """ can (optionally) warn if there are keys present in the file that are not in the schema (e.g. a setting gets refactored or removed, user upgrades and cannot figure out why his setting is now ignored.) """
# Application.py class Application(...): _configSchema = ConfigSchema( "Application", "0.7", [ ConfigOption("PrintConfigAtStartup", 1, "does what it says"), ConfigOption("AdminPassword","webware", "blah blah blah"), ...]) def configSchema(self): return self._configSchema
documentation and code are less likely to get out of sync
developers are more likely to provide documentation consistently
when schema changes, things are less likely to break without giving a clue as to what the problem is
config files can be upgraded automatically (if versioning is implemented)
an introspective tool can be written for configuring webware components/applications
if setting names or default values change, they change in one place.
future proofing:
In Application, there are a dozen settings that deal with error handling, half of a dozen that deal with sessions, and a few that are already dictionaries with only an informal internal structure.
It would be nice to be able to group these into their own schema with a separate namespace.
"AdminPassword" is in Application.config. If the current Admin context were to get replaced (or if the "ErrorEmail" stuff were to get refactored), it would be nice to be able to break these out into another config file.
it would be nice to be able to automatically upgrade .config files, either in an =upgrade.py= script, or as the file is read into memmory. This could accommodate name changes, namespace changes,
an option could be deprecated by adding a deprecated attribute to the ConfigOption.
an option could be marked as experimental in the same way.
a reserved "ConfigSchema" key/namespace to be included in all configuration files:
# foo.config { "ConfigSchema": { "Namespace": "Foo", "Version": "0.0.1", "Owner": "FooKit", } ... }
this could also extend to "inline" namespaces such as "ErrorControl" or "SessionControl": if a dictionary has a "ConfigSchema" key, it can be versioned and handled by the config tool and treated as a "namespace".
If a config file does not have a "ConfigSchema" key, it is treated as a legacy config with a mild suggestion that the user update the file to match current conventions.
e.g. current code does: application.setting("Debug")["Sessions"]. New code might say application.setting("ErrorControl")["EmailHost"] ... but this would get out of control quickly. Maybe Configurable could be made to handle "Debug.Sessions" or "ErrorControl.EmailHost"
Maybe Configurable should become a delegate instead of a superclass, then a refactored ErrorManager, could look up setting("EmailHost") which might delegate to application.setting("EmailHost",namespace="ErrorControl") or even:
import config host = config.setting("EmailHost",namespace=("Application","ErrorControl")) ...
OK. Lets calm down and take it one step at a time.
---++ Blue Sky
if ConfigOption could be related somehow to optik.Option, settings could be overridden on the startup command line. (OnceAndOnlyOnce again)
A simple type system could eliminate the need to look at the name for "Filename" or "Dir" in ConfigurableForServerSidePath. Use option.type == TYPE_SERVER_PATH as the predicate.
-- TerrelShumway - 25 Apr 2002