private Result DoClone(string fullEnlistmentRootPathParameter, string normalizedEnlistmentRootPath) { Result cloneResult = null; cloneResult = this.TryCreateEnlistment(fullEnlistmentRootPathParameter, normalizedEnlistmentRootPath, out this.enlistment); if (!cloneResult.Success) { this.tracer.RelatedError($"Error while creating enlistment: {cloneResult.ErrorMessage}"); return(cloneResult); } this.tracer.AddLogFileEventListener( ScalarEnlistment.GetNewScalarLogFileName(this.enlistment.ScalarLogsRoot, ScalarConstants.LogFileTypes.Clone), EventLevel.Informational, Keywords.Any); this.tracer.WriteStartEvent( this.enlistment.EnlistmentRoot, this.enlistment.RepoUrl, this.CacheServerUrl, this.AddVerbDataToMetadata(new EventMetadata { { nameof(this.Branch), this.Branch }, { nameof(this.LocalCacheRoot), this.LocalCacheRoot }, { nameof(this.SingleBranch), this.SingleBranch }, { nameof(this.FullClone), this.FullClone }, { nameof(this.NoFetchCommitsAndTrees), this.NoFetchCommitsAndTrees }, { nameof(this.Unattended), this.Unattended }, { nameof(ScalarPlatform.Instance.IsElevated), ScalarPlatform.Instance.IsElevated() }, { "ProcessID", Process.GetCurrentProcess().Id }, { nameof(this.EnlistmentRootPathParameter), this.EnlistmentRootPathParameter }, { nameof(fullEnlistmentRootPathParameter), fullEnlistmentRootPathParameter }, })); this.cacheServerResolver = new CacheServerResolver(this.tracer, this.enlistment); this.cacheServer = this.cacheServerResolver.ParseUrlOrFriendlyName(this.CacheServerUrl); string resolvedLocalCacheRoot; if (string.IsNullOrWhiteSpace(this.LocalCacheRoot)) { if (!LocalCacheResolver.TryGetDefaultLocalCacheRoot(this.enlistment, out resolvedLocalCacheRoot, out string localCacheRootError)) { this.ReportErrorAndExit( this.tracer, $"Failed to determine the default location for the local Scalar cache: `{localCacheRootError}`"); } } else { resolvedLocalCacheRoot = Path.GetFullPath(this.LocalCacheRoot); } this.Output.WriteLine("Clone parameters:"); this.Output.WriteLine(" Repo URL: " + this.enlistment.RepoUrl); this.Output.WriteLine(" Branch: " + (string.IsNullOrWhiteSpace(this.Branch) ? "Default" : this.Branch)); this.Output.WriteLine(" Cache Server: " + this.cacheServer); this.Output.WriteLine(" Local Cache: " + resolvedLocalCacheRoot); this.Output.WriteLine(" Destination: " + this.enlistment.EnlistmentRoot); this.Output.WriteLine(" FullClone: " + this.FullClone); string authErrorMessage; if (!this.TryAuthenticate(this.tracer, this.enlistment, out authErrorMessage)) { this.ReportErrorAndExit(this.tracer, "Cannot clone because authentication failed: " + authErrorMessage); } this.retryConfig = this.GetRetryConfig(this.tracer, this.enlistment, TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes)); this.serverScalarConfig = this.QueryScalarConfig(this.tracer, this.enlistment, this.retryConfig); this.cacheServer = this.ResolveCacheServer(this.tracer, this.cacheServer, this.cacheServerResolver, this.serverScalarConfig); this.ValidateClientVersions(this.tracer, this.enlistment, this.serverScalarConfig, showWarnings: true); using (this.objectRequestor = new GitObjectsHttpRequestor(this.tracer, this.enlistment, this.cacheServer, this.retryConfig)) { cloneResult = this.CreateScalarDirctories(resolvedLocalCacheRoot); if (!cloneResult.Success) { this.tracer.RelatedError(cloneResult.ErrorMessage); return(cloneResult); } this.ShowStatusWhileRunning( () => { cloneResult = this.CreateClone(); return(cloneResult.Success); }, "Cloning"); if (!cloneResult.Success) { this.tracer.RelatedError(cloneResult.ErrorMessage); return(cloneResult); } if (!this.NoFetchCommitsAndTrees) { ReturnCode result = this.Execute <RunVerb>( this.enlistment, verb => { verb.MaintenanceTask = ScalarConstants.VerbParameters.Maintenance.FetchTaskName; verb.SkipVersionCheck = true; verb.ResolvedCacheServer = this.cacheServer; verb.ServerScalarConfig = this.serverScalarConfig; }); if (result != ReturnCode.Success) { this.Output.WriteLine("\r\nError while fetching commits and trees @ {0}", fullEnlistmentRootPathParameter); return(cloneResult); } } this.ShowStatusWhileRunning( () => { cloneResult = this.CheckoutRepo(); return(cloneResult.Success); }, "Populating working directory"); } if (cloneResult.Success) { cloneResult = this.TryRegisterRepo(); } return(cloneResult); }
public override void Execute() { int exitCode = 0; this.ValidatePathParameter(this.EnlistmentRootPath); this.ValidatePathParameter(this.LocalCacheRoot); this.EnlistmentRootPath = this.GetCloneRoot(); if (!string.IsNullOrWhiteSpace(this.LocalCacheRoot)) { if (Path.GetFullPath(this.LocalCacheRoot).StartsWith( Path.Combine(this.EnlistmentRootPath, GVFSConstants.WorkingDirectoryRootName), StringComparison.OrdinalIgnoreCase)) { this.ReportErrorAndExit("'--local-cache-path' cannot be inside the src folder"); } } this.CheckNTFSVolume(); this.CheckGVFltHealthy(); this.CheckNotInsideExistingRepo(); this.BlockEmptyCacheServerUrl(this.CacheServerUrl); try { GVFSEnlistment enlistment; Result cloneResult = new Result(false); CacheServerInfo cacheServer = null; GVFSConfig gvfsConfig = null; using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "GVFSClone")) { cloneResult = this.TryCreateEnlistment(out enlistment); if (cloneResult.Success) { tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Clone), EventLevel.Informational, Keywords.Any); tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, this.CacheServerUrl, new EventMetadata { { "Branch", this.Branch }, { "LocalCacheRoot", this.LocalCacheRoot }, { "SingleBranch", this.SingleBranch }, { "NoMount", this.NoMount }, { "NoPrefetch", this.NoPrefetch }, { "Unattended", this.Unattended }, { "IsElevated", ProcessHelper.IsAdminElevated() }, }); CacheServerResolver cacheServerResolver = new CacheServerResolver(tracer, enlistment); cacheServer = cacheServerResolver.ParseUrlOrFriendlyName(this.CacheServerUrl); string error; string resolvedLocalCacheRoot; if (string.IsNullOrWhiteSpace(this.LocalCacheRoot)) { if (!LocalCacheResolver.TryGetDefaultLocalCacheRoot(enlistment, out resolvedLocalCacheRoot, out error)) { this.ReportErrorAndExit(tracer, "Cannot clone, error determining local cache path: " + error); } } else { resolvedLocalCacheRoot = Path.GetFullPath(this.LocalCacheRoot); } this.Output.WriteLine("Clone parameters:"); this.Output.WriteLine(" Repo URL: " + enlistment.RepoUrl); this.Output.WriteLine(" Branch: " + (string.IsNullOrWhiteSpace(this.Branch) ? "Default" : this.Branch)); this.Output.WriteLine(" Cache Server: " + cacheServer); this.Output.WriteLine(" Local Cache: " + resolvedLocalCacheRoot); this.Output.WriteLine(" Destination: " + enlistment.EnlistmentRoot); string authErrorMessage = null; if (!this.ShowStatusWhileRunning( () => enlistment.Authentication.TryRefreshCredentials(tracer, out authErrorMessage), "Authenticating")) { this.ReportErrorAndExit(tracer, "Cannot clone because authentication failed"); } RetryConfig retryConfig = this.GetRetryConfig(tracer, enlistment, TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes)); gvfsConfig = this.QueryGVFSConfig(tracer, enlistment, retryConfig); cacheServer = this.ResolveCacheServer(tracer, cacheServer, cacheServerResolver, gvfsConfig); this.ValidateClientVersions(tracer, enlistment, gvfsConfig, showWarnings: true); this.ShowStatusWhileRunning( () => { cloneResult = this.TryClone(tracer, enlistment, cacheServer, retryConfig, gvfsConfig, resolvedLocalCacheRoot); return(cloneResult.Success); }, "Cloning"); } if (!cloneResult.Success) { tracer.RelatedError(cloneResult.ErrorMessage); } } if (cloneResult.Success) { if (!this.NoPrefetch) { this.Execute <PrefetchVerb>( this.EnlistmentRootPath, verb => { verb.Commits = true; verb.SkipVersionCheck = true; verb.ResolvedCacheServer = cacheServer; verb.GVFSConfig = gvfsConfig; }); } if (this.NoMount) { this.Output.WriteLine("\r\nIn order to mount, first cd to within your enlistment, then call: "); this.Output.WriteLine("gvfs mount"); } else { this.Execute <MountVerb>( this.EnlistmentRootPath, verb => { verb.SkipMountedCheck = true; verb.SkipVersionCheck = true; verb.ResolvedCacheServer = cacheServer; verb.DownloadedGVFSConfig = gvfsConfig; }); } } else { this.Output.WriteLine("\r\nCannot clone @ {0}", this.EnlistmentRootPath); this.Output.WriteLine("Error: {0}", cloneResult.ErrorMessage); exitCode = (int)ReturnCode.GenericError; } } catch (AggregateException e) { this.Output.WriteLine("Cannot clone @ {0}:", this.EnlistmentRootPath); foreach (Exception ex in e.Flatten().InnerExceptions) { this.Output.WriteLine("Exception: {0}", ex.ToString()); } exitCode = (int)ReturnCode.GenericError; } catch (VerbAbortedException) { throw; } catch (Exception e) { this.ReportErrorAndExit("Cannot clone @ {0}: {1}", this.EnlistmentRootPath, e.ToString()); } Environment.Exit(exitCode); }
public override void Execute() { int exitCode = 0; this.ValidatePathParameter(this.EnlistmentRootPathParameter); this.ValidatePathParameter(this.LocalCacheRoot); string fullEnlistmentRootPathParameter; string normalizedEnlistmentRootPath = this.GetCloneRoot(out fullEnlistmentRootPathParameter); if (!string.IsNullOrWhiteSpace(this.LocalCacheRoot)) { string fullLocalCacheRootPath = Path.GetFullPath(this.LocalCacheRoot); string errorMessage; string normalizedLocalCacheRootPath; if (!GVFSPlatform.Instance.FileSystem.TryGetNormalizedPath(fullLocalCacheRootPath, out normalizedLocalCacheRootPath, out errorMessage)) { this.ReportErrorAndExit($"Failed to determine normalized path for '--local-cache-path' path {fullLocalCacheRootPath}: {errorMessage}"); } if (normalizedLocalCacheRootPath.StartsWith( Path.Combine(normalizedEnlistmentRootPath, GVFSConstants.WorkingDirectoryRootName), StringComparison.OrdinalIgnoreCase)) { this.ReportErrorAndExit("'--local-cache-path' cannot be inside the src folder"); } } this.CheckKernelDriverSupported(normalizedEnlistmentRootPath); this.CheckNotInsideExistingRepo(normalizedEnlistmentRootPath); this.BlockEmptyCacheServerUrl(this.CacheServerUrl); try { GVFSEnlistment enlistment; Result cloneResult = new Result(false); CacheServerInfo cacheServer = null; ServerGVFSConfig serverGVFSConfig = null; using (JsonTracer tracer = new JsonTracer(GVFSConstants.GVFSEtwProviderName, "GVFSClone")) { cloneResult = this.TryCreateEnlistment(fullEnlistmentRootPathParameter, normalizedEnlistmentRootPath, out enlistment); if (cloneResult.Success) { tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Clone), EventLevel.Informational, Keywords.Any); tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, this.CacheServerUrl, new EventMetadata { { "Branch", this.Branch }, { "LocalCacheRoot", this.LocalCacheRoot }, { "SingleBranch", this.SingleBranch }, { "NoMount", this.NoMount }, { "NoPrefetch", this.NoPrefetch }, { "Unattended", this.Unattended }, { "IsElevated", GVFSPlatform.Instance.IsElevated() }, { "NamedPipeName", enlistment.NamedPipeName }, { nameof(this.EnlistmentRootPathParameter), this.EnlistmentRootPathParameter }, { nameof(fullEnlistmentRootPathParameter), fullEnlistmentRootPathParameter }, }); CacheServerResolver cacheServerResolver = new CacheServerResolver(tracer, enlistment); cacheServer = cacheServerResolver.ParseUrlOrFriendlyName(this.CacheServerUrl); string resolvedLocalCacheRoot; if (string.IsNullOrWhiteSpace(this.LocalCacheRoot)) { string localCacheRootError; if (!LocalCacheResolver.TryGetDefaultLocalCacheRoot(enlistment, out resolvedLocalCacheRoot, out localCacheRootError)) { this.ReportErrorAndExit( tracer, $"Failed to determine the default location for the local GVFS cache: `{localCacheRootError}`"); } } else { resolvedLocalCacheRoot = Path.GetFullPath(this.LocalCacheRoot); } this.Output.WriteLine("Clone parameters:"); this.Output.WriteLine(" Repo URL: " + enlistment.RepoUrl); this.Output.WriteLine(" Branch: " + (string.IsNullOrWhiteSpace(this.Branch) ? "Default" : this.Branch)); this.Output.WriteLine(" Cache Server: " + cacheServer); this.Output.WriteLine(" Local Cache: " + resolvedLocalCacheRoot); this.Output.WriteLine(" Destination: " + enlistment.EnlistmentRoot); string authErrorMessage; if (!this.TryAuthenticate(tracer, enlistment, out authErrorMessage)) { this.ReportErrorAndExit(tracer, "Cannot clone because authentication failed: " + authErrorMessage); } RetryConfig retryConfig = this.GetRetryConfig(tracer, enlistment, TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes)); serverGVFSConfig = this.QueryGVFSConfig(tracer, enlistment, retryConfig); cacheServer = this.ResolveCacheServer(tracer, cacheServer, cacheServerResolver, serverGVFSConfig); this.ValidateClientVersions(tracer, enlistment, serverGVFSConfig, showWarnings: true); this.ShowStatusWhileRunning( () => { cloneResult = this.TryClone(tracer, enlistment, cacheServer, retryConfig, serverGVFSConfig, resolvedLocalCacheRoot); return(cloneResult.Success); }, "Cloning", normalizedEnlistmentRootPath); } if (!cloneResult.Success) { tracer.RelatedError(cloneResult.ErrorMessage); } } if (cloneResult.Success) { if (!this.NoPrefetch) { ReturnCode result = this.Execute <PrefetchVerb>( enlistment, verb => { verb.Commits = true; verb.SkipVersionCheck = true; verb.ResolvedCacheServer = cacheServer; verb.ServerGVFSConfig = serverGVFSConfig; }); if (result != ReturnCode.Success) { this.Output.WriteLine("\r\nError during prefetch @ {0}", fullEnlistmentRootPathParameter); exitCode = (int)result; } } if (this.NoMount) { this.Output.WriteLine("\r\nIn order to mount, first cd to within your enlistment, then call: "); this.Output.WriteLine("gvfs mount"); } else { this.Execute <MountVerb>( enlistment, verb => { verb.SkipMountedCheck = true; verb.SkipVersionCheck = true; verb.ResolvedCacheServer = cacheServer; verb.DownloadedGVFSConfig = serverGVFSConfig; }); } } else { this.Output.WriteLine("\r\nCannot clone @ {0}", fullEnlistmentRootPathParameter); this.Output.WriteLine("Error: {0}", cloneResult.ErrorMessage); exitCode = (int)ReturnCode.GenericError; } } catch (AggregateException e) { this.Output.WriteLine("Cannot clone @ {0}:", fullEnlistmentRootPathParameter); foreach (Exception ex in e.Flatten().InnerExceptions) { this.Output.WriteLine("Exception: {0}", ex.ToString()); } exitCode = (int)ReturnCode.GenericError; } catch (VerbAbortedException) { throw; } catch (Exception e) { this.ReportErrorAndExit("Cannot clone @ {0}: {1}", fullEnlistmentRootPathParameter, e.ToString()); } Environment.Exit(exitCode); }
private Result DoClone(string fullEnlistmentRootPathParameter, string normalizedEnlistmentRootPath) { Result cloneResult = null; cloneResult = this.TryCreateEnlistment(fullEnlistmentRootPathParameter, normalizedEnlistmentRootPath, out this.enlistment); if (!cloneResult.Success) { this.tracer.RelatedError($"Error while creating enlistment: {cloneResult.ErrorMessage}"); return(cloneResult); } this.tracer.AddLogFileEventListener( ScalarEnlistment.GetNewScalarLogFileName(this.enlistment.ScalarLogsRoot, ScalarConstants.LogFileTypes.Clone), EventLevel.Informational, Keywords.Any); this.tracer.WriteStartEvent( this.enlistment.EnlistmentRoot, this.enlistment.RepoUrl, this.CacheServerUrl, this.AddVerbDataToMetadata(new EventMetadata { { nameof(this.Branch), this.Branch }, { nameof(this.LocalCacheRoot), this.LocalCacheRoot }, { nameof(this.SingleBranch), this.SingleBranch }, { nameof(this.FullClone), this.FullClone }, { nameof(this.NoFetchCommitsAndTrees), this.NoFetchCommitsAndTrees }, { nameof(this.Unattended), this.Unattended }, { nameof(ScalarPlatform.Instance.IsElevated), ScalarPlatform.Instance.IsElevated() }, { "ProcessID", Process.GetCurrentProcess().Id }, { nameof(this.EnlistmentRootPathParameter), this.EnlistmentRootPathParameter }, { nameof(fullEnlistmentRootPathParameter), fullEnlistmentRootPathParameter }, })); this.cacheServerResolver = new CacheServerResolver(this.tracer, this.enlistment); this.cacheServer = this.cacheServerResolver.ParseUrlOrFriendlyName(this.CacheServerUrl); string resolvedLocalCacheRoot; if (string.IsNullOrWhiteSpace(this.LocalCacheRoot)) { if (!LocalCacheResolver.TryGetDefaultLocalCacheRoot(this.enlistment, out resolvedLocalCacheRoot, out string localCacheRootError)) { this.ReportErrorAndExit( this.tracer, $"Failed to determine the default location for the local Scalar cache: `{localCacheRootError}`"); } } else { resolvedLocalCacheRoot = Path.GetFullPath(this.LocalCacheRoot); } // Determine what features of Git we have available to guide how we init/clone the repository var gitFeatures = GitFeatureFlags.None; string gitBinPath = ScalarPlatform.Instance.GitInstallation.GetInstalledGitBinPath(); this.tracer.RelatedInfo("Attempting to determine Git version for installation '{0}'", gitBinPath); if (GitProcess.TryGetVersion(gitBinPath, out var gitVersion, out string gitVersionError)) { this.tracer.RelatedInfo("Git installation '{0}' has version '{1}", gitBinPath, gitVersion); gitFeatures = gitVersion.GetFeatures(); }