-
Notifications
You must be signed in to change notification settings - Fork 141
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix custom config reference syntax for
diff-file
This replaces the implementation for custom configparser option references in the diff-file option. Moves detection and handling for the custom syntax into a dedicated submodule. Uses a regular expression to preserve text before and after the reference.
- Loading branch information
1 parent
29790f2
commit d6fbfe3
Showing
4 changed files
with
148 additions
and
11 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
""" | ||
Custom configparser section/option reference syntax for the diff-file option. | ||
diff-file supports a "section reference" syntax for it's value: | ||
[mirror] | ||
... | ||
diff-file = /folder{{ <SECTION>_<OPTION> }}/more | ||
<SECTION> matches a configparser section and <OPTION> matches an option in that section. | ||
The portion of the diff-file value delimited with {{ and }} is replaced with the | ||
value from the specified option, which should be a string. | ||
The configparser module's ExtendedInterpolation feature is preferred to this custom syntax. | ||
""" | ||
|
||
import re | ||
from configparser import ConfigParser, NoOptionError, NoSectionError | ||
|
||
# Pattern to check if a string contains a custom section reference | ||
_LEGACY_REF_PAT = r".*\{\{.+_.+\}\}.*" | ||
|
||
# Pattern to decompose a custom section reference into parts | ||
_LEGACY_REF_COMPONENT_PAT = r""" | ||
# capture everything from start-of-line to the opening '{{' braces into group 'pre' | ||
^(?P<pre>.*)\{\{ | ||
# restrict section names to ignore surrounding whitespace (different from | ||
# configparser's default SECTRE) and disallow '_' (since that's our separator) | ||
\s* | ||
(?P<section>[^_\s](?:[^_]*[^_\s])) | ||
# allow (but ignore) whitespace around the section-option delimiter | ||
\s*_\s* | ||
# option names ignore surrounding whitespace and can include any character, but | ||
# must start and end with a non-whitespace character | ||
(?P<option>\S(?:.*\S)?) | ||
\s* | ||
# capture from the closing '}}' braces to end-of-line into group 'post' | ||
\}\}(?P<post>.*)$ | ||
""" | ||
|
||
|
||
def has_legacy_config_ref(value: str) -> bool: | ||
return re.match(_LEGACY_REF_PAT, value) is not None | ||
|
||
|
||
def eval_legacy_config_ref(config: ConfigParser, value: str) -> str: | ||
match_result = re.match(_LEGACY_REF_COMPONENT_PAT, value, re.VERBOSE) | ||
|
||
if match_result is None: | ||
raise ValueError(f"Unable to parse config option reference from '{value}'") | ||
|
||
pre, sect_name, opt_name, post = match_result.group( | ||
"pre", "section", "option", "post" | ||
) | ||
|
||
try: | ||
ref_value = config.get(sect_name, opt_name) | ||
return pre + ref_value + post | ||
except (NoSectionError, NoOptionError) as exc: | ||
raise ValueError(exc.message) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters