Updated the enable gem and disable gem API (#54)

* Updated the enable gem and disable gem API
Renamed remove_gem_project.py -> disable_gem.py
Renamed add_gem_project.py -> enable_gem.py
Renamed the "add-gem-to-project" command -> "enable-gem"
Renamed the "remove-gem-from-project" command -> "disable-gem"

Fixed the parsing of the enabled gems from the enabled_gems.cmake file

* Adding newline to the end of the CMakeLists.txt
main
lumberyard-employee-dm 5 years ago committed by GitHub
parent f9b2517ea3
commit 394ac7ab6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -286,8 +286,8 @@ namespace O3DE::ProjectManager
m_register = pybind11::module::import("o3de.register");
m_manifest = pybind11::module::import("o3de.manifest");
m_engineTemplate = pybind11::module::import("o3de.engine_template");
m_addGemProject = pybind11::module::import("o3de.add_gem_project");
m_removeGemProject = pybind11::module::import("o3de.remove_gem_project");
m_enableGemProject = pybind11::module::import("o3de.enable_gem");
m_disableGemProject = pybind11::module::import("o3de.disable_gem");
return result == 0 && !PyErr_Occurred();
} catch ([[maybe_unused]] const std::exception& e)
@ -588,7 +588,7 @@ namespace O3DE::ProjectManager
pybind11::str pyGemPath = gemPath.toStdString();
pybind11::str pyProjectPath = projectPath.toStdString();
m_addGemProject.attr("add_gem_to_project")(
m_enableGemProject.attr("enable_gem_in_project")(
pybind11::none(), // gem_name
pyGemPath,
pybind11::none(), // project_name
@ -605,7 +605,7 @@ namespace O3DE::ProjectManager
pybind11::str pyGemPath = gemPath.toStdString();
pybind11::str pyProjectPath = projectPath.toStdString();
m_removeGemProject.attr("remove_gem_from_project")(
m_disableGemProject.attr("disable_gem_in_project")(
pybind11::none(), // gem_name
pyGemPath,
pybind11::none(), // project_name

@ -68,7 +68,7 @@ namespace O3DE::ProjectManager
AZStd::recursive_mutex m_lock;
pybind11::handle m_register;
pybind11::handle m_manifest;
pybind11::handle m_addGemProject;
pybind11::handle m_removeGemProject;
pybind11::handle m_enableGemProject;
pybind11::handle m_disableGemProject;
};
}

@ -32,7 +32,7 @@ def add_args(parser, subparsers) -> None:
# add the scripts/o3de directory to the front of the sys.path
sys.path.insert(0, str(o3de_package_dir))
from o3de import engine_template, global_project, register, print_registration, get_registration, download, \
add_gem_project, remove_gem_project, sha256
enable_gem, disable_gem, sha256
# Remove the temporarily added path
sys.path = sys.path[1:]
@ -54,10 +54,10 @@ def add_args(parser, subparsers) -> None:
download.add_args(subparsers)
# add a gem to a project
add_gem_project.add_args(subparsers)
enable_gem.add_args(subparsers)
# remove a gem from a project
remove_gem_project.add_args(subparsers)
disable_gem.add_args(subparsers)
# sha256
sha256.add_args(subparsers)

@ -26,9 +26,9 @@ def get_project_gems(project_path: pathlib.Path,
return get_gems_from_cmake_file(get_enabled_gem_cmake_file(project_path=project_path, platform=platform))
def get_gem_from_cmake_file(cmake_file: pathlib.Path) -> set:
def get_enabled_gems(cmake_file: pathlib.Path) -> set:
"""
Gets a list of declared gem targets dependencies of a cmake file
Gets a list of enabled gems from the cmake file
:param cmake_file: path to the cmake file
:return: set of gem targets found
"""
@ -38,11 +38,29 @@ def get_gem_from_cmake_file(cmake_file: pathlib.Path) -> set:
logger.error(f'Failed to locate cmake file {cmake_file}')
return set()
enable_gem_start_marker = 'set(ENABLED_GEMS'
enable_gem_end_marker = ')'
gem_target_set = set()
with cmake_file.open('r') as s:
in_gem_list = False
for line in s:
gem_name = line.strip()
gem_target_set.add(gem_name)
line = line.strip()
if line.startswith(enable_gem_start_marker):
# Set the flag to indicate that we are in the ENABLED_GEMS variable
in_gem_list = True
# Skip pass the 'set(ENABLED_GEMS' marker just in case their are gems declared on the same line
line = line[len(enable_gem_start_marker):]
if in_gem_list:
# Since we are inside the ENABLED_GEMS variable determine if the line has the end_marker of ')'
if line.endswith(enable_gem_end_marker):
# Strip away the line end marker
line = line[:-len(enable_gem_end_marker)]
# Set the flag to indicate that we are no longer in the ENABLED_GEMS variable after this line
in_gem_list = False
# Split the rest of the line on whitespace just in case there are multiple gems in a line
gem_name_list = line.split()
gem_target_set.update(gem_name_list)
return gem_target_set
@ -72,7 +90,7 @@ def get_enabled_gem_cmake_file(project_name: str = None,
project_path = manifest.get_registered(project_name=project_name)
project_path = pathlib.Path(project_path).resolve()
enable_gem_filename = "enabled_gem.cmake"
enable_gem_filename = "enabled_gems.cmake"
if platform == 'Common':
project_code_dir = project_path / 'Gem/Code'

@ -58,20 +58,18 @@ def remove_gem_dependency(cmake_file: pathlib.Path,
return 0
def remove_gem_from_project(gem_name: str = None,
gem_path: pathlib.Path = None,
project_name: str = None,
project_path: pathlib.Path = None,
enabled_gem_file: pathlib.Path = None,
platforms: str = 'Common') -> int:
def disable_gem_in_project(gem_name: str = None,
gem_path: pathlib.Path = None,
project_name: str = None,
project_path: pathlib.Path = None,
enabled_gem_file: pathlib.Path = None) -> int:
"""
remove a gem from a project
disable a gem in a projects enabled_gems.cmake file
:param gem_name: name of the gem to add
:param gem_path: path to the gem to add
:param project_name: name of the project to add the gem to
:param project_path: path to the project to add the gem to
:param enabled_gem_file: File to remove enabled gem from
:param platforms: str to specify common or which specific platforms
:return: 0 for success or non 0 failure code
"""
@ -122,53 +120,37 @@ def remove_gem_from_project(gem_name: str = None,
# when removing we will try to do as much as possible even with failures so ret_val will be the last error code
ret_val = 0
# if the user has specified the dependencies file then ignore the runtime_dependency and tool_dependency flags
if enabled_gem_file:
# make sure this is a project has an enabled_gem file
if not enabled_gem_file.is_file():
logger.error(f'Enabled gem file {enabled_gem_file} is not present.')
return 1
# remove the dependency
error_code = remove_gem_dependency(dependencies_file, gem_json_data['gem_name'])
if error_code:
ret_val = error_code
else:
if ',' in platforms:
platforms = platforms.split(',')
else:
platforms = [platforms]
for platform in platforms:
# make sure this is a project has a enabled_gem.cmake file
project_enabled_gem_file = cmake.get_enabled_gem_cmake_file(project_path=project_path, platform=platform)
if not project_enabled_gem_file.is_file():
logger.error(f'Enabled gem file {project_enabled_gem_file} is not present.')
else:
# remove the dependency
error_code = remove_gem_dependency(project_enabled_gem_file, gem_json_data['gem_name'])
if error_code:
ret_val = error_code
if not enabled_gem_file:
enabled_gem_file = cmake.get_enabled_gem_cmake_file(project_path=project_path)
# make sure this is a project has an enabled gems file
if not enabled_gem_file.is_file():
logger.error(f'Enabled gem file {enabled_gem_file} is not present.')
return 1
# remove the gem
error_code = remove_gem_dependency(enabled_gem_file, gem_json_data['gem_name'])
if error_code:
ret_val = error_code
return ret_val
def _run_remove_gem_from_project(args: argparse) -> int:
def _run_disable_gem_in_project(args: argparse) -> int:
if args.override_home_folder:
manifest.override_home_folder = args.override_home_folder
return remove_gem_from_project(args.gem_name,
return disable_gem_in_project(args.gem_name,
args.gem_path,
args.project_name,
args.project_path,
args.enabled_gem_file,
args.platforms)
args.enabled_gem_file)
def add_parser_args(parser):
"""
add_parser_args is called to add arguments to each command such that it can be
invoked locally or added by a central python file.
Ex. Directly run from this file alone with: python remove_gem_project.py --project-path D:/Test --gem-name Atom
Ex. Directly run from this file alone with: python disable_gem.py --project-path D:/Test --gem-name Atom
:param parser: the caller passes an argparse parser like instance to this method
"""
group = parser.add_mutually_exclusive_group(required=True)
@ -182,17 +164,13 @@ def add_parser_args(parser):
group.add_argument('-gn', '--gem-name', type=str, required=False,
help='The name of the gem.')
parser.add_argument('-egf', '--enabled-gem-file', type=pathlib.Path, required=False,
help='The cmake enabled gem file in which gem dependencies are to be removed from.'
help='The cmake enabled gem file in which gem names are to be removed from.'
'If not specified it will assume ')
parser.add_argument('-pl', '--platforms', type=str, required=False,
default='Common',
help='Optional list of platforms this gem should be removed from'
' Ex. --platforms Mac,Windows,Linux')
parser.add_argument('-ohf', '--override-home-folder', type=pathlib.Path, required=False,
help='By default the home folder is the user folder, override it to this folder.')
parser.set_defaults(func=_run_remove_gem_from_project)
parser.set_defaults(func=_run_disable_gem_in_project)
def add_args(subparsers) -> None:
@ -200,16 +178,16 @@ def add_args(subparsers) -> None:
add_args is called to add subparsers arguments to each command such that it can be
a central python file such as o3de.py.
It can be run from the o3de.py script as follows
call add_args and execute: python o3de.py remove-gem-from-project --project-path D:/Test --gem-name Atom
call add_args and execute: python o3de.py disable-gem-from-cmake --project-path D:/Test --gem-name Atom
:param subparsers: the caller instantiates subparsers and passes it in here
"""
remove_gem_project_subparser = subparsers.add_parser('remove-gem-from-project')
add_parser_args(remove_gem_project_subparser)
disable_gem_project_subparser = subparsers.add_parser('disable-gem')
add_parser_args(disable_gem_project_subparser)
def main():
"""
Runs remove_gem_project.py script as standalone script
Runs disable_gem_project.py script as standalone script
"""
# parse the command line args
the_parser = argparse.ArgumentParser()

@ -75,20 +75,18 @@ def add_gem_dependency(cmake_file: pathlib.Path,
return 0
def add_gem_to_project(gem_name: str = None,
gem_path: pathlib.Path = None,
project_name: str = None,
project_path: pathlib.Path = None,
enabled_gem_file: pathlib.Path = None,
platforms: str = 'Common') -> int:
def enable_gem_in_project(gem_name: str = None,
gem_path: pathlib.Path = None,
project_name: str = None,
project_path: pathlib.Path = None,
enabled_gem_file: pathlib.Path = None) -> int:
"""
add a gem to a project
enable a gem in a projects enabled_gems.cmake file
:param gem_name: name of the gem to add
:param gem_path: path to the gem to add
:param project_name: name of to the project to add the gem to
:param project_path: path to the project to add the gem to
:param enabled_gem_file_file: if this dependency goes/is in a specific file
:param platforms: str to specify common or which specific platforms
:return: 0 for success or non 0 failure code
"""
# we need either a project name or path
@ -138,47 +136,41 @@ def add_gem_to_project(gem_name: str = None,
ret_val = 0
if enabled_gem_file:
# make sure this is a project has a dependencies_file
# make sure this is a project has an enabled gems file
if not enabled_gem_file.is_file():
logger.error(f'Enabled gem file {enabled_gem_file} is not present.')
return 1
# add the dependency
# add the gem
ret_val = add_gem_dependency(enabled_gem_file, gem_json_data['gem_name'])
else:
if ',' in platforms:
platforms = platforms.split(',')
else:
platforms = [platforms]
for platform in platforms:
# Find the path to enabled gem file.
# It will be created by add_gem_dependency if it doesn't exist
project_enabled_gem_file = cmake.get_enabled_gem_cmake_file(project_path=project_path, platform=platform)
if not project_enabled_gem_file.is_file():
project_enabled_gem_file.touch()
# add the dependency
ret_val = add_gem_dependency(project_enabled_gem_file, gem_json_data['gem_name'])
# Find the path to enabled gem file.
# It will be created if it doesn't exist
project_enabled_gem_file = cmake.get_enabled_gem_cmake_file(project_path=project_path)
if not project_enabled_gem_file.is_file():
project_enabled_gem_file.touch()
# add the gem
ret_val = add_gem_dependency(project_enabled_gem_file, gem_json_data['gem_name'])
return ret_val
def _run_add_gem_to_project(args: argparse) -> int:
def _run_enable_gem_in_project(args: argparse) -> int:
if args.override_home_folder:
manifest.override_home_folder = args.override_home_folder
return add_gem_to_project(args.gem_name,
args.gem_path,
args.project_name,
args.project_path,
args.enabled_gem_file,
args.platforms)
return enable_gem_in_project(args.gem_name,
args.gem_path,
args.project_name,
args.project_path,
args.enabled_gem_file)
def add_parser_args(parser):
"""
add_parser_args is called to add arguments to each command such that it can be
invoked locally or added by a central python file.
Ex. Directly run from this file alone with: python add_gem_project.py --project-path "D:/TestProject" --gem-path "D:/TestGem"
Ex. Directly run from this file alone with: python enable_gem.py --project-path "D:/TestProject" --gem-path "D:/TestGem"
:param parser: the caller passes an argparse parser like instance to this method
"""
group = parser.add_mutually_exclusive_group(required=True)
@ -192,17 +184,13 @@ def add_parser_args(parser):
group.add_argument('-gn', '--gem-name', type=str, required=False,
help='The name of the gem.')
parser.add_argument('-egf', '--enabled-gem-file', type=pathlib.Path, required=False,
help='The cmake enabled_gem file in which the gem dependencies are specified.'
help='The cmake enabled_gem file in which the gem names are specified.'
'If not specified it will assume enabled_gems.cmake')
parser.add_argument('-pl', '--platforms', type=str, required=False,
default='Common',
help='Optional list of platforms this gem should be added to.'
' Ex. --platforms Mac,Windows,Linux')
parser.add_argument('-ohf', '--override-home-folder', type=pathlib.Path, required=False,
help='By default the home folder is the user folder, override it to this folder.')
parser.set_defaults(func=_run_add_gem_to_project)
parser.set_defaults(func=_run_enable_gem_in_project)
def add_args(subparsers) -> None:
@ -213,13 +201,13 @@ def add_args(subparsers) -> None:
call add_args and execute: python o3de.py add-gem-to-project --project-path "D:/TestProject" --gem-path "D:/TestGem"
:param subparsers: the caller instantiates subparsers and passes it in here
"""
add_gem_project_subparser = subparsers.add_parser('add-gem-to-project')
add_parser_args(add_gem_project_subparser)
enable_gem_project_subparser = subparsers.add_parser('enable-gem')
add_parser_args(enable_gem_project_subparser)
def main():
"""
Runs add_gem_project.py script as standalone script
Runs enable_gem.py script as standalone script
"""
# parse the command line args
the_parser = argparse.ArgumentParser()

@ -231,6 +231,11 @@ def get_gems() -> list:
return list(filter(is_gem_subdirectory, external_subdirs)) if external_subdirs else []
def get_external_subdirectories() -> list:
json_data = load_o3de_manifest()
return json_data['external_subdirectories']
def get_templates() -> list:
json_data = load_o3de_manifest()
return json_data['templates']
@ -241,11 +246,6 @@ def get_restricted() -> list:
return json_data['restricted']
def get_external_subdirectories() -> list:
json_data = load_o3de_manifest()
return json_data['external_subdirectories']
def get_repos() -> list:
json_data = load_o3de_manifest()
return json_data['repos']
@ -266,25 +266,25 @@ def get_engine_gems() -> list:
return list(filter(is_gem_subdirectory, external_subdirs)) if external_subdirs else []
def get_engine_templates() -> list:
def get_engine_external_subdirectories() -> list:
engine_path = get_this_engine_path()
engine_object = get_engine_json_data(engine_path=engine_path)
return list(map(lambda rel_path: (pathlib.Path(engine_path) / rel_path).as_posix(),
engine_object['templates']))
engine_object['external_subdirectories'])) if 'external_subdirectories' in engine_object else []
def get_engine_restricted() -> list:
def get_engine_templates() -> list:
engine_path = get_this_engine_path()
engine_object = get_engine_json_data(engine_path=engine_path)
return list(map(lambda rel_path: (pathlib.Path(engine_path) / rel_path).as_posix(),
engine_object['restricted'])) if 'restricted' in engine_object else []
engine_object['templates']))
def get_engine_external_subdirectories() -> list:
def get_engine_restricted() -> list:
engine_path = get_this_engine_path()
engine_object = get_engine_json_data(engine_path=engine_path)
return list(map(lambda rel_path: (pathlib.Path(engine_path) / rel_path).as_posix(),
engine_object['external_subdirectories'])) if 'external_subdirectories' in engine_object else []
engine_object['restricted'])) if 'restricted' in engine_object else []
# project.json queries
@ -292,7 +292,7 @@ def get_project_gems(project_path: pathlib.Path) -> list:
def is_gem_subdirectory(subdir):
return (pathlib.Path(subdir) / 'gem.json').exists()
external_subdirs = get_project_external_subdirectories()
external_subdirs = get_project_external_subdirectories(project_path)
return list(filter(is_gem_subdirectory, external_subdirs)) if external_subdirs else []
@ -302,26 +302,42 @@ def get_project_external_subdirectories(project_path: pathlib.Path) -> list:
project_object['external_subdirectories'])) if 'external_subdirectories' in project_object else []
# Combined manifest queries
def get_all_projects() -> list:
engine_projects = get_engine_projects()
projects_data = get_projects()
projects_data.extend(engine_projects)
return projects_data
projects_data = set(get_projects())
projects_data.update(get_engine_projects())
return list(projects_data)
def get_all_gems() -> list:
engine_gems = get_engine_gems()
gems_data = get_gems()
gems_data.extend(engine_gems)
return gems_data
def get_all_gems(project_path: pathlib.Path = None) -> list:
gems_data = set(get_gems())
gems_data.update(get_engine_gems())
if project_path:
gems_data.update(get_project_gems(project_path))
return list(gems_data)
def get_all_external_subdirectories(project_path: pathlib.Path = None) -> list:
external_subdirectories_data = set(get_external_subdirectories())
external_subdirectories_data.update(get_engine_external_subdirectories())
if project_path:
external_subdirectories_data.update(get_project_external_subdirectories(project_path))
return list(templates_data)
def get_all_templates() -> list:
engine_templates = get_engine_templates()
templates_data = get_templates()
templates_data.extend(engine_templates)
return templates_data
templates_data = set(get_templates())
templates_data.update(get_engine_templates())
return list(templates_data)
def get_all_restricted() -> list:
restricted_data = set(get_restricted())
restricted_data.update(get_engine_restricted())
return list(gems_data)
# Template functions
def get_project_templates(): # temporary until we have a better way to do this... maybe template_type element
project_templates = []
for template in get_all_templates():

