Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue_58 - Add support for conditions #59

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 126 additions & 28 deletions PantheonCMD/pcbuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ def build_content(content_files, lang, output_format, repo_location, yaml_file_l
for item, members in main_yaml_file.items():
if item == 'variants':
attributes_file_location = repo_location + members[0]["path"]
with open(attributes_file_location,'r') as attributes_file:
attributes = parse_attributes(attributes_file.readlines())
attributes, lines = coalesce_document(attributes_file_location)
break
try:
pool = concurrent.futures.ThreadPoolExecutor()
Expand All @@ -52,20 +51,6 @@ def build_content(content_files, lang, output_format, repo_location, yaml_file_l
return True


def parse_attributes(attributes):
"""Read an attributes file and parse values into a key:value dictionary."""

final_attributes = {}

for line in attributes:
if re.match(r'^:\S+:.*', line):
attribute_name = line.split(":")[1].strip()
attribute_value = line.split(":")[2].strip()
final_attributes[attribute_name] = attribute_value

return final_attributes


def copy_resources(resources):
"""Copy resources such as images and files to the build directory."""
script_dir = os.path.dirname(os.path.realpath(__file__))
Expand Down Expand Up @@ -116,6 +101,8 @@ def coalesce_document(main_file, attributes=None, depth=0, top_level=True):
"""Combines the content from includes into a single, contiguous source file."""
attributes = attributes or {}
comment_block = False
condition_block = False
conditions_set = ''
lines = []

# Create a copy of global attributes
Expand All @@ -124,40 +111,150 @@ def coalesce_document(main_file, attributes=None, depth=0, top_level=True):

# Open the file, iterate over lines
if os.path.exists(main_file):

with open(main_file) as input_file:

# Iterate over content
for line in input_file:
# Process comment block start and finish
if line.strip().startswith('////'):

# CONDITIONS

# Line matches the end of a condition_block
matches = re.match(r'^endif::(.*?)\[\]', line)

if matches:
if matches.group(1) == '':
condition_block = False
else:
if matches.group(1) == conditions_set:
conditions_set = ''
condition_block = False
continue
adahms marked this conversation as resolved.
Show resolved Hide resolved

# Line matches the middle of a condition block
if condition_block:
continue

# Line matches the start of an ifdef condition
matches = re.match(r'^ifdef::(\S+)\[(.*?)\]', line)

if matches:
conditions_missing = False
conditions = matches.group(1)
conditions_set = matches.group(1)

# Multiple conditions - single match is enough
if conditions.__contains__('+'):
conditions_list = conditions.split('+')
for condition in conditions_list:
if not condition in attributes.keys():
conditions_missing = True
break

# Multiple conditions - all must match
elif conditions.__contains__(','):
conditions_missing = False
conditions_list = conditions.split(',')
for condition in conditions_list:
if not condition in attributes.keys():
conditions_missing = True
else:
conditions_missing = True
if conditions_missing:
conditions_missing = False
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, both if and else statements result in conditions_missing = True. can't it be:

Suggested change
for condition in conditions_list:
if not condition in attributes.keys():
conditions_missing = True
else:
conditions_missing = True
if conditions_missing:
conditions_missing = False
if conditions_missing:
conditions_missing = False
else:
conditions_missing = True

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm - yep, good point.

I'll run through this one again to see if there was something I was trying to do there. Maybe I've just confused myself.


# Single condition
elif not conditions in attributes.keys():
conditions_missing = True
Copy link
Collaborator

@Levi-Leah Levi-Leah Nov 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the above is applied this part might also be redundant


if conditions_missing:
if matches.group(2).strip() == '':
condition_block = True
else:
if matches.group(2).strip() != '':
lines.append(matches.group(2).strip() + '\n')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if matches.group(2).strip() != '':
lines.append(matches.group(2).strip() + '\n')
lines.append(matches.group(2).strip() + '\n')

continue

# Line matches the start of an ifndef condition
matches = re.match(r'^ifndef::(\S+)\[(.*?)\]', line)

if matches:
conditions_missing = False
conditions = matches.group(1)
conditions_set = matches.group(1)

# Multiple conditions - single match is enough
if conditions.__contains__(','):
conditions_list = conditions.split(',')
for condition in conditions_list:
if condition in attributes.keys():
conditions_missing = True
break

# Multiple conditions - all must match
elif conditions.__contains__('+'):
conditions_missing = False
conditions_list = conditions.split('+')
for condition in conditions_list:
if condition in attributes.keys():
conditions_missing = True
else:
conditions_missing = True
if conditions_missing:
conditions_missing = False

# Single condition
elif conditions in attributes.keys():
conditions_missing = True
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar to one of my comments above:

Suggested change
for condition in conditions_list:
if condition in attributes.keys():
conditions_missing = True
else:
conditions_missing = True
if conditions_missing:
conditions_missing = False
# Single condition
elif conditions in attributes.keys():
conditions_missing = True
if conditions_missing:
conditions_missing = False
else:
conditions_missing = True


if conditions_missing:
if matches.group(2).strip() == '':
condition_block = True
else:
if matches.group(2).strip() != '':
lines.append(matches.group(2).strip() + '\n')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if matches.group(2).strip() != '':
lines.append(matches.group(2).strip() + '\n')
lines.append(matches.group(2).strip() + '\n')

continue

# COMMENTS

# Line matches comment block start or finish
if re.match(r'^////.*', line.strip()):
comment_block = True if not comment_block else False
continue
# Process comment block continuation

# Line matches the middle of a comment block
elif comment_block:
continue
# Process inline comments
elif line.strip().startswith('//'):

# Line matches an inline comment
elif re.match(r'^//.*', line.strip()):
continue
# Process section depth

# OTHER CONDITIONS

# Line matches a section header; adjust depth
elif re.match(r'^=+ \S+', line.strip()):
if depth > 0:
lines.append(('=' * depth) + line.strip())
lines.append(('=' * depth) + line.strip() + '\n')
else:
lines.append(line.strip())
# Process includes - recusrive
elif line.strip().startswith("include::"):
lines.append(line.strip() + '\n')

# Line matches an include; process recusrively
elif re.match(r'^include::.*', line.strip()):
include_depth = 0
include_file = line.replace("include::", "").split("[")[0]
include_options = line.split("[")[1].split("]")[0].split(',')
for include_option in include_options:
if include_option.__contains__("leveloffset=+"):
include_depth += int(include_option.split("+")[1])
# Replace attributes in includes, if their values are defined
if re.match(r'^\{\S+\}.*', include_file):
if re.match(r'.*\{\S+\}.*', include_file):
include_file = resolve_attribute_tree(include_file, attributes)
include_filepath = os.path.join(os.path.dirname(main_file), include_file)
attributes, include_lines = coalesce_document(include_filepath, attributes, include_depth, False)
lines.extend(include_lines)
# Build dictionary of found attributes

# Line matches an attribute declaration
elif re.match(r'^:\S+:.*', line):
attribute_name = line.split(":")[1].strip()
attribute_value = line.split(":")[2].strip()
Expand All @@ -166,6 +263,7 @@ def coalesce_document(main_file, attributes=None, depth=0, top_level=True):
lines.append(line)
else:
lines.append(line)

# Add global attribute definitions if main file
if top_level:
lines.insert(0,'\n\n')
Expand Down