private ReturnCode RunAndRecordGVFSVerb <TVerb>(string archiveFolderPath, string outputFileName) where TVerb : GVFSVerb, new() { try { using (FileStream file = new FileStream(Path.Combine(archiveFolderPath, outputFileName), FileMode.CreateNew)) using (StreamWriter writer = new StreamWriter(file)) { return(GVFSVerb.Execute <TVerb>( this.EnlistmentRootPath, verb => { verb.Output = writer; verb.ServiceName = this.ServiceName; })); } } catch (Exception e) { this.WriteMessage(string.Format( "Verb {0} failed with exception {1}", typeof(TVerb), e)); return(ReturnCode.GenericError); } }
private ReturnCode ExecuteGVFSVerb <TVerb>(ITracer tracer) where TVerb : GVFSVerb, new() { try { ReturnCode returnCode; StringBuilder commandOutput = new StringBuilder(); using (StringWriter writer = new StringWriter(commandOutput)) { returnCode = GVFSVerb.Execute <TVerb>(this.EnlistmentRootPath, verb => verb.Output = writer); } tracer.RelatedEvent( EventLevel.Informational, typeof(TVerb).Name, new EventMetadata { { "Output", commandOutput.ToString() }, { "ReturnCode", returnCode } }); return(returnCode); } catch (Exception e) { tracer.RelatedError( new EventMetadata { { "Verb", typeof(TVerb).Name }, { "Exception", e.ToString() } }); return(ReturnCode.GenericError); } }
private ReturnCode RunAndRecordGVFSVerb <TVerb>(string archiveFolderPath, string outputFileName, Action <TVerb> customConfigureVerb = null) where TVerb : GVFSVerb, new() { try { using (FileStream file = new FileStream(Path.Combine(archiveFolderPath, outputFileName), FileMode.CreateNew)) using (StreamWriter writer = new StreamWriter(file)) { customConfigureVerb = customConfigureVerb ?? new Action <TVerb>(verb => { }); Action <TVerb> composedVerbConfiguration; composedVerbConfiguration = verb => { customConfigureVerb(verb); verb.Output = writer; verb.ServiceName = this.ServiceName; }; return(GVFSVerb.Execute <TVerb>(this.EnlistmentRootPath, composedVerbConfiguration)); } } catch (Exception e) { this.WriteMessage(string.Format( "Verb {0} failed with exception {1}", typeof(TVerb), e)); return(ReturnCode.GenericError); } }
public override void Execute() { if (string.IsNullOrWhiteSpace(this.EnlistmentRootPath)) { this.EnlistmentRootPath = Environment.CurrentDirectory; } GVFSEnlistment enlistment = GVFSEnlistment.CreateWithoutRepoUrlFromDirectory( this.EnlistmentRootPath, GitProcess.GetInstalledGitBinPath()); if (enlistment == null) { this.ReportErrorAndExit("'gvfs repair' must be run within a GVFS enlistment"); } if (!this.Confirmed) { this.Output.WriteLine( @"WARNING: THIS IS AN EXPERIMENTAL FEATURE This command detects and repairs issues that prevent a GVFS repo from mounting. A few such checks are currently implemented, and some of them can be repaired. More repairs and more checks are coming soon. Without --confirm, it will non-invasively check if repairs are necessary. To actually execute any necessary repair(s), run 'gvfs repair --confirm' "); } if (!ConsoleHelper.ShowStatusWhileRunning( () => { return(GVFSVerb.Execute <StatusVerb>(enlistment.EnlistmentRoot, verb => verb.Output = new StringWriter()) != ReturnCode.Success); }, "Checking 'gvfs status'", this.Output, showSpinner: true, suppressGvfsLogMessage: true)) { this.ReportErrorAndExit("You can only run 'gvfs repair' if GVFS is not mounted. Run 'gvfs unmount' and try again."); } this.Output.WriteLine(); using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "RepairVerb")) { tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Repair), EventLevel.Verbose, Keywords.Any); tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, enlistment.CacheServerUrl, new EventMetadata { { "Confirmed", this.Confirmed } }); List <RepairJob> jobs = new List <RepairJob>(); // Repair ESENT Databases jobs.Add(new BackgroundOperationDatabaseRepairJob(tracer, this.Output, enlistment)); jobs.Add(new BlobSizeDatabaseRepairJob(tracer, this.Output, enlistment)); jobs.Add(new PlaceholderDatabaseRepairJob(tracer, this.Output, enlistment)); jobs.Add(new RepoMetadataDatabaseRepairJob(tracer, this.Output, enlistment)); jobs.Add(new GitHeadRepairJob(tracer, this.Output, enlistment)); Dictionary <RepairJob, List <string> > healthy = new Dictionary <RepairJob, List <string> >(); Dictionary <RepairJob, List <string> > cantFix = new Dictionary <RepairJob, List <string> >(); Dictionary <RepairJob, List <string> > fixable = new Dictionary <RepairJob, List <string> >(); foreach (RepairJob job in jobs) { List <string> messages = new List <string>(); switch (job.HasIssue(messages)) { case RepairJob.IssueType.None: healthy[job] = messages; break; case RepairJob.IssueType.CantFix: cantFix[job] = messages; break; case RepairJob.IssueType.Fixable: fixable[job] = messages; break; } } foreach (RepairJob job in healthy.Keys) { this.WriteMessage(tracer, string.Format("{0, -30}: Healthy", job.Name)); this.WriteMessages(tracer, healthy[job]); } if (healthy.Count > 0) { this.Output.WriteLine(); } foreach (RepairJob job in cantFix.Keys) { this.WriteMessage(tracer, job.Name); this.WriteMessages(tracer, cantFix[job]); this.Indent(); this.WriteMessage(tracer, "'gvfs repair' does not currently support fixing this problem"); this.Output.WriteLine(); } foreach (RepairJob job in fixable.Keys) { this.WriteMessage(tracer, job.Name); this.WriteMessages(tracer, fixable[job]); this.Indent(); if (this.Confirmed) { List <string> repairMessages = new List <string>(); if (job.TryFixIssues(repairMessages)) { this.WriteMessage(tracer, "Repair succeeded"); } else { this.WriteMessage(tracer, "Repair failed. Run 'gvfs log' for more info."); } this.WriteMessages(tracer, repairMessages); } else { this.WriteMessage(tracer, "Run 'gvfs repair --confirm' to attempt a repair"); } this.Output.WriteLine(); } } }