@ -20,3 +20,10 @@ ly_add_pytest(
TEST_SUITE smoke
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
)
ly_add_pytest(
NAME o3de_cmake
PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_cmake.py
TEST_SUITE smoke
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
)

@ -1,259 +0,0 @@
#
# 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.
#
import os
import pytest
from o3de import add_gem_project
TEST_WITHOUT_NO_GEM_CONTENT = """
# {BEGIN_LICENSE}
# 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.
# {END_LICENSE}
set(GEM_DEPENDENCIES
)
"""
TEST_WITHOUT_ONLY_GEM_CONTENT = """
# {BEGIN_LICENSE}
# 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.
# {END_LICENSE}
set(GEM_DEPENDENCIES
Gem::TestGem
)
"""
TEST_WITHOUT_ADDED_GEM_CONTENT = """
# {BEGIN_LICENSE}
# 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.
# {END_LICENSE}
set(GEM_DEPENDENCIES
Gem::ExistingGem
)
"""
TEST_WITH_ADDED_GEM_CONTENT = """
# {BEGIN_LICENSE}
# 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.
# {END_LICENSE}
set(GEM_DEPENDENCIES
Gem::TestGem
Gem::ExistingGem
)
"""
@pytest.mark.parametrize(
"contents, gem, expected_result, runtime_present, expect_failure", [
pytest.param(TEST_WITHOUT_ADDED_GEM_CONTENT, "TestGem", TEST_WITH_ADDED_GEM_CONTENT, True, False),
pytest.param(TEST_WITHOUT_ADDED_GEM_CONTENT, "TestGem", TEST_WITH_ADDED_GEM_CONTENT, False, True),
pytest.param(TEST_WITHOUT_ADDED_GEM_CONTENT, "/TestGem", TEST_WITH_ADDED_GEM_CONTENT, True, True),
pytest.param(TEST_WITHOUT_NO_GEM_CONTENT, "TestGem", TEST_WITHOUT_ONLY_GEM_CONTENT, True, False),
]
)
def test_add_gem_dependency(tmpdir, contents, gem, expected_result, runtime_present, expect_failure):
dev_root = str(tmpdir.join('dev').realpath()).replace('\\', '/')
os.makedirs(dev_root, exist_ok=True)
dev_project_gem_code = f'{dev_root}/TestProject/Gem/Code'
os.makedirs(dev_project_gem_code, exist_ok=True)
runtime_dependencies_cmake_file = f'{dev_project_gem_code}/runtime_dependencies.cmake'
if runtime_present:
if os.path.isfile(runtime_dependencies_cmake_file):
os.unlink(runtime_dependencies_cmake_file)
with open(runtime_dependencies_cmake_file, 'a') as s:
s.write(contents)
result = add_gem_project.add_gem_dependency(runtime_dependencies_cmake_file, gem)
if expect_failure:
assert result != 0
else:
assert result == 0
with open(runtime_dependencies_cmake_file, 'r') as s:
s_data = s.read()
assert s_data == expected_result
@pytest.mark.parametrize(
"contents, gem, expected_result, runtime_present, expect_failure", [
pytest.param(TEST_WITH_ADDED_GEM_CONTENT, "TestGem", TEST_WITHOUT_ADDED_GEM_CONTENT, True, False),
pytest.param(TEST_WITH_ADDED_GEM_CONTENT, "TestGem", TEST_WITHOUT_ADDED_GEM_CONTENT, False, True),
pytest.param(TEST_WITHOUT_ADDED_GEM_CONTENT, "TestGem", TEST_WITHOUT_ADDED_GEM_CONTENT, True, True)
]
)
def test_remove_gem_dependency(tmpdir, contents, gem, expected_result, runtime_present, expect_failure):
dev_root = str(tmpdir.join('dev').realpath()).replace('\\', '/')
os.makedirs(dev_root, exist_ok=True)
dev_project_gem_code = f'{dev_root}/TestProject/Gem/Code'
os.makedirs(dev_project_gem_code, exist_ok=True)
runtime_dependencies_cmake_file = f'{dev_project_gem_code}/runtime_dependencies.cmake'
if runtime_present:
if os.path.isfile(runtime_dependencies_cmake_file):
os.unlink(runtime_dependencies_cmake_file)
with open(runtime_dependencies_cmake_file, 'a') as s:
s.write(contents)
result = add_remove_gem.remove_gem_dependency(runtime_dependencies_cmake_file, gem)
if expect_failure:
assert result != 0
else:
assert result == 0
with open(runtime_dependencies_cmake_file, 'r') as s:
s_data = s.read()
assert s_data == expected_result
@pytest.mark.parametrize("add,"
" contents, gem, project, expected_result,"
" runtime_present, tool_present,"
" ask_for_runtime, ask_for_tool,"
" expect_failure", [
pytest.param(True,
TEST_WITHOUT_ADDED_GEM_CONTENT, "TestGem", "TestProject",
TEST_WITH_ADDED_GEM_CONTENT,
True, True,
True, True,
False),
pytest.param(True,
TEST_WITHOUT_ADDED_GEM_CONTENT, "TestGem", "TestProject",
TEST_WITH_ADDED_GEM_CONTENT,
True, False,
True, True,
True),
pytest.param(True,
TEST_WITHOUT_ADDED_GEM_CONTENT, "TestGem", "TestProject",
TEST_WITH_ADDED_GEM_CONTENT,
False, True,
True, True,
True),
pytest.param(True,
TEST_WITHOUT_ADDED_GEM_CONTENT, "TestGem", "TestProject",
TEST_WITH_ADDED_GEM_CONTENT,
False, False,
True, True,
True),
pytest.param(False,
TEST_WITH_ADDED_GEM_CONTENT, "TestGem", "TestProject",
TEST_WITHOUT_ADDED_GEM_CONTENT,
True, True,
True, True,
False),
pytest.param(False,
TEST_WITH_ADDED_GEM_CONTENT, "TestGem", "TestProject",
TEST_WITHOUT_ADDED_GEM_CONTENT,
True, False,
True, True,
True),
pytest.param(False,
TEST_WITH_ADDED_GEM_CONTENT, "TestGem", "TestProject",
TEST_WITHOUT_ADDED_GEM_CONTENT,
False, True,
True, True,
True),
pytest.param(False,
TEST_WITH_ADDED_GEM_CONTENT, "TestGem", "TestProject",
TEST_WITHOUT_ADDED_GEM_CONTENT,
False, False,
True, True,
True)
]
)
def test_add_remove_gem(tmpdir,
add,
contents, gem, project,
expected_result,
runtime_present, tool_present,
ask_for_runtime, ask_for_tool,
expect_failure):
dev_root = str(tmpdir.join('dev').realpath()).replace('\\', '/')
os.makedirs(dev_root, exist_ok=True)
dev_project_gem_code = f'{dev_root}/TestProject/Gem/Code'
os.makedirs(dev_project_gem_code, exist_ok=True)
runtime_dependencies_cmake_file = f'{dev_project_gem_code}/runtime_dependencies.cmake'
if runtime_present:
if os.path.isfile(runtime_dependencies_cmake_file):
os.unlink(runtime_dependencies_cmake_file)
with open(runtime_dependencies_cmake_file, 'a') as s:
s.write(contents)
tool_dependencies_cmake_file = f'{dev_project_gem_code}/tool_dependencies.cmake'
os.makedirs(dev_project_gem_code, exist_ok=True)
if tool_present:
if os.path.isfile(tool_dependencies_cmake_file):
os.unlink(tool_dependencies_cmake_file)
with open(tool_dependencies_cmake_file, 'w') as s:
s.write(contents)
project_folder = f'{dev_root}/TestProject'
os.makedirs(project_folder, exist_ok=True)
gems_folder = f'{dev_root}/Gems'
os.makedirs(gems_folder, exist_ok=True)
gem_folder = f'{gems_folder}/{gem}'
os.makedirs(gem_folder, exist_ok=True)
result = add_remove_gem.add_remove_gem(add, dev_root, gem, project, ask_for_runtime, ask_for_tool)
if expect_failure:
assert result != 0
else:
assert result == 0
if runtime_present:
with open(runtime_dependencies_cmake_file, 'r') as s:
s_data = s.read()
assert s_data == expected_result
if tool_present:
with open(tool_dependencies_cmake_file, 'r') as s:
s_data = s.read()
assert s_data == expected_result

