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

Commit 4cc04a6

Browse files
authored
Merge pull request #578 from github-for-unity/fixes/simpler-init
Make it possible to branch out on task success and failure. Cleanups
2 parents 81f08d9 + ae352ef commit 4cc04a6

File tree

13 files changed

+454
-343
lines changed

13 files changed

+454
-343
lines changed

src/GitHub.Api/Application/ApplicationManagerBase.cs

Lines changed: 48 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -47,66 +47,23 @@ public void Run(bool firstRun)
4747
{
4848
Logger.Trace("Run - CurrentDirectory {0}", NPath.CurrentDirectory);
4949

50-
var afterGitSetup = new ActionTask(CancellationToken, RestartRepository)
51-
.ThenInUI(InitializeUI);
52-
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) => {
56-
if (!string.IsNullOrEmpty(credentialHelper))
57-
{
58-
Logger.Trace("Windows CredentialHelper: {0}", credentialHelper);
59-
afterGitSetup.Start();
60-
}
61-
else
62-
{
63-
Logger.Warning("No Windows CredentialHeloper found: Setting to wincred");
64-
65-
GitClient.SetConfig("credential.helper", "wincred", GitConfigSource.Global)
66-
.Then(() => { afterGitSetup.Start(); }).Start();
67-
}
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();
80-
}
81-
else
82-
{
83-
afterGitSetup.Start();
84-
}
85-
});
86-
87-
88-
var gitExecutablePath = SystemSettings.Get(Constants.GitInstallPathKey)?.ToNPath();
89-
if (gitExecutablePath != null && gitExecutablePath.FileExists())
50+
var gitExecutablePath = SystemSettings.Get(Constants.GitInstallPathKey)?.ToNPath();
51+
if (gitExecutablePath != null && gitExecutablePath.FileExists()) // we have a git path
9052
{
9153
Logger.Trace("Using git install path from settings: {0}", gitExecutablePath);
92-
93-
new FuncTask<NPath>(CancellationToken, () => gitExecutablePath)
94-
.Then(afterPathDetermined)
95-
.Start();
54+
InitializeEnvironment(gitExecutablePath);
9655
}
97-
else
56+
else // we need to go find git
9857
{
9958
Logger.Trace("No git path found in settings");
10059

60+
var initEnvironmentTask = new ActionTask<NPath>(CancellationToken, (b, path) => InitializeEnvironment(path)) { Affinity = TaskAffinity.UI };
10161
var findExecTask = new FindExecTask("git", CancellationToken)
102-
.Finally((b, ex, path) => {
62+
.FinallyInUI((b, ex, path) => {
10363
if (b && path != null)
10464
{
10565
Logger.Trace("FindExecTask Success: {0}", path);
106-
107-
new FuncTask<NPath>(CancellationToken, () => path)
108-
.Then(afterPathDetermined)
109-
.Start();
66+
InitializeEnvironment(gitExecutablePath);
11067
}
11168
else
11269
{
@@ -119,15 +76,8 @@ public void Run(bool firstRun)
11976
var installDetails = new GitInstallDetails(applicationDataPath, true);
12077
var gitInstaller = new GitInstaller(Environment, CancellationToken, installDetails);
12178

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-
}));
79+
// if successful, continue with environment initialization, otherwise try to find an existing git installation
80+
gitInstaller.SetupGitIfNeeded(initEnvironmentTask, findExecTask);
13181
}
13282
}
13383

@@ -216,6 +166,45 @@ protected void SetupMetrics(string unityVersion, bool firstRun)
216166
protected abstract void InitializeUI();
217167
protected abstract void SetProjectToTextSerialization();
218168

169+
/// <summary>
170+
/// Initialize environment after finding where git is. This needs to run on the main thread
171+
/// </summary>
172+
/// <param name="gitExecutablePath"></param>
173+
private void InitializeEnvironment(NPath gitExecutablePath)
174+
{
175+
var afterGitSetup = new ActionTask(CancellationToken, RestartRepository)
176+
.ThenInUI(InitializeUI);
177+
178+
Environment.GitExecutablePath = gitExecutablePath;
179+
Environment.User.Initialize(GitClient);
180+
181+
if (Environment.IsWindows)
182+
{
183+
GitClient
184+
.GetConfig("credential.helper", GitConfigSource.Global)
185+
.Then((b, credentialHelper) => {
186+
if (!string.IsNullOrEmpty(credentialHelper))
187+
{
188+
Logger.Trace("Windows CredentialHelper: {0}", credentialHelper);
189+
afterGitSetup.Start();
190+
}
191+
else
192+
{
193+
Logger.Warning("No Windows CredentialHeloper found: Setting to wincred");
194+
195+
GitClient.SetConfig("credential.helper", "wincred", GitConfigSource.Global)
196+
.Then(afterGitSetup)
197+
.Start();
198+
}
199+
})
200+
.Start();
201+
}
202+
else
203+
{
204+
afterGitSetup.Start();
205+
}
206+
}
207+
219208
private bool disposed = false;
220209
protected virtual void Dispose(bool disposing)
221210
{

src/GitHub.Api/Installer/GitInstaller.cs

Lines changed: 81 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ class GitInstallDetails
1111
public NPath GitExecPath { get; }
1212
public string GitLfsExec { get; }
1313
public NPath GitLfsExecPath { get; }
14+
public UriString GitZipMd5Url { get; set; } = DefaultGitZipMd5Url;
15+
public UriString GitZipUrl { get; set; } = DefaultGitZipUrl;
16+
public UriString GitLfsZipMd5Url { get; set; } = DefaultGitLfsZipMd5Url;
17+
public UriString GitLfsZipUrl { get; set; } = DefaultGitLfsZipUrl;
18+
19+
public const string DefaultGitZipMd5Url = "https://ghfvs-installer.github.com/unity/portable_git/git.zip.MD5.txt";
20+
public const string DefaultGitZipUrl = "https://ghfvs-installer.github.com/unity/portable_git/git.zip";
21+
public const string DefaultGitLfsZipMd5Url = "https://ghfvs-installer.github.com/unity/portable_git/git-lfs.zip.MD5.txt";
22+
public const string DefaultGitLfsZipUrl = "https://ghfvs-installer.github.com/unity/portable_git/git-lfs.zip";
23+
1424

1525
public const string GitExtractedMD5 = "e6cfc0c294a2312042f27f893dfc9c0a";
1626
public const string GitLfsExtractedMD5 = "36e3ae968b69fbf42dff72311040d24a";
@@ -99,102 +109,91 @@ public void SetupGitIfNeeded(ActionTask<NPath> onSuccess, ITask onFailure)
99109
return;
100110
}
101111

102-
new FuncTask<bool>(cancellationToken, IsGitExtracted)
103-
.Finally((success, ex, isPortableGitExtracted) => {
104-
Logger.Trace("IsPortableGitExtracted: {0}", isPortableGitExtracted);
105-
106-
if (isPortableGitExtracted)
107-
{
108-
Logger.Trace("SetupGitIfNeeded: Skipped");
109-
110-
new FuncTask<NPath>(cancellationToken, () => installDetails.GitExecPath)
111-
.Then(onSuccess)
112-
.Start();
113-
}
114-
else
115-
{
116-
ITask downloadFilesTask = null;
117-
if (gitArchiveFilePath == null || gitLfsArchivePath == null)
118-
{
119-
downloadFilesTask = CreateDownloadTask();
120-
}
121-
122-
var tempZipExtractPath = NPath.CreateTempDirectory("git_zip_extract_zip_paths");
123-
var gitExtractPath = tempZipExtractPath.Combine("git").CreateDirectory();
124-
var gitLfsExtractPath = tempZipExtractPath.Combine("git-lfs").CreateDirectory();
125-
126-
var resultTask = new UnzipTask(cancellationToken, gitArchiveFilePath, gitExtractPath, sharpZipLibHelper, environment.FileSystem, GitInstallDetails.GitExtractedMD5)
127-
.Then(new UnzipTask(cancellationToken, gitLfsArchivePath, gitLfsExtractPath, sharpZipLibHelper, environment.FileSystem, GitInstallDetails.GitLfsExtractedMD5))
128-
.Then(() => {
129-
var targetGitLfsExecPath = installDetails.GetGitLfsExecPath(gitExtractPath);
130-
var extractGitLfsExePath = gitLfsExtractPath.Combine(installDetails.GitLfsExec);
131-
132-
Logger.Trace("Moving Git LFS Exe:\"{0}\" to target in tempDirectory:\"{1}\" ", extractGitLfsExePath,
133-
targetGitLfsExecPath);
134-
135-
extractGitLfsExePath.Move(targetGitLfsExecPath);
136-
137-
Logger.Trace("Moving tempDirectory:\"{0}\" to extractTarget:\"{1}\"", gitExtractPath,
138-
installDetails.GitInstallPath);
139-
140-
installDetails.GitInstallPath.EnsureParentDirectoryExists();
141-
gitExtractPath.Move(installDetails.GitInstallPath);
142-
143-
Logger.Trace("Deleting targetGitLfsExecPath:\"{0}\"", targetGitLfsExecPath);
144-
targetGitLfsExecPath.DeleteIfExists();
145-
146-
Logger.Trace("Deleting tempZipPath:\"{0}\"", tempZipExtractPath);
147-
tempZipExtractPath.DeleteIfExists();
148-
})
149-
.Finally((b, exception) => {
150-
if (b)
151-
{
152-
Logger.Trace("SetupGitIfNeeded: Success");
153-
154-
new FuncTask<NPath>(cancellationToken, () => installDetails.GitExecPath)
155-
.Then(onSuccess)
156-
.Start();
157-
}
158-
else
159-
{
160-
Logger.Warning("SetupGitIfNeeded: Failed");
161-
162-
onFailure.Start();
163-
}
164-
});
165-
166-
if (downloadFilesTask != null)
167-
{
168-
resultTask = downloadFilesTask.Then(resultTask);
169-
}
170-
171-
resultTask.Start();
172-
}
173-
}).Start();
112+
new ActionTask(cancellationToken, () => {
113+
if (IsGitExtracted())
114+
{
115+
Logger.Trace("SetupGitIfNeeded: Skipped");
116+
onSuccess.PreviousResult = installDetails.GitExecPath;
117+
onSuccess.Start();
118+
}
119+
else
120+
{
121+
ExtractPortableGit(onSuccess, onFailure);
122+
}
123+
}).Start();
124+
}
125+
126+
private void ExtractPortableGit(ActionTask<NPath> onSuccess, ITask onFailure)
127+
{
128+
ITask downloadFilesTask = null;
129+
if (gitArchiveFilePath == null || gitLfsArchivePath == null)
130+
{
131+
downloadFilesTask = CreateDownloadTask();
132+
}
133+
134+
var tempZipExtractPath = NPath.CreateTempDirectory("git_zip_extract_zip_paths");
135+
var gitExtractPath = tempZipExtractPath.Combine("git").CreateDirectory();
136+
var gitLfsExtractPath = tempZipExtractPath.Combine("git-lfs").CreateDirectory();
137+
138+
var resultTask = new UnzipTask(cancellationToken, gitArchiveFilePath, gitExtractPath, sharpZipLibHelper, environment.FileSystem, GitInstallDetails.GitExtractedMD5)
139+
.Then(new UnzipTask(cancellationToken, gitLfsArchivePath, gitLfsExtractPath, sharpZipLibHelper, environment.FileSystem, GitInstallDetails.GitLfsExtractedMD5))
140+
.Then(s =>
141+
{
142+
var targetGitLfsExecPath = installDetails.GetGitLfsExecPath(gitExtractPath);
143+
var extractGitLfsExePath = gitLfsExtractPath.Combine(installDetails.GitLfsExec);
144+
145+
Logger.Trace("Moving Git LFS Exe:\"{0}\" to target in tempDirectory:\"{1}\" ", extractGitLfsExePath,
146+
targetGitLfsExecPath);
147+
148+
extractGitLfsExePath.Move(targetGitLfsExecPath);
149+
150+
Logger.Trace("Moving tempDirectory:\"{0}\" to extractTarget:\"{1}\"", gitExtractPath,
151+
installDetails.GitInstallPath);
152+
153+
installDetails.GitInstallPath.EnsureParentDirectoryExists();
154+
gitExtractPath.Move(installDetails.GitInstallPath);
155+
156+
Logger.Trace("Deleting targetGitLfsExecPath:\"{0}\"", targetGitLfsExecPath);
157+
targetGitLfsExecPath.DeleteIfExists();
158+
159+
Logger.Trace("Deleting tempZipPath:\"{0}\"", tempZipExtractPath);
160+
tempZipExtractPath.DeleteIfExists();
161+
return installDetails.GitExecPath;
162+
});
163+
164+
resultTask.Then(onFailure, TaskRunOptions.OnFailure);
165+
resultTask.Then(onSuccess, TaskRunOptions.OnSuccess);
166+
167+
if (downloadFilesTask != null)
168+
{
169+
resultTask = downloadFilesTask.Then(resultTask);
170+
}
171+
172+
resultTask.Start();
174173
}
175174

176175
private ITask CreateDownloadTask()
177176
{
178177
var tempZipPath = NPath.CreateTempDirectory("git_zip_paths");
179-
gitArchiveFilePath = tempZipPath.Combine("git");
180-
gitLfsArchivePath = tempZipPath.Combine("git-lfs");
178+
gitArchiveFilePath = tempZipPath.Combine("git.zip");
179+
gitLfsArchivePath = tempZipPath.Combine("git-lfs.zip");
181180

182181
var downloadGitMd5Task = new DownloadTextTask(TaskManager.Instance.Token,
183182
environment.FileSystem,
184-
"https://ghfvs-installer.github.com/unity/portable_git/git.zip.MD5.txt",
185-
gitArchiveFilePath);
183+
installDetails.GitZipMd5Url,
184+
tempZipPath);
186185

187186
var downloadGitTask = new DownloadTask(TaskManager.Instance.Token, environment.FileSystem,
188-
"https://ghfvs-installer.github.com/unity/portable_git/git.zip",
189-
gitArchiveFilePath, retryCount: 1);
187+
installDetails.GitZipUrl,
188+
tempZipPath);
190189

191190
var downloadGitLfsMd5Task = new DownloadTextTask(TaskManager.Instance.Token, environment.FileSystem,
192-
"https://ghfvs-installer.github.com/unity/portable_git/git-lfs.zip.MD5.txt",
193-
gitLfsArchivePath);
191+
installDetails.GitLfsZipMd5Url,
192+
tempZipPath);
194193

