update_deps¶
update_deps
task.
Update dependencies in a pyproject.toml
file.
ignore_version(current, latest, version_rules, semver_rules)
¶
Determine whether the latest version can be ignored.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
current |
list[str] |
The current version as a list of version parts. It's expected, but not required, the version is a semantic version. |
required |
latest |
list[str] |
The latest version as a list of version parts. It's expected, but not required, the version is a semantic version. |
required |
version_rules |
"list[dict[Literal['operator', 'version'], str]]" |
Version ignore rules. |
required |
semver_rules |
"dict[Literal['version-update'], list[Literal['major', 'minor', 'patch']]]" |
Semantic version ignore rules. |
required |
Returns:
Type | Description |
---|---|
bool |
Whether or not the latest version can be ignored based on the version and semantic version ignore rules. |
Source code in ci_cd/tasks/update_deps.py
def ignore_version(
current: list[str],
latest: list[str],
version_rules: "list[dict[Literal['operator', 'version'], str]]",
semver_rules: "dict[Literal['version-update'], list[Literal['major', 'minor', 'patch']]]", # pylint: disable=line-too-long
) -> bool:
"""Determine whether the latest version can be ignored.
Parameters:
current: The current version as a list of version parts. It's expected, but not
required, the version is a semantic version.
latest: The latest version as a list of version parts. It's expected, but not
required, the version is a semantic version.
version_rules: Version ignore rules.
semver_rules: Semantic version ignore rules.
Returns:
Whether or not the latest version can be ignored based on the version and
semantic version ignore rules.
"""
# ignore all updates
if not version_rules and not semver_rules:
# A package name has been specified without specific rules, ignore all updates
# for package.
return True
# version rules
if _ignore_version_rules(latest, version_rules):
return True
# semver rules
if "version-update" in semver_rules and _ignore_semver_rules(
current, latest, semver_rules
):
return True
return False
parse_ignore_entries(entries, separator)
¶
Parser for the --ignore
option.
The --ignore
option values are given as key/value-pairs in the form:
key=value...key=value
. Here ...
is the separator value supplied by
--ignore-separator
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
entries |
list[str] |
The list of supplied |
required |
separator |
str |
The supplied |
required |
Returns:
Type | Description |
---|---|
'dict[str, dict[Literal["versions", "update-types"], list[str]]]' |
A parsed mapping of dependencies to ignore rules. |
Source code in ci_cd/tasks/update_deps.py
def parse_ignore_entries(
entries: list[str], separator: str
) -> 'dict[str, dict[Literal["versions", "update-types"], list[str]]]':
"""Parser for the `--ignore` option.
The `--ignore` option values are given as key/value-pairs in the form:
`key=value...key=value`. Here `...` is the separator value supplied by
`--ignore-separator`.
Parameters:
entries: The list of supplied `--ignore` options.
separator: The supplied `--ignore-separator` value.
Returns:
A parsed mapping of dependencies to ignore rules.
"""
ignore_entries: 'dict[str, dict[Literal["versions", "update-types"], list[str]]]' = (
{}
)
for entry in entries:
pairs = entry.split(separator, maxsplit=2)
for pair in pairs:
if separator in pair:
raise InputParserError(
"More than three key/value-pairs were given for an `--ignore` "
"option, while there are only three allowed key names. Input "
f"value: --ignore={entry}"
)
ignore_entry: 'dict[Literal["dependency-name", "versions", "update-types"], str]' = ( # pylint: disable=line-too-long
{}
)
for pair in pairs:
match = re.match(
r"^(?P<key>dependency-name|versions|update-types)=(?P<value>.*)$",
pair,
)
if match is None:
raise InputParserError(
f"Could not parse ignore configuration: {pair!r} (part of the "
f"ignore option: {entry!r}"
)
if match.group("key") in ignore_entry:
raise InputParserError(
"An ignore configuration can only be given once per option. The "
f"configuration key {match.group('key')!r} was found multiple "
f"times in the option {entry!r}"
)
ignore_entry[match.group("key")] = match.group("value").strip() # type: ignore[index] # pylint: disable=line-too-long
if "dependency-name" not in ignore_entry:
raise InputError(
"Ignore option entry missing required 'dependency-name' "
f"configuration. Ignore option entry: {entry}"
)
dependency_name: str = ignore_entry.pop("dependency-name", "")
if dependency_name not in ignore_entries:
ignore_entries[dependency_name] = {
key: [value] for key, value in ignore_entry.items() # type: ignore[misc]
}
else:
for key, value in ignore_entry.items():
ignore_entries[dependency_name][key].append(value) # type: ignore[index]
return ignore_entries
parse_ignore_rules(rules)
¶
Parser for a specific set of ignore rules.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
rules |
"dict[Literal['versions', 'update-types'], list[str]]" |
A set of ignore rules for one or more packages. |
required |
Returns:
Type | Description |
---|---|
"tuple[list[dict[Literal['operator', 'version'], str]], dict[Literal['version-update'], list[Literal['major', 'minor', 'patch']]]]" |
A tuple of the parsed 'versions' and 'update-types' entries as dictionaries. |
Source code in ci_cd/tasks/update_deps.py
def parse_ignore_rules(
rules: "dict[Literal['versions', 'update-types'], list[str]]",
) -> "tuple[list[dict[Literal['operator', 'version'], str]], dict[Literal['version-update'], list[Literal['major', 'minor', 'patch']]]]": # pylint: disable=line-too-long
"""Parser for a specific set of ignore rules.
Parameters:
rules: A set of ignore rules for one or more packages.
Returns:
A tuple of the parsed 'versions' and 'update-types' entries as dictionaries.
"""
if not rules:
# Ignore package altogether
return [{"operator": ">=", "version": "0"}], {}
versions: 'list[dict[Literal["operator", "version"], str]]' = []
update_types: "dict[Literal['version-update'], list[Literal['major', 'minor', 'patch']]]" = ( # pylint: disable=line-too-long
{}
)
if "versions" in rules:
for versions_entry in rules["versions"]:
match = re.match(
r"^(?P<operator>>|<|<=|>=|==|!=|~=)\s*"
r"(?P<version>[0-9]+(?:\.[0-9]+){0,2})$",
versions_entry,
)
if match is None:
raise InputParserError(
"Ignore option's 'versions' value cannot be parsed. It "
"must be a single operator followed by a version number.\n"
f"Unparseable 'versions' value: {versions_entry!r}"
)
versions.append(match.groupdict()) # type: ignore[arg-type]
if "update-types" in rules:
update_types["version-update"] = []
for update_type_entry in rules["update-types"]:
match = re.match(
r"^version-update:semver-(?P<semver_part>major|minor|patch)$",
update_type_entry,
)
if match is None:
raise InputParserError(
"Ignore option's 'update-types' value cannot be parsed."
" It must be either: 'version-update:semver-major', "
"'version-update:semver-minor' or "
"'version-update:semver-patch'.\nUnparseable 'update-types' "
f"value: {update_type_entry!r}"
)
update_types["version-update"].append(match.group("semver_part")) # type: ignore[arg-type] # pylint: disable=line-too-long
return versions, update_types