Skip to content

Commit 3fa6f80

Browse files
authored
Separate validation into two phases
- snippet contents (always) and full-repo (optional; includes sample files, bad words, and SPDX checks) (#22)
1 parent bd26f0c commit 3fa6f80

File tree

5 files changed

+75
-43
lines changed

5 files changed

+75
-43
lines changed

action.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ inputs:
44
root:
55
description: "Root of the repository checkout to validate metadata within"
66
default: ${{ github.workspace }}
7-
check_spdx:
8-
description: "Check for two-line SDPX header conformance"
9-
default: "False"
7+
doc_gen_only:
8+
description: "Only perform extended validation on doc_gen snippets"
9+
default: "True"
1010
runs:
1111
using: "composite"
1212
steps:
@@ -18,5 +18,5 @@ runs:
1818
run: pip install -e "${{ github.action_path }}"
1919
shell: bash
2020
- name: Run validator
21-
run: python3 -m "aws_doc_sdk_examples_tools.validate" --root "${{ inputs.root }}" --check-spdx "${{ inputs.check_spdx }}"
21+
run: python3 -m "aws_doc_sdk_examples_tools.validate" --root "${{ inputs.root }}" --doc_gen_only "${{ inputs.doc_gen_only }}"
2222
shell: bash

aws_doc_sdk_examples_tools/doc_gen.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616
)
1717
from .metadata_errors import MetadataErrors, MetadataError
1818
from .metadata_validator import validate_metadata
19-
from .project_validator import check_files, verify_sample_files, ValidationConfig
19+
from .project_validator import ValidationConfig
2020
from .sdks import Sdk, parse as parse_sdks
2121
from .services import Service, parse as parse_services
2222
from .snippets import (
2323
Snippet,
2424
collect_snippets,
25+
collect_snippet_files,
2526
validate_snippets,
2627
)
2728

