diff --git a/ci/validate b/ci/validate new file mode 100755 index 0000000..c9e6a32 --- /dev/null +++ b/ci/validate @@ -0,0 +1,57 @@ +#!/usr/bin/python3 +# Validate basic syntax of shell script and yaml. + +import os +import stat +import subprocess +import yaml + +validated=0 + +def openat(dirfd, name, mode='r'): + def opener(path, flags): + return os.open(path, flags, dir_fd=dirfd) + return open(name, mode, opener=opener) + + +def validate_shell(rootfd, name): + subprocess.check_call(['bash', '-n', name], preexec_fn=lambda: os.fchdir(rootfd)) + global validated + validated +=1 + + +for root, dirs, files, rootfd in os.fwalk('.'): + # Skip folders that do not include content to validate + for d in ['.git', '.github', 'repo', 'cache', 'tmp', 'logs', 'fedora-comps']: + if d in dirs: + dirs.remove(d) + for f in ['.gitlab-ci.yml']: + if f in files: + files.remove(f) + for name in files: + if name.endswith(('.yaml', '.yml')): + print("Validating:", name) + with open(os.open(name, dir_fd=rootfd, flags=os.O_RDONLY)) as f: + yaml.safe_load(f) + result = subprocess.run(['grep', '-RniEv', '^( )*[a-z#/-]|^( )*\\[|^$|^#', name], encoding='UTF-8', + preexec_fn=lambda: os.fchdir(rootfd)) + if result.returncode == 0: + raise Exception("Found likely invalid indentation in YAML file: {}".format(name)) + validated +=1 + continue + elif name.endswith('.sh'): + print("Validating:", name) + validate_shell(rootfd, name) + continue + stbuf = os.lstat(name, dir_fd=rootfd) + if not stat.S_ISREG(stbuf.st_mode): + continue + if not stbuf.st_mode & stat.S_IXUSR: + continue + mimetype = subprocess.check_output(['file', '-b', '--mime-type', name], encoding='UTF-8', + preexec_fn=lambda: os.fchdir(rootfd)).strip() + if mimetype == 'text/x-shellscript': + print("Validating:", name) + validate_shell(rootfd, name) + +print(f"Validated {validated} files")