From 2fa65eb5e12f14bf7a99179b2400e3193fe2f84a Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Fri, 12 Jun 2020 16:36:38 +0200 Subject: [PATCH] validate-modules: allow YAML dates in module documentation and meta/runtime.yml. (#70025) --- .../validate-modules/validate_modules/main.py | 14 ++++++++++++-- .../validate-modules/validate_modules/schema.py | 2 +- .../validate-modules/validate_modules/utils.py | 9 +++++++-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/test/lib/ansible_test/_data/sanity/validate-modules/validate_modules/main.py b/test/lib/ansible_test/_data/sanity/validate-modules/validate_modules/main.py index 56506fdebf3..667d65b5bff 100644 --- a/test/lib/ansible_test/_data/sanity/validate-modules/validate_modules/main.py +++ b/test/lib/ansible_test/_data/sanity/validate-modules/validate_modules/main.py @@ -93,6 +93,16 @@ OS_CALL_REGEX = re.compile(r'os\.call.*') LOOSE_ANSIBLE_VERSION = LooseVersion('.'.join(ansible_version.split('.')[:3])) +def compare_dates(d1, d2): + try: + date1 = parse_isodate(d1, allow_date=True) + date2 = parse_isodate(d2, allow_date=True) + return date1 == date2 + except ValueError: + # At least one of d1 and d2 cannot be parsed. Simply compare values. + return d1 == d2 + + class ReporterEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, Exception): @@ -1126,7 +1136,7 @@ class ModuleValidator(Validator): # to make comparison possible and to avoid confusing the user. documentation_date = doc_deprecation.get('removed_at_date') documentation_version = doc_deprecation.get('removed_in') - if routing_date != documentation_date: + if compare_dates(routing_date, documentation_date): self.reporter.error( path=self.object_path, code='deprecation-mismatch', @@ -2174,7 +2184,7 @@ class ModuleValidator(Validator): if 'removed_at_date' in docs['deprecated']: try: removed_at_date = docs['deprecated']['removed_at_date'] - if parse_isodate(removed_at_date) < datetime.date.today(): + if parse_isodate(removed_at_date, allow_date=True) < datetime.date.today(): msg = "Module's deprecated.removed_at_date date '%s' is before today" % removed_at_date self.reporter.error(path=self.object_path, code='deprecated-date', msg=msg) except ValueError: diff --git a/test/lib/ansible_test/_data/sanity/validate-modules/validate_modules/schema.py b/test/lib/ansible_test/_data/sanity/validate-modules/validate_modules/schema.py index e14d4919b2f..0905a3c0f40 100644 --- a/test/lib/ansible_test/_data/sanity/validate-modules/validate_modules/schema.py +++ b/test/lib/ansible_test/_data/sanity/validate-modules/validate_modules/schema.py @@ -37,7 +37,7 @@ def _add_ansible_error_code(exception, error_code): def isodate(v, error_code=None): try: - parse_isodate(v) + parse_isodate(v, allow_date=True) except ValueError as e: raise _add_ansible_error_code(Invalid(str(e)), error_code or 'ansible-invalid-date') return v diff --git a/test/lib/ansible_test/_data/sanity/validate-modules/validate_modules/utils.py b/test/lib/ansible_test/_data/sanity/validate-modules/validate_modules/utils.py index 1a350213737..939ae651da8 100644 --- a/test/lib/ansible_test/_data/sanity/validate-modules/validate_modules/utils.py +++ b/test/lib/ansible_test/_data/sanity/validate-modules/validate_modules/utils.py @@ -199,8 +199,13 @@ class NoArgsAnsibleModule(AnsibleModule): self.params = {'_ansible_selinux_special_fs': [], '_ansible_remote_tmp': '/tmp', '_ansible_keep_remote_files': False, '_ansible_check_mode': False} -def parse_isodate(v): - msg = 'Expected ISO 8601 date string (YYYY-MM-DD)' +def parse_isodate(v, allow_date): + if allow_date: + if isinstance(v, datetime.date): + return v + msg = 'Expected ISO 8601 date string (YYYY-MM-DD) or YAML date' + else: + msg = 'Expected ISO 8601 date string (YYYY-MM-DD)' if not isinstance(v, string_types): raise ValueError(msg) # From Python 3.7 in, there is datetime.date.fromisoformat(). For older versions,