/* * SPDX-License-Identifier: AGPL-3.0-or-later * Copyright (C) 2025 Sergej Görzen * This file is part of xAPI4Unity. */ #if UNITY_EDITOR using System.Diagnostics; using System.IO; using Dir = System.IO.Directory; namespace xAPI4Unity.Editor { /// /// Handles Git-related operations such as cloning repositories and managing submodules for xAPI4Unity. /// public class GitHelper { private Process _processHandle; // Maintains the process handle for ongoing Git operations. public string Url; // The repository URL. public string Directory; // The local directory where the repository is cloned. public bool IsBusy { get; private set; } // Indicates if a Git operation is in progress. /// /// Gets the path to the "xapi" directory in the repository. /// public string RepoDirectory => Path.Combine(Directory, "xapi"); /// /// Checks if the repository is valid and contains the required structure. /// public bool IsCloned => IsValidRepo(RepoDirectory); /// /// Initializes a new instance of with the specified repository URL and local directory. /// /// The repository URL (e.g., SSH or HTTPS). /// The local directory for cloning the repository. public GitHelper(string repoUrl, string directory) { Url = repoUrl; Directory = directory; } /// /// Determines if the provided repository path contains a "definitions" folder. /// /// The path to the repository. /// True if the "definitions" folder exists, otherwise false. public static bool HasDefinitionsFolder(string repoPath) => Dir.Exists(Path.Combine(repoPath, "definitions")); /// /// Validates if the provided path is a valid Git repository. /// /// The path to the repository. /// True if valid, otherwise false. public static bool IsValidRepo(string repoPath) => Dir.Exists(repoPath) && HasDefinitionsFolder(repoPath); /// /// Clones the repository as a submodule into the specified directory. /// Optionally checks out a specific branch. /// /// The branch to checkout after cloning. Optional. public void SubmoduleClone(string branch = default) { TerminateOngoingProcess(); IsBusy = true; // Run the "submodule add" command var gitCloneProcess = ProcessHelper.Cmd("git", $"submodule add {Url}", false, Directory); gitCloneProcess.WaitForExit(); // Optionally checkout the branch if (!string.IsNullOrEmpty(branch)) { var gitCheckoutProcess = ProcessHelper.Cmd("git", $"checkout -b {branch}", false, RepoDirectory); gitCheckoutProcess.WaitForExit(); } IsBusy = false; } /// /// Clones the repository into the specified directory. /// Optionally checks out a specific branch. /// /// The branch to checkout after cloning. Optional. public void Clone(string branch = default) { TerminateOngoingProcess(); IsBusy = true; // Run the "clone" command var gitCloneProcess = ProcessHelper.Cmd("git", $"clone {Url}", false, Directory); gitCloneProcess.WaitForExit(); // Optionally checkout the branch if (!string.IsNullOrEmpty(branch)) { var gitCheckoutProcess = ProcessHelper.Cmd("git", $"checkout -b {branch}", false, RepoDirectory); gitCheckoutProcess.WaitForExit(); } IsBusy = false; } /// /// Terminates any ongoing Git process. /// private void TerminateOngoingProcess() { if (_processHandle != null) { _processHandle.Kill(); _processHandle = null; } } } } #endif