Skip to content
Empty file added PantheonCMD/__init__.py
Empty file.
78 changes: 16 additions & 62 deletions PantheonCMD/pcmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
import sys

from pcutil import PantheonRepo, get_not_exist, get_exist, is_pantheon_repo
from pcvalidator import validation
from pcyamlchecks import yaml_validation
from validation.pcvalidator import validate_build_files
from validation.pcyamlchecks import yaml_validation
from subprocess import call
from pcprvalidator import get_changed_files, get_all_modules, get_all_assemblies, get_undetermined_files, get_no_prefix_files

from validation.pcprvalidator import validate_merge_request_files
from validation.pcentrypointvalidator import validate_entry_point_files
from validation.pcmsg import print_message, print_report_message


def print_header():
Expand Down Expand Up @@ -47,6 +48,7 @@ def parse_args():
# 'Validate' command
parser_d = subparsers.add_parser('validate', help='Validate entries in your pantheon2.yml file.')
parser_d.add_argument('--mr', action='store_true', help='Validate files commited on a merge request.')
parser_d.add_argument('--e', nargs=1, help='Validate files from an entry point.')

# 'Generate' command
parser_e = subparsers.add_parser('generate', help='Generate pantheon2.yml file from a template.')
Expand Down Expand Up @@ -76,66 +78,24 @@ def parse_args():
# validate modules and assemblies
elif args.command == 'validate':

if args.mr:

changed_files = get_changed_files()
files_found = get_exist(changed_files)
no_prefix_files = get_no_prefix_files(files_found)
modules_found = get_all_modules(files_found, no_prefix_files)
assemblies_found = get_all_assemblies(files_found, no_prefix_files)
undetermined_file_type = get_undetermined_files(no_prefix_files)

if undetermined_file_type:
print("\nYour Merge Request contains the following files that can not be classified as modules or assemblies:\n")
# user provides paths to files that are relative to current pwd

for file in undetermined_file_type:
if args.e:
entry_point_list = args.e
validate_entry_point_files(entry_point_list)

print('\t' + file)
elif args.mr:

print("\nTotal: ", str(len(undetermined_file_type)))
validate_merge_request_files()

validate = validation(files_found, modules_found, assemblies_found)

if validate.count != 0:
print("\nYour Merge Request contains the following files that did not pass validation:\n")
validate.print_report()
sys.exit(2)
else:
print("All files passed validation.")
sys.exit(0)
else:

pantheon_repo = PantheonRepo(repo_location)

if os.path.exists('pantheon2.yml'):

# call yaml file validation + attribute file validation
yaml_validation('pantheon2.yml')

exists = get_not_exist(pantheon_repo.get_content())

if exists:

print("\nYour pantheon2.yml contains the following files that do not exist in your repository:\n")

for exist in exists:

print('\t' + exist)

print("\nTotal: ", str(len(exists)))

files_found = get_exist(pantheon_repo.get_content())
modules_found = pantheon_repo.get_existing_content("modules")
assemblies_found = pantheon_repo.get_existing_content("assemblies")

validate = validation(files_found, modules_found, assemblies_found)

if validate.count != 0:
print("\nYour pantheon2.yml contains the following files that did not pass validation:\n")
validate.print_report()
sys.exit(2)
else:
print("All files passed validation.")
validate_build_files()

else:

Expand All @@ -153,12 +113,12 @@ def parse_args():
# Else parse actions
# Action - preview
if args.command == 'preview':

if args.format == 'pdf':
output_format = 'pdf'
else:
output_format = 'html'

# Did a user specify a set of files? If so, only build those.
if args.files:
# Handle different interpretations of directories
Expand Down Expand Up @@ -211,13 +171,7 @@ def parse_args():
duplicates = pantheon_repo.get_duplicates()

if duplicates:

print("Your pantheon2.yml contains the following duplicate entries:\n")

for duplicate in duplicates:
print(duplicate)

print("\nTotal: ", str(len(duplicates)))
print_message(duplicates, 'pantheon2.yml', 'contains the following duplicate entries')

else:

Expand Down
13 changes: 6 additions & 7 deletions PantheonCMD/pcchecks.py → PantheonCMD/validation/pcchecks.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ class Tags:
class Regex:
"""Define regular expresiions for the checks."""

ATTRIBUTE = re.compile(r':[^\s]*:.*(?=\n)')
INCLUDE = re.compile(r'include::.*\]\n')
MODULE_TYPE = re.compile(r':_module-type: (PROCEDURE|CONCEPT|REFERENCE)')
INCLUDED_CONTENT = re.compile(r'(?<=include::).*?(?=\[)')
CONTENT_TYPE = re.compile(r':_content-type: (PROCEDURE|CONCEPT|REFERENCE|ASSEMBLY)')
PREFIX_ASSEMBLIES = re.compile(r'.*\/assembly.*\.adoc')
PREFIX_MODULES = re.compile(r'.*\/con.*\.adoc|.*\/proc.*\.adoc|.*\/ref.*\.adoc')
# should exclude pseudo vanilla like <<some content>>
Expand Down Expand Up @@ -109,17 +111,14 @@ def html_markup_check(stripped_file):
# Standalone check on modules_found
def nesting_in_modules_check(report, stripped_file, file_path):
"""Check if modules contains nested content."""
if re.findall(Regex.NESTED_ASSEMBLY, stripped_file):
report.create_report('nesting in modules. nesting', file_path)
if re.findall(Regex.NESTED_MODULES, stripped_file):
if re.findall(Regex.NESTED_ASSEMBLY, stripped_file) or re.findall(Regex.NESTED_MODULES, stripped_file):
report.create_report('nesting in modules. nesting', file_path)


