Game.Modding.Toolchain.Dependencies.NpxModProjectDependency
Assembly:
Namespace: Game.Modding.Toolchain.Dependencies
Type: class
Base: BaseDependency
Summary:
Handles installing, uninstalling and checking the Colossal UI mod NPX template ("create-csii-ui-mod") in the user's global npm modules. It uses the npm CLI (via CliWrap) to query the global npm prefix and to run npm link
in the packaged template folder. The dependency declares a runtime dependency on NodeJSDependency and exposes environment variables used by the toolchain.
Fields
-
private const string kProjectName = "UI Mod project template"
This human-friendly name used in logs and state messages. -
private const string kModuleNamespace = "@colossalorder"
The npm scope / namespace under which the NPX package is installed. -
private const string kModuleName = "create-csii-ui-mod"
The NPX package name that provides the UI mod creation template. -
private static readonly string kNpxPackagePath = Path.GetFullPath(Path.Combine(ToolchainDependencyManager.kGameToolingPath, "npx-create-csii-ui-mod"))
Absolute path inside the toolchain installation that contains the local package which will be linked into the global npm modules vianpm link
. Used when installing and when verifying if the global module points back to this package (symlink target comparison).
Properties
-
public override Type[] dependsOnInstallation { get; }
Depends on NodeJSDependency for installation. The property returns an array containing typeof(NodeJSDependency), indicating Node.js must be present before installing this dependency. -
public override Type[] dependsOnUninstallation { get; }
Depends on NodeJSDependency for uninstallation as well (same as installation dependency). -
public override IEnumerable<string> envVariables { get; }
Enumerates environment variables that are relevant to this dependency: "CSII_PATHSET" and "CSII_USERDATAPATH". These are yielded by the property for the toolchain to know which env vars are used. -
public override string name { get; }
Returns the display name: "UI template". -
public override string icon { get; }
Returns the icon path used in the UI: "Media/Menu/ColossalLogo.svg".
Constructors
public NpxModProjectDependency()
No explicit constructor is declared in the class; the default parameterless constructor is used. Initialization is minimal — most work is performed in the async methods.
Methods
-
private async Task<string> GetGlobalNodeModulePath(CancellationToken token)
Queriesnpm config get prefix
using CliWrap to obtain the global npm prefix (the folder where global packages and node_modules are located). Captures stdout into a string and logs errors or warnings via IToolchainDependency.log. Returns the raw path string (may be empty on failure). Handles Win32Exception and general Exception logging. -
public override async Task<bool> IsInstalled(CancellationToken token)
Determines whether the scoped folder "@colossalorder" exists under the global npm prefix's "node_modules". Uses GetGlobalNodeModulePath and LongDirectory utilities. Returns true if the expected namespace folder exists. -
public override async Task<bool> IsUpToDate(CancellationToken token)
Checks whether the global installed package "create-csii-ui-mod" is a symlink that points to the packaged kNpxPackagePath. Uses LongFile.TryGetSymlinkTarget to resolve the symlink target. If the package is not present or not a symlink, the method conservatively returns true in some cases (i.e., nothing to update) but if a symlink exists it compares the target to kNpxPackagePath. -
public override Task<bool> NeedDownload(CancellationToken token)
Returns Task.FromResult(false). This dependency does not need network download through the toolchain (it uses a local package + npm link). -
public override Task Download(CancellationToken token)
A no-op; returns Task.CompletedTask. -
public override async Task Install(CancellationToken token)
Performs installation by runningnpm link
in the kNpxPackagePath folder via CliWrap. Updates base.state to DependencyState.Installing and logs progress. Captures stdout/stderr and logs warnings if any stderr output is produced. Exceptions are translated into ToolchainException(ToolchainError.Install) for failures (except for OperationCanceledException and ToolchainException which are rethrown). -
private static async Task DeleteNpxModule(string globalNodeModulePath, string moduleNamespace, string moduleName, CancellationToken token)
Removes files matching moduleName* inside the globalNodeModulePath and deletes the scoped node_modules/moduleNamespace directory recursively. Validates arguments (throws ArgumentException or DirectoryNotFoundException as appropriate) then uses LongDirectory.GetFiles and AsyncUtils.DeleteFileAsync / DeleteDirectoryAsync to clean up the files and namespace directory. -
public override async Task Uninstall(CancellationToken token)
Removes the NPX module from the global prefix. Queries the global path using GetGlobalNodeModulePath, then calls DeleteNpxModule to delete matching module files and the scoped namespace folder. Updates base.state to DependencyState.Removing. Exceptions are translated into ToolchainException(ToolchainError.Uninstall) except for cancellations and existing ToolchainExceptions. -
public override Task<List<IToolchainDependency.DiskSpaceRequirements>> GetRequiredDiskSpace(CancellationToken token)
Returns an empty list of disk space requirements (Task.FromResult(new List<...>())), indicating no special disk reservations are required by the toolchain for this dependency.
Usage Example
// Example usage: check install state, install if missing.
// Assumes you have a CancellationToken `token` and the toolchain environment configured.
var dep = new NpxModProjectDependency();
if (!await dep.IsInstalled(token).ConfigureAwait(false))
{
try
{
// Install will run `npm link` inside the packaged template path.
await dep.Install(token).ConfigureAwait(false);
}
catch (ToolchainException tex)
{
// Installation failed — handle or surface the error to the user.
IToolchainDependency.log.Error(tex, "Failed to install UI template");
throw;
}
}
// To uninstall:
await dep.Uninstall(token).ConfigureAwait(false);
{{ Additional notes:
- This class relies on the npm CLI being available on PATH (hence the NodeJSDependency requirement).
- It uses CliWrap to run external commands and LongFile/LongDirectory helpers for large-path-safe filesystem operations.
- Installation performs an npm link
from the toolchain's packaged npx-create-csii-ui-mod
folder to the global node_modules, so administrative privileges may be required on some systems depending on npm configuration.
- IsUpToDate specifically checks for a symlink target pointing to the packaged path; if users have a different version installed or a real installation (not a symlink), behavior is conservative.
}}