-
Notifications
You must be signed in to change notification settings - Fork 384
Open
Milestone
Description
Realized in real-world nontrivial usage that we're still missing a useful config level: the task level.
Scenario
- Collection-level overrides setting, say,
run.hide = True, because most of yourruncalls should be silent (maybe you have a lot of explicit status output stuff using spinners, progress bars, etc) - Now you're inside a given task that you do want to be verbose by default, for whichever reason - violating that low-level collection-specified value. What levels are available to you?
- Config file levels are above collection-level, but those are all, well, globally applied - there's no way to limit the setting to just some tasks.
- Env var and overrides are the highest, and could technically work here, but you'd have to remember to specify them every time, which is a no-go (and they wouldn't help if you wanted to run >1 task in a session, only one of which wants to be verbose)
- You could manually modify your context at the top of the task, setting
c.run.hide = False. Great! Limited just to this task. - ...until you want to re-override that override at runtime, e.g. you don't actually want the normally chatty task to be chatty for once. "Context-level" or "user-level" manipulation of a "completed" config is absolute and cares not for any other level, so using global CLI flags or env vars doesn't help.
- You could give the task its own variant of
--hide(i.e.def mytask(hide=False)), then supply that value to the 'manual' override. This works, but requires two spots of boilerplate (signature and body code) and is poorly extensible (you'd have to do this for every task and for every config value that you want this treatment on).
Solution
The obvious solution is to allow @task to specify its own config level, which is slotted in above defaults, collection-level and config files, but below env var and overrides/CLI. This would fit in the hierarchy naturally (it's closer to runtime but doesn't win over those vectors) and should be relatively easy to implement, IIRC:
- Add
configureorconfigurationarg to@task/Taskaccepting a dict just likeCollection.configuredoes - Add the new level to
Config, plusConfig.load_task()(to mirrorload_collection()) Executorintrospects this data when it's performing config updates (inconfig_forprobably) and callsconfig.load_task(task.configuration)or whatnotConfighandles the hierarchy business- The user then sees a context/config that has the settings they expect
Other thoughts
This could also be used, directly or with some wrappers, to implement things like Fabric 1's @tasks/@roles, which are similarly task-level "configuration".