Skip to content

Commit 7e66a1c

Browse files
committed
Associate updating policies to shell-like globbing patterns.
Change the type of the policies argument to `must_install_file` from a dictionary to a list of tuples, where the first item in each tuple is a shell-like globbing pattern. This is slightly less efficient as it requires iterating over the entire list to find a matching policy (instead of the on-average constant access time of a hashtable), but is more convenient as it allows to have a single policy for an entire subtree. Notably, it allows to do policies.add(('src/sparql/*', ALWAYS)) to apply a ALWAYS policy to all files under `src/sparql`, without having to enumerate them all.
1 parent b97557a commit 7e66a1c

File tree

1 file changed

+33
-26
lines changed

1 file changed

+33
-26
lines changed

odk/odk.py

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import yaml
2020
import os
2121
import glob
22+
import fnmatch
2223
import subprocess
2324
import shutil
2425
from shutil import copy, copymode
@@ -877,7 +878,7 @@ def save_project_yaml(project : OntologyProject, path : str):
877878
with open(path, "w") as f:
878879
f.write(yaml.dump(json_obj, default_flow_style=False))
879880

880-
def unpack_files(basedir, txt, policies={}):
881+
def unpack_files(basedir, txt, policies=[]):
881882
"""
882883
This unpacks a custom tar-like format in which multiple file paths
883884
can be specified, separated by ^^^s
@@ -937,21 +938,33 @@ def must_install_file(templatefile, targetfile, policies):
937938
Given a template filename, indicate whether the file should be
938939
installed according to any per-file policy.
939940
940-
policies is a dictionary associating a template filename to one
941-
of the following three values:
942-
* IF_MISSING (default): install the file if it does not already exist
941+
policies is a list of (PATTERN,POLICY) tuples where PATTERN is
942+
a shell-like globbing pattern and POLICY is the update policy
943+
that should be applied to any template whose pathname matches
944+
the pattern.
945+
946+
Patterns are tested in the order they are found in the list,
947+
and the first match takes precedence over any subsequent match.
948+
If there is no match, the default policy is IF_MISSING.
949+
950+
Valid policies are:
951+
* IF_MISSING: install the file if it does not already exist
943952
* ALWAYS: always install the file, overwrite any existing file
944953
* NEVER: never install the file
945954
"""
946-
policy = policies.get(templatefile, IF_MISSING)
955+
policy = IF_MISSING
956+
for pattern, pattern_policy in policies:
957+
if fnmatch.fnmatch(templatefile, pattern):
958+
policy = pattern_policy
959+
break
947960
if policy == ALWAYS:
948961
return True
949962
elif policy == NEVER:
950963
return False
951964
else:
952965
return not os.path.exists(targetfile)
953966

954-
def install_template_files(generator, templatedir, targetdir, policies={}):
967+
def install_template_files(generator, templatedir, targetdir, policies=[]):
955968
"""
956969
Installs all template-derived files into a target directory.
957970
"""
@@ -1086,30 +1099,24 @@ def update(templatedir):
10861099
# missing (e.g. DOSDP example files) or on the contrary
10871100
# always reinstalled to overwrite any local changes (e.g.
10881101
# the main Makefile). We declare the corresponding policies.
1089-
policies = {}
1090-
policies['CODE_OF_CONDUCT.md'] = NEVER
1091-
policies['CONTRIBUTING.md'] = NEVER
1092-
policies['issue_template.md'] = NEVER
1093-
policies['README.md'] = NEVER
1094-
policies['src/patterns/data/default/example.tsv'] = NEVER
1095-
policies['src/patterns/dosdp-patterns/example.yaml'] = NEVER
1096-
policies['src/ontology/Makefile'] = ALWAYS
1097-
policies['src/ontology/run.sh'] = ALWAYS
1098-
policies['docs/odk-workflows'] = ALWAYS
1102+
policies = [
1103+
('CODE_OF_CONDUCT.md', NEVER),
1104+
('CONTRIBUTING.md', NEVER),
1105+
('issue_template.md', NEVER),
1106+
('README.md', NEVER),
1107+
('src/patterns/data/default/example.tsv', NEVER),
1108+
('src/patterns/dosdp-patterns/example.yaml', NEVER),
1109+
('src/ontology/Makefile', ALWAYS),
1110+
('src/ontology/run.sh', ALWAYS),
1111+
('src/sparql/*', ALWAYS),
1112+
('docs/odk-workflows/*', ALWAYS)
1113+
]
10991114
if 'github_actions' in project.ci:
11001115
for workflow in ['qc', 'diff', 'release-diff']:
11011116
if workflow in project.workflows:
1102-
policies['.github/workflows/' + workflow + '.yml'] = ALWAYS
1117+
policies.append(('.github/workflows/' + workflow + '.yml', ALWAYS))
11031118
if project.documentation is not None and 'docs' in project.workflows:
1104-
policies['github/workflows/docs.yml'] = ALWAYS
1105-
# HACK: For the odk-workflows documentation directory,
1106-
# we want to clean up that directory completely. The
1107-
# policy dictionary only works on files, so to force
1108-
# reinstalling the entire directory (also removing any
1109-
# non-standard file along the way), we forcefully
1110-
# remove the directory.
1111-
if project.documentation is not None:
1112-
shutil.rmtree('../../docs/odk-workflows')
1119+
policies.append(('.github/workflows/docs.yml', ALWAYS))
11131120

11141121
# Proceed with template instantiation, using the policies
11151122
# declared above. We instantiate directly at the root of

0 commit comments

Comments
 (0)