# Standalone check on modules_found
def add_res_section_module_check(report, stripped_file, file_path):
if re.findall(Regex.ADDITIONAL_RES, stripped_file):
if not re.findall(Regex.ADD_RES_MODULE, stripped_file):
report.create_report("Additional resources section for modules should be `.Additional resources`. Wrong section name was", file_path)
if re.findall(Regex.ADD_RES_ASSEMBLY, stripped_file):
report.create_report("Additional resources section for modules should be `.Additional resources`. Wrong section name was", file_path)


# Standalone check on assemblies_found
Expand Down
126 changes: 126 additions & 0 deletions PantheonCMD/validation/pcentrypointvalidator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/python3

import argparse
import re
import os
from validation.pcchecks import Regex
import sys
from pcutil import get_exist, get_not_exist
from validation.pcprvalidator import get_no_prefix_files, get_all_modules, get_all_assemblies, get_undetermined_files
from validation.pcvalidator import validation
from validation.pcmsg import print_message, print_report_message

parser = argparse.ArgumentParser()


def get_nonexisting_entry_points(entry_point_list):
nonexistent_files = get_not_exist(entry_point_list)

if nonexistent_files:
print_message(nonexistent_files, 'entry point', 'does not exist in your repository')
sys.exit(2)


def get_includes(entry_points):
path_to_includes = []

for entry in entry_points:
path_to_entry_point = os.path.dirname(os.path.abspath(entry))

with open(entry, 'r') as file:
original = file.read()
stripped = Regex.MULTI_LINE_COMMENT.sub('', original)
stripped = Regex.SINGLE_LINE_COMMENT.sub('', stripped)

included_files = re.findall(Regex.INCLUDED_CONTENT, stripped)

if included_files:

for include in included_files[:]:
if include.startswith('_'):
included_files.remove(include)

for i in included_files:
path_to_includes.append(os.path.join(path_to_entry_point, i))

return path_to_includes


def get_level_one_includes(files):
path_to_level_one_includes = get_includes(files)

return path_to_level_one_includes


def get_level_two_includes(files):
path_to_level_two_includes = get_includes(files)

return path_to_level_two_includes


def get_level_three_includes(files):
path_to_level_three_includes = get_includes(files)

return path_to_level_three_includes


def get_level_four_includes(files):
path_to_level_four_includes = get_includes(files)

return path_to_level_four_includes


def get_concatenated_includes(entry_point_list):
existing_entry_points = get_exist(entry_point_list)
level_one_includes = get_level_one_includes(existing_entry_points)
level_two_includes = get_level_two_includes(level_one_includes)
level_three_includes = get_level_three_includes(level_two_includes)
level_four_includes = get_level_four_includes(level_three_includes)
no_prefix_level_four_includes = get_no_prefix_files(level_four_includes)
level_four_modules = get_all_modules(level_four_includes, no_prefix_level_four_includes)
level_four_assemblies = get_all_assemblies(level_four_includes, no_prefix_level_four_includes)

all_includes = level_one_includes + level_two_includes + level_three_includes + level_four_modules

return all_includes, level_four_assemblies


def get_level_four_assemblies(entry_point_list):
all_includes, level_four_assemblies = get_concatenated_includes(entry_point_list)

return level_four_assemblies


def get_all_includes(entry_point_list):
all_includes, level_four_assemblies = get_concatenated_includes(entry_point_list)

for entry in entry_point_list:
if not entry.endswith('master.adoc'):
all_includes = all_includes + entry_point_list

for include in all_includes:
if os.path.basename(include).startswith('_'):
all_includes.remove(include)

return all_includes


def validate_entry_point_files(entry_point_list):
# exit if entry point doesn't exist
get_nonexisting_entry_points(entry_point_list)
existing_entry_points = get_exist(entry_point_list)
includes = get_all_includes(entry_point_list)
no_prefix_files = get_no_prefix_files(includes)
modules_found = get_all_modules(includes, no_prefix_files)
assemblies_found = get_all_assemblies(includes, no_prefix_files)
undetermined_file_type = get_undetermined_files(no_prefix_files)
level_four_assemblies = get_level_four_assemblies(existing_entry_points)

if level_four_assemblies:
print_message(level_four_assemblies, 'entry point', 'contains unsupported level of nesting for the following files')

if undetermined_file_type:
print_message(undetermined_file_type, 'entry point', 'contains the following files that can not be classified as modules or assemblies')

validate = validation(includes, modules_found, assemblies_found)
print_report_message(validate, 'entry point')
45 changes: 45 additions & 0 deletions PantheonCMD/validation/pcmsg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/python3

import sys


class Report():
"""Create and print report. thank u J."""

def __init__(self):
"""Create placeholder for problem description."""
self.report = {}
self.count = 0

def create_report(self, category, file_path):
"""Generate report."""
self.count += 1
if not category in self.report:
self.report[category] = []
self.report[category].append(file_path)

def print_report(self):

"""Print report."""
separator = "\n\t"

for category, files in self.report.items():
print("\nERROR: {} found in the following files:".format(category))
print('\t' + separator.join(files))


def print_message(variable, specification, msg):
print(f'\nYour {specification} {msg}:\n')
for var in variable:
print('\t', var)
print("\nTotal: ", str(len(variable)))


def print_report_message(variable, specification):
if variable.count != 0:
print(f"\nYour {specification} contains the following files that did not pass validation:\n")
variable.print_report()
sys.exit(2)
else:
print("All files passed validation.")
sys.exit(0)
Loading