diff --git a/docs/using/quick-guide.md b/docs/using/quick-guide.md index 5164e1832..f089be9d6 100644 --- a/docs/using/quick-guide.md +++ b/docs/using/quick-guide.md @@ -9,6 +9,7 @@ These documents contain more details on how to use the GitHub for Unity plugin: - **[Managing Branches](https://github.com/github-for-unity/Unity/blob/master/docs/using/managing-branches.md)** - **[Locking Files](https://github.com/github-for-unity/Unity/blob/master/docs/using/locking-files.md)** - **[Working with Changes](https://github.com/github-for-unity/Unity/blob/master/docs/using/working-with-changes.md)** +- **[Using the Api](https://github.com/github-for-unity/Unity/blob/master/docs/using/using-the-api.md)** ## Table of Contents diff --git a/docs/using/using-the-api.md b/docs/using/using-the-api.md new file mode 100644 index 000000000..ab75cab55 --- /dev/null +++ b/docs/using/using-the-api.md @@ -0,0 +1,75 @@ +# Using the API + +GitHub for Unity provides access to a git client to help users create their own tools to assist in their workflow. + +Users can separate the user interface from the API by removing `GitHub.Unity.dll`. All other libraries are required by the API. + +## Creating an instance of `GitClient` +```cs +var defaultEnvironment = new DefaultEnvironment(); +defaultEnvironment.Initialize(null, NPath.Default, NPath.Default, NPath.Default, Application.dataPath.ToNPath()); + +var processEnvironment = new ProcessEnvironment(defaultEnvironment); +var processManager = new ProcessManager(defaultEnvironment, processEnvironment, TaskManager.Instance.Token); + +var gitClient = new GitClient(defaultEnvironment, processManager, TaskManager.Instance.Token); +``` + +## Full Example +This example creates a window that has a single button which commits all changes. +```cs +using System; +using System.Globalization; +using GitHub.Unity; +using UnityEditor; +using UnityEngine; + +public class CustomGitEditor : EditorWindow +{ + [MenuItem("Window/Custom Git")] + public static void ShowWindow() + { + EditorWindow.GetWindow(typeof(CustomGitEditor)); + } + + [NonSerialized] private GitClient gitClient; + + public void OnEnable() + { + InitGitClient(); + } + + private void InitGitClient() + { + if (gitClient != null) return; + + Debug.Log("Init GitClient"); + + var defaultEnvironment = new DefaultEnvironment(); + defaultEnvironment.Initialize(null, NPath.Default, NPath.Default, + NPath.Default, Application.dataPath.ToNPath()); + + var processEnvironment = new ProcessEnvironment(defaultEnvironment); + var processManager = new ProcessManager(defaultEnvironment, processEnvironment, TaskManager.Instance.Token); + + gitClient = new GitClient(defaultEnvironment, processManager, TaskManager.Instance.Token); + } + + void OnGUI() + { + GUILayout.Label("Custom Git Window", EditorStyles.boldLabel); + + if (GUILayout.Button("Commit Stuff")) + { + var message = DateTime.Now.ToString(CultureInfo.InvariantCulture); + var body = string.Empty; + + gitClient.AddAll() + .Then(gitClient.Commit(message, body)) + .Start(); + } + } +} +``` + + diff --git a/src/GitHub.Api/Git/GitClient.cs b/src/GitHub.Api/Git/GitClient.cs index 8dc75d6b6..c345a47a7 100644 --- a/src/GitHub.Api/Git/GitClient.cs +++ b/src/GitHub.Api/Git/GitClient.cs @@ -6,44 +6,279 @@ namespace GitHub.Unity { + /// + /// Client that provides access to git functionality + /// public interface IGitClient { + /// + /// Executes `git init` to initialize a git repo. + /// + /// A custom output processor instance + /// String output of git command ITask Init(IOutputProcessor processor = null); + + /// + /// Executes `git lfs install` to install LFS hooks. + /// + /// A custom output processor instance + /// String output of git command ITask LfsInstall(IOutputProcessor processor = null); + + /// + /// Executes `git rev-list` to determine the ahead/behind status between two refs. + /// + /// Ref to compare + /// Ref to compare against + /// A custom output processor instance + /// output ITask AheadBehindStatus(string gitRef, string otherRef, IOutputProcessor processor = null); + + /// + /// Executes `git status` to determine the working directory status. + /// + /// A custom output processor instance + /// output ITask Status(IOutputProcessor processor = null); + + /// + /// Executes `git config get` to get a configuration value. + /// + /// The configuration key to get + /// The config source (unspecified, local,user,global) to use + /// A custom output processor instance + /// String output of git command ITask GetConfig(string key, GitConfigSource configSource, IOutputProcessor processor = null); + + /// + /// Executes `git config set` to set a configuration value. + /// + /// The configuration key to set + /// The value to set + /// The config source (unspecified, local,user,global) to use + /// A custom output processor instance + /// String output of git command ITask SetConfig(string key, string value, GitConfigSource configSource, IOutputProcessor processor = null); + + /// + /// Executes two `git config get` commands to get the git user and email. + /// + /// output ITask GetConfigUserAndEmail(); + + /// + /// Executes `git lfs locks` to get a list of lfs locks from the git lfs server. + /// + /// + /// A custom output processor instance + /// of output ITask> ListLocks(bool local, BaseOutputListProcessor processor = null); + + /// + /// Executes `git pull` to perform a pull operation. + /// + /// The remote to pull from + /// The branch to pull + /// A custom output processor instance + /// String output of git command ITask Pull(string remote, string branch, IOutputProcessor processor = null); + + /// + /// Executes `git push` to perform a push operation. + /// + /// The remote to push to + /// The branch to push + /// A custom output processor instance + /// String output of git command ITask Push(string remote, string branch, IOutputProcessor processor = null); + + /// + /// Executes `git revert` to perform a revert operation. + /// + /// The changeset to revert + /// A custom output processor instance + /// String output of git command ITask Revert(string changeset, IOutputProcessor processor = null); + + /// + /// Executes `git fetch` to perform a fetch operation. + /// + /// The remote to fetch from + /// A custom output processor instance + /// String output of git command ITask Fetch(string remote, IOutputProcessor processor = null); + + /// + /// Executes `git checkout` to switch branches. + /// + /// The branch to checkout + /// A custom output processor instance + /// String output of git command ITask SwitchBranch(string branch, IOutputProcessor processor = null); + + /// + /// Executes `git branch -d` to delete a branch. + /// + /// The branch to delete + /// The flag to indicate the branch should be deleted even if not merged + /// A custom output processor instance + /// String output of git command ITask DeleteBranch(string branch, bool deleteUnmerged = false, IOutputProcessor processor = null); + + /// + /// Executes `git branch` to create a branch. + /// + /// The name of branch to create + /// The name of branch to create from + /// A custom output processor instance + /// String output of git command ITask CreateBranch(string branch, string baseBranch, IOutputProcessor processor = null); + + /// + /// Executes `git remote add` to add a git remote. + /// + /// The remote to add + /// The url of the remote + /// A custom output processor instance + /// String output of git command ITask RemoteAdd(string remote, string url, IOutputProcessor processor = null); + + /// + /// Executes `git remote rm` to remove a git remote. + /// + /// The remote to remove + /// A custom output processor instance + /// String output of git command ITask RemoteRemove(string remote, IOutputProcessor processor = null); + + /// + /// Executes `git remote set-url` to change the url of a git remote. + /// + /// The remote to change + /// The url to change to + /// A custom output processor instance + /// String output of git command ITask RemoteChange(string remote, string url, IOutputProcessor processor = null); + + /// + /// Executes `git commit` to perform a commit operation. + /// + /// The commit message summary + /// The commit message body + /// A custom output processor instance + /// String output of git command ITask Commit(string message, string body, IOutputProcessor processor = null); + + /// + /// Executes at least one `git add` command to add the list of files to the git index. + /// + /// The file to add + /// A custom output processor instance + /// String output of git command ITask Add(IList files, IOutputProcessor processor = null); + + /// + /// Executes `git add -A` to add all files to the git index. + /// + /// A custom output processor instance + /// String output of git command ITask AddAll(IOutputProcessor processor = null); + + /// + /// Executes at least one `git checkout` command to discard changes to the list of files. + /// + /// The files to discard + /// A custom output processor instance + /// String output of git command ITask Discard(IList files, IOutputProcessor processor = null); + + /// + /// Executes `git checkout -- .` to discard all changes in the working directory. + /// + /// A custom output processor instance + /// String output of git command ITask DiscardAll(IOutputProcessor processor = null); + + /// + /// Executes `git reset HEAD` command to remove files from the git index. + /// + /// The files to remove + /// A custom output processor instance + /// String output of git command ITask Remove(IList files, IOutputProcessor processor = null); + + /// + /// Executes at least one `git add` command to add the list of files to the git index. Followed by a `git commit` command to commit the changes. + /// + /// The files to add and commit + /// The commit message summary + /// The commit message body + /// A custom output processor instance + /// String output of git command ITask AddAndCommit(IList files, string message, string body, IOutputProcessor processor = null); + + /// + /// Executes `git lfs lock` to lock a file. + /// + /// The file to lock + /// A custom output processor instance + /// String output of git command ITask Lock(NPath file, IOutputProcessor processor = null); + + /// + /// Executes `git lfs unlock` to unlock a file. + /// + /// The file to unlock + /// If force should be used + /// A custom output processor instance + /// String output of git command ITask Unlock(NPath file, bool force, IOutputProcessor processor = null); + + /// + /// Executes `git log` to get the history of the current branch. + /// + /// A custom output processor instance + /// of output ITask> Log(BaseOutputListProcessor processor = null); + + /// + /// Executes `git --version` to get the git version. + /// + /// A custom output processor instance + /// output ITask Version(IOutputProcessor processor = null); + + /// + /// Executes `git lfs version` to get the git lfs version. + /// + /// A custom output processor instance + /// output ITask LfsVersion(IOutputProcessor processor = null); + + /// + /// Executes `git count-objects` to get the size of the git repo in kilobytes. + /// + /// A custom output processor instance + /// output ITask CountObjects(IOutputProcessor processor = null); + + /// + /// Executes two `git set config` commands to set the git name and email. + /// + /// The username to set + /// The email to set + /// output ITask SetConfigNameAndEmail(string username, string email); + + /// + /// Executes `git rev-parse --short HEAD` to get the current commit sha of the current branch. + /// + /// A custom output processor instance + /// String output of git command ITask GetHead(IOutputProcessor processor = null); } - class GitClient : IGitClient + public class GitClient : IGitClient { private const string UserNameConfigKey = "user.name"; private const string UserEmailConfigKey = "user.email"; @@ -58,66 +293,77 @@ public GitClient(IEnvironment environment, IProcessManager processManager, Cance this.cancellationToken = cancellationToken; } + /// public ITask Init(IOutputProcessor processor = null) { return new GitInitTask(cancellationToken, processor) .Configure(processManager); } + /// public ITask LfsInstall(IOutputProcessor processor = null) { return new GitLfsInstallTask(cancellationToken, processor) .Configure(processManager); } + /// public ITask Status(IOutputProcessor processor = null) { return new GitStatusTask(new GitObjectFactory(environment), cancellationToken, processor) .Configure(processManager); } + /// public ITask AheadBehindStatus(string gitRef, string otherRef, IOutputProcessor processor = null) { return new GitAheadBehindStatusTask(gitRef, otherRef, cancellationToken, processor) .Configure(processManager); } + /// public ITask> Log(BaseOutputListProcessor processor = null) { return new GitLogTask(new GitObjectFactory(environment), cancellationToken, processor) .Configure(processManager); } + /// public ITask Version(IOutputProcessor processor = null) { return new GitVersionTask(cancellationToken, processor) .Configure(processManager); } + /// public ITask LfsVersion(IOutputProcessor processor = null) { return new GitLfsVersionTask(cancellationToken, processor) .Configure(processManager); } + /// public ITask CountObjects(IOutputProcessor processor = null) { return new GitCountObjectsTask(cancellationToken, processor) .Configure(processManager); } + /// public ITask GetConfig(string key, GitConfigSource configSource, IOutputProcessor processor = null) { return new GitConfigGetTask(key, configSource, cancellationToken, processor) .Configure(processManager); } + /// public ITask SetConfig(string key, string value, GitConfigSource configSource, IOutputProcessor processor = null) { return new GitConfigSetTask(key, value, configSource, cancellationToken, processor) .Configure(processManager); } + /// public ITask GetConfigUserAndEmail() { string username = null; @@ -141,6 +387,7 @@ public ITask GetConfigUserAndEmail() }); } + /// public ITask SetConfigNameAndEmail(string username, string email) { return SetConfig(UserNameConfigKey, username, GitConfigSource.User) @@ -148,18 +395,21 @@ public ITask SetConfigNameAndEmail(string username, string email) .Then(b => new GitUser(username, email)); } + /// public ITask> ListLocks(bool local, BaseOutputListProcessor processor = null) { return new GitListLocksTask(local, cancellationToken, processor) .Configure(processManager, environment.GitLfsExecutablePath); } + /// public ITask Pull(string remote, string branch, IOutputProcessor processor = null) { return new GitPullTask(remote, branch, cancellationToken, processor) .Configure(processManager); } + /// public ITask Push(string remote, string branch, IOutputProcessor processor = null) { @@ -167,12 +417,14 @@ public ITask Push(string remote, string branch, .Configure(processManager); } + /// public ITask Revert(string changeset, IOutputProcessor processor = null) { return new GitRevertTask(changeset, cancellationToken, processor) .Configure(processManager); } + /// public ITask Fetch(string remote, IOutputProcessor processor = null) { @@ -180,12 +432,14 @@ public ITask Fetch(string remote, .Configure(processManager); } + /// public ITask SwitchBranch(string branch, IOutputProcessor processor = null) { return new GitSwitchBranchesTask(branch, cancellationToken, processor) .Configure(processManager); } + /// public ITask DeleteBranch(string branch, bool deleteUnmerged = false, IOutputProcessor processor = null) { @@ -193,6 +447,7 @@ public ITask DeleteBranch(string branch, bool deleteUnmerged = false, .Configure(processManager); } + /// public ITask CreateBranch(string branch, string baseBranch, IOutputProcessor processor = null) { @@ -200,6 +455,7 @@ public ITask CreateBranch(string branch, string baseBranch, .Configure(processManager); } + /// public ITask RemoteAdd(string remote, string url, IOutputProcessor processor = null) { @@ -207,6 +463,7 @@ public ITask RemoteAdd(string remote, string url, .Configure(processManager); } + /// public ITask RemoteRemove(string remote, IOutputProcessor processor = null) { @@ -214,6 +471,7 @@ public ITask RemoteRemove(string remote, .Configure(processManager); } + /// public ITask RemoteChange(string remote, string url, IOutputProcessor processor = null) { @@ -221,6 +479,7 @@ public ITask RemoteChange(string remote, string url, .Configure(processManager); } + /// public ITask Commit(string message, string body, IOutputProcessor processor = null) { @@ -228,12 +487,14 @@ public ITask Commit(string message, string body, .Configure(processManager); } + /// public ITask AddAll(IOutputProcessor processor = null) { return new GitAddTask(cancellationToken, processor) .Configure(processManager); } + /// public ITask Add(IList files, IOutputProcessor processor = null) { @@ -255,6 +516,7 @@ public ITask Add(IList files, return last; } + /// public ITask Discard( IList files, IOutputProcessor processor = null) { @@ -276,12 +538,14 @@ public ITask Discard( IList files, return last; } + /// public ITask DiscardAll(IOutputProcessor processor = null) { return new GitCheckoutTask(cancellationToken, processor) .Configure(processManager); } + /// public ITask Remove(IList files, IOutputProcessor processor = null) { @@ -289,6 +553,7 @@ public ITask Remove(IList files, .Configure(processManager); } + /// public ITask AddAndCommit(IList files, string message, string body, IOutputProcessor processor = null) { @@ -297,6 +562,7 @@ public ITask AddAndCommit(IList files, string message, string bo .Configure(processManager)); } + /// public ITask Lock(NPath file, IOutputProcessor processor = null) { @@ -304,6 +570,7 @@ public ITask Lock(NPath file, .Configure(processManager, environment.GitLfsExecutablePath); } + /// public ITask Unlock(NPath file, bool force, IOutputProcessor processor = null) { @@ -311,6 +578,7 @@ public ITask Unlock(NPath file, bool force, .Configure(processManager, environment.GitLfsExecutablePath); } + /// public ITask GetHead(IOutputProcessor processor = null) { return new FirstNonNullLineProcessTask(cancellationToken, "rev-parse --short HEAD") { Name = "Getting current head..." } diff --git a/src/GitHub.Api/Git/Repository.cs b/src/GitHub.Api/Git/Repository.cs index 38b499f5e..61935cccc 100644 --- a/src/GitHub.Api/Git/Repository.cs +++ b/src/GitHub.Api/Git/Repository.cs @@ -423,9 +423,12 @@ public class User : IUser public User(ICacheContainer cacheContainer) { - this.cacheContainer = cacheContainer; - cacheContainer.CacheInvalidated += (type) => { if (type == CacheType.GitUser) GitUserCacheOnCacheInvalidated(); }; - cacheContainer.CacheUpdated += (type, dt) => { if (type == CacheType.GitUser) CacheHasBeenUpdated(dt); }; + if (cacheContainer != null) + { + this.cacheContainer = cacheContainer; + cacheContainer.CacheInvalidated += (type) => { if (type == CacheType.GitUser) GitUserCacheOnCacheInvalidated(); }; + cacheContainer.CacheUpdated += (type, dt) => { if (type == CacheType.GitUser) CacheHasBeenUpdated(dt); }; + } } public void CheckAndRaiseEventsIfCacheNewer(CacheType cacheType, CacheUpdateEvent cacheUpdateEvent) => cacheContainer.CheckAndRaiseEventsIfCacheNewer(CacheType.GitUser, cacheUpdateEvent); diff --git a/src/GitHub.Api/OutputProcessors/ProcessManager.cs b/src/GitHub.Api/OutputProcessors/ProcessManager.cs index f67c6a6c2..3cf767a91 100644 --- a/src/GitHub.Api/OutputProcessors/ProcessManager.cs +++ b/src/GitHub.Api/OutputProcessors/ProcessManager.cs @@ -7,7 +7,7 @@ namespace GitHub.Unity { - class ProcessManager : IProcessManager + public class ProcessManager : IProcessManager { private static readonly ILogging logger = LogHelper.GetLogger(); diff --git a/src/GitHub.Api/Platform/ProcessEnvironment.cs b/src/GitHub.Api/Platform/ProcessEnvironment.cs index b1609faa3..685a07b60 100644 --- a/src/GitHub.Api/Platform/ProcessEnvironment.cs +++ b/src/GitHub.Api/Platform/ProcessEnvironment.cs @@ -5,7 +5,7 @@ namespace GitHub.Unity { - class ProcessEnvironment : IProcessEnvironment + public class ProcessEnvironment : IProcessEnvironment { protected IEnvironment Environment { get; private set; } protected ILogging Logger { get; private set; } diff --git a/src/GitHub.Api/Tasks/TaskManager.cs b/src/GitHub.Api/Tasks/TaskManager.cs index 5bff94012..7a3e80749 100644 --- a/src/GitHub.Api/Tasks/TaskManager.cs +++ b/src/GitHub.Api/Tasks/TaskManager.cs @@ -5,7 +5,7 @@ namespace GitHub.Unity { - class TaskManager : ITaskManager + public class TaskManager : ITaskManager { private static readonly ILogging logger = LogHelper.GetLogger(); @@ -17,7 +17,19 @@ class TaskManager : ITaskManager public CancellationToken Token { get { return cts.Token; } } private static ITaskManager instance; - public static ITaskManager Instance => instance; + public static ITaskManager Instance + { + get + { + if (instance == null) + { + instance = new TaskManager(); + } + + return instance; + } + } + private ProgressReporter progressReporter = new ProgressReporter(); public event Action OnProgress