@ -0,0 +1,69 @@
#
# 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.
#
import io
import json
import logging
import pytest
import pathlib
from unittest.mock import patch
from o3de import cmake
class TestGetEnabledGems:
@pytest.mark.parametrize(
"enable_gems_cmake_data, expected_set", [
pytest.param("""
# Comment
set(ENABLED_GEMS foo bar baz)
""", set(['foo', 'bar', 'baz'])),
pytest.param("""
# Comment
set(ENABLED_GEMS
foo
bar
baz
)
""", set(['foo', 'bar', 'baz'])),
pytest.param("""
# Comment
set(ENABLED_GEMS
foo
bar
baz)
""", set(['foo', 'bar', 'baz'])),
pytest.param("""
# Comment
set(ENABLED_GEMS
foo bar
baz)
""", set(['foo', 'bar', 'baz'])),
pytest.param("""
# Comment
set(RANDOM_VARIABLE TestGame, TestProject Test Engine)
set(ENABLED_GEMS HelloWorld IceCream
foo
baz bar
baz baz baz baz baz morebaz lessbaz
)
Random Text
""", set(['HelloWorld', 'IceCream', 'foo', 'bar', 'baz', 'morebaz', 'lessbaz'])),
]
)
def test_get_enabled_gems(self, enable_gems_cmake_data, expected_set):
enabled_gems_set = set()
with patch('pathlib.Path.resolve', return_value=pathlib.Path('enabled_gems.cmake')) as pathlib_is_resolve_mock,\
patch('pathlib.Path.is_file', return_value=True) as pathlib_is_file_mock,\
patch('pathlib.Path.open', return_value=io.StringIO(enable_gems_cmake_data)) as pathlib_open_mock:
enabled_gems_set = cmake.get_enabled_gems(pathlib.Path('enabled_gems.cmake'))
assert enabled_gems_set == expected_set

