mirror of
https://github.com/conan-io/conan-center-index.git
synced 2025-08-15 11:08:38 +00:00
(#13274) linters: Add annotations for YAML lint + add schema verification for config.yml
and conandata.yml
* first attempt at a yaml linter wit github actions output * This is less strict but has more information * fixup message * run config linter in Action * better ux feedback * try to use newlines https://github.com/actions/toolkit/issues/193#issuecomment-605394935 * clean up * fixup file name * trying custom class for quoted str * underlying yaml parser does not keep quotes * trying to catch ints as problems * remove test code * and to "linter testing" * install deps * run new linter unconditionally * revert testing changes * new script for conandata (this one is much harder to spec) * debugging * lets see all the errors * yamale -s ../linter/config_yaml_schema.yml aaf/config.yml from linters folder as a test * adjust script to match meeting discussion * make sure the docs and linters match * fix link * Update conandata.yml * exit 1 is not needed with annotations * add annotation matchers for yaml since those do do much * fix search for type * fix whitespace * tryout a yamllint file with a better looking matcher * copy syntax from readme * test if it's running in the wrong dir 🤔 * try with debug output * bump since i dont have permissions * bump - dont glob star * bump * less star globs * also add action to conandata way * bump * drop action for cli + matcher * more docs around linters * fix file and name * cleanup
This commit is contained in:
82
linter/conandata_yaml_linter.py
Normal file
82
linter/conandata_yaml_linter.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import argparse
|
||||
from strictyaml import (
|
||||
load,
|
||||
Map,
|
||||
Str,
|
||||
YAMLValidationError,
|
||||
MapPattern,
|
||||
Optional,
|
||||
Seq,
|
||||
Enum,
|
||||
Any,
|
||||
)
|
||||
from yaml_linting import file_path
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Validate Conan's 'conandata.yaml' file to ConanCenterIndex's requirements."
|
||||
)
|
||||
parser.add_argument(
|
||||
"path",
|
||||
nargs="?",
|
||||
type=file_path,
|
||||
help="file to validate.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
patch_fields = Map(
|
||||
{
|
||||
"patch_file": Str(),
|
||||
"patch_description": Str(),
|
||||
"patch_type": Enum(
|
||||
["official", "conan", "portability", "backport", "vulnerability"]
|
||||
),
|
||||
Optional("patch_source"): Str(),
|
||||
Optional("sha256"): Str(), # Really uncommon
|
||||
# No longer required for v2 recipes with layouts
|
||||
Optional("base_path"): Str(),
|
||||
}
|
||||
)
|
||||
schema = Map(
|
||||
{
|
||||
"sources": MapPattern(Str(), Any(), minimum_keys=1),
|
||||
Optional("patches"): MapPattern(Str(), Seq(patch_fields), minimum_keys=1),
|
||||
}
|
||||
)
|
||||
|
||||
with open(args.path) as f:
|
||||
content = f.read()
|
||||
|
||||
try:
|
||||
parsed = load(content, schema)
|
||||
|
||||
if "patches" in parsed:
|
||||
for version in parsed["patches"]:
|
||||
patches = parsed["patches"][version]
|
||||
for i, patch in enumerate(patches):
|
||||
type = parsed["patches"][version][i]["patch_type"]
|
||||
if (
|
||||
type in ["official", "backport", "vulnerability"]
|
||||
and not "patch_source" in patch
|
||||
):
|
||||
print(
|
||||
f"::warning file={args.path},line={type.start_line},endline={type.end_line},"
|
||||
f"title='patch_type' should have 'patch_source'"
|
||||
"::As per https://github.com/conan-io/conan-center-index/blob/master/docs/conandata_yml_format.md#patches-fields"
|
||||
" it is expected to have a source (e.g. a URL) to where it originates from to help with reviewing and consumers to evaluate patches\n"
|
||||
)
|
||||
except YAMLValidationError as error:
|
||||
e = error.__str__().replace("\n", "%0A")
|
||||
print(
|
||||
f"::error file={args.path},line={error.context_mark.line},endline={error.problem_mark.line},"
|
||||
f"title=config.yml schema error"
|
||||
f"::{e}\n"
|
||||
)
|
||||
except error:
|
||||
e = error.__str__().replace("\n", "%0A")
|
||||
print(f"::error ::{e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user