195194
var downloadGitLfsTask = new DownloadTask(TaskManager.Instance.Token, environment.FileSystem,
196-
"https://ghfvs-installer.github.com/unity/portable_git/git-lfs.zip",
197-
gitLfsArchivePath, retryCount: 1);
195+
installDetails.GitLfsZipUrl,
196+
tempZipPath);
198197

199198
return downloadGitMd5Task
200199
.Then((b, s) => {

src/GitHub.Api/Tasks/ActionTask.cs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,42 @@ class ActionTask<T> : TaskBase
7272
protected Action<bool, T> Callback { get; }
7373
protected Action<bool, Exception, T> CallbackWithException { get; }
7474

75-
public ActionTask(CancellationToken token, Action<bool, T> action)
75+
/// <summary>
76+
///
77+
/// </summary>
78+
/// <param name="token"></param>
79+
/// <param name="action"></param>
80+
/// <param name="getPreviousResult">Method to call that returns the value that this task is going to work with. You can also use the PreviousResult property to set this value</param>
81+
public ActionTask(CancellationToken token, Action<bool, T> action, Func<T> getPreviousResult = null)
7682
: base(token)
7783
{
7884
Guard.ArgumentNotNull(action, "action");
7985
this.Callback = action;
80-
Task = new Task(() => Run(DependsOn.Successful, DependsOn.Successful ? ((ITask<T>)DependsOn).Result : default(T)),
86+
Task = new Task(() => Run(DependsOn?.Successful ?? true,
87+
// if this task depends on another task and the dependent task was successful, use the value of that other task as input to this task
88+
// otherwise if there's a method to retrieve the value, call that
89+
// otherwise use the PreviousResult property
90+
(DependsOn?.Successful ?? false) ? ((ITask<T>)DependsOn).Result : getPreviousResult != null ? getPreviousResult() : PreviousResult),
8191
Token, TaskCreationOptions.None);
8292
Name = $"ActionTask<{typeof(T)}>";
8393
}
8494

85-
public ActionTask(CancellationToken token, Action<bool, Exception, T> action)
95+
/// <summary>
96+
///
97+
/// </summary>
98+
/// <param name="token"></param>
99+
/// <param name="action"></param>
100+
/// <param name="getPreviousResult">Method to call that returns the value that this task is going to work with. You can also use the PreviousResult property to set this value</param>
101+
public ActionTask(CancellationToken token, Action<bool, Exception, T> action, Func<T> getPreviousResult = null)
86102
: base(token)
87103
{
88104
Guard.ArgumentNotNull(action, "action");
89105
this.CallbackWithException = action;
90-
Task = new Task(() => Run(DependsOn.Successful, DependsOn.Successful ? ((ITask<T>)DependsOn).Result : default(T)),
106+
Task = new Task(() => Run(DependsOn?.Successful ?? true,
107+
// if this task depends on another task and the dependent task was successful, use the value of that other task as input to this task
108+
// otherwise if there's a method to retrieve the value, call that
109+
// otherwise use the PreviousResult property
110+
(DependsOn?.Successful ?? false) ? ((ITask<T>)DependsOn).Result : getPreviousResult != null ? getPreviousResult() : PreviousResult),
91111
Token, TaskCreationOptions.None);
92112
Name = $"ActionTask<Exception, {typeof(T)}>";
93113
}
@@ -124,6 +144,8 @@ protected virtual void Run(bool success, T previousResult)
124144
RaiseOnEnd();
125145
}
126146
}
147+
148+
public T PreviousResult { get; set; } = default(T);
127149
}
128150

129151
class FuncTask<T> : TaskBase<T>

src/GitHub.Api/Tasks/DownloadTask.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ protected virtual string RunDownload(bool success)
141141
return Destination;
142142
}
143143

144+
public override string ToString()
145+
{
146+
return $"{base.ToString()} {Url}";
147+
}
144148

145149
public UriString Url { get; }
146150

0 commit comments

Comments
 (0)