@@ -53,6 +54,9 @@ def collect_snippets(
5354
if snippets_root is None:
5455
snippets_root = self.root
5556
snippets, errs = collect_snippets(snippets_root, prefix)
57+
collect_snippet_files(
58+
self.examples.values(), snippets=snippets, errors=errs, root=self.root
59+
)
5660
self.snippets = snippets
5761
self.errors.extend(errs)
5862

@@ -193,19 +197,17 @@ def for_root(self, root: Path, config: Optional[Path] = None) -> "DocGen":
193197
def from_root(cls, root: Path, config: Optional[Path] = None) -> "DocGen":
194198
return DocGen.empty().for_root(root, config)
195199

196-
def validate(self, check_spdx: bool):
200+
def validate(self):
197201
for sdk in self.sdks.values():
198202
sdk.validate(self.errors)
199203
for service in self.services.values():
200204
service.validate(self.errors)
201-
check_files(self.root, check_spdx, self.validation, self.errors)
202-
verify_sample_files(self.root, self.validation, self.errors)
203205
validate_metadata(self.root, self.errors)
204206
validate_no_duplicate_api_examples(self.examples.values(), self.errors)
205207
validate_snippets(
206208
[*self.examples.values()],
207209
self.snippets,
208-
self.snippet_files,
210+
self.validation,
209211
self.errors,
210212
self.root,
211213
)

aws_doc_sdk_examples_tools/project_validator.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ def clone(self):
5252

5353
def check_files(
5454
root: Path,
55-
do_check_spdx: bool,
5655
validation: ValidationConfig,
5756
errors: MetadataErrors,
5857
):
@@ -78,8 +77,7 @@ def check_files(
7877

7978
verify_no_deny_list_words(file_contents, file_path, errors)
8079
verify_no_secret_keys(file_contents, file_path, validation, errors)
81-
if do_check_spdx:
82-
verify_spdx(file_contents, file_path, errors)
80+
verify_spdx(file_contents, file_path, errors)
8381

8482
print(f"{file_count} files scanned in {root}.\n")
8583

aws_doc_sdk_examples_tools/snippets.py

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@
33

44
from dataclasses import dataclass
55
from pathlib import Path
6-
from typing import Any, Dict, List, Optional, Set, Tuple
6+
from typing import Any, Dict, Iterable, List, Optional, Set, Tuple
77
from shutil import copyfile
88
import re
99

1010
from .validator_config import skip
1111
from .file_utils import get_files, clear
1212
from .metadata import Example
1313
from .metadata_errors import MetadataErrors, MetadataError
14+
from .project_validator import (
15+
verify_no_deny_list_words,
16+
verify_no_secret_keys,
17+
ValidationConfig,
18+
)
1419

1520
SNIPPET_START = "snippet-start:["
1621
SNIPPET_END = "snippet-end:["
@@ -171,6 +176,49 @@ def collect_snippets(
171176
return snippets, errors
172177

173178

179+
def collect_snippet_files(
180+
examples: Iterable[Example],
181+
snippets: Dict[str, Snippet],
182+
errors: MetadataErrors,
183+
root: Path,
184+
):
185+
for example in examples:
186+
for lang in example.languages:
187+
language = example.languages[lang]
188+
for version in language.versions:
189+
for excerpt in version.excerpts:
190+
for snippet_file in excerpt.snippet_files:
191+
if not (root / snippet_file).exists():
192+
# Ensure all snippet_files exist
193+
errors.append(
194+
MissingSnippetFile(
195+
file=example.file,
196+
snippet_file=snippet_file,
197+
id=f"{lang}:{version.sdk_version}",
198+
)
199+
)
200+
continue
201+
if re.search(win_unsafe_re, str(snippet_file)):
202+
errors.append(
203+
WindowsUnsafeSnippetFile(
204+
file=example.file,
205+
snippet_file=snippet_file,
206+
id=f"{lang}:{version.sdk_version}",
207+
)
208+
)
209+
continue
210+
name = str(snippet_file).replace("/", ".")
211+
with open(root / snippet_file, encoding="utf8") as file:
212+
code = file.readlines()
213+
snippets[name] = Snippet(
214+
id=name,
215+
file=str(snippet_file),
216+
line_start=0,
217+
line_end=len(code),
218+
code="\n".join(file),
219+
)
220+
221+
174222
@dataclass
175223
class MissingSnippet(MetadataError):
176224
tag: Optional[str] = None
@@ -200,9 +248,9 @@ def message(self):
200248

201249

202250
def validate_snippets(
203-
examples: List[Example],
251+
examples: Iterable[Example],
204252
snippets: Dict[str, Snippet],
205-
snippet_files: Set[str],
253+
validation: ValidationConfig,
206254
errors: MetadataErrors,
207255
root: Path,
208256
):
@@ -221,24 +269,10 @@ def validate_snippets(
221269
tag=snippet_tag,
222270
)
223271
)
224-
for snippet_file in excerpt.snippet_files:
225-
if not (root / snippet_file).exists():
226-
# Ensure all snippet_files exist
227-
errors.append(
228-
MissingSnippetFile(
229-
file=example.file,
230-
snippet_file=snippet_file,
231-
id=f"{lang}:{version.sdk_version}",
232-
)
233-
)
234-
if re.search(win_unsafe_re, str(snippet_file)):
235-
errors.append(
236-
WindowsUnsafeSnippetFile(
237-
file=example.file,
238-
snippet_file=snippet_file,
239-
id=f"{lang}:{version.sdk_version}",
240-
)
241-
)
272+
273+
for snippet in snippets.values():
274+
verify_no_deny_list_words(snippet.code, root / snippet.file, errors)
275+
verify_no_secret_keys(snippet.code, root / snippet.file, validation, errors)
242276

243277

244278
def write_snippets(root: Path, snippets: Dict[str, Snippet], check: bool = False):

aws_doc_sdk_examples_tools/validate.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from sys import exit
88

99
from .doc_gen import DocGen
10+
from .project_validator import check_files, verify_sample_files
1011

1112

1213
def main():
@@ -16,25 +17,22 @@ def main():
1617
default=f"{Path(__file__).parent.parent.parent}",
1718
help="The root path from which to search for files to check. The default is the root of the git repo (two up from this file).",
1819
)
19-
# parser.add_argument(
20-
# "--doc-gen",
21-
# default=f"{Path(__file__).parent.parent.parent / '.doc_gen'}",
22-
# help="The folder that contains schema and metadata files. The default is .doc_gen in the root of this repo.",
23-
# required=False,
24-
# )
2520
parser.add_argument(
26-
"--check-spdx",
21+
"--doc_gen_only",
2722
type=literal_eval,
28-
default=False,
29-
help="Verify all files start with SPDX header",
23+
default=True,
24+
help="Only perform extended validation on snippet contents",
3025
required=False,
3126
)
3227
args = parser.parse_args()
3328
root_path = Path(args.root).resolve()
3429

3530
doc_gen = DocGen.from_root(root=root_path)
3631
doc_gen.collect_snippets(snippets_root=root_path)
37-
doc_gen.validate(args.check_spdx)
32+
doc_gen.validate()
33+
if not args.doc_gen_only:
34+
check_files(doc_gen.root, doc_gen.validation, doc_gen.errors)
35+
verify_sample_files(doc_gen.root, doc_gen.validation, doc_gen.errors)
3836

3937
error_count = len(doc_gen.errors)
4038
if error_count > 0:

0 commit comments

Comments
 (0)