Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/planemo/conda_lint.py @ 2:6af9afd405e9 draft
"planemo upload commit 0a63dd5f4d38a1f6944587f52a8cd79874177fc1"
| author | shellac |
|---|---|
| date | Thu, 14 May 2020 14:56:58 -0400 |
| parents | 26e78fe6e8c4 |
| children |
comparison
equal
deleted
inserted
replaced
| 1:75ca89e9b81c | 2:6af9afd405e9 |
|---|---|
| 1 """Logic for linting conda recipes.""" | |
| 2 | |
| 3 from __future__ import absolute_import | |
| 4 | |
| 5 from functools import wraps | |
| 6 | |
| 7 from galaxy.tool_util.deps.conda_compat import raw_metadata | |
| 8 from galaxy.util import unicodify | |
| 9 | |
| 10 from planemo.conda_verify.recipe import ( | |
| 11 check_build_number, | |
| 12 check_dir_content, | |
| 13 check_license_family, | |
| 14 check_name, | |
| 15 check_requirements, | |
| 16 check_source, | |
| 17 check_url, | |
| 18 check_version, | |
| 19 FIELDS, | |
| 20 get_field, | |
| 21 RecipeError, | |
| 22 ) | |
| 23 from planemo.exit_codes import ( | |
| 24 EXIT_CODE_GENERIC_FAILURE, | |
| 25 EXIT_CODE_OK, | |
| 26 ) | |
| 27 from planemo.io import ( | |
| 28 coalesce_return_codes, | |
| 29 find_matching_directories, | |
| 30 info, | |
| 31 ) | |
| 32 from planemo.lint import ( | |
| 33 handle_lint_complete, | |
| 34 setup_lint, | |
| 35 ) | |
| 36 | |
| 37 | |
| 38 def lint_recipes_on_paths(ctx, paths, **kwds): | |
| 39 """Apply conda linting procedure to recipes on supplied paths.""" | |
| 40 assert_tools = kwds.get("assert_recipes", True) | |
| 41 recursive = kwds.get("recursive", False) | |
| 42 exit_codes = [] | |
| 43 for recipe_dir in yield_recipes_on_paths(ctx, paths, recursive): | |
| 44 if lint_conda_recipe(ctx, recipe_dir, **kwds) != 0: | |
| 45 exit_codes.append(EXIT_CODE_GENERIC_FAILURE) | |
| 46 else: | |
| 47 exit_codes.append(EXIT_CODE_OK) | |
| 48 return coalesce_return_codes(exit_codes, assert_at_least_one=assert_tools) | |
| 49 | |
| 50 | |
| 51 def lint_conda_recipe(ctx, recipe_dir, **kwds): | |
| 52 info("Linting conda recipe %s" % recipe_dir) | |
| 53 lint_args, lint_ctx = setup_lint(ctx, **kwds) | |
| 54 | |
| 55 def apply(f): | |
| 56 lint_ctx.lint(f.__name__, f, recipe_dir) | |
| 57 | |
| 58 apply(lint_name) | |
| 59 apply(lint_version) | |
| 60 apply(lint_summary) | |
| 61 apply(lint_build_number) | |
| 62 apply(lint_directory_content) | |
| 63 apply(lint_license_family) | |
| 64 apply(lint_about_urls) | |
| 65 apply(lint_source) | |
| 66 apply(lint_fields) | |
| 67 apply(lint_requirements) | |
| 68 | |
| 69 return handle_lint_complete(lint_ctx, lint_args) | |
| 70 | |
| 71 | |
| 72 def wraps_recipe_error(is_error=True): | |
| 73 | |
| 74 def outer_wrapper(f): | |
| 75 | |
| 76 @wraps(f) | |
| 77 def wrapper(recipe_dir, lint_ctx): | |
| 78 try: | |
| 79 f(recipe_dir, lint_ctx) | |
| 80 except RecipeError as e: | |
| 81 if is_error: | |
| 82 lint_ctx.error(unicodify(e)) | |
| 83 else: | |
| 84 lint_ctx.warn(unicodify(e)) | |
| 85 except TypeError as e: # Errors in recipe checking code from YAML. | |
| 86 lint_ctx.error(unicodify(e)) | |
| 87 | |
| 88 return wrapper | |
| 89 | |
| 90 return outer_wrapper | |
| 91 | |
| 92 | |
| 93 def lints_metadata(f): | |
| 94 | |
| 95 @wraps(f) | |
| 96 def wrapper(recipe_dir, lint_ctx): | |
| 97 meta = raw_metadata(recipe_dir) | |
| 98 f(meta, lint_ctx) | |
| 99 | |
| 100 return wrapper | |
| 101 | |
| 102 | |
| 103 @wraps_recipe_error(is_error=False) | |
| 104 def lint_directory_content(recipe_dir, lint_ctx): | |
| 105 check_dir_content(recipe_dir) | |
| 106 lint_ctx.info("Directory content seems okay.") | |
| 107 | |
| 108 | |
| 109 @lints_metadata | |
| 110 @wraps_recipe_error(is_error=False) | |
| 111 def lint_license_family(meta, lint_ctx): | |
| 112 check_license_family(meta) | |
| 113 lint_ctx.info("License from vaild license family.") | |
| 114 | |
| 115 | |
| 116 @lints_metadata | |
| 117 def lint_summary(meta, lint_ctx): | |
| 118 summary = get_field(meta, 'about/summary') | |
| 119 | |
| 120 if not summary: | |
| 121 lint_ctx.warn("No summary supplied in about metadata.") | |
| 122 | |
| 123 if summary and len(summary) > 80: | |
| 124 msg = "summary exceeds 80 characters" | |
| 125 lint_ctx.warn(msg) | |
| 126 | |
| 127 | |
| 128 @lints_metadata | |
| 129 @wraps_recipe_error(is_error=False) | |
| 130 def lint_about_urls(meta, lint_ctx): | |
| 131 for field in ('about/home', 'about/dev_url', 'about/doc_url', | |
| 132 'about/license_url'): | |
| 133 url = get_field(meta, field) | |
| 134 if url: | |
| 135 check_url(url) | |
| 136 lint_ctx.info("About urls (if present) are valid") | |
| 137 | |
| 138 | |
| 139 @lints_metadata | |
| 140 @wraps_recipe_error(is_error=True) | |
| 141 def lint_source(meta, lint_ctx): | |
| 142 check_source(meta) | |
| 143 lint_ctx.info("Source (if present) is valid") | |
| 144 | |
| 145 | |
| 146 @lints_metadata | |
| 147 @wraps_recipe_error(is_error=True) | |
| 148 def lint_build_number(meta, lint_ctx): | |
| 149 build_number = get_field(meta, 'build/number', 0) | |
| 150 check_build_number(build_number) | |
| 151 lint_ctx.info("Valid build number [%s]" % build_number) | |
| 152 | |
| 153 | |
| 154 @lints_metadata | |
| 155 @wraps_recipe_error(is_error=True) | |
| 156 def lint_version(meta, lint_ctx): | |
| 157 version = get_field(meta, 'package/version') | |
| 158 check_version(version) | |
| 159 lint_ctx.info("Valid version number [%s]" % version) | |
| 160 | |
| 161 | |
| 162 @lints_metadata | |
| 163 @wraps_recipe_error(is_error=True) | |
| 164 def lint_name(meta, lint_ctx): | |
| 165 name = get_field(meta, 'package/name') | |
| 166 check_name(name) | |
| 167 lint_ctx.info("Valid recipe name [%s]" % name) | |
| 168 | |
| 169 | |
| 170 @lints_metadata | |
| 171 @wraps_recipe_error(is_error=False) | |
| 172 def lint_fields(meta, lint_ctx): | |
| 173 # Taken from validate_meta | |
| 174 for section in meta: | |
| 175 if section not in FIELDS: | |
| 176 raise RecipeError("Unknown section: %s" % section) | |
| 177 submeta = meta.get(section) | |
| 178 if submeta is None: | |
| 179 submeta = {} | |
| 180 for key in submeta: | |
| 181 # Next two lines added for planemo since we don't do the | |
| 182 # select lines thing. | |
| 183 if key == "skip": | |
| 184 continue | |
| 185 | |
| 186 if key not in FIELDS[section]: | |
| 187 raise RecipeError("in section %r: unknown key %r" % | |
| 188 (section, key)) | |
| 189 | |
| 190 | |
| 191 @lints_metadata | |
| 192 @wraps_recipe_error(is_error=False) | |
| 193 def lint_requirements(meta, lint_ctx): | |
| 194 check_requirements(meta) | |
| 195 lint_ctx.info("Reference recipe files appear valid") | |
| 196 | |
| 197 | |
| 198 def yield_recipes_on_paths(ctx, paths, recursive): | |
| 199 for path in paths: | |
| 200 recipe_dirs = find_matching_directories( | |
| 201 path, "meta.yaml", recursive=recursive | |
| 202 ) | |
| 203 for recipe_dir in recipe_dirs: | |
| 204 yield recipe_dir | |
| 205 | |
| 206 | |
| 207 __all__ = ( | |
| 208 "lint_recipes_on_paths", | |
| 209 ) |
