#!/usr/bin/python3# Validate basic syntax of shell script and yaml.import osimport statimport subprocessimport yamlvalidated=0def openat(dirfd, name, mode='r'):def opener(path, flags):return os.open(path, flags, dir_fd=dirfd)return open(name, mode, opener=opener, encoding='UTF-8')def validate_shell(rootfd, name):subprocess.check_call(['bash', '-n', name], preexec_fn=lambda: os.fchdir(rootfd))global validatedvalidated +=1for root, dirs, files, rootfd in os.fwalk('.'):# Skip folders that do not include content to validatefor 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:", os.path.join(root, name))with open(os.open(name, dir_fd=rootfd, flags=os.O_RDONLY), encoding='UTF-8') 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 +=1continueif name.endswith('.sh'):print("Validating:", os.path.join(root, name))validate_shell(rootfd, name)continuestbuf = os.lstat(name, dir_fd=rootfd)if not stat.S_ISREG(stbuf.st_mode):continueif not stbuf.st_mode & stat.S_IXUSR:continuemimetype = 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:", os.path.join(root, name))validate_shell(rootfd, name)print(f"Validated {validated} files")