33using System . Threading ;
44using System . Threading . Tasks ;
55using Octokit ;
6+ using System . Collections . Generic ;
67
78namespace GitHub . Unity
89{
@@ -21,12 +22,13 @@ public ApplicationManagerBase(SynchronizationContext synchronizationContext)
2122 UIScheduler = TaskScheduler . FromCurrentSynchronizationContext ( ) ;
2223 ThreadingHelper . MainThreadScheduler = UIScheduler ;
2324 TaskManager = new TaskManager ( UIScheduler ) ;
24- // accessing Environment triggers environment initialization if it hasn't happened yet
25- Platform = new Platform ( Environment ) ;
2625 }
2726
2827 protected void Initialize ( )
2928 {
29+ // accessing Environment triggers environment initialization if it hasn't happened yet
30+ Platform = new Platform ( Environment ) ;
31+
3032 UserSettings = new UserSettings ( Environment ) ;
3133 LocalSettings = new LocalSettings ( Environment ) ;
3234 SystemSettings = new SystemSettings ( Environment ) ;
@@ -38,103 +40,134 @@ protected void Initialize()
3840 Logging . TracingEnabled = UserSettings . Get ( Constants . TraceLoggingKey , false ) ;
3941 ProcessManager = new ProcessManager ( Environment , Platform . GitEnvironment , CancellationToken ) ;
4042 Platform . Initialize ( ProcessManager , TaskManager ) ;
41- GitClient = new GitClient ( Environment , ProcessManager , Platform . CredentialManager , TaskManager ) ;
4243 }
4344
44- public virtual ITask Run ( )
45+ public virtual async Task Run ( bool firstRun )
4546 {
46- Logger . Trace ( "Run" ) ;
47-
48- var progress = new ProgressReport ( ) ;
49- return new ActionTask ( SetupAndRestart ( progress ) )
50- . Then ( new ActionTask ( LoadKeychain ( ) ) ) ;
51- }
47+ Logger . Trace ( "Run - CurrentDirectory {0}" , NPath . CurrentDirectory ) ;
5248
53- private async Task LoadKeychain ( )
54- {
55- Logger . Trace ( "Loading Keychain" ) ;
56-
57- var firstConnection = Platform . Keychain . Connections . FirstOrDefault ( ) ;
58- if ( firstConnection == null )
49+ if ( Environment . GitExecutablePath != null )
5950 {
60- Logger . Trace ( "No Host Found" ) ;
51+ GitClient = new GitClient ( Environment , ProcessManager , Platform . CredentialManager , TaskManager ) ;
6152 }
6253 else
6354 {
64- Logger . Trace ( "Loading Connection to Host:\" {0}\" " , firstConnection ) ;
65- var keychainAdapter = await Platform . Keychain . Load ( firstConnection ) . SafeAwait ( ) ;
66- if ( keychainAdapter . OctokitCredentials == Credentials . Anonymous )
67- { }
55+ var progress = new ProgressReport ( ) ;
56+
57+ var gitClient = new GitClient ( Environment , ProcessManager , Platform . CredentialManager , TaskManager ) ;
58+ var gitSetup = new GitSetup ( Environment , CancellationToken ) ;
59+ var expectedPath = gitSetup . GitInstallationPath ;
60+ var setupDone = await gitSetup . SetupIfNeeded ( progress . Percentage , progress . Remaining ) ;
61+ if ( setupDone )
62+ Environment . GitExecutablePath = gitSetup . GitExecutablePath ;
63+ else
64+ Environment . GitExecutablePath = await LookForGitInstallationPath ( gitClient , SystemSettings ) . SafeAwait ( ) ;
65+
66+ GitClient = gitClient ;
67+
68+ Logger . Trace ( "Environment.GitExecutablePath \" {0}\" Exists:{1}" , gitSetup . GitExecutablePath , gitSetup . GitExecutablePath . FileExists ( ) ) ;
69+
70+ if ( Environment . IsWindows )
71+ {
72+ var credentialHelper = await GitClient . GetConfig ( "credential.helper" , GitConfigSource . Global ) . StartAwait ( ) ;
73+ if ( string . IsNullOrEmpty ( credentialHelper ) )
74+ {
75+ await GitClient . SetConfig ( "credential.helper" , "wincred" , GitConfigSource . Global ) . StartAwait ( ) ;
76+ }
77+ }
6878 }
69- }
7079
71- protected abstract string DetermineInstallationPath ( ) ;
72- protected abstract string GetAssetsPath ( ) ;
73- protected abstract string GetUnityPath ( ) ;
80+ RestartRepository ( ) ;
81+ InitializeUI ( ) ;
7482
75- public virtual ITask RestartRepository ( )
76- {
77- return new FuncTask < bool > ( TaskManager . Token , _ =>
78- {
79- Environment . Initialize ( ) ;
83+ new ActionTask ( CancellationToken , SetupMetrics ) . Start ( ) ;
84+ new ActionTask ( new Task ( ( ) => LoadKeychain ( ) . Start ( ) ) ) . Start ( ) ;
85+ new ActionTask ( CancellationToken , RunRepositoryManager ) . Start ( ) ;
86+ }
8087
81- if ( Environment . RepositoryPath == null )
82- return false ;
83- return true ;
88+ public ITask InitializeRepository ( )
89+ {
90+ Logger . Trace ( "Running Repository Initialize" ) ;
91+
92+ var targetPath = NPath . CurrentDirectory ;
93+
94+ var unityYamlMergeExec = Environment . UnityApplication . Parent . Combine ( "Tools" , "UnityYAMLMerge" ) ;
95+ var yamlMergeCommand = $@ "'{ unityYamlMergeExec } ' merge -p ""$BASE"" ""$REMOTE"" ""$LOCAL"" ""$MERGED""";
96+
97+ var gitignore = targetPath . Combine ( ".gitignore" ) ;
98+ var gitAttrs = targetPath . Combine ( ".gitattributes" ) ;
99+ var assetsGitignore = targetPath . Combine ( "Assets" , ".gitignore" ) ;
100+
101+ var filesForInitialCommit = new List < string > { gitignore , gitAttrs , assetsGitignore } ;
102+
103+ var task =
104+ GitClient . Init ( )
105+ . Then ( GitClient . SetConfig ( "merge.unityyamlmerge.cmd" , yamlMergeCommand , GitConfigSource . Local ) )
106+ . Then ( GitClient . SetConfig ( "merge.unityyamlmerge.trustExitCode" , "false" , GitConfigSource . Local ) )
107+ . Then ( GitClient . LfsInstall ( ) )
108+ . ThenInUI ( SetProjectToTextSerialization )
109+ . Then ( new ActionTask ( CancellationToken , _ => {
110+ AssemblyResources . ToFile ( ResourceType . Generic , ".gitignore" , targetPath ) ;
111+ AssemblyResources . ToFile ( ResourceType . Generic , ".gitattributes" , targetPath ) ;
112+
113+ assetsGitignore . CreateFile ( ) ;
114+ } ) )
115+ . Then ( GitClient . Add ( filesForInitialCommit ) )
116+ . Then ( GitClient . Commit ( "Initial commit" , null ) )
117+ . Then ( RestartRepository )
118+ . ThenInUI ( InitializeUI )
119+ . Then ( RunRepositoryManager ) ;
120+ return task ;
121+ }
84122
85- } )
86- . Defer ( async s =>
123+ public void RestartRepository ( )
124+ {
125+ Environment . InitializeRepository ( ) ;
126+ if ( Environment . RepositoryPath != null )
87127 {
88- if ( ! s )
89- return false ;
90-
91128 var repositoryPathConfiguration = new RepositoryPathConfiguration ( Environment . RepositoryPath ) ;
92129 var gitConfig = new GitConfig ( repositoryPathConfiguration . DotGitConfig ) ;
93130
94131 var repositoryWatcher = new RepositoryWatcher ( Platform , repositoryPathConfiguration , TaskManager . Token ) ;
95132 repositoryManager = new RepositoryManager ( Platform , TaskManager , UsageTracker , gitConfig , repositoryWatcher ,
96133 GitClient , repositoryPathConfiguration , TaskManager . Token ) ;
97-
98- await repositoryManager . Initialize ( ) . SafeAwait ( ) ;
99134 Environment . Repository = repositoryManager . Repository ;
100135 Logger . Trace ( $ "Got a repository? { Environment . Repository } ") ;
101- repositoryManager . Start ( ) ;
102- return true ;
103- } )
104- . Finally ( ( _ , __ ) => { } ) ;
136+ }
105137 }
106138
107- private async Task SetupAndRestart ( ProgressReport progress )
139+ private void RunRepositoryManager ( )
108140 {
109- Logger . Trace ( "SetupAndRestart" ) ;
110-
111- var gitSetup = new GitSetup ( Environment , CancellationToken ) ;
112- var expectedPath = gitSetup . GitInstallationPath ;
113- var setupDone = await gitSetup . SetupIfNeeded ( progress . Percentage , progress . Remaining ) ;
114- if ( setupDone )
115- Environment . GitExecutablePath = gitSetup . GitExecutablePath ;
116- else
117- Environment . GitExecutablePath = await LookForGitInstallationPath ( ) ;
141+ Logger . Trace ( "RunRepositoryManager" ) ;
118142
119- Logger . Trace ( "Environment.GitExecutablePath \" {0}\" Exists:{1}" , gitSetup . GitExecutablePath , gitSetup . GitExecutablePath . FileExists ( ) ) ;
143+ if ( Environment . RepositoryPath != null )
144+ {
145+ new ActionTask ( repositoryManager . Initialize ( ) )
146+ . Then ( repositoryManager . Start )
147+ . Start ( ) ; ;
148+ }
149+ }
120150
121- await RestartRepository ( ) . StartAwait ( ) ;
151+ private async Task LoadKeychain ( )
152+ {
153+ Logger . Trace ( "Loading Keychain" ) ;
122154
123- if ( Environment . IsWindows )
155+ var firstConnection = Platform . Keychain . Connections . FirstOrDefault ( ) ;
156+ if ( firstConnection == null )
124157 {
125- var credentialHelper = await GitClient . GetConfig ( "credential.helper" , GitConfigSource . Global ) . StartAwait ( ) ;
126-
127- if ( string . IsNullOrEmpty ( credentialHelper ) )
128- {
129- await GitClient . SetConfig ( "credential.helper" , "wincred" , GitConfigSource . Global ) . StartAwait ( ) ;
130- }
158+ Logger . Trace ( "No Host Found" ) ;
159+ }
160+ else
161+ {
162+ Logger . Trace ( "Loading Connection to Host: \" {0} \" " , firstConnection ) ;
163+ await Platform . Keychain . Load ( firstConnection ) . SafeAwait ( ) ;
131164 }
132165 }
133166
134- private async Task < NPath > LookForGitInstallationPath ( )
167+ private static async Task < NPath > LookForGitInstallationPath ( IGitClient gitClient , ISettings systemSettings )
135168 {
136169 NPath cachedGitInstallPath = null ;
137- var path = SystemSettings . Get ( Constants . GitInstallPathKey ) ;
170+ var path = systemSettings . Get ( Constants . GitInstallPathKey ) ;
138171 if ( ! String . IsNullOrEmpty ( path ) )
139172 cachedGitInstallPath = path . ToNPath ( ) ;
140173
@@ -143,7 +176,7 @@ private async Task<NPath> LookForGitInstallationPath()
143176 {
144177 return cachedGitInstallPath ;
145178 }
146- return await GitClient . FindGitInstallation ( ) . SafeAwait ( ) ;
179+ return await gitClient . FindGitInstallation ( ) ;
147180 }
148181
149182 protected void SetupMetrics ( string unityVersion , bool firstRun )
@@ -172,6 +205,10 @@ protected void SetupMetrics(string unityVersion, bool firstRun)
172205 }
173206 }
174207
208+ protected abstract void SetupMetrics ( ) ;
209+ protected abstract void InitializeUI ( ) ;
210+ protected abstract void SetProjectToTextSerialization ( ) ;
211+
175212 private bool disposed = false ;
176213 protected virtual void Dispose ( bool disposing )
177214 {
@@ -189,27 +226,7 @@ public void Dispose()
189226 Dispose ( true ) ;
190227 }
191228
192- public IEnvironment Environment
193- {
194- get
195- {
196- // if this is called while still null, it's because Unity wants
197- // to render something and we need to load icons, and that runs
198- // before EntryPoint. Do an early initialization
199- if ( environment == null )
200- {
201- environment = new DefaultEnvironment ( ) ;
202- var assetsPath = GetAssetsPath ( ) ;
203- var unityPath = GetUnityPath ( ) ;
204- var extensionInstallPath = DetermineInstallationPath ( ) ;
205-
206- // figure out where we are
207- environment . Initialize ( extensionInstallPath . ToNPath ( ) , unityPath . ToNPath ( ) , assetsPath . ToNPath ( ) ) ;
208- }
209- return environment ;
210- }
211- protected set { environment = value ; }
212- }
229+ public abstract IEnvironment Environment { get ; }
213230
214231 public IPlatform Platform { get ; protected set ; }
215232 public virtual IProcessEnvironment GitEnvironment { get ; set ; }
0 commit comments