You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
6.2 KiB
Python
134 lines
6.2 KiB
Python
#
|
|
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
# its licensors.
|
|
#
|
|
# For complete copyright and license terms please see the LICENSE at the root of this
|
|
# distribution (the "License"). All use of this software is governed by the License,
|
|
# or, if provided, by the license below or the license accompanying this file. Do not
|
|
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
#
|
|
from __future__ import absolute_import
|
|
import os
|
|
import re
|
|
import json
|
|
import sys
|
|
try:
|
|
import six
|
|
except ImportError:
|
|
import pip
|
|
pip.main(['install', 'six', '--ignore-installed', '-q'])
|
|
import six
|
|
from pathlib import Path
|
|
|
|
this_file_path = os.path.dirname(os.path.realpath(__file__))
|
|
|
|
# resolve symlinks and eliminate ".." components
|
|
engine_root_path = Path(__file__).resolve().parents[3]
|
|
|
|
def convert_glob_pattern_to_regex_pattern(glob_pattern):
|
|
# switch to forward slashes because way easier to pattern match against
|
|
pattern = re.sub(r'\\', r'/', glob_pattern)
|
|
|
|
# Replace the dots and question marks
|
|
pattern = re.sub(r'\.', r'\\.', pattern)
|
|
pattern = re.sub(r'\?', r'.', pattern)
|
|
|
|
# Handle the * vs ** expansions
|
|
pattern = re.sub(r'([^*])\*($|[^*])', r'\1[^/\\\\]*\2', pattern)
|
|
pattern = re.sub(r'\*\*/', r'(.*/)?', pattern)
|
|
pattern = re.sub(r'\*\*', r'.*', pattern)
|
|
|
|
# replace the forward slashes with [/\\] so it works on PC/unix
|
|
pattern = re.sub(r'([^^])/', r'\1[/\\\\]', pattern)
|
|
return pattern
|
|
|
|
# Convert the package json into a pair of regexes we can use to look for includes and excludes
|
|
def convert_glob_list_to_regex_list(filelist, prefix):
|
|
includes = []
|
|
excludes = []
|
|
for key, value in six.iteritems(filelist):
|
|
glob_pattern = os.path.join(prefix, key)
|
|
if isinstance(value, dict):
|
|
(sub_includes, sub_excludes) = convert_glob_list_to_regex_list(value, glob_pattern)
|
|
includes.extend(sub_includes)
|
|
excludes.extend(sub_excludes)
|
|
else:
|
|
# Simulate what glob would do with file walking to scope the * within a directory
|
|
# and ** across directories
|
|
regex_pattern = convert_glob_pattern_to_regex_pattern(os.path.normpath(glob_pattern))
|
|
|
|
# Deal with the commands. include/exclude are straight forward. Moves/renames are to be considered
|
|
# includes, and we will stick with validating the original contents for now
|
|
if value == "#include":
|
|
includes.append(regex_pattern)
|
|
elif value == "#exclude":
|
|
excludes.append(regex_pattern)
|
|
elif value.startswith('#move:'):
|
|
includes.append(regex_pattern)
|
|
elif value.startswith('#rename:'):
|
|
includes.append(regex_pattern)
|
|
else:
|
|
pass
|
|
return (includes, excludes)
|
|
|
|
def generate_excludes_for_platform(root, platform):
|
|
if platform == 'all':
|
|
platform_exclusions_filename = os.path.join(this_file_path, 'platform_exclusions.json')
|
|
with open(platform_exclusions_filename, 'r') as platform_exclusions_file:
|
|
platform_exclusions = json.load(platform_exclusions_file)
|
|
else:
|
|
# Use real path in case root is a symlink path
|
|
if os.name == 'posix' and os.path.islink(root):
|
|
root = os.readlink(root)
|
|
# "root" is the root of the folder structure we're validating
|
|
# "engine_root_path" is the engine root where the restricted platform folder is linked
|
|
relative_folder = os.path.relpath(this_file_path, engine_root_path)
|
|
platform_exclusions_filename = os.path.join(engine_root_path, 'restricted', platform, relative_folder, platform.lower() + '_exclusions.json')
|
|
with open(platform_exclusions_filename, 'r') as platform_exclusions_file:
|
|
platform_exclusions = json.load(platform_exclusions_file)
|
|
|
|
if platform not in platform_exclusions:
|
|
raise KeyError('No {} found in {}'.format(platform, platform_exclusions_filename))
|
|
if '@lyengine' not in platform_exclusions[platform]:
|
|
raise KeyError('No {}/@lyengine found in {}'.format(platform, package_file_list))
|
|
(_, excludes) = convert_glob_list_to_regex_list(platform_exclusions[platform]['@lyengine'], root)
|
|
del _
|
|
return excludes
|
|
|
|
def generate_include_exclude_regexes(package_platform, package_type, root, prohibited_platforms):
|
|
# The general contents will be indicated by the package file
|
|
if package_type == 'all':
|
|
package_file_list = os.path.join(this_file_path, 'package_filelists', 'all.json')
|
|
else:
|
|
# Search non-restricted platform first
|
|
package_file_list = os.path.join(this_file_path, 'Platform', package_platform, 'package_filelists', f'{package_type}.json')
|
|
if not os.path.exists(filelist):
|
|
# Use real path in case root is a symlink path
|
|
if os.name == 'posix' and os.path.islink(root):
|
|
root = os.readlink(root)
|
|
# "root" is the root of the folder structure we're validating
|
|
# "engine_root_path" is the engine root where the restricted platform folder is linked
|
|
rel_path = os.path.relpath(this_file_path, engine_root_path)
|
|
package_file_list = os.path.join(engine_root_path, 'restricted', package_platform, rel_path, 'package_filelists',
|
|
f'{package_type}.json')
|
|
with open(package_file_list, 'r') as package_file:
|
|
package = json.load(package_file)
|
|
|
|
if '@lyengine' not in package:
|
|
raise KeyError('No @lyengine found in {}'.format(package_file_list))
|
|
|
|
(includes_list, excludes_list) = convert_glob_list_to_regex_list(package['@lyengine'], root)
|
|
prohibited_platforms.append('all')
|
|
|
|
# Add the exclusions of each prohibited platform
|
|
for p in prohibited_platforms:
|
|
excludes_list.extend(generate_excludes_for_platform(root, p))
|
|
|
|
includes = re.compile('|'.join(includes_list), re.IGNORECASE)
|
|
excludes = re.compile('|'.join(excludes_list), re.IGNORECASE)
|
|
return (includes, excludes)
|
|
|
|
def generate_exclude_regexes_for_platform(root, platform):
|
|
return re.compile('|'.join(generate_excludes_for_platform(root, platform)), re.IGNORECASE)
|