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

Commit d024758

Browse files
Adding functionality to asynchronously install portable git
1 parent 81a4071 commit d024758

18 files changed

+478
-571
lines changed

src/GitHub.Api/Application/ApplicationManagerBase.cs

Lines changed: 76 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -39,46 +39,103 @@ 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+
ITaskManager taskManager = TaskManager;
43+
GitClient = new GitClient(Environment, ProcessManager, taskManager.Token);
4344
SetupMetrics();
4445
}
4546

4647
public void Run(bool firstRun)
4748
{
48-
new ActionTask(SetupGit())
49+
Logger.Trace("Run - CurrentDirectory {0}", NPath.CurrentDirectory);
50+
51+
SetupGit()
4952
.Then(RestartRepository)
5053
.ThenInUI(InitializeUI)
5154
.Start();
5255
}
5356

54-
private async Task SetupGit()
57+
private ITask SetupGit()
5558
{
56-
Logger.Trace("Run - CurrentDirectory {0}", NPath.CurrentDirectory);
59+
return BuildDetermineGitPathTask()
60+
.Then((b, path) => {
61+
Logger.Trace("Setting GitExecutablePath: {0}", path);
62+
Environment.GitExecutablePath = path;
63+
})
64+
.Then(() => {
65+
if (Environment.GitExecutablePath == null)
66+
{
67+
if (Environment.IsWindows)
68+
{
69+
GitClient.GetConfig("credential.helper", GitConfigSource.Global).Then(
70+
(b, credentialHelper) => {
71+
if (!string.IsNullOrEmpty(credentialHelper))
72+
{
73+
Logger.Trace("Windows CredentialHelper: {0}", credentialHelper);
74+
}
75+
else
76+
{
77+
Logger.Warning(
78+
"No Windows CredentialHeloper found: Setting to wincred");
79+
80+
GitClient.SetConfig("credential.helper", "wincred", GitConfigSource.Global).Start().Wait();
81+
}
82+
});
83+
}
84+
}
85+
})
86+
.ThenInUI(() => {
87+
Environment.User.Initialize(GitClient);
88+
});
89+
}
5790

58-
if (Environment.GitExecutablePath == null)
91+
private TaskBase<NPath> BuildDetermineGitPathTask()
92+
{
93+
TaskBase<NPath> determinePath = new FuncTask<NPath>(CancellationToken, () => {
94+
if (Environment.GitExecutablePath != null)
95+
{
96+
return Environment.GitExecutablePath;
97+
}
98+
99+
var gitExecutablePath = SystemSettings.Get(Constants.GitInstallPathKey)?.ToNPath();
100+
if (gitExecutablePath != null && gitExecutablePath.FileExists())
101+
{
102+
Logger.Trace("Using git install path from settings");
103+
return gitExecutablePath;
104+
}
105+
106+
return null;
107+
});
108+
109+
var environmentIsWindows = Environment.IsWindows;
110+
if (environmentIsWindows)
59111
{
60-
Environment.GitExecutablePath = await DetermineGitExecutablePath();
112+
var applicationDataPath = Environment.GetSpecialFolder(System.Environment.SpecialFolder.LocalApplicationData).ToNPath();
113+
var installDetails = new PortableGitInstallDetails(applicationDataPath, true);
114+
var installTask = new PortableGitInstallTask(CancellationToken, Environment, installDetails);
61115

62-
Logger.Trace("Environment.GitExecutablePath \"{0}\" Exists:{1}", Environment.GitExecutablePath, Environment.GitExecutablePath.FileExists());
116+
determinePath = determinePath.Then(new ShortCircuitTask<NPath>(CancellationToken, installTask));
117+
}
63118

64-
if (Environment.IsWindows)
65-
{
66-
var credentialHelper = await GitClient.GetConfig("credential.helper", GitConfigSource.Global).StartAwait();
119+
if (!environmentIsWindows)
120+
{
121+
determinePath = determinePath.Then(new ShortCircuitTask<NPath>(CancellationToken, () => {
122+
var p = new NPath("/usr/local/bin/git");
67123

68-
if (!string.IsNullOrEmpty(credentialHelper))
124+
if (p.FileExists())
69125
{
70-
Logger.Trace("Windows CredentialHelper: {0}", credentialHelper);
126+
return p;
71127
}
72-
else
73-
{
74-
Logger.Warning("No Windows CredentialHeloper found: Setting to wincred");
75128

76-
await GitClient.SetConfig("credential.helper", "wincred", GitConfigSource.Global).StartAwait();
77-
}
78-
}
129+
return null;
130+
}));
131+
132+
var findExecTask = new FindExecTask("git", CancellationToken);
133+
findExecTask.Configure(ProcessManager);
134+
135+
determinePath = determinePath.Then(new ShortCircuitTask<NPath>(CancellationToken, findExecTask));
79136
}
80137

81-
Environment.User.Initialize(GitClient);
138+
return determinePath;
82139
}
83140

84141
public ITask InitializeRepository()
@@ -136,27 +193,6 @@ public void RestartRepository()
136193
}
137194
}
138195

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-
160196
protected void SetupMetrics(string unityVersion, bool firstRun)
161197
{
162198
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: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@
117117
<Compile Include="Application\ApplicationManagerBase.cs" />
118118
<Compile Include="Helpers\Constants.cs" />
119119
<Compile Include="Helpers\Validation.cs" />
120+
<Compile Include="Installer\PortableGitInstallTask.cs" />
121+
<Compile Include="Installer\ShortCircuitTask.cs" />
120122
<Compile Include="Installer\UnzipTask.cs" />
121123
<Compile Include="OutputProcessors\GitAheadBehindStatusOutputProcessor.cs" />
122124
<Compile Include="OutputProcessors\LfsVersionOutputProcessor.cs" />
@@ -156,9 +158,7 @@
156158
<Compile Include="Git\Tasks\GitRemoteChangeTask.cs" />
157159
<Compile Include="Git\Tasks\GitRemoveFromIndexTask.cs" />
158160
<Compile Include="Threading\IMainThreadSynchronizationContext.cs" />
159-
<Compile Include="Installer\IGitInstaller.cs" />
160161
<Compile Include="Installer\IZipHelper.cs" />
161-
<Compile Include="Installer\GitInstaller.cs" />
162162
<Compile Include="Installer\ZipHelper.cs" />
163163
<Compile Include="Extensions\AsyncExtensions.cs" />
164164
<Compile Include="Platform\Settings.cs" />

0 commit comments

Comments
 (0)