Skip to content

Commit

Permalink
core: support building template with editor
Browse files Browse the repository at this point in the history
  • Loading branch information
ericoporto committed Nov 24, 2024
1 parent ae0e77a commit a1fdd8e
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 9 deletions.
9 changes: 9 additions & 0 deletions src/agstoolbox/core/ags/ags_editor_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

from typing import Final

from agstoolbox.core.version.version import Version
from agstoolbox.core.version.version_utils import version_str_to_version, is_version_a_bigger_than_b


def get_installable_ags_versions() -> list[str]:
versions: Final[list[str]] = [
'3.4.3',
Expand All @@ -15,3 +19,8 @@ def get_installable_ags_versions() -> list[str]:
'4.0.0']

return versions

def is_ags4(version: Version) -> bool:
# there is an off-by-one mistake here, but let's leave this for now
ags4_first: Version = version_str_to_version('3.99.99')
return is_version_a_bigger_than_b(version, ags4_first)
5 changes: 5 additions & 0 deletions src/agstoolbox/core/ags/ags_local_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ def ags_editor_load(editor: LocalAgsEditor, project: GameProject, block: bool =
def ags_editor_build(editor: LocalAgsEditor, project: GameProject, block: bool = False) -> int:
project_path = get_absolute_path(project.path)
return run_exe_params(editor.path, block, ['/compile', project_path])


def ags_editor_template_build(editor: LocalAgsEditor, project: GameProject, block: bool = False) -> int:
project_path = get_absolute_path(project.path)
return run_exe_params(editor.path, block, ['/template', project_path])
53 changes: 47 additions & 6 deletions src/agstoolbox/core/ags/ags_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
import fnmatch
import os
import re
from shutil import move as shutil_move
from typing import List
from pathlib import Path

from agstoolbox.core.ags.ags_editor_versions import is_ags4
from agstoolbox.core.ags.datafile_writer import get_multifile_lib, make_data_file_from_multifile_lib
from agstoolbox.core.ags.game_project import GameProject
from agstoolbox.core.ags.multifilelib import MultiFileLib
from agstoolbox.core.utils.file import join_paths_as_posix
from agstoolbox.core.utils.file import join_paths_as_posix, get_file_if_exists, get_absolute_path, \
get_posix
from agstoolbox.core.version.version import Version
from agstoolbox.core.version.version_utils import version_str_to_version, \
is_version_a_bigger_than_b, is_version_a_between_bc


def case_insensitive_glob(directory: str, file_mask: str) -> list[Path]:
Expand Down Expand Up @@ -75,16 +81,51 @@ def create_template_from_game_dir(project_dir: str, template_filepath: str):
mlib: MultiFileLib = get_multifile_lib(filelist, project_dir, template_filename, False)
make_data_file_from_multifile_lib(mlib, template_dir)

# Note, in ags
# v4.0.0.9, v4.0.0.10 ...
# and
# v3.6.2.1, v3.6.2.2 ...
# /template command is supported in the Editor

# the command below builds using a reimplemented template export
# the one using the editor is in ags_local_run
def create_template_from_project(game_project: GameProject, template_name: str, out: str | None):
if out is None:
out = game_project.directory

template_name = Path(template_name).name
template_filepath: str = join_paths_as_posix(out, template_name)
create_template_from_game_dir(game_project.directory, template_filepath)


# Note, in ags
# v4.0.0.9, v4.0.0.10 ...
# and
# v3.6.2.1, v3.6.2.2 ...
# /template command is supported in the Editor
def editor_supports_template_export(game_project: GameProject) -> bool:
ags3_first_sup: Version = version_str_to_version('3.6.2.1')
ags4_first_sup: Version = version_str_to_version('4.0.0.9')
ags3_to_ags4_ver: Version = version_str_to_version('3.99.0.0')
ags4: bool = is_ags4(game_project.ags_editor_version)
if ags4:
return is_version_a_bigger_than_b(game_project.ags_editor_version, ags4_first_sup)
else:
return is_version_a_between_bc(game_project.ags_editor_version, ags3_first_sup, ags3_to_ags4_ver)


# Template built with editor uses instead GameFileName + ".agt"
def fix_editor_built_template(game_project: GameProject, out_dir: str, filename: str) -> bool:
built_dir: str = game_project.directory
built_file: str = game_project.game_file + ".agt"
built_filename = get_file_if_exists(built_dir, built_file)
if built_filename is None:
return False

built_filename = get_posix(get_absolute_path(built_filename))
target_filename: str = get_posix(get_absolute_path(os.path.join(out_dir, filename)))
if target_filename == built_filename:
# no need to do anything
return True

existing_target_filename: str = get_file_if_exists(out_dir, filename)
if existing_target_filename is not None:
shutil_move(existing_target_filename, existing_target_filename + ".bkp")

shutil_move(built_filename, target_filename)
return True
53 changes: 50 additions & 3 deletions src/agstoolbox/core/cmdline/cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
from agstoolbox.core.ags.ags_editor import LocalAgsEditor
from agstoolbox.core.ags.ags_export import export_script_module_from_project
from agstoolbox.core.ags.ags_local_run import ags_editor_load, ags_editor_start, \
ags_editor_build
from agstoolbox.core.ags.ags_template import create_template_from_project
ags_editor_build, ags_editor_template_build
from agstoolbox.core.ags.ags_template import create_template_from_project, \
editor_supports_template_export, fix_editor_built_template
from agstoolbox.core.ags.game_project import GameProject
from agstoolbox.core.ags.get_game_projects import list_game_projects_in_dir, \
list_game_projects_in_dir_list, get_unique_game_project_in_path
Expand All @@ -30,6 +31,12 @@
from agstoolbox.core.version.version_utils import version_str_to_version


class MetaCmdProjectArgs:
which_only: bool
block: bool
prj_path: str


def meta_cmd_project(args, is_open: bool,
ags_editor_proj_command: Callable[
[LocalAgsEditor, GameProject, bool], int] = None) -> int:
Expand All @@ -38,6 +45,18 @@ def meta_cmd_project(args, is_open: bool,
which_only = args.which_editor and True
block: bool = not args.non_blocking
prj_path: str = args.PROJECT_PATH
meta_args: MetaCmdProjectArgs = MetaCmdProjectArgs()
meta_args.block = block
meta_args.which_only = which_only
meta_args.prj_path = prj_path
return base_meta_cmd_project(meta_args, is_open, ags_editor_proj_command)

def base_meta_cmd_project(meta_args: MetaCmdProjectArgs, is_open: bool,
ags_editor_proj_command: Callable[
[LocalAgsEditor, GameProject, bool], int] = None) -> int:
which_only: bool = meta_args.which_only
block: bool = meta_args.block
prj_path: str = meta_args.prj_path

if not Path(prj_path).exists():
print('ERROR: Invalid project path')
Expand Down Expand Up @@ -290,10 +309,31 @@ def at_cmd_settings(args):
return


def at_cmd_export_template_editor(game_project: GameProject, out_dir: str, template_name: str) -> int:
meta_args: MetaCmdProjectArgs = MetaCmdProjectArgs()
meta_args.block = True
meta_args.which_only = False
meta_args.prj_path = game_project.path

if not editor_supports_template_export(game_project):
print('ERROR: Project uses Editor "' + game_project.ags_editor_version.as_str +
'", which doesn\'t support /template command')
return -1

res: int = base_meta_cmd_project(meta_args, False, ags_editor_template_build)
success: bool = fix_editor_built_template(game_project, out_dir, template_name)
if not success:
print('ERROR: Failed to rename template')
return -1

return res


def at_cmd_export(args):
target_name: str = str()
prj_path: str = args.PROJECT_PATH
out_dir: str = args.OUT_DIR
force_editor: bool = not args.force_editor
if args.sub_export == 'script':
target_name = args.MODULE_NAME
else:
Expand Down Expand Up @@ -323,7 +363,12 @@ def at_cmd_export(args):

export_script_module_from_project(game_project, mod_name, out_dir)
else:
create_template_from_project(game_project, target_name, out_dir)
if force_editor:
return at_cmd_export_template_editor(game_project=game_project,
template_name=target_name,
out_dir=out_dir)
else:
create_template_from_project(game_project, target_name, out_dir)


def cmdline(show_help_when_empty: bool, program_name: str):
Expand Down Expand Up @@ -426,6 +471,8 @@ def cmdline(show_help_when_empty: bool, program_name: str):
help='name of the template (e.g. "template.agt")')
p_eet.add_argument('OUT_DIR',
help='where to export the template').complete = shtab.DIRECTORY
p_eet.add_argument('-f', '--force-editor', action='store_true', default=False,
help='use editor for template export')

args = parser.parse_args()
if 'func' in args.__dict__:
Expand Down
4 changes: 4 additions & 0 deletions src/agstoolbox/core/utils/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def get_file(filepath: str):
return os.path.basename(Path(filepath).as_posix())


def get_posix(filepath: str):
return Path(filepath).as_posix()


def get_absolute_path(filepath: str) -> str:
return os.path.abspath(os.path.expanduser(os.path.expandvars(filepath)))

Expand Down
8 changes: 8 additions & 0 deletions src/agstoolbox/core/version/version_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,11 @@ def tag_to_version(tag: str) -> Version:

def version_str_to_version(version_str: str) -> Version:
return tag_to_version(version_str)


def is_version_a_bigger_than_b(a: Version, b: Version) -> bool:
return a.as_int > b.as_int


def is_version_a_between_bc(a: Version, b: Version, c: Version) -> bool:
return (a.as_int > b.as_int) and (a.as_int < c.as_int)

0 comments on commit a1fdd8e

Please sign in to comment.