Skip to content

Commit 93f41cf

Browse files
committed
site-wide default config
1 parent 42cdb95 commit 93f41cf

File tree

3 files changed

+111
-18
lines changed

3 files changed

+111
-18
lines changed

README.md

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,49 @@ moving the conda environment.
162162

163163
No registry edits, no GPO, no per-user configuration needed.
164164

165+
### Site-wide default configuration (all-users installs)
166+
167+
When picasso-workflow is installed for all users, individual users may not
168+
have their own `config.yaml` yet. An administrator can place a shared
169+
default at:
170+
171+
| Platform | Site config path |
172+
|---|---|
173+
| Windows | `C:\ProgramData\picasso_workflow\config.yaml` |
174+
| macOS / Linux | `/etc/picasso_workflow/config.yaml` |
175+
176+
Config files are **deep-merged** in this priority order (highest wins):
177+
178+
1. Per-user — `~/.config/picasso_workflow/config.yaml`
179+
2. Site-wide — path above
180+
3. Bundled package default
181+
182+
Each file only needs to contain the keys it wants to override. For
183+
example, a site config that sets shared cluster and Confluence defaults
184+
while leaving everything else to the package default:
185+
186+
```yaml
187+
Confluence:
188+
URL: "https://confluence.example.com"
189+
Space: "PAINT"
190+
SlurmLoginNodes:
191+
hpccluster: hpcl8001
192+
ClusterEnvironment:
193+
anaconda_module: "anaconda/3/2023.03"
194+
conda_env: "picasso-workflow"
195+
```
196+
197+
Users then only need their own config if they want to override something
198+
specific (e.g. their personal Confluence page or a different template
199+
path). Keys they do not specify are inherited from the site config.
200+
201+
To create the directory and drop in the config on Windows (elevated prompt):
202+
203+
```powershell
204+
New-Item -ItemType Directory -Force "C:\ProgramData\picasso_workflow"
205+
# then copy or create config.yaml there
206+
```
207+
165208
### macOS deployment — single-user app bundle
166209

167210
On macOS the standard way to make a Python GUI launchable from Finder (or
@@ -197,8 +240,8 @@ easily accessible:
197240
to `~/Desktop` while holding `Cmd+Alt`
198241

199242
**Icon** — the script converts `picasso_workflow/picasso-workflow.ico`
200-
to the macOS `.icns` format automatically using `sips` and `iconutil`
201-
(both are built into macOS). No extra tools needed.
243+
to the macOS `.icns` format automatically using Pillow (installed with
244+
the package) and `iconutil` (built into macOS). No extra tools needed.
202245

203246
Re-run the script after upgrading the package or moving the conda
204247
environment.

picasso_workflow/__init__.py

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,26 +66,69 @@ def config_logger():
6666
)
6767

6868

69+
def _deep_merge(base: dict, override: dict) -> dict:
70+
"""Return a new dict with override merged on top of base, recursively."""
71+
result = base.copy()
72+
for key, val in override.items():
73+
if (
74+
key in result
75+
and isinstance(result[key], dict)
76+
and isinstance(val, dict)
77+
):
78+
result[key] = _deep_merge(result[key], val)
79+
else:
80+
result[key] = val
81+
return result
82+
83+
84+
def _site_config_path() -> Path:
85+
"""Return the platform-appropriate site-wide config path."""
86+
if sys.platform == "win32":
87+
base = Path(os.environ.get("ProgramData", r"C:\ProgramData"))
88+
else:
89+
base = Path("/etc")
90+
return base / "picasso_workflow" / "config.yaml"
91+
92+
93+
def _load_yaml(path) -> dict:
94+
with open(path, "r") as f:
95+
return yaml.safe_load(f) or {}
96+
97+
6998
def load_config():
70-
"""Load the picasso-workflow configuration yaml file"""
71-
# 1. User config path
72-
user_config = Path.home() / ".config" / "picasso_workflow" / "config.yaml"
73-
if user_config.exists():
74-
with open(user_config, "r") as f:
75-
return yaml.safe_load(f)
76-
# 2. Fallback to package default
99+
"""Load the picasso-workflow configuration yaml file.
100+
101+
Configs are deep-merged in increasing priority order so that
102+
higher-priority files only need to specify the keys they override:
103+
104+
1. Bundled package default (config.yaml / config_template.yaml)
105+
2. Site-wide admin config (C:\\ProgramData\\picasso_workflow\\config.yaml
106+
or /etc/picasso_workflow/config.yaml)
107+
3. Per-user config (~/.config/picasso_workflow/config.yaml)
108+
"""
109+
# 1. Package default
77110
try:
78-
default_config = importlib.resources.files("picasso_workflow").joinpath(
111+
pkg_config = importlib.resources.files("picasso_workflow").joinpath(
79112
"config.yaml"
80113
)
81-
with open(default_config, "r") as f:
82-
return yaml.safe_load(f)
83-
except FileNotFoundError:
84-
template_config = importlib.resources.files("picasso_workflow").joinpath(
114+
config = _load_yaml(pkg_config)
115+
except (FileNotFoundError, TypeError):
116+
template = importlib.resources.files("picasso_workflow").joinpath(
85117
"config_template.yaml"
86118
)
87-
with open(template_config, "r") as f:
88-
return yaml.safe_load(f)
119+
config = _load_yaml(template)
120+
121+
# 2. Site-wide admin config (optional)
122+
site_config = _site_config_path()
123+
if site_config.exists():
124+
config = _deep_merge(config, _load_yaml(site_config))
125+
126+
# 3. Per-user config (optional)
127+
user_config = Path.home() / ".config" / "picasso_workflow" / "config.yaml"
128+
if user_config.exists():
129+
config = _deep_merge(config, _load_yaml(user_config))
130+
131+
return config
89132

90133

91134
config_logger()

picasso_workflow/config_template.yaml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
# default located in picasso-workflow/picasso_workflow folder
2-
# user-specific version can be in ~/.config/picasso_workflow/config.yaml or %APPDATA%\picasso_workflow\config.yaml
1+
# Bundled package default — lowest priority.
2+
#
3+
# Config loading order (deep-merged, highest priority wins):
4+
# 1. Per-user: ~/.config/picasso_workflow/config.yaml
5+
# 2. Site-wide: C:\ProgramData\picasso_workflow\config.yaml (Windows)
6+
# /etc/picasso_workflow/config.yaml (macOS/Linux)
7+
# 3. This file: bundled package default
8+
#
9+
# Each file only needs to specify the keys it wants to override.
310
Templates:
411
TemplateName: "/local/path/to/template"
512
TestData:

0 commit comments

Comments
 (0)