|
@@ -9,7 +9,7 @@
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
#
|
|
|
"""
|
|
|
-Contains command to add a gem to a project's cmake scripts
|
|
|
+Contains command to add a gem to a project's enabled_gem.cmake file
|
|
|
"""
|
|
|
|
|
|
import argparse
|
|
@@ -24,55 +24,51 @@ from o3de import cmake, manifest, validation
|
|
|
logger = logging.getLogger()
|
|
|
logging.basicConfig()
|
|
|
|
|
|
-def add_gem_dependency(cmake_file: str or pathlib.Path,
|
|
|
- gem_target: str) -> int:
|
|
|
+def add_gem_dependency(cmake_file: pathlib.Path,
|
|
|
+ gem_name: str) -> int:
|
|
|
"""
|
|
|
adds a gem dependency to a cmake file
|
|
|
:param cmake_file: path to the cmake file
|
|
|
- :param gem_target: name of the cmake target
|
|
|
+ :param gem_name: name of the gem
|
|
|
:return: 0 for success or non 0 failure code
|
|
|
"""
|
|
|
- if not os.path.isfile(cmake_file):
|
|
|
- logger.error(f'Failed to locate cmake file {cmake_file}')
|
|
|
+ if not cmake_file.is_file():
|
|
|
+ logger.error(f'Failed to locate cmake file {str(cmake_file)}')
|
|
|
return 1
|
|
|
|
|
|
- # on a line by basis, see if there already is Gem::{gem_name}
|
|
|
+ # on a line by basis, see if there already is {gem_name}
|
|
|
# find the first occurrence of a gem, copy its formatting and replace
|
|
|
# the gem name with the new one and append it
|
|
|
# if the gem is already present fail
|
|
|
t_data = []
|
|
|
added = False
|
|
|
+ line_index_to_append = None
|
|
|
with open(cmake_file, 'r') as s:
|
|
|
+ line_index = 0
|
|
|
for line in s:
|
|
|
- if f'Gem::{gem_target}' in line:
|
|
|
- logger.warning(f'{gem_target} is already a gem dependency.')
|
|
|
+ if 'ENABLED_GEMS' in line:
|
|
|
+ line_index_to_append = line_index
|
|
|
+ if f'{gem_name}' == line.strip():
|
|
|
+ logger.warning(f'{gem_name} is already enabled in file {str(cmake_file)}.')
|
|
|
return 0
|
|
|
- if not added and r'Gem::' in line:
|
|
|
- new_gem = ' ' * line.find(r'Gem::') + f'Gem::{gem_target}\n'
|
|
|
- t_data.append(new_gem)
|
|
|
- added = True
|
|
|
t_data.append(line)
|
|
|
+ line_index += 1
|
|
|
|
|
|
- # if we didn't add it the set gem dependencies could be empty so
|
|
|
+
|
|
|
+ indent = 4
|
|
|
+ if line_index_to_append:
|
|
|
+ t_data[line_index_to_append] = f'{" " * indent}{gem_name}\n'
|
|
|
+ added = True
|
|
|
+
|
|
|
+ # if we didn't add, then create a new set(ENABLED_GEMS) variable
|
|
|
# add a new gem, if empty the correct format is 1 tab=4spaces
|
|
|
- if not added:
|
|
|
- index = 0
|
|
|
- for line in t_data:
|
|
|
- index = index + 1
|
|
|
- if r'set(GEM_DEPENDENCIES' in line:
|
|
|
- t_data.insert(index, f' Gem::{gem_target}\n')
|
|
|
- added = True
|
|
|
- break
|
|
|
-
|
|
|
- # if we didn't add it then it's not here, add a whole new one
|
|
|
if not added:
|
|
|
t_data.append('\n')
|
|
|
- t_data.append('set(GEM_DEPENDENCIES\n')
|
|
|
- t_data.append(f' Gem::{gem_target}\n')
|
|
|
+ t_data.append('set(ENABLED_GEMS\n')
|
|
|
+ t_data.append(f'{" " * indent}{gem_name}\n')
|
|
|
t_data.append(')\n')
|
|
|
|
|
|
# write the cmake
|
|
|
- os.unlink(cmake_file)
|
|
|
with open(cmake_file, 'w') as s:
|
|
|
s.writelines(t_data)
|
|
|
|
|
@@ -80,29 +76,19 @@ def add_gem_dependency(cmake_file: str or pathlib.Path,
|
|
|
|
|
|
|
|
|
def add_gem_to_project(gem_name: str = None,
|
|
|
- gem_path: str or pathlib.Path = None,
|
|
|
- gem_target: str = None,
|
|
|
+ gem_path: pathlib.Path = None,
|
|
|
project_name: str = None,
|
|
|
- project_path: str or pathlib.Path = None,
|
|
|
- dependencies_file: str or pathlib.Path = None,
|
|
|
- runtime_dependency: bool = False,
|
|
|
- tool_dependency: bool = False,
|
|
|
- server_dependency: bool = False,
|
|
|
- platforms: str = 'Common',
|
|
|
- add_to_cmake: bool = True) -> int:
|
|
|
+ project_path: pathlib.Path = None,
|
|
|
+ enabled_gem_file: pathlib.Path = None,
|
|
|
+ platforms: str = 'Common') -> int:
|
|
|
"""
|
|
|
add a gem to a project
|
|
|
:param gem_name: name of the gem to add
|
|
|
:param gem_path: path to the gem to add
|
|
|
- :param gem_target: the name of the cmake gem module
|
|
|
: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 dependencies_file: if this dependency goes/is in a specific file
|
|
|
- :param runtime_dependency: bool to specify this is a runtime gem for the game
|
|
|
- :param tool_dependency: bool to specify this is a tool gem for the editor
|
|
|
- :param server_dependency: bool to specify this is a server gem for the server
|
|
|
+ :param enabled_gem_file_file: if this dependency goes/is in a specific file
|
|
|
:param platforms: str to specify common or which specific platforms
|
|
|
- :param add_to_cmake: bool to specify that this gem should be added to cmake
|
|
|
:return: 0 for success or non 0 failure code
|
|
|
"""
|
|
|
# we need either a project name or path
|
|
@@ -113,35 +99,16 @@ def add_gem_to_project(gem_name: str = None,
|
|
|
# if project name resolve it into a path
|
|
|
if project_name and not project_path:
|
|
|
project_path = manifest.get_registered(project_name=project_name)
|
|
|
+ if not project_path:
|
|
|
+ logger.error(f'Unable to locate project path from the registered manifest.json files:'
|
|
|
+ f' {str(pathlib.Path.home() / ".o3de/manifest.json")}, engine.json')
|
|
|
+ return 1
|
|
|
+
|
|
|
project_path = pathlib.Path(project_path).resolve()
|
|
|
if not project_path.is_dir():
|
|
|
logger.error(f'Project path {project_path} is not a folder.')
|
|
|
return 1
|
|
|
|
|
|
- # get the engine name this project is associated with
|
|
|
- # and resolve that engines path
|
|
|
- project_json = project_path / 'project.json'
|
|
|
- if not validation.valid_o3de_project_json(project_json):
|
|
|
- logger.error(f'Project json {project_json} is not valid.')
|
|
|
- return 1
|
|
|
- with project_json.open('r') as s:
|
|
|
- try:
|
|
|
- project_json_data = json.load(s)
|
|
|
- except json.JSONDecodeError as e:
|
|
|
- logger.error(f'Error loading Project json {project_json}: {str(e)}')
|
|
|
- return 1
|
|
|
- else:
|
|
|
- try:
|
|
|
- engine_name = project_json_data['engine']
|
|
|
- except KeyError as e:
|
|
|
- logger.error(f'Project json {project_json} "engine" not found: {str(e)}')
|
|
|
- return 1
|
|
|
- else:
|
|
|
- engine_path = manifest.get_registered(engine_name=engine_name)
|
|
|
- if not engine_path:
|
|
|
- logger.error(f'Engine {engine_name} is not registered.')
|
|
|
- return 1
|
|
|
-
|
|
|
# we need either a gem name or path
|
|
|
if not gem_name and not gem_path:
|
|
|
logger.error(f'Must either specify a Gem path or Gem Name.')
|
|
@@ -150,94 +117,47 @@ def add_gem_to_project(gem_name: str = None,
|
|
|
# if gem name resolve it into a path
|
|
|
if gem_name and not gem_path:
|
|
|
gem_path = manifest.get_registered(gem_name=gem_name)
|
|
|
+ if not gem_path:
|
|
|
+ logger.error(f'Unable to locate gem path from the registered manifest.json files:'
|
|
|
+ f' {str(pathlib.Path.home() / ".o3de/manifest.json")},'
|
|
|
+ f' {project_path / "project.json"}, engine.json')
|
|
|
+ return 1
|
|
|
+
|
|
|
gem_path = pathlib.Path(gem_path).resolve()
|
|
|
# make sure this gem already exists if we're adding. We can always remove a gem.
|
|
|
if not gem_path.is_dir():
|
|
|
logger.error(f'Gem Path {gem_path} does not exist.')
|
|
|
return 1
|
|
|
|
|
|
- # if add to cmake, make sure the gem.json exists and valid before we proceed
|
|
|
- if add_to_cmake:
|
|
|
- gem_json = gem_path / 'gem.json'
|
|
|
- if not gem_json.is_file():
|
|
|
- logger.error(f'Gem json {gem_json} is not present.')
|
|
|
- return 1
|
|
|
- if not validation.valid_o3de_gem_json(gem_json):
|
|
|
- logger.error(f'Gem json {gem_json} is not valid.')
|
|
|
- return 1
|
|
|
-
|
|
|
- # find all available modules in this gem_path
|
|
|
- modules = cmake.get_gem_targets(gem_path=gem_path)
|
|
|
- if len(modules) == 0:
|
|
|
- logger.error(f'No gem modules found under {gem_path}.')
|
|
|
- return 1
|
|
|
-
|
|
|
- # if the gem has no modules and the user has specified a target fail
|
|
|
- if gem_target and not modules:
|
|
|
- logger.error(f'Gem has no targets, but gem target {gem_target} was specified.')
|
|
|
+ # Read gem.json from the gem path
|
|
|
+ gem_json_data = manifest.get_gem_json_data(gem_path=gem_path)
|
|
|
+ if not gem_json_data:
|
|
|
+ logger.error(f'Could not read gem.json content under {gem_path}.')
|
|
|
return 1
|
|
|
|
|
|
- # if the gem target is not in the modules
|
|
|
- if gem_target not in modules:
|
|
|
- logger.error(f'Gem target not in gem modules: {modules}')
|
|
|
- return 1
|
|
|
|
|
|
- if gem_target:
|
|
|
- # if the user has not specified either we will assume they meant the most common which is runtime
|
|
|
- if not runtime_dependency and not tool_dependency and not server_dependency and not dependencies_file:
|
|
|
- logger.warning("Dependency type not specified: Assuming '--runtime-dependency'")
|
|
|
- runtime_dependency = True
|
|
|
-
|
|
|
- ret_val = 0
|
|
|
-
|
|
|
- # if the user has specified the dependencies file then ignore the runtime_dependency and tool_dependency flags
|
|
|
- if dependencies_file:
|
|
|
- dependencies_file = pathlib.Path(dependencies_file).resolve()
|
|
|
- # make sure this is a project has a dependencies_file
|
|
|
- if not dependencies_file.is_file():
|
|
|
- logger.error(f'Dependencies file {dependencies_file} is not present.')
|
|
|
- return 1
|
|
|
- # add the dependency
|
|
|
- ret_val = add_gem_dependency(dependencies_file, gem_target)
|
|
|
+ ret_val = 0
|
|
|
+ if enabled_gem_file:
|
|
|
+ # make sure this is a project has a dependencies_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
|
|
|
+ ret_val = add_gem_dependency(enabled_gem_file, gem_json_data['gem_name'])
|
|
|
|
|
|
+ else:
|
|
|
+ if ',' in platforms:
|
|
|
+ platforms = platforms.split(',')
|
|
|
else:
|
|
|
- if ',' in platforms:
|
|
|
- platforms = platforms.split(',')
|
|
|
- else:
|
|
|
- platforms = [platforms]
|
|
|
- for platform in platforms:
|
|
|
- if runtime_dependency:
|
|
|
- # make sure this is a project has a runtime_dependencies.cmake file
|
|
|
- project_runtime_dependencies_file = pathlib.Path(
|
|
|
- cmake.get_dependencies_cmake_file(project_path=project_path, dependency_type='runtime',
|
|
|
- platform=platform)).resolve()
|
|
|
- if not project_runtime_dependencies_file.is_file():
|
|
|
- logger.error(f'Runtime dependencies file {project_runtime_dependencies_file} is not present.')
|
|
|
- return 1
|
|
|
- # add the dependency
|
|
|
- ret_val = add_gem_dependency(project_runtime_dependencies_file, gem_target)
|
|
|
-
|
|
|
- if (ret_val == 0) and tool_dependency:
|
|
|
- # make sure this is a project has a tool_dependencies.cmake file
|
|
|
- project_tool_dependencies_file = pathlib.Path(
|
|
|
- cmake.get_dependencies_cmake_file(project_path=project_path, dependency_type='tool',
|
|
|
- platform=platform)).resolve()
|
|
|
- if not project_tool_dependencies_file.is_file():
|
|
|
- logger.error(f'Tool dependencies file {project_tool_dependencies_file} is not present.')
|
|
|
- return 1
|
|
|
- # add the dependency
|
|
|
- ret_val = add_gem_dependency(project_tool_dependencies_file, gem_target)
|
|
|
-
|
|
|
- if (ret_val == 0) and server_dependency:
|
|
|
- # make sure this is a project has a tool_dependencies.cmake file
|
|
|
- project_server_dependencies_file = pathlib.Path(
|
|
|
- cmake.get_dependencies_cmake_file(project_path=project_path, dependency_type='server',
|
|
|
- platform=platform)).resolve()
|
|
|
- if not project_server_dependencies_file.is_file():
|
|
|
- logger.error(f'Server dependencies file {project_server_dependencies_file} is not present.')
|
|
|
- return 1
|
|
|
- # add the dependency
|
|
|
- ret_val = add_gem_dependency(project_server_dependencies_file, gem_target)
|
|
|
+ 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'])
|
|
|
|
|
|
return ret_val
|
|
|
|
|
@@ -248,15 +168,10 @@ def _run_add_gem_to_project(args: argparse) -> int:
|
|
|
|
|
|
return add_gem_to_project(args.gem_name,
|
|
|
args.gem_path,
|
|
|
- args.gem_target,
|
|
|
args.project_name,
|
|
|
args.project_path,
|
|
|
- args.dependencies_file,
|
|
|
- args.runtime_dependency,
|
|
|
- args.tool_dependency,
|
|
|
- args.server_dependency,
|
|
|
- args.platforms,
|
|
|
- args.add_to_cmake)
|
|
|
+ args.enabled_gem_file,
|
|
|
+ args.platforms)
|
|
|
|
|
|
|
|
|
def add_parser_args(parser):
|
|
@@ -267,38 +182,24 @@ def add_parser_args(parser):
|
|
|
:param parser: the caller passes an argparse parser like instance to this method
|
|
|
"""
|
|
|
group = parser.add_mutually_exclusive_group(required=True)
|
|
|
- group.add_argument('-pp', '--project-path', type=str, required=False,
|
|
|
+ group.add_argument('-pp', '--project-path', type=pathlib.Path, required=False,
|
|
|
help='The path to the project.')
|
|
|
group.add_argument('-pn', '--project-name', type=str, required=False,
|
|
|
help='The name of the project.')
|
|
|
group = parser.add_mutually_exclusive_group(required=True)
|
|
|
- group.add_argument('-gp', '--gem-path', type=str, required=False,
|
|
|
+ group.add_argument('-gp', '--gem-path', type=pathlib.Path, required=False,
|
|
|
help='The path to the gem.')
|
|
|
group.add_argument('-gn', '--gem-name', type=str, required=False,
|
|
|
help='The name of the gem.')
|
|
|
- parser.add_argument('-gt', '--gem-target', type=str, required=False,
|
|
|
- help='The cmake target name to add. If not specified it will assume gem_name')
|
|
|
- parser.add_argument('-df', '--dependencies-file', type=str, required=False,
|
|
|
- help='The cmake dependencies file in which the gem dependencies are specified.'
|
|
|
- 'If not specified it will assume ')
|
|
|
- parser.add_argument('-rd', '--runtime-dependency', action='store_true', required=False,
|
|
|
- default=False,
|
|
|
- help='Optional toggle if this gem should be added as a runtime dependency')
|
|
|
- parser.add_argument('-td', '--tool-dependency', action='store_true', required=False,
|
|
|
- default=False,
|
|
|
- help='Optional toggle if this gem should be added as a tool dependency')
|
|
|
- parser.add_argument('-sd', '--server-dependency', action='store_true', required=False,
|
|
|
- default=False,
|
|
|
- help='Optional toggle if this gem should be added as a server dependency')
|
|
|
+ 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.'
|
|
|
+ '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('-a', '--add-to-cmake', type=bool, required=False,
|
|
|
- default=True,
|
|
|
- help='Automatically call add-gem-to-cmake.')
|
|
|
|
|
|
- parser.add_argument('-ohf', '--override-home-folder', type=str, required=False,
|
|
|
+ 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)
|