@ -29,7 +29,7 @@ executable_path = ''
logger = logging.getLogger()
logger.setLevel(logging.INFO)
from o3de import add_gem_project, cmake, engine_template, manifest, register, remove_gem_project
from o3de import disable_gem, enable_gem, cmake, engine_template, manifest, register
o3de_folder = manifest.get_o3de_folder()
o3de_logs_folder = manifest.get_o3de_logs_folder()
@ -671,8 +671,8 @@ class ProjectManagerDialog(QObject):
gem_paths = manifest.get_all_gems()
for gem_target in self.manage_project_gem_targets_get_selected_available_gems():
for gem_path in gem_paths:
add_gem_project.add_gem_to_project(gem_path=gem_path,
project_path=self.get_selected_project_path())
enable_gem.enable_gem_in_project(gem_path=gem_path,
project_path=self.get_selected_project_path())
self.refresh_project_gem_targets_available_list()
self.refresh_project_gem_targets_enabled_list()
return
@ -683,8 +683,8 @@ class ProjectManagerDialog(QObject):
gem_paths = manifest.get_all_gems()
for gem_target in self.manage_project_gem_targets_get_selected_enabled_gems():
for gem_path in gem_paths:
remove_gem_project.remove_gem_from_project(gem_path=gem_path,
project_path=self.get_selected_project_path())
disable_gem.disable_gem_in_project(gem_path=gem_path,
project_path=self.get_selected_project_path())
self.refresh_project_gem_targets_available_list()
self.refresh_project_gem_targets_enabled_list()
return

Loading…
Cancel
Save