Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .changelog/21.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Various fixes for the engine resolver
23 changes: 14 additions & 9 deletions src/uepyscripts/internal/engine_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from pydantic import BaseModel

from .. import logger
from ..internal.project import Project
from ..tools.helpers import get_engine_root_folder_from_env_var, is_engine_from_egs
from ..tools.winreg import get_registry_value
Expand All @@ -17,9 +18,7 @@ def resolve_engine_from_env_var(project: Project) -> Optional[Path]:
def resolve_engine_from_registry(project: Project) -> Optional[Path]:
path = get_registry_value(winreg.HKEY_CURRENT_USER, r"SOFTWARE\Epic Games\Unreal Engine\Builds", project.engine_association)
if path:
path = Path(path)
if path.exists():
return path
return Path(path)

return None

Expand All @@ -30,9 +29,7 @@ def resolve_engine_from_egs(project: Project) -> Optional[Path]:
winreg.HKEY_LOCAL_MACHINE, rf"SOFTWARE\EpicGames\Unreal Engine\{project.engine_association}", "InstalledDirectory"
)
if registry_value:
path = Path(registry_value)
if path.exists():
return path
return Path(registry_value)

# Some installations are listed in LauncherInstalled.dat
class EpicInstallation(BaseModel):
Expand Down Expand Up @@ -69,13 +66,16 @@ def get_dat_file_path() -> Path:
return Path(item.InstallLocation)

except Exception as e:
print(f"Error parsing manifest: {e}")
logger.error(f"Error parsing manifest: {e}")

return None


def resolve_engine_from_path(project: Project) -> Optional[Path]:
path = Path(project.engine_association)
if not os.path.isabs(path):
path = (project.root_folder / path).resolve()

if os.path.isabs(path):
return path

Expand All @@ -84,20 +84,25 @@ def resolve_engine_from_path(project: Project) -> Optional[Path]:

def resolve_engine_path(project: Project) -> Path:
resolvers = [
resolve_engine_from_env_var,
resolve_engine_from_registry,
resolve_engine_from_egs,
resolve_engine_from_path,
# Resolve last with the environment variable to avoid failing the resolution on a machine
# where there's the environment variable but the engine is installed using the launcher
resolve_engine_from_env_var,
]

for resolver in resolvers:
path = resolver(project)
if path:
logger.info(f"Engine path resolved via '{resolver.__name__}': {path}")
break
else:
raise FileNotFoundError("Impossible to locate the engine")

if not (path.exists() and str(path).replace(" ", "") not in ["", ".", "\\"]):
path_str = str(path).strip()
# Check that the path exists and is not a degenerate path containing only . or \\
if not (path.exists() and path_str not in ["", ".", "\\"]):
raise FileNotFoundError("Impossible to locate the engine")

return path
5 changes: 1 addition & 4 deletions src/uepyscripts/tools/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ def get_engine_root_folder_from_env_var(project_engine_association: str) -> Opti
path = Path(node_ue_root)
if project_engine_association:
path = path.joinpath(project_engine_association)
if path.exists():
return path

raise FileNotFoundError(f"The environment variable is set to {node_ue_root} but the folder {path} does not exist")
return path

return None

Expand Down
8 changes: 7 additions & 1 deletion src/uepyscripts/tools/ue/check_engine_installation.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"""

import argparse
from pathlib import Path

from ... import logger
from ...internal.engine import resolve_engine
Expand All @@ -26,6 +27,11 @@
def parse_arguments() -> argparse.Namespace:
"""Parse command line arguments."""
parser = argparse.ArgumentParser(description="Check and install Unreal Engine installation for the given project.")
parser.add_argument(
"--uproject_path",
type=Path,
help=("Optional path to a uproject file.If not set, resolve_project will try to find one in its folder hierarchy"),
)
parser.add_argument("--unattended", action="store_true", help="Disable interactive prompts")

return parser.parse_args()
Expand All @@ -37,7 +43,7 @@ def main() -> None:
args = parse_arguments()

try:
project = resolve_project()
project = resolve_project(args.uproject_path)
except Exception as e:
logger.fatal(f"Project resolution failed: {e}")
exit(1)
Expand Down
Loading