33using System . Threading . Tasks ;
44using System . Collections . Generic ;
55using GitHub . Logging ;
6+ using static GitHub . Unity . GitInstaller ;
67
78namespace GitHub . Unity
89{
@@ -13,6 +14,9 @@ abstract class ApplicationManagerBase : IApplicationManager
1314 private RepositoryManager repositoryManager ;
1415 private Progress progressReporter ;
1516 protected bool isBusy ;
17+ protected bool firstRun ;
18+ protected Guid instanceId ;
19+
1620 public event Action < IProgress > OnProgress
1721 {
1822 add { progressReporter . OnProgress += value ; }
@@ -41,94 +45,168 @@ protected void Initialize()
4145 GitClient = new GitClient ( Environment , ProcessManager , TaskManager . Token ) ;
4246 }
4347
44- public void Run ( bool firstRun )
48+ public void Run ( )
4549 {
4650 isBusy = true ;
4751
4852 var thread = new Thread ( obj =>
4953 {
5054 CancellationToken token = ( CancellationToken ) obj ;
51- var endTask = new ActionTask < GitInstaller . GitInstallationState > ( token , ( _ , s ) => InitializeEnvironment ( s ) ) { Affinity = TaskAffinity . UI } ;
52- string path = null ;
55+ SetupMetrics ( Environment . UnityVersion , firstRun , instanceId ) ;
5356
5457 if ( Environment . IsMac )
5558 {
5659 var getEnvPath = new SimpleProcessTask ( token , "bash" . ToNPath ( ) , "-c \" /usr/libexec/path_helper\" " )
5760 . Configure ( ProcessManager , dontSetupGit : true )
5861 . Catch ( e => true ) ; // make sure this doesn't throw if the task fails
59- path = getEnvPath . RunWithReturn ( true ) ;
62+ var path = getEnvPath . RunWithReturn ( true ) ;
6063 if ( getEnvPath . Successful )
6164 {
6265 Logger . Trace ( "Existing Environment Path Original:{0} Updated:{1}" , Environment . Path , path ) ;
6366 Environment . Path = path ? . Split ( new [ ] { "\" " } , StringSplitOptions . None ) [ 1 ] ;
6467 }
6568 }
6669
67- Environment . OctorunScriptPath = new OctorunInstaller ( Environment , TaskManager ) . SetupOctorunIfNeeded ( ) ;
70+ GitInstallationState state = new GitInstallationState ( ) ;
71+ var runInstallers = firstRun ;
72+
73+ if ( ! runInstallers )
74+ {
75+ state = SystemSettings . Get < GitInstallationState > ( Constants . GitInstallationState ) ?? state ;
76+ var now = DateTimeOffset . Now ;
77+ runInstallers = now . Date != state . GitLastCheckTime . Date || ( ! ( state . GitIsValid && state . GitLfsIsValid ) ) ;
78+ }
79+
80+ if ( runInstallers )
81+ {
82+ Environment . OctorunScriptPath = new OctorunInstaller ( Environment , TaskManager )
83+ . SetupOctorunIfNeeded ( ) ;
84+
85+ state = new GitInstaller ( Environment , ProcessManager , TaskManager , SystemSettings )
86+ { Progress = progressReporter }
87+ . SetupGitIfNeeded ( ) ;
88+ }
89+
90+ SetupGit ( state ) ;
6891
69- var state = new GitInstaller ( Environment , ProcessManager , TaskManager , SystemSettings )
70- { Progress = progressReporter }
71- . SetupGitIfNeeded ( ) ;
72- endTask . PreviousResult = state ;
73- endTask . Start ( ) ;
92+ if ( state . GitIsValid && state . GitLfsIsValid )
93+ {
94+ RestartRepository ( ) ;
95+ }
96+
97+ new ActionTask < bool > ( token , ( s , gitIsValid ) =>
98+ {
99+ InitializationComplete ( ) ;
100+ if ( gitIsValid )
101+ {
102+ InitializeUI ( ) ;
103+ }
104+ } ,
105+ ( ) => state . GitIsValid && state . GitLfsIsValid )
106+ { Affinity = TaskAffinity . UI }
107+ . Start ( ) ;
74108 } ) ;
75109 thread . Start ( CancellationToken ) ;
76110 }
77111
78- public ITask InitializeRepository ( )
112+ private void SetupGit ( GitInstaller . GitInstallationState state )
79113 {
80- var targetPath = NPath . CurrentDirectory ;
81-
82- var unityYamlMergeExec = Environment . UnityApplicationContents . Combine ( "Tools" , "UnityYAMLMerge" + Environment . ExecutableExtension ) ;
83-
84- var yamlMergeCommand = Environment . IsWindows
85- ? $@ "' { unityYamlMergeExec } ' merge -p ""$BASE"" ""$REMOTE"" ""$LOCAL"" ""$MERGED"""
86- : $@ "' { unityYamlMergeExec } ' merge -p '$BASE' '$REMOTE' '$LOCAL' '$MERGED'" ;
87-
88- var gitignore = targetPath . Combine ( ".gitignore" ) ;
89- var gitAttrs = targetPath . Combine ( ".gitattributes" ) ;
90- var assetsGitignore = targetPath . Combine ( "Assets " , ".gitignore" ) ;
91-
92- var filesForInitialCommit = new List < string > { gitignore , gitAttrs , assetsGitignore } ;
93-
94- var task =
95- GitClient . Init ( )
96- . Then ( GitClient . SetConfig ( "merge.unityyamlmerge.cmd" , yamlMergeCommand , GitConfigSource . Local ) )
97- . Then ( GitClient . SetConfig ( "merge.unityyamlmerge.trustExitCode" , "false" , GitConfigSource . Local ) )
98- . Then ( GitClient . LfsInstall ( ) )
99- . ThenInUI ( SetProjectToTextSerialization )
100- . Then ( new ActionTask ( CancellationToken , _ => {
101- AssemblyResources . ToFile ( ResourceType . Generic , ".gitignore" , targetPath , Environment ) ;
102- AssemblyResources . ToFile ( ResourceType . Generic , ".gitattributes" , targetPath , Environment ) ;
103-
104- assetsGitignore . CreateFile ( ) ;
105- } ) )
106- . Then ( GitClient . Add ( filesForInitialCommit ) )
107- . Then ( GitClient . Commit ( "Initial commit" , null ) )
108- . Then ( _ =>
109- {
110- Environment . InitializeRepository ( ) ;
111- RestartRepository ( ) ;
112- } )
113- . ThenInUI ( ( ) =>
114+ if ( ! ( state . GitIsValid && state . GitLfsIsValid ) )
115+ return ;
116+
117+ Environment . GitExecutablePath = state . GitExecutablePath ;
118+ Environment . GitLfsExecutablePath = state . GitLfsExecutablePath ;
119+ Environment . IsCustomGitExecutable = state . IsCustomGitPath ;
120+ Environment . User . Initialize ( GitClient ) ;
121+
122+ if ( firstRun )
123+ {
124+ var unityYamlMergeExec = Environment . UnityApplicationContents . Combine ( "Tools " , "UnityYAMLMerge" + Environment . ExecutableExtension ) ;
125+
126+ var yamlMergeCommand = Environment . IsWindows
127+ ? $@ "' { unityYamlMergeExec } ' merge -p ""$BASE"" ""$REMOTE"" ""$LOCAL"" ""$MERGED"""
128+ : $@ "' { unityYamlMergeExec } ' merge -p '$BASE' '$REMOTE' '$LOCAL' '$MERGED'" ;
129+
130+ GitClient . SetConfig ( "merge.unityyamlmerge.cmd" , yamlMergeCommand , GitConfigSource . Local )
131+ . Catch ( e =>
132+ {
133+ Logger . Error ( e , "Error setting merge.unityyamlmerge.cmd" ) ;
134+ return true ;
135+ } )
136+ . RunWithReturn ( true ) ;
137+ GitClient . SetConfig ( "merge.unityyamlmerge.trustExitCode" , "false" , GitConfigSource . Local )
138+ . Catch ( e =>
139+ {
140+ Logger . Error ( e , "Error setting merge.unityyamlmerge.trustExitCode" ) ;
141+ return true ;
142+ } )
143+ . RunWithReturn ( true ) ;
144+
145+ GitClient . LfsInstall ( ) . RunWithReturn ( true ) ;
146+
147+ if ( Environment . IsWindows )
114148 {
115- TaskManager . Run ( UsageTracker . IncrementProjectsInitialized ) ;
116- InitializeUI ( ) ;
117- } ) ;
118- return task ;
149+ var credentialHelper = GitClient . GetConfig ( "credential.helper" , GitConfigSource . Global )
150+ . Catch ( e =>
151+ {
152+ Logger . Error ( e , "Error getting the credential helper" ) ;
153+ return true ;
154+ } ) . RunWithReturn ( true ) ;
155+
156+ if ( string . IsNullOrEmpty ( credentialHelper ) )
157+ {
158+ Logger . Warning ( "No Windows CredentialHelper found: Setting to wincred" ) ;
159+ GitClient . SetConfig ( "credential.helper" , "wincred" , GitConfigSource . Global )
160+ . Catch ( e =>
161+ {
162+ Logger . Error ( e , "Error setting the credential helper" ) ;
163+ return true ;
164+ } )
165+ . RunWithReturn ( true ) ;
166+ }
167+ }
168+ }
119169 }
120170
121- public void RestartRepository ( )
171+ public void InitializeRepository ( )
122172 {
123- if ( Environment . RepositoryPath . IsInitialized )
173+ var thread = new Thread ( obj =>
124174 {
125- repositoryManager = Unity . RepositoryManager . CreateInstance ( Platform , TaskManager , GitClient , Environment . FileSystem , Environment . RepositoryPath ) ;
126- repositoryManager . Initialize ( ) ;
127- Environment . Repository . Initialize ( repositoryManager , TaskManager ) ;
128- repositoryManager . Start ( ) ;
129- Environment . Repository . Start ( ) ;
130- Logger . Trace ( $ "Got a repository? { ( Environment . Repository != null ? Environment . Repository . LocalPath : "null" ) } ") ;
131- }
175+ CancellationToken token = ( CancellationToken ) obj ;
176+ var targetPath = NPath . CurrentDirectory ;
177+
178+ var gitignore = targetPath . Combine ( ".gitignore" ) ;
179+ var gitAttrs = targetPath . Combine ( ".gitattributes" ) ;
180+ var assetsGitignore = targetPath . Combine ( "Assets" , ".gitignore" ) ;
181+
182+ var filesForInitialCommit = new List < string > { gitignore , gitAttrs , assetsGitignore } ;
183+
184+ GitClient . Init ( ) . RunWithReturn ( true ) ;
185+ GitClient . LfsInstall ( ) . RunWithReturn ( true ) ;
186+ AssemblyResources . ToFile ( ResourceType . Generic , ".gitignore" , targetPath , Environment ) ;
187+ AssemblyResources . ToFile ( ResourceType . Generic , ".gitattributes" , targetPath , Environment ) ;
188+ assetsGitignore . CreateFile ( ) ;
189+ GitClient . Add ( filesForInitialCommit ) . RunWithReturn ( true ) ;
190+ GitClient . Commit ( "Initial commit" , null ) . RunWithReturn ( true ) ;
191+ Environment . InitializeRepository ( ) ;
192+ RestartRepository ( ) ;
193+ UsageTracker . IncrementProjectsInitialized ( ) ;
194+ TaskManager . RunInUI ( InitializeUI ) ;
195+ } ) ;
196+ thread . Start ( CancellationToken ) ;
197+ }
198+
199+ public void RestartRepository ( )
200+ {
201+ if ( ! Environment . RepositoryPath . IsInitialized )
202+ return ;
203+
204+ repositoryManager = Unity . RepositoryManager . CreateInstance ( Platform , TaskManager , GitClient , Environment . FileSystem , Environment . RepositoryPath ) ;
205+ repositoryManager . Initialize ( ) ;
206+ Environment . Repository . Initialize ( repositoryManager , TaskManager ) ;
207+ repositoryManager . Start ( ) ;
208+ Environment . Repository . Start ( ) ;
209+ Logger . Trace ( $ "Got a repository? { ( Environment . Repository != null ? Environment . Repository . LocalPath : "null" ) } ") ;
132210 }
133211
134212 protected void SetupMetrics ( string unityVersion , bool firstRun , Guid instanceId )
@@ -156,62 +234,12 @@ protected void SetupMetrics(string unityVersion, bool firstRun, Guid instanceId)
156234
157235 if ( firstRun )
158236 {
159- TaskManager . Run ( UsageTracker . IncrementNumberOfStartups ) ;
237+ UsageTracker . IncrementNumberOfStartups ( ) ;
160238 }
161239#endif
162240 }
163- protected abstract void SetupMetrics ( ) ;
164241 protected abstract void InitializeUI ( ) ;
165- protected abstract void SetProjectToTextSerialization ( ) ;
166-
167- /// <summary>
168- /// Initialize environment after finding where git is. This needs to run on the main thread
169- /// </summary>
170- /// <param name="gitExecutablePath"></param>
171- /// <param name="octorunScriptPath"></param>
172- private void InitializeEnvironment ( GitInstaller . GitInstallationState installationState )
173- {
174- isBusy = false ;
175- SetupMetrics ( ) ;
176-
177- if ( ! installationState . GitIsValid )
178- {
179- return ;
180- }
181-
182- var gitInstallDetails = new GitInstaller . GitInstallDetails ( Environment . UserCachePath , Environment . IsWindows ) ;
183- var isCustomGitExec = installationState . GitExecutablePath != gitInstallDetails . GitExecutablePath ;
184-
185- Environment . GitExecutablePath = installationState . GitExecutablePath ;
186- Environment . GitLfsExecutablePath = installationState . GitLfsExecutablePath ;
187-
188- Environment . IsCustomGitExecutable = isCustomGitExec ;
189- Environment . User . Initialize ( GitClient ) ;
190-
191- var afterGitSetup = new ActionTask ( CancellationToken , RestartRepository )
192- . ThenInUI ( InitializeUI ) ;
193-
194- ITask task = afterGitSetup ;
195- if ( Environment . IsWindows )
196- {
197- var credHelperTask = GitClient . GetConfig ( "credential.helper" , GitConfigSource . Global ) ;
198- credHelperTask . OnEnd += ( thisTask , credentialHelper , success , exception ) =>
199- {
200- if ( ! success || string . IsNullOrEmpty ( credentialHelper ) )
201- {
202- Logger . Warning ( "No Windows CredentialHelper found: Setting to wincred" ) ;
203- thisTask
204- . Then ( GitClient . SetConfig ( "credential.helper" , "wincred" , GitConfigSource . Global ) )
205- . Then ( afterGitSetup ) ;
206- }
207- else
208- thisTask . Then ( afterGitSetup ) ;
209- } ;
210- task = credHelperTask ;
211- }
212- task . Start ( ) ;
213- }
214-
242+ protected abstract void InitializationComplete ( ) ;
215243
216244 private bool disposed = false ;
217245 protected virtual void Dispose ( bool disposing )
0 commit comments