Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit 9a36b39

Browse files
Merge pull request #552 from github-for-unity/enhancements/async-git-setup
Async install of Portable Git
2 parents e6ad7a6 + 2220d77 commit 9a36b39

19 files changed

+355
-428
lines changed

src/GitHub.Api/Application/ApplicationManagerBase.cs

Lines changed: 71 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -39,46 +39,96 @@ protected void Initialize()
3939
Logging.TracingEnabled = UserSettings.Get(Constants.TraceLoggingKey, false);
4040
ProcessManager = new ProcessManager(Environment, Platform.GitEnvironment, CancellationToken);
4141
Platform.Initialize(ProcessManager, TaskManager);
42-
GitClient = new GitClient(Environment, ProcessManager, TaskManager);
42+
GitClient = new GitClient(Environment, ProcessManager, TaskManager.Token);
4343
SetupMetrics();
4444
}
4545

4646
public void Run(bool firstRun)
47-
{
48-
new ActionTask(SetupGit())
49-
.Then(RestartRepository)
50-
.ThenInUI(InitializeUI)
51-
.Start();
52-
}
53-
54-
private async Task SetupGit()
5547
{
5648
Logger.Trace("Run - CurrentDirectory {0}", NPath.CurrentDirectory);
5749

58-
if (Environment.GitExecutablePath == null)
59-
{
60-
Environment.GitExecutablePath = await DetermineGitExecutablePath();
61-
62-
Logger.Trace("Environment.GitExecutablePath \"{0}\" Exists:{1}", Environment.GitExecutablePath, Environment.GitExecutablePath.FileExists());
63-
64-
if (Environment.IsWindows)
65-
{
66-
var credentialHelper = await GitClient.GetConfig("credential.helper", GitConfigSource.Global).StartAwait();
50+
var afterGitSetup = new ActionTask(CancellationToken, RestartRepository)
51+
.ThenInUI(InitializeUI);
6752

53+
//GitClient.GetConfig cannot be called until there is a git path set so it is wrapped in an ActionTask
54+
var windowsCredentialSetup = new ActionTask(CancellationToken, () => {
55+
GitClient.GetConfig("credential.helper", GitConfigSource.Global).Then((b, credentialHelper) => {
6856
if (!string.IsNullOrEmpty(credentialHelper))
6957
{
7058
Logger.Trace("Windows CredentialHelper: {0}", credentialHelper);
59+
afterGitSetup.Start();
7160
}
7261
else
7362
{
7463
Logger.Warning("No Windows CredentialHeloper found: Setting to wincred");
7564

76-
await GitClient.SetConfig("credential.helper", "wincred", GitConfigSource.Global).StartAwait();
65+
GitClient.SetConfig("credential.helper", "wincred", GitConfigSource.Global)
66+
.Then(() => { afterGitSetup.Start(); }).Start();
7767
}
68+
}).Start();
69+
});
70+
71+
var afterPathDetermined = new ActionTask<NPath>(CancellationToken, (b, path) => {
72+
Logger.Trace("Setting Environment git path: {0}", path);
73+
Environment.GitExecutablePath = path;
74+
}).ThenInUI(() => {
75+
Environment.User.Initialize(GitClient);
76+
77+
if (Environment.IsWindows)
78+
{
79+
windowsCredentialSetup.Start();
7880
}
79-
}
81+
else
82+
{
83+
afterGitSetup.Start();
84+
}
85+
});
8086

81-
Environment.User.Initialize(GitClient);
87+
88+
var gitExecutablePath = SystemSettings.Get(Constants.GitInstallPathKey)?.ToNPath();
89+
if (gitExecutablePath != null && gitExecutablePath.FileExists())
90+
{
91+
Logger.Trace("Using git install path from settings: {0}", gitExecutablePath);
92+
93+
new FuncTask<NPath>(CancellationToken, () => gitExecutablePath)
94+
.Then(afterPathDetermined)
95+
.Start();
96+
}
97+
else
98+
{
99+
Logger.Trace("No git path found in settings");
100+
101+
var findExecTask = new FindExecTask("git", CancellationToken)
102+
.Finally((b, ex, path) => {
103+
if (b && path != null)
104+
{
105+
Logger.Trace("FindExecTask Success: {0}", path);
106+
107+
new FuncTask<NPath>(CancellationToken, () => path)
108+
.Then(afterPathDetermined)
109+
.Start();
110+
}
111+
else
112+
{
113+
Logger.Warning("FindExecTask Failure");
114+
Logger.Error("Git not found");
115+
}
116+
});
117+
118+
var applicationDataPath = Environment.GetSpecialFolder(System.Environment.SpecialFolder.LocalApplicationData).ToNPath();
119+
var installDetails = new GitInstallDetails(applicationDataPath, true);
120+
var gitInstaller = new GitInstaller(Environment, CancellationToken, installDetails);
121+
122+
gitInstaller.SetupGitIfNeeded(new ActionTask<NPath>(CancellationToken, (b, path) => {
123+
Logger.Trace("GitInstaller Success: {0}", path);
124+
new FuncTask<NPath>(CancellationToken, () => path)
125+
.Then(afterPathDetermined)
126+
.Start();
127+
}), new ActionTask(CancellationToken, () => {
128+
Logger.Warning("GitInstaller Failure");
129+
findExecTask.Start();
130+
}));
131+
}
82132
}
83133

84134
public ITask InitializeRepository()
@@ -136,27 +186,6 @@ public void RestartRepository()
136186
}
137187
}
138188

139-
private async Task<NPath> DetermineGitExecutablePath(ProgressReport progress = null)
140-
{
141-
var gitExecutablePath = SystemSettings.Get(Constants.GitInstallPathKey)?.ToNPath();
142-
if (gitExecutablePath != null && gitExecutablePath.FileExists())
143-
{
144-
Logger.Trace("Using git install path from settings");
145-
return gitExecutablePath;
146-
}
147-
148-
var gitInstaller = new GitInstaller(Environment, CancellationToken);
149-
var setupDone = await gitInstaller.SetupIfNeeded(progress?.Percentage, progress?.Remaining);
150-
if (setupDone)
151-
{
152-
Logger.Trace("Setup performed using new path");
153-
return gitInstaller.GitExecutablePath;
154-
}
155-
156-
Logger.Trace("Finding git install path");
157-
return await GitClient.FindGitInstallation().SafeAwait();
158-
}
159-
160189
protected void SetupMetrics(string unityVersion, bool firstRun)
161190
{
162191
Logger.Trace("Setup metrics");

src/GitHub.Api/Git/GitClient.cs

Lines changed: 2 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ namespace GitHub.Unity
88
{
99
public interface IGitClient
1010
{
11-
Task<NPath> FindGitInstallation();
1211
ITask<ValidateGitInstallResult> ValidateGitInstall(NPath path);
1312

1413
ITask Init(IOutputProcessor<string> processor = null);
@@ -96,84 +95,13 @@ class GitClient : IGitClient
9695
private const string UserEmailConfigKey = "user.email";
9796
private readonly IEnvironment environment;
9897
private readonly IProcessManager processManager;
99-
private readonly ITaskManager taskManager;
10098
private readonly CancellationToken cancellationToken;
10199

102-
public GitClient(IEnvironment environment, IProcessManager processManager, ITaskManager taskManager)
100+
public GitClient(IEnvironment environment, IProcessManager processManager, CancellationToken cancellationToken)
103101
{
104102
this.environment = environment;
105103
this.processManager = processManager;
106-
this.taskManager = taskManager;
107-
this.cancellationToken = taskManager.Token;
108-
}
109-
110-
public async Task<NPath> FindGitInstallation()
111-
{
112-
if (!String.IsNullOrEmpty(environment.GitExecutablePath))
113-
return environment.GitExecutablePath;
114-
115-
NPath path = null;
116-
117-
if (environment.IsWindows)
118-
path = await LookForPortableGit();
119-
120-
if (path == null)
121-
path = await LookForSystemGit();
122-
123-
if (path == null)
124-
{
125-
Logger.Trace("Git Installation not discovered");
126-
}
127-
else
128-
{
129-
Logger.Trace("Git Installation discovered: '{0}'", path);
130-
}
131-
132-
return path;
133-
}
134-
135-
private Task<NPath> LookForPortableGit()
136-
{
137-
Logger.Trace("LookForPortableGit");
138-
139-
var gitHubLocalAppDataPath = environment.UserCachePath;
140-
if (!gitHubLocalAppDataPath.DirectoryExists())
141-
return null;
142-
143-
var searchPath = "PortableGit_";
144-
145-
var portableGitPath = gitHubLocalAppDataPath.Directories()
146-
.Where(s => s.FileName.StartsWith(searchPath, StringComparison.OrdinalIgnoreCase))
147-
.FirstOrDefault();
148-
149-
if (portableGitPath != null)
150-
{
151-
portableGitPath = portableGitPath.Combine("cmd", $"git{environment.ExecutableExtension}");
152-
}
153-
154-
return TaskEx.FromResult(portableGitPath);
155-
}
156-
157-
private async Task<NPath> LookForSystemGit()
158-
{
159-
Logger.Trace("LookForSystemGit");
160-
161-
NPath path = null;
162-
if (!environment.IsWindows)
163-
{
164-
var p = new NPath("/usr/local/bin/git");
165-
166-
if (p.FileExists())
167-
path = p;
168-
}
169-
170-
if (path == null)
171-
{
172-
path = await new FindExecTask("git", taskManager.Token)
173-
.Configure(processManager).StartAwait();
174-
}
175-
176-
return path;
104+
this.cancellationToken = cancellationToken;
177105
}
178106

179107
public ITask<ValidateGitInstallResult> ValidateGitInstall(NPath path)

src/GitHub.Api/GitHub.Api.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
<Compile Include="Application\ApplicationManagerBase.cs" />
118118
<Compile Include="Helpers\Constants.cs" />
119119
<Compile Include="Helpers\Validation.cs" />
120+
<Compile Include="Installer\GitInstaller.cs" />
120121
<Compile Include="Installer\UnzipTask.cs" />
121122
<Compile Include="OutputProcessors\GitAheadBehindStatusOutputProcessor.cs" />
122123
<Compile Include="OutputProcessors\LfsVersionOutputProcessor.cs" />
@@ -157,9 +158,7 @@
157158
<Compile Include="Git\Tasks\GitRemoteChangeTask.cs" />
158159
<Compile Include="Git\Tasks\GitRemoveFromIndexTask.cs" />
159160
<Compile Include="Threading\IMainThreadSynchronizationContext.cs" />
160-
<Compile Include="Installer\IGitInstaller.cs" />
161161
<Compile Include="Installer\IZipHelper.cs" />
162-
<Compile Include="Installer\GitInstaller.cs" />
163162
<Compile Include="Installer\ZipHelper.cs" />
164163
<Compile Include="Extensions\AsyncExtensions.cs" />
165164
<Compile Include="Platform\Settings.cs" />

0 commit comments

Comments
 (0)