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,135 @@ 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 {
4647 Logger . Trace ( "Run" ) ;
48+ Logger . Trace ( "CurrentDirectory" , NPath . CurrentDirectory ) ;
4749
48- var progress = new ProgressReport ( ) ;
49- return new ActionTask ( SetupAndRestart ( progress ) )
50- . Then ( new ActionTask ( LoadKeychain ( ) ) ) ;
51- }
52-
53- private async Task LoadKeychain ( )
54- {
55- Logger . Trace ( "Loading Keychain" ) ;
56-
57- var firstConnection = Platform . Keychain . Connections . FirstOrDefault ( ) ;
58- if ( firstConnection == null )
50+ if ( Environment . GitExecutablePath != null )
5951 {
60- Logger . Trace ( "No Host Found" ) ;
52+ GitClient = new GitClient ( Environment , ProcessManager , Platform . CredentialManager , TaskManager ) ;
6153 }
6254 else
6355 {
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- { }
56+ var progress = new ProgressReport ( ) ;
57+
58+ var gitClient = new GitClient ( Environment , ProcessManager , Platform . CredentialManager , TaskManager ) ;
59+ var gitSetup = new GitSetup ( Environment , CancellationToken ) ;
60+ var expectedPath = gitSetup . GitInstallationPath ;
61+ var setupDone = await gitSetup . SetupIfNeeded ( progress . Percentage , progress . Remaining ) ;
62+ if ( setupDone )
63+ Environment . GitExecutablePath = gitSetup . GitExecutablePath ;
64+ else
65+ Environment . GitExecutablePath = await LookForGitInstallationPath ( gitClient , SystemSettings ) . SafeAwait ( ) ;
66+
67+ GitClient = gitClient ;
68+
69+ Logger . Trace ( "Environment.GitExecutablePath \" {0}\" Exists:{1}" , gitSetup . GitExecutablePath , gitSetup . GitExecutablePath . FileExists ( ) ) ;
70+
71+ if ( Environment . IsWindows )
72+ {
73+ var credentialHelper = await GitClient . GetConfig ( "credential.helper" , GitConfigSource . Global ) . StartAwait ( ) ;
74+ if ( string . IsNullOrEmpty ( credentialHelper ) )
75+ {
76+ await GitClient . SetConfig ( "credential.helper" , "wincred" , GitConfigSource . Global ) . StartAwait ( ) ;
77+ }
78+ }
6879 }
69- }
7080
71- protected abstract string DetermineInstallationPath ( ) ;
72- protected abstract string GetAssetsPath ( ) ;
73- protected abstract string GetUnityPath ( ) ;
81+ RestartRepository ( ) ;
82+ InitializeUI ( ) ;
7483
75- public virtual ITask RestartRepository ( )
76- {
77- return new FuncTask < bool > ( TaskManager . Token , _ =>
78- {
79- Environment . Initialize ( ) ;
84+ new ActionTask ( CancellationToken , SetupMetrics ) . Start ( ) ;
85+ new ActionTask ( new Task ( ( ) => LoadKeychain ( ) . Start ( ) ) ) . Start ( ) ;
86+ new ActionTask ( CancellationToken , RunRepositoryManager ) . Start ( ) ;
87+ }
8088
81- if ( Environment . RepositoryPath == null )
82- return false ;
83- return true ;
89+ public ITask InitializeRepository ( )
90+ {
91+ Logger . Trace ( "Running Repository Initialize" ) ;
92+
93+ var targetPath = NPath . CurrentDirectory ;
94+
95+ var unityYamlMergeExec = Environment . UnityApplication . Parent . Combine ( "Tools" , "UnityYAMLMerge" ) ;
96+ var yamlMergeCommand = $@ "'{ unityYamlMergeExec } ' merge -p ""$BASE"" ""$REMOTE"" ""$LOCAL"" ""$MERGED""";
97+
98+ var gitignore = targetPath . Combine ( ".gitignore" ) ;
99+ var gitAttrs = targetPath . Combine ( ".gitattributes" ) ;
100+ var assetsGitignore = targetPath . Combine ( "Assets" , ".gitignore" ) ;
101+
102+ var filesForInitialCommit = new List < string > { gitignore , gitAttrs , assetsGitignore } ;
103+
104+ var task =
105+ GitClient . Init ( )
106+ . Then ( GitClient . SetConfig ( "merge.unityyamlmerge.cmd" , yamlMergeCommand , GitConfigSource . Local ) )
107+ . Then ( GitClient . SetConfig ( "merge.unityyamlmerge.trustExitCode" , "false" , GitConfigSource . Local ) )
108+ . Then ( GitClient . LfsInstall ( ) )
109+ . ThenInUI ( SetProjectToTextSerialization )
110+ . Then ( new ActionTask ( CancellationToken , _ => {
111+ AssemblyResources . ToFile ( ResourceType . Generic , ".gitignore" , targetPath ) ;
112+ AssemblyResources . ToFile ( ResourceType . Generic , ".gitattributes" , targetPath ) ;
113+
114+ assetsGitignore . CreateFile ( ) ;
115+ } ) )
116+ . Then ( GitClient . Add ( filesForInitialCommit ) )
117+ . Then ( GitClient . Commit ( "Initial commit" , null ) )
118+ . Then ( RestartRepository )
119+ . ThenInUI ( InitializeUI )
120+ . Then ( RunRepositoryManager ) ;
121+ return task ;
122+ }
84123
85- } )
86- . Defer ( async s =>
124+ public void RestartRepository ( )
125+ {
126+ Environment . InitializeRepository ( ) ;
127+ if ( Environment . RepositoryPath != null )
87128 {
88- if ( ! s )
89- return false ;
90-
91129 var repositoryPathConfiguration = new RepositoryPathConfiguration ( Environment . RepositoryPath ) ;
92130 var gitConfig = new GitConfig ( repositoryPathConfiguration . DotGitConfig ) ;
93131
94132 var repositoryWatcher = new RepositoryWatcher ( Platform , repositoryPathConfiguration , TaskManager . Token ) ;
95133 repositoryManager = new RepositoryManager ( Platform , TaskManager , UsageTracker , gitConfig , repositoryWatcher ,
96134 GitClient , repositoryPathConfiguration , TaskManager . Token ) ;
97-
98- await repositoryManager . Initialize ( ) . SafeAwait ( ) ;
99135 Environment . Repository = repositoryManager . Repository ;
100136 Logger . Trace ( $ "Got a repository? { Environment . Repository } ") ;
101- repositoryManager . Start ( ) ;
102- return true ;
103- } )
104- . Finally ( ( _ , __ ) => { } ) ;
137+ }
105138 }
106139
107- private async Task SetupAndRestart ( ProgressReport progress )
140+ private void RunRepositoryManager ( )
108141 {
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 ( ) ;
142+ Logger . Trace ( "RestartRepository" ) ;
118143
119- Logger . Trace ( "Environment.GitExecutablePath \" {0}\" Exists:{1}" , gitSetup . GitExecutablePath , gitSetup . GitExecutablePath . FileExists ( ) ) ;
144+ if ( Environment . RepositoryPath != null )
145+ {
146+ new ActionTask ( repositoryManager . Initialize ( ) )
147+ . Then ( repositoryManager . Start )
148+ . Start ( ) ; ;
149+ }
150+ }
120151
121- await RestartRepository ( ) . StartAwait ( ) ;
152+ private async Task LoadKeychain ( )
153+ {
154+ Logger . Trace ( "Loading Keychain" ) ;
122155
123- if ( Environment . IsWindows )
156+ var firstConnection = Platform . Keychain . Connections . FirstOrDefault ( ) ;
157+ if ( firstConnection == null )
124158 {
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- }
159+ Logger . Trace ( "No Host Found" ) ;
160+ }
161+ else
162+ {
163+ Logger . Trace ( "Loading Connection to Host: \" {0} \" " , firstConnection ) ;
164+ await Platform . Keychain . Load ( firstConnection ) . SafeAwait ( ) ;
131165 }
132166 }
133167
134- private async Task < NPath > LookForGitInstallationPath ( )
168+ private static async Task < NPath > LookForGitInstallationPath ( IGitClient gitClient , ISettings systemSettings )
135169 {
136170 NPath cachedGitInstallPath = null ;
137- var path = SystemSettings . Get ( Constants . GitInstallPathKey ) ;
171+ var path = systemSettings . Get ( Constants . GitInstallPathKey ) ;
138172 if ( ! String . IsNullOrEmpty ( path ) )
139173 cachedGitInstallPath = path . ToNPath ( ) ;
140174
@@ -143,7 +177,7 @@ private async Task<NPath> LookForGitInstallationPath()
143177 {
144178 return cachedGitInstallPath ;
145179 }
146- return await GitClient . FindGitInstallation ( ) . SafeAwait ( ) ;
180+ return await gitClient . FindGitInstallation ( ) ;
147181 }
148182
149183 protected void SetupMetrics ( string unityVersion , bool firstRun )
@@ -172,6 +206,10 @@ protected void SetupMetrics(string unityVersion, bool firstRun)
172206 }
173207 }
174208
209+ protected abstract void SetupMetrics ( ) ;
210+ protected abstract void InitializeUI ( ) ;
211+ protected abstract void SetProjectToTextSerialization ( ) ;
212+
175213 private bool disposed = false ;
176214 protected virtual void Dispose ( bool disposing )
177215 {
@@ -189,27 +227,7 @@ public void Dispose()
189227 Dispose ( true ) ;
190228 }
191229
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- }
230+ public abstract IEnvironment Environment { get ; }
213231
214232 public IPlatform Platform { get ; protected set ; }
215233 public virtual IProcessEnvironment GitEnvironment { get ; set ; }
0 commit comments