private static async Task <(CSharpCompilation?, ZipArchive?)> GetCompilationAsync(Installation installation, string branch) { var archive = await GetSnapshotAsync(branch); if (archive == null) { return(null, null); } CSharpCompilation?compilation = null; AnsiConsole .Status() .Start("Compiling trainer", _ => { var compiler = new Compiler(archive, installation); compilation = compiler.Compile(); var errors = compilation .GetDiagnostics() .Where(d => d.Severity == DiagnosticSeverity.Error) .ToList(); if (errors.Any()) { AnsiConsole.MarkupLine($"[yellow]Compilation failed for {branch} branch.[/]"); compilation = null; } else { AnsiConsole.MarkupLine($"Compilation [green]succeed[/] for [blue]{branch}[/] branch."); } }); return(compilation, archive); }
public static void ScaffoldApi(string buildSolutionDirectory, ApiTemplate template, IFileSystem fileSystem) { var projectName = template.ProjectName; AnsiConsole.Status() .AutoRefresh(true) .Spinner(Spinner.Known.Dots2) .Start($"[yellow]Creating {template.ProjectName} [/]", ctx => { FileParsingHelper.RunPrimaryKeyGuard(template.Entities); FileParsingHelper.RunSolutionNameAssignedGuard(projectName); FileParsingHelper.SolutionNameDoesNotEqualEntityGuard(projectName, template.Entities); // add an accelerate.config.yaml file to the root? var bcDirectory = $"{buildSolutionDirectory}{Path.DirectorySeparatorChar}{projectName}"; var srcDirectory = Path.Combine(bcDirectory, "src"); var testDirectory = Path.Combine(bcDirectory, "tests"); fileSystem.Directory.CreateDirectory(srcDirectory); fileSystem.Directory.CreateDirectory(testDirectory); ctx.Spinner(Spinner.Known.BouncingBar); ctx.Status($"[bold blue]Building {projectName} Projects [/]"); SolutionBuilder.AddProjects(buildSolutionDirectory, srcDirectory, testDirectory, template.DbContext.Provider, template.DbContext.DatabaseName, projectName, template.AddJwtAuthentication, fileSystem); // add all files based on the given template config ctx.Status($"[bold blue]Scaffolding Files for {projectName} [/]"); RunTemplateBuilders(bcDirectory, srcDirectory, testDirectory, template, fileSystem); WriteLogMessage($"File scaffolding for {template.ProjectName} was successful"); }); }
public static async Task IndexDataIntoElastic(string type, IHost host, CancellationToken token) { var serviceProvider = host.Services; var indexer = serviceProvider.GetRequiredService <IIndexingService>(); var loggerFactory = serviceProvider.GetRequiredService <ILoggerFactory>(); var logger = loggerFactory.CreateLogger(typeof(Program)); logger.LogInformation($"Indexing {type}"); switch (type) { case "entries": await RenderStatus(async ctx => { await indexer.IndexEntries(token, page => { ctx.Status = $"Page {page} of {type} indexed"; }); }); break; case "leagues": await RenderStatus(async ctx => { await indexer.IndexLeagues(token, page => { ctx.Status = $"Page {page} of {type} indexed"; }); }); break; } async Task RenderStatus(Func <StatusContext, Task> runner) { await AnsiConsole.Status() .AutoRefresh(true) .Spinner(Spinner.Known.Runner) .SpinnerStyle(Style.Parse("green bold")) .StartAsync($"Indexing {type}...", runner); } }
private static async Task <ZipArchive?> GetSnapshotAsync(string branch) { var status = $"Downloading repository snapshot ({branch} branch)..."; ZipArchive?result = null; try { await AnsiConsole .Status() .StartAsync(status, async ctx => { using var client = new WebClient(); client.DownloadProgressChanged += (_, eventArgs) => { ctx.Status($"{status}{eventArgs.BytesReceived / 1024}K"); }; var buffer = await client.DownloadDataTaskAsync(new Uri($"https://github.com/sailro/EscapeFromTarkov-Trainer/archive/refs/heads/{branch}.zip")); var stream = new MemoryStream(buffer); result = new ZipArchive(stream, ZipArchiveMode.Read); }); } catch (Exception ex) { AnsiConsole.MarkupLine(ex is WebException { Response: HttpWebResponse { StatusCode: HttpStatusCode.NotFound } } ? $"[yellow]Branch {branch} not found.[/]" : $"[red]Error: {ex.Message}[/]");
public static void Main() { AnsiConsole.Status() .AutoRefresh(true) .Spinner(Spinner.Known.Default) .Start("[yellow]Initializing warp drive[/]", ctx => { // Initialize Thread.Sleep(3000); WriteLogMessage("Starting gravimetric field displacement manifold"); Thread.Sleep(1000); WriteLogMessage("Warming up deuterium chamber"); Thread.Sleep(2000); WriteLogMessage("Generating antideuterium"); // Warp nacelles Thread.Sleep(3000); ctx.Spinner(Spinner.Known.BouncingBar); ctx.Status("[bold blue]Unfolding warp nacelles[/]"); WriteLogMessage("Unfolding left warp nacelle"); Thread.Sleep(2000); WriteLogMessage("Left warp nacelle [green]online[/]"); WriteLogMessage("Unfolding right warp nacelle"); Thread.Sleep(1000); WriteLogMessage("Right warp nacelle [green]online[/]"); // Warp bubble Thread.Sleep(3000); ctx.Spinner(Spinner.Known.Star2); ctx.Status("[bold blue]Generating warp bubble[/]"); Thread.Sleep(3000); ctx.Spinner(Spinner.Known.Star); ctx.Status("[bold blue]Stabilizing warp bubble[/]"); // Safety ctx.Spinner(Spinner.Known.Monkey); ctx.Status("[bold blue]Performing safety checks[/]"); WriteLogMessage("Enabling interior dampening"); Thread.Sleep(2000); WriteLogMessage("Interior dampening [green]enabled[/]"); // Warp! Thread.Sleep(3000); ctx.Spinner(Spinner.Known.Moon); WriteLogMessage("Preparing for warp"); Thread.Sleep(1000); for (var warp = 1; warp < 10; warp++) { ctx.Status($"[bold blue]Warp {warp}[/]"); Thread.Sleep(500); } }); // Done AnsiConsole.MarkupLine("[bold green]Crusing at Warp 9.8[/]"); }
public async Task StopAsync(CancellationToken cancellationToken) { await AnsiConsole.Status().StartAsync("Disconnecting...", async ctx => { ctx.Spinner(Spinner.Known.Dots); var cancellation = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); using var _ = cancellationToken.Register(() => cancellation.TrySetCanceled(cancellationToken)); await Task.WhenAny(Client.Close(), cancellation.Task); }); }
public override async Task <int> ExecuteAsync(CommandContext context, ShowLogHeaderSettings settings) { if (witsmlClient == null) { return(-1); } var table = CreateTable(); var wellName = "<?>"; var wellboreName = "<?>"; var logName = "<?>"; await AnsiConsole.Status() .Spinner(Spinner.Known.Dots) .StartAsync("Fetching log...".WithColor(Color.Orange1), async _ => { var log = await GetLogHeader(settings.WellUid, settings.WellboreUid, settings.LogUid); wellName = log.NameWell; wellboreName = log.NameWellbore; logName = log.Name; var list = settings.OrderByEndIndex ? log.LogCurveInfo.OrderByDescending(lci => DateTime.Parse(lci.MaxDateTimeIndex)).ToList() : log.LogCurveInfo; foreach (var logCurveInfo in list.Take(settings.MaxMnemonics)) { if (!string.IsNullOrEmpty(settings.FilterOnMnemonic) && logCurveInfo.Mnemonic != settings.FilterOnMnemonic) { continue; } table.AddRow( logCurveInfo.Mnemonic, logCurveInfo.MinDateTimeIndex ?? $"{logCurveInfo.MinIndex.Value}{logCurveInfo.MinIndex.Uom}", logCurveInfo.MaxDateTimeIndex ?? $"{logCurveInfo.MaxIndex.Value}{logCurveInfo.MaxIndex.Uom}" ); } }); AnsiConsole.WriteLine(); AnsiConsole.MarkupLine($"{"Well UID:".Bold()} {settings.WellUid}"); AnsiConsole.MarkupLine($"{"Wellbore UID:".Bold()} {settings.WellboreUid}"); AnsiConsole.MarkupLine($"{"Log UID".Bold()} {settings.LogUid}"); AnsiConsole.MarkupLine($"{"Well name:".Bold()} {wellName}"); AnsiConsole.MarkupLine($"{"Wellbore name:".Bold()} {wellboreName}"); AnsiConsole.MarkupLine($"{"Log name:".Bold()} {logName}"); AnsiConsole.Write(table); return(0); }
public ProjectionStatus(string name, Task completion) { _name = name; AnsiConsole .Status() .AutoRefresh(true) .StartAsync("Waiting...", context => { context.Spinner(Spinner.Known.Clock); context.SpinnerStyle(Style.Parse("grey italic")); context.Refresh(); _context = context; return(completion); }); }
private static async Task HandleGenerate(Uri endpoint, string output, string @namespace, string context, IConsole console) { //var webClient = new WebClient(); //webClient.Headers.Add("Content-Type", "application/json"); //var downloadString = webClient.UploadString("endpoint", query); AnsiConsole.MarkupLine("[bold]Welcome to GraphQL Client Scaffolding tool[/]"); AnsiConsole.WriteLine(); string outputFolder = Path.IsPathRooted(output) ? output : Path.Combine(Environment.CurrentDirectory, output); AnsiConsole.MarkupLine("Scaffolding GraphQL client code for [bold]{0}[/] to [bold]{1}[/]", endpoint, outputFolder); var schema = await AnsiConsole.Status().StartAsync("Performing introspection", async ctx => { AnsiConsole.WriteLine("Running introspection query ..."); using var httpClient = new HttpClient(); using var responseMessage = await httpClient.PostAsJsonAsync(endpoint, new { query = IntrospectionQuery }); AnsiConsole.WriteLine("Reading and deserializing schema information ..."); var schemaJson = await responseMessage.Content.ReadAsStringAsync(); return(JsonSerializer.Deserialize <RootSchemaObject>(schemaJson, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })); }); AnsiConsole.WriteLine(); var contextClassFullName = AnsiConsole.Status().Start($"Scaffolding GraphQL client code {endpoint}", statusContext => { var codeGenerationOptions = new CodeGenerationOptions { Namespace = @namespace, NormalizeCasing = true, OutputDirectory = outputFolder, ContextName = context }; var graphQLClassesGenerator = new GraphQLClassesGenerator(codeGenerationOptions); return(graphQLClassesGenerator.GenerateClient(schema.Data.Schema, endpoint.AbsoluteUri)); }); AnsiConsole.WriteLine(); AnsiConsole.MarkupLine("[bold]Scaffolding complete[/]"); AnsiConsole.MarkupLine("Use [bold]{0}[/] to run strongly typed LINQ queries", contextClassFullName); Console.ReadKey(); }
public override int Execute([NotNull] CommandContext context, [NotNull] AvdStartCommandSettings settings) { var ok = true; try { var emu = new Emulator(settings?.Home); Emulator.AndroidEmulatorProcess process = null; AnsiConsole.Status() .Start($"Starting {settings.Name}...", ctx => { process = emu.Start(settings.Name, new Emulator.EmulatorStartOptions { WipeData = settings.WipeData, NoSnapshot = settings.NoSnapshot }); var timeout = settings.Timeout.HasValue ? TimeSpan.FromSeconds(settings.Timeout.Value) : TimeSpan.Zero; if (settings.WaitForBoot) { ctx.Status($"Waiting for {settings.Name} to finish booting..."); ok = process.WaitForBootComplete(timeout); } if (settings.WaitForExit) { ctx.Status($"Booted, waiting for {settings.Name} to exit..."); ok = process.WaitForExit() == 0; } }); if (!ok) { AnsiConsole.WriteException(new Exception("Failed to start AVD: " + string.Join(Environment.NewLine, process.GetStandardOutput()))); } } catch (SdkToolFailedExitException sdkEx) { Program.WriteException(sdkEx); return(1); } return(ok ? 0 : 1); }
/// <summary> /// Парсинг чейнджлогов в директории. Игнорируются файлы начинающиеся с точки. /// </summary> /// <param name="folderPath">Путь до директории.</param> /// <returns></returns> public static IDictionary <string, Changelog> ParseChangelogs(this string folderPath) { IDictionary <string, Changelog>?changelogs = null; AnsiConsole.Status() .Start($"{ChangelogGeneratorResources.SEARCHING_CHANGELOGS_IN} {folderPath}", ctx => { ctx.Spinner(Spinner.Known.Line); IEnumerable <string> files = from f in Directory.GetFiles(folderPath) where Path.GetFileName(f)[0] != '.' select f; changelogs = ParseChangelogsInternal(files, ctx); }); return(changelogs !); }
public Task StartAsync(CancellationToken cancellationToken) => AnsiConsole.Status().StartAsync("Connecting to server", async ctx => { ctx.Spinner(Spinner.Known.Dots); ctx.Status = "Connecting..."; await Client.Connect(async error => { AnsiConsole.MarkupLine("[bold red]Error:[/] error connecting to server!"); AnsiConsole.WriteException(error); ctx.Status = "Waiting to retry..."; await Task.Delay(TimeSpan.FromSeconds(2)); ctx.Status = "Retrying connection..."; return(true); }); ctx.Status = "Connected!"; });
private static async Task <(CSharpCompilation?, ZipArchive?, Diagnostic[])> GetCompilationAsync(int @try, Installation installation, string branch, params string[] exclude) { var errors = Array.Empty <Diagnostic>(); var archive = await GetSnapshotAsync(@try, branch); if (archive == null) { return(null, null, errors); } CSharpCompilation?compilation = null; AnsiConsole .Status() .Start("Compiling trainer", _ => { var compiler = new Compiler(archive, installation, exclude); compilation = compiler.Compile(); errors = compilation .GetDiagnostics() .Where(d => d.Severity == DiagnosticSeverity.Error) .ToArray(); #if DEBUG foreach (var error in errors) { AnsiConsole.MarkupLine($">> {error.Id} [[{error.Location.SourceTree?.FilePath}]]: {error.GetMessage()}"); } #endif if (errors.Any()) { AnsiConsole.MarkupLine($">> [blue]Try #{@try}[/] [yellow]Compilation failed for {branch.EscapeMarkup()} branch.[/]"); compilation = null; } else { AnsiConsole.MarkupLine($">> [blue]Try #{@try}[/] Compilation [green]succeed[/] for [blue]{branch.EscapeMarkup()}[/] branch."); } }); return(compilation, archive, errors); }
public static Installation?GetTargetInstallation(string?path, string promptTitle) { var installations = new List <Installation>(); AnsiConsole .Status() .Start("Discovering [green]Escape From Tarkov[/] installations...", _ => { installations = Installation .DiscoverInstallations() .Distinct() .ToList(); }); if (path is not null && Installation.TryDiscoverInstallation(path, out var installation)) { installations.Add(installation); } installations = installations .Distinct() .OrderBy(i => i.Location) .ToList(); switch (installations.Count) { case 0: AnsiConsole.MarkupLine("[yellow]No [green]EscapeFromTarkov[/] installation found, please re-run this installer, passing the installation path as argument.[/]"); return(null); case 1: var first = installations.First(); return(AnsiConsole.Confirm($"Continue with [green]EscapeFromTarkov ({first.Version})[/] in [blue]{first.Location}[/] ?") ? first : null); default: var prompt = new SelectionPrompt <Installation> { Converter = i => i.Location, Title = promptTitle }; prompt.AddChoices(installations); return(AnsiConsole.Prompt(prompt)); } }
public void Do(int currentRotation, string mediaFile) { var outputPath = GetOutputPath(mediaFile); if (!File.Exists(mediaFile)) { Console.WriteLine("Input file does not exist"); return; } if (!Directory.Exists(outputPath)) { Console.WriteLine($"Output path {outputPath} does not exist"); return; } string outputFile = Path.Combine(outputPath, Path.GetFileName(mediaFile)); var letterBox = $"-vf \"scale=(iw*sar)*min(1280/(iw*sar)\\,720/ih):ih*min(1280/(iw*sar)\\,720/ih), pad=1280:720:(1280-iw*min(1280/iw\\,720/ih))/2:(720-ih*min(1280/iw\\,720/ih))/2\""; string arguments = $"-i {mediaFile} {letterBox} \"{outputFile}\""; var status = AnsiConsole .Status() .Spinner(Spinner.Known.Clock) .AutoRefresh(true); status.Start("[green]Processing media file...[/]", ctx => { using (var process = new Process()) { process.StartInfo.FileName = _config.GetSection("ffmpeg").Value; process.StartInfo.Arguments = arguments; process.StartInfo.CreateNoWindow = true; process.StartInfo.UseShellExecute = false; process.Start(); process.WaitForExit(); } ctx.Status($"File exported to {outputPath}"); }); }
private static Installation?GetTargetInstallation(Settings settings) { var installations = new List <Installation>(); AnsiConsole .Status() .Start("Discovering [green]Escape From Tarkov[/] installations...", _ => { installations = Installation .DiscoverInstallations() .Distinct() .ToList(); }); if (settings.Path is not null && Installation.TryDiscoverInstallation(settings.Path, out var installation)) { installations.Add(installation); } installations = installations .Distinct() .OrderBy(i => i.Location) .ToList(); switch (installations.Count) { case 0: AnsiConsole.MarkupLine("[yellow]No [green]EscapeFromTarkov[/] installation found, please re-run this installer, passing the installation path as argument.[/]"); return(null); case 1: return(installations.First()); default: var prompt = new SelectionPrompt <Installation> { Converter = i => i.Location, Title = "Please select where to install the trainer" }; prompt.AddChoices(installations); return(AnsiConsole.Prompt(prompt)); } }
public static void RunDbMigrations(List <ApiTemplate> boundedContexts, string domainDirectory) { AnsiConsole.Status() .AutoRefresh(true) .Spinner(Spinner.Known.Dots2) .Start($"[yellow]Running Migrations [/]", ctx => { foreach (var bc in boundedContexts) { var bcDirectory = $"{domainDirectory}{Path.DirectorySeparatorChar}{bc.ProjectName}"; var srcDirectory = Path.Combine(bcDirectory, "src"); ctx.Spinner(Spinner.Known.Dots2); ctx.Status($"[bold blue]Running {bc.ProjectName} Database Migrations [/]"); if (Utilities.RunDbMigration(bc, srcDirectory)) { WriteLogMessage($"Database Migrations for {bc.ProjectName} were successful"); } } }); }
public override async Task <int> ExecuteAsync(CommandContext context, GetQuerySettings settings) { if (witsmlClient == null) { return(-1); } await AnsiConsole.Status() .Spinner(Spinner.Known.Dots) .StartAsync("Executing query...".WithColor(Color.Orange1), async _ => { var results = await ExecuteQuery(settings.QueryFile, settings.ReturnElements, settings.MaxReturnNodes); await using var memoryStream = new MemoryStream(); await using var writer = new XmlTextWriter(memoryStream, Encoding.Unicode) { Formatting = Formatting.Indented }; var document = new XmlDocument(); document.LoadXml(results); document.WriteContentTo(writer); writer.Flush(); memoryStream.Flush(); memoryStream.Position = 0; var streamReader = new StreamReader(memoryStream); while (true) { var line = await streamReader.ReadLineAsync(); if (string.IsNullOrEmpty(line)) { break; } AnsiConsole.WriteLine(line); } }); return(0); }
public override async Task <int> ExecuteAsync(CommandContext context, ListRisksSettings settings) { if (witsmlClient == null) { return(-1); } var table = CreateTable(); IList <WitsmlRisk> risks = new List <WitsmlRisk>(); await AnsiConsole.Status() .Spinner(Spinner.Known.Dots) .StartAsync("Fetching risks...".WithColor(Color.Orange1), async _ => { risks = await GetRisks(settings.WellUid, settings.WellboreUid, settings.Source, settings.LastChanged); if (risks.Count > 100) { AnsiConsole.MarkupLine($"\nToo many risks returned ({risks.Count}). Please filter your query".WithColor(Color.Red1)); } foreach (var risk in risks) { table.AddRow( risk.Uid, risk.UidWell, risk.UidWellbore, risk.NameWellbore, risk.Summary, risk.CommonData.SourceName ?? "", risk.CommonData.DTimLastChange); } }); if (risks.Any()) { AnsiConsole.Write(table); } return(0); }
public override async Task <int> ExecuteAsync(CommandContext context, ShowTubularSettings settings) { if (witsmlClient == null) { return(-1); } await AnsiConsole.Status() .Spinner(Spinner.Known.Dots) .StartAsync("Fetching tubular...".WithColor(Color.Orange1), async _ => { var tubular = await GetTubular(settings.WellUid, settings.WellboreUid, settings.TubularUid); var jsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true }; AnsiConsole.WriteLine(JsonSerializer.Serialize(tubular, jsonSerializerOptions)); }); return(0); }
public override async Task <int> ExecuteAsync(CommandContext context, ListBhaRunsSettings settings) { if (witsmlClient == null) { return(-1); } var table = CreateTable(); var wellName = "<?>"; var wellboreName = "<?>"; await AnsiConsole.Status() .Spinner(Spinner.Known.Dots) .StartAsync("Fetching bha runs...".WithColor(Color.Orange1), async _ => { var bhaRuns = (await GetBhaRuns(settings.WellUid, settings.WellboreUid)).ToList(); wellName = bhaRuns.FirstOrDefault()?.NameWell; wellboreName = bhaRuns.FirstOrDefault()?.NameWellbore; foreach (var bhaRun in bhaRuns.OrderBy(r => r.CommonData.DTimLastChange)) { table.AddRow( bhaRun.Uid, bhaRun.Name, bhaRun.Tubular.UidRef, bhaRun.CommonData.DTimLastChange); } }); AnsiConsole.WriteLine(); AnsiConsole.MarkupLine($"{"Well UID:".Bold()} {settings.WellUid}"); AnsiConsole.MarkupLine($"{"Wellbore UID:".Bold()} {settings.WellboreUid}"); AnsiConsole.MarkupLine($"{"Well name:".Bold()} {wellName}"); AnsiConsole.MarkupLine($"{"Wellbore name:".Bold()} {wellboreName}"); AnsiConsole.Write(table); return(0); }
private async Task <Stream> FetchSourcePackage(Settings settings) { var input = string.IsNullOrEmpty(settings.Input) ? _environment.WorkingDirectory : new DirectoryPath(settings.Input); var file = _fileSystem.File.Retrieve(input.CombineWithFilePath(NCursesFilename)); if (!file.Exists) { await AnsiConsole.Status() .StartAsync($"Downloading [yellow]{NCursesUrl}[/]...", async ctx => { using var http = new HttpClient(); using var httpStream = await http.GetStreamAsync(NCursesUrl); using var outStream = file.OpenWrite(); await httpStream.CopyToAsync(outStream); }); } return(file.OpenRead()); }
public override async Task <int> ExecuteAsync(CommandContext context) { if (witsmlClient == null) { return(-1); } var table = CreateTable(); await AnsiConsole.Status() .Spinner(Spinner.Known.Dots) .StartAsync("Fetching active wellbores...".WithColor(Color.Orange1), async _ => { await foreach (var wellbore in GetActiveWellbores()) { table.AddRow(wellbore.UidWell, wellbore.Uid, wellbore.NameWell, wellbore.Name); } }); AnsiConsole.WriteLine(); AnsiConsole.Write(table); return(0); }
private void InitCvrSystemWrapper() { try { AnsiConsole.Status().Start(_appSettings.LanguageDataSet.GetValue(nameof(LanguageDataSet.OpenVRInitializing)), action => { _cvrSystemWrapper = new CvrSystemWrapper(); var vrOverlayError = OpenVR.Overlay.CreateOverlay(Guid.NewGuid().ToString(), _appSettings.ApplicationID, ref _overlayWindowHandle); if (vrOverlayError != EVROverlayError.None) { throw new Exception($"{nameof(EVROverlayError)} {vrOverlayError}"); } }); } catch (Exception) { AnsiConsole.WriteLine(_appSettings.LanguageDataSet.GetValue(nameof(LanguageDataSet.OpenVRInitError))); throw; } _cvrSystemWrapper.CvrEvent += CvrSystemWrapper_CVREvent; _cvrSystemWrapper.BeginEventLoop(); }
public async Task <bool> Execute(FileInfo file, List <string> additionalArgs, CancellationToken token) { _log.LogDebug("Starting"); var success = true; await AnsiConsole.Status() .StartAsync("Compiling...", async ctx => { try { var csprojDirectory = GetCsprojDirectory(file); var fileToRun = Path.GetRelativePath(csprojDirectory.FullName, file.FullName); var response = await RunDotnetProcess(file, token, new List <string>() { "build", $"/p:ActiveDebugProfile={fileToRun}" }, false); if (response != 0) { _log.LogError("Could not compile your project. Terminating."); success = false; return; } success = await RunTestProject(file, additionalArgs, token, ctx); } catch (TaskCanceledException h) { _log.LogDebug(h, "Task canceled during run"); } catch (Exception e) { _log.LogError(e, "Error during run"); success = false; } }); return(success); }
public override async Task <int> ExecuteAsync(CommandContext context, CheckSettings settings) { Util.Verbose = settings.Verbose; Util.CI = settings.CI; if (settings.CI) { settings.NonInteractive = true; } Console.Title = ToolInfo.ToolName; AnsiConsole.Render( new FigletText(".NET MAUI").LeftAligned().Color(Color.Green)); AnsiConsole.MarkupLine($"[underline bold green]{Icon.Ambulance} {ToolInfo.ToolName} {Icon.Recommend}[/]"); AnsiConsole.Render(new Rule()); AnsiConsole.MarkupLine("This tool will attempt to evaluate your .NET MAUI development environment."); AnsiConsole.MarkupLine("If problems are detected, this tool may offer the option to try and fix them for you, or suggest a way to fix them yourself."); AnsiConsole.WriteLine(); AnsiConsole.MarkupLine("Thanks for choosing .NET MAUI!"); AnsiConsole.Render(new Rule()); if (!Util.IsAdmin() && Util.IsWindows) { var suTxt = Util.IsWindows ? "Administrator" : "Superuser (su)"; AnsiConsole.MarkupLine($"[bold red]{Icon.Bell} {suTxt} is required to fix most issues. Consider exiting and running the tool with {suTxt} permissions.[/]"); AnsiConsole.Render(new Rule()); if (!settings.NonInteractive) { if (!AnsiConsole.Confirm("Would you still like to continue?", false)) { return(1); } } } var cts = new System.Threading.CancellationTokenSource(); var checkupStatus = new Dictionary <string, Models.Status>(); var sharedState = new SharedState(); var results = new Dictionary <string, DiagnosticResult>(); var consoleStatus = AnsiConsole.Status(); var skippedChecks = new List <string>(); AnsiConsole.Markup($"[bold blue]{Icon.Thinking} Synchronizing configuration...[/]"); var manifest = await ToolInfo.LoadManifest(settings.Manifest, settings.Dev); if (!ToolInfo.Validate(manifest)) { ToolInfo.ExitPrompt(settings.NonInteractive); return(-1); } AnsiConsole.MarkupLine(" ok"); AnsiConsole.Markup($"[bold blue]{Icon.Thinking} Scheduling appointments...[/]"); if (!string.IsNullOrEmpty(settings.DotNetSdkRoot)) { sharedState.SetEnvironmentVariable("DOTNET_ROOT", settings.DotNetSdkRoot); } var checkups = CheckupManager.BuildCheckupGraph(manifest, sharedState); AnsiConsole.MarkupLine(" ok"); var checkupId = string.Empty; for (int i = 0; i < checkups.Count(); i++) { var checkup = checkups.ElementAt(i); // Set the manifest checkup.Manifest = manifest; // If the ID is the same, it's a retry var isRetry = checkupId == checkup.Id; // Track the last used id so we can detect retry checkupId = checkup.Id; if (!checkup.ShouldExamine(sharedState)) { checkupStatus[checkup.Id] = Models.Status.Ok; continue; } var skipCheckup = false; var dependencies = checkup.DeclareDependencies(checkups.Select(c => c.Id)); // Make sure our dependencies succeeded first if (dependencies?.Any() ?? false) { foreach (var dep in dependencies) { var depCheckup = checkups.FirstOrDefault(c => c.Id.StartsWith(dep.CheckupId, StringComparison.OrdinalIgnoreCase)); if (depCheckup != null && depCheckup.IsPlatformSupported(Util.Platform)) { if (!checkupStatus.TryGetValue(dep.CheckupId, out var depStatus) || depStatus == Models.Status.Error) { skipCheckup = dep.IsRequired; break; } } } } // See if --skip was specified if (settings.Skip?.Any(s => s.Equals(checkup.Id, StringComparison.OrdinalIgnoreCase) || s.Equals(checkup.GetType().Name, StringComparison.OrdinalIgnoreCase)) ?? false) { skipCheckup = true; } if (skipCheckup) { skippedChecks.Add(checkup.Id); checkupStatus[checkup.Id] = Models.Status.Error; AnsiConsole.WriteLine(); AnsiConsole.MarkupLine($"[bold red]{Icon.Error} Skipped: " + checkup.Title + "[/]"); continue; } checkup.OnStatusUpdated += checkupStatusUpdated; AnsiConsole.WriteLine(); AnsiConsole.MarkupLine($"[bold]{Icon.Checking} " + checkup.Title + " Checkup[/]..."); Console.Title = checkup.Title; DiagnosticResult diagnosis = null; try { diagnosis = await checkup.Examine(sharedState); } catch (Exception ex) { Util.Exception(ex); diagnosis = new DiagnosticResult(Models.Status.Error, checkup, ex.Message); } results[checkup.Id] = diagnosis; // Cache the status for dependencies checkupStatus[checkup.Id] = diagnosis.Status; if (diagnosis.Status == Models.Status.Ok) { continue; } var statusEmoji = diagnosis.Status == Models.Status.Error ? Icon.Error : Icon.Warning; var statusColor = diagnosis.Status == Models.Status.Error ? "red" : "darkorange3_1"; var msg = !string.IsNullOrEmpty(diagnosis.Message) ? " - " + diagnosis.Message : string.Empty; if (diagnosis.HasSuggestion) { Console.WriteLine(); AnsiConsole.Render(new Rule()); AnsiConsole.MarkupLine($"[bold blue]{Icon.Recommend} Recommendation:[/][blue] {diagnosis.Suggestion.Name}[/]"); if (!string.IsNullOrEmpty(diagnosis.Suggestion.Description)) { AnsiConsole.MarkupLine("" + diagnosis.Suggestion.Description + ""); } AnsiConsole.Render(new Rule()); Console.WriteLine(); // See if we should fix // needs to have a remedy available to even bother asking/trying var doFix = diagnosis.Suggestion.HasSolution && ( // --fix + --non-interactive == auto fix, no prompt (settings.NonInteractive && settings.Fix) // interactive (default) + prompt/confirm they want to fix || (!settings.NonInteractive && AnsiConsole.Confirm($"[bold]{Icon.Bell} Attempt to fix?[/]")) ); if (doFix && !isRetry) { var isAdmin = Util.IsAdmin(); var adminMsg = Util.IsWindows ? $"{Icon.Bell} [red]Administrator Permissions Required. Try opening a new console as Administrator and running this tool again.[/]" : $"{Icon.Bell} [red]Super User Permissions Required. Try running this tool again with 'sudo'.[/]"; var didFix = false; foreach (var remedy in diagnosis.Suggestion.Solutions) { try { remedy.OnStatusUpdated += remedyStatusUpdated; AnsiConsole.MarkupLine($"{Icon.Thinking} Attempting to fix: " + checkup.Title); await remedy.Implement(sharedState, cts.Token); didFix = true; AnsiConsole.MarkupLine($"[bold]Fix applied. Checking again...[/]"); } catch (Exception x) when(x is AccessViolationException || x is UnauthorizedAccessException) { Util.Exception(x); AnsiConsole.Markup(adminMsg); } catch (Exception ex) { Util.Exception(ex); AnsiConsole.MarkupLine("[bold red]Fix failed - " + ex.Message + "[/]"); } finally { remedy.OnStatusUpdated -= remedyStatusUpdated; } } // RETRY The check again if (didFix) { i--; } } } checkup.OnStatusUpdated -= checkupStatusUpdated; } AnsiConsole.Render(new Rule()); AnsiConsole.WriteLine(); var erroredChecks = results.Values.Where(d => d.Status == Models.Status.Error && !skippedChecks.Contains(d.Checkup.Id)); foreach (var ec in erroredChecks) { Util.Log($"Checkup had Error status: {ec.Checkup.Id}"); } var hasErrors = erroredChecks.Any(); if (hasErrors) { AnsiConsole.MarkupLine($"[bold red]{Icon.Bell} There were one or more problems detected.[/]"); AnsiConsole.MarkupLine($"[bold red]Please review the errors and correct them and run {ToolInfo.ToolCommand} again.[/]"); } else { AnsiConsole.MarkupLine($"[bold blue]{Icon.Success} Congratulations, everything looks great![/]"); } Console.Title = ToolInfo.ToolName; ToolInfo.ExitPrompt(settings.NonInteractive); Util.Log($"Has Errors? {hasErrors}"); var exitCode = hasErrors ? 1 : 0; Environment.ExitCode = exitCode; return(exitCode); }
public static async Task <PingSession> StartAsync(PingRequestOptions options) { var pingRequestAgent = new PingRequestAgent(); var cancellationTokenSource = new CancellationTokenSource(); Console.CancelKeyPress += (sender, e) => { e.Cancel = true; cancellationTokenSource.Cancel(); }; PingSession results = null; if (options.NumberOfPings != -1) { await AnsiConsole.Progress() .Columns(new ProgressColumn[] { new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn(), new RemainingTimeColumn() }) .StartAsync(async ctx => { var requestsRemaining = ctx.AddTask($"Sending {options.NumberOfPings} pings to [yellow]{options.Address}[/]", new ProgressTaskSettings { MaxValue = options.NumberOfPings }); pingRequestAgent.PingCompleted += (sender, e) => { requestsRemaining.Increment(1); }; results = await pingRequestAgent.StartAsync(options, cancellationTokenSource.Token); }); } else { await AnsiConsole.Status() .Spinner(Spinner.Known.Dots8Bit) .StartAsync($"Pinging {options.Address}...", async ctx => { pingRequestAgent.PingCompleted += (sender, e) => { if (e.CompletedPing.Status != IPStatus.Success) { AnsiConsole.MarkupLine("[grey54]{0:yyyy-MM-ddTHH:mm:ss}: {1}[/]", e.CompletedPing.RequestTime, e.CompletedPing.Status); } var packetsLostColour = "grey54"; if (e.Session.PacketsLostPercentage > 5) { packetsLostColour = "red"; } else if (Math.Round(e.Session.PacketsLostPercentage, 2) > 0) { packetsLostColour = "maroon"; } ctx.Status($"Continuously pinging [yellow]{options.Address}[/] [grey54]({e.Session.PacketsSent} sent, [{packetsLostColour}]{e.Session.PacketsLostPercentage:0.00}% lost[/], {e.Session.AverageRoundtrip}ms average, {(int)e.Session.Elapsed.TotalMinutes}:{e.Session.Elapsed.Seconds:00} elapsed)[/]"); }; results = await pingRequestAgent.StartAsync(options, cancellationTokenSource.Token); }); } if (results != null && results.PacketsSent > 0) { AnsiConsole.WriteLine(); AnsiConsole.Render(new Rule($"[white]Ping results for [yellow]{options.Address}[/][/]").RuleStyle("grey54")); AnsiConsole.WriteLine(); var table = new Table() .Centered() .AddColumns( new TableColumn("Packets (Sent/Received/Lost)").Centered(), new TableColumn("Minimum Roundtrip").Centered(), new TableColumn("Maximum Roundtrip").Centered(), new TableColumn("Average Roundtrip").Centered(), new TableColumn("Elapsed Time").Centered() ) .SimpleBorder(); table.AddRow( $"{results.PacketsSent} / {results.PacketsReceived} / {results.PacketsLost}", results.MinimumRoundtrip.ToString("0ms"), results.MaximumRoundtrip.ToString("0ms"), results.AverageRoundtrip.ToString("0ms"), $"{(int)results.Elapsed.TotalMinutes}:{results.Elapsed.Seconds:00}" ); AnsiConsole.Render(table); } else { AnsiConsole.WriteLine("No results available."); } AnsiConsole.WriteLine(); return(results); }
static async Task Main(string[] args) { string name, surname; int birthday; List <Person> personsList = new List <Person> (); do { Console.WriteLine("1- Para agregar persona\n2- Para mostrar información"); var option = int.Parse(Console.ReadLine()); switch (option) { case 1: name = AnsiConsole.Ask <string> ("Cual es tu [blue]nombre[/]?"); surname = AnsiConsole.Ask <string> ("Cual es tu [blue]apellido[/]?"); birthday = AnsiConsole.Ask <int> ("Cual es tu [green]año de nacimiento[/]?"); Person persona = new Person(name, surname, birthday); personsList.Add(persona); AnsiConsole.Status() .Start("Guardando...", ctx => { Thread.Sleep(1000); // Update the status and spinner ctx.Status("Finalizado"); ctx.Spinner(Spinner.Known.Star); ctx.SpinnerStyle(Style.Parse("green")); Thread.Sleep(1000); }); Console.Clear(); break; case 2: var saveTable = AnsiConsole.Confirm("Guardar tabla?"); AnsiConsole.Record(); Table table = new Table(); table.AddColumn("Nombre"); table.AddColumn("Apellido"); table.AddColumn("Edad"); table.AddColumn("Pais"); table.AddColumn("Ciudad"); table.AddColumn("Idioma"); table.AddColumn("Cordenadas"); foreach (var item in personsList) { table.AddRow(item.Name, item.Surname, item.Birthday.ToString(), item.Country, item.City, item.Language, item.Cordinates); } var title = new TableTitle("Empleado", Style.WithDecoration(Decoration.Bold)); table.Title = title; table.Border(TableBorder.Rounded); table.BorderColor <Table> (Color.Blue); AnsiConsole.Render(table); if (saveTable) { string html = AnsiConsole.ExportHtml(); Directory.CreateDirectory("../Employes"); File.WriteAllText("../Employes/index.html", html); Console.ForegroundColor = Color.Green; Console.WriteLine("Guardado Exitosamente"); Console.ForegroundColor = Color.White; } break; default: break; } } while (true); }
public override async Task <int> ExecuteAsync(CommandContext context, DoctorSettings settings) { Console.Title = ToolName; AnsiConsole.MarkupLine($"[underline bold green]{Icon.Ambulance} {ToolName} {Icon.Recommend}[/]"); AnsiConsole.Render(new Rule()); AnsiConsole.MarkupLine("This tool will attempt to evaluate your .NET MAUI development environment."); AnsiConsole.MarkupLine("If problems are detected, this tool may offer the option to try and fix them for you, or suggest a way to fix them yourself."); AnsiConsole.WriteLine(); AnsiConsole.MarkupLine("Thanks for choosing .NET MAUI!"); AnsiConsole.WriteLine(); if (!settings.NonInteractive) { AnsiConsole.Markup("Press any key to start..."); Console.ReadKey(); AnsiConsole.WriteLine(); } AnsiConsole.Render(new Rule()); var clinic = new Clinic(); var cts = new System.Threading.CancellationTokenSource(); var checkupStatus = new Dictionary <string, Doctoring.Status>(); var patientHistory = new PatientHistory(); var diagnoses = new List <Diagonosis>(); var consoleStatus = AnsiConsole.Status(); AnsiConsole.Markup($"[bold blue]{Icon.Thinking} Synchronizing configuration...[/]"); var chart = await Manifest.Chart.FromFileOrUrl(settings.Manifest); var toolVersion = chart?.Doctor?.ToolVersion; var fileVersion = NuGetVersion.Parse(FileVersionInfo.GetVersionInfo(this.GetType().Assembly.Location).FileVersion); if (string.IsNullOrEmpty(toolVersion) || !NuGetVersion.TryParse(toolVersion, out var toolVer) || fileVersion < toolVer) { Console.WriteLine(); AnsiConsole.MarkupLine($"[bold red]{Icon.Error} Updating to version {toolVersion} or newer is required:[/]"); AnsiConsole.MarkupLine($"[red]Update with the following:[/]"); var installCmdVer = string.IsNullOrEmpty(toolVersion) ? "" : $" --version {toolVersion}"; AnsiConsole.Markup($" dotnet tool install --global {ToolPackageId}{installCmdVer}"); return(-1); } AnsiConsole.MarkupLine(" ok"); AnsiConsole.Markup($"[bold blue]{Icon.Thinking} Scheduling appointments...[/]"); if (chart.Doctor.OpenJdk != null) { clinic.OfferService(new OpenJdkCheckup(chart.Doctor.OpenJdk.MinimumVersion, chart.Doctor.OpenJdk.ExactVersion)); } if (chart.Doctor.Android != null) { clinic.OfferService(new AndroidSdkManagerCheckup()); clinic.OfferService(new AndroidSdkPackagesCheckup(chart.Doctor.Android.Packages.ToArray())); clinic.OfferService(new AndroidSdkLicensesCheckup()); } if (chart.Doctor.XCode != null) { clinic.OfferService(new XCodeCheckup(chart.Doctor.XCode.MinimumVersion, chart.Doctor.XCode.ExactVersion)); } if (chart.Doctor.VSMac != null && !string.IsNullOrEmpty(chart.Doctor.VSMac.MinimumVersion)) { clinic.OfferService(new VisualStudioMacCheckup(chart.Doctor.VSMac.MinimumVersion, chart.Doctor.VSMac.ExactVersion)); } if (chart.Doctor.VSWin != null && !string.IsNullOrEmpty(chart.Doctor.VSWin.MinimumVersion)) { clinic.OfferService(new VisualStudioWindowsCheckup(chart.Doctor.VSWin.MinimumVersion, chart.Doctor.VSWin.ExactVersion)); } if (chart.Doctor.DotNet?.Sdks?.Any() ?? false) { clinic.OfferService(new DotNetCheckup(chart.Doctor.DotNet.Sdks.ToArray())); foreach (var sdk in chart.Doctor.DotNet.Sdks) { clinic.OfferService(new DotNetWorkloadsCheckup(sdk.Version, sdk.Workloads.ToArray(), sdk.PackageSources.ToArray())); // Always run the packs checkup even if manifest is empty, since the workloads may resolve some required packs dynamically that aren't from the manifest clinic.OfferService(new DotNetPacksCheckup(sdk.Version, sdk.Packs?.ToArray() ?? Array.Empty <Manifest.NuGetPackage>(), sdk.PackageSources.ToArray())); } } var checkups = clinic.ScheduleCheckups(); AnsiConsole.MarkupLine(" ok"); foreach (var checkup in checkups) { var skipCheckup = false; // Make sure our dependencies succeeded first if (checkup.Dependencies?.Any() ?? false) { foreach (var dep in checkup.Dependencies) { if (!checkupStatus.TryGetValue(dep.CheckupId, out var depStatus) || depStatus != Doctoring.Status.Ok) { skipCheckup = dep.IsRequired; break; } } } if (skipCheckup) { checkupStatus.Add(checkup.Id, Doctoring.Status.Error); AnsiConsole.WriteLine(); AnsiConsole.MarkupLine($"[bold red]{Icon.Error} Skipped: " + checkup.Title + "[/]"); continue; } checkup.OnStatusUpdated += (s, e) => { var msg = ""; if (e.Status == Doctoring.Status.Error) { msg = $"[red]{Icon.Error} {e.Message}[/]"; } else if (e.Status == Doctoring.Status.Warning) { msg = $"[red]{Icon.Error} {e.Message}[/]"; } else if (e.Status == Doctoring.Status.Ok) { msg = $"[green]{Icon.Success} {e.Message}[/]"; } else { msg = $"{Icon.ListItem} {e.Message}"; } AnsiConsole.MarkupLine(" " + msg); }; AnsiConsole.WriteLine(); AnsiConsole.MarkupLine($"[bold]{Icon.Checking} " + checkup.Title + " Checkup[/]..."); Console.Title = checkup.Title; Diagonosis diagnosis = null; try { diagnosis = await checkup.Examine(patientHistory); } catch (Exception ex) { diagnosis = new Diagonosis(Doctoring.Status.Error, checkup, ex.Message); } diagnoses.Add(diagnosis); // Cache the status for dependencies checkupStatus.Add(checkup.Id, diagnosis.Status); if (diagnosis.Status == Doctoring.Status.Ok) { continue; } var statusEmoji = diagnosis.Status == Doctoring.Status.Error ? Icon.Error : Icon.Warning; var statusColor = diagnosis.Status == Doctoring.Status.Error ? "red" : "orange3"; var msg = !string.IsNullOrEmpty(diagnosis.Message) ? " - " + diagnosis.Message : string.Empty; //AnsiConsole.MarkupLine($"[{statusColor}]{statusEmoji} {checkup.Title}{msg}[/]"); if (diagnosis.HasPrescription) { AnsiConsole.MarkupLine($" [bold blue]{Icon.Recommend} Recommendation:[/] {diagnosis.Prescription.Name}"); if (!string.IsNullOrEmpty(diagnosis.Prescription.Description)) { AnsiConsole.MarkupLine(" " + diagnosis.Prescription.Description); } // See if we should fix // needs to have a remedy available to even bother asking/trying var doFix = diagnosis.Prescription.HasRemedy && ( // --fix + --non-interactive == auto fix, no prompt (settings.NonInteractive && settings.Fix) // interactive (default) + prompt/confirm they want to fix || (!settings.NonInteractive && AnsiConsole.Confirm($" [bold]{Icon.Bell} Attempt to fix?[/]")) ); if (doFix) { var isAdmin = Util.IsAdmin(); foreach (var remedy in diagnosis.Prescription.Remedies) { if (!remedy.HasPrivilegesToRun(isAdmin, Util.Platform)) { AnsiConsole.Markup("Fix requires running with adminstrator privileges. Try opening a terminal as administrator and running maui-doctor again."); continue; } try { remedy.OnStatusUpdated += (s, e) => { AnsiConsole.MarkupLine(" " + e.Message); }; AnsiConsole.MarkupLine($"{Icon.Thinking} Attempting to fix: " + checkup.Title); await remedy.Cure(cts.Token); AnsiConsole.MarkupLine(" Fix applied. Run doctor again to verify."); } catch (Exception ex) { AnsiConsole.MarkupLine(" Fix failed - " + ex.Message); } } } } } AnsiConsole.Render(new Rule()); AnsiConsole.WriteLine(); if (diagnoses.Any(d => d.Status == Doctoring.Status.Error)) { AnsiConsole.MarkupLine($"[bold red]{Icon.Bell} There were one or more problems detected.[/]"); AnsiConsole.MarkupLine($"[bold red]Please review the errors and correct them and run maui-doctor again.[/]"); } else { AnsiConsole.MarkupLine($"[bold blue]{Icon.Success} Congratulations, everything looks great![/]"); } Console.Title = ToolName; return(0); }
static void Main(string[] args) { var timer = new Stopwatch(); timer.Start(); var src = args.Length > 0 ? args[0] : "O:/Old software/Amiga/TOSEC 2016-11-11/Commodore Amiga - Demos - Animations and Videos"; var dest = args.Length > 1 ? args[1] : "./files"; var noSplit = args.Any(x => x.Equals("--nosplit", StringComparison.InvariantCultureIgnoreCase)); var unpack = args.Any(x => x.Equals("--unpack", StringComparison.InvariantCultureIgnoreCase)); var useFilter = args.Any(x => x.Equals("--filter", StringComparison.InvariantCultureIgnoreCase)); var dryrun = args.Any(x => x.Equals("--dryrun", StringComparison.InvariantCultureIgnoreCase)); var includeFolders = args.Any(x => x.Equals("--folders", StringComparison.InvariantCultureIgnoreCase)); var flattenSubdirs = args.Any(x => x.Equals("--flatten", StringComparison.InvariantCultureIgnoreCase)); List<FileSystemInfo> fsItems = null; // List<DirectoryInfo> dirs = null; AnsiConsole.Status() .Start($"Reading files from [bold]{src.Replace("[", "[[").Replace("]", "]]")}[/]", ctx => { ctx.Spinner(Spinner.Known.Dots); var srcDir = new DirectoryInfo(src); if (!includeFolders) fsItems = srcDir .GetFiles() .Select(x => x as FileSystemInfo) .Where(f => !useFilter || !Filter.IsMatch(f.Name)) .OrderBy(x => x.Name) .ToList(); else fsItems = srcDir .GetFileSystemInfos() .Select(x => x as FileSystemInfo) .Where(f => !useFilter || !Filter.IsMatch(f.Name)) .OrderBy(x => x.Name) .ToList(); }); AnsiConsole.MarkupLine($"Found [green]{fsItems.Count}[/] files in [bold]{src.Replace("[", "[[").Replace("]", "]]")}[/]."); var duplicates = 0; var useSubFolders = !noSplit && fsItems.Count > 200; AnsiConsole.Progress() .AutoClear(false) .Columns(new ProgressColumn[] { new TaskDescriptionColumn(), // Task description new ProgressBarColumn(), // Progress bar new PercentageColumn(), // Percentage new RemainingTimeColumn(), // Remaining time new SpinnerColumn(), // Spinner }) .Start(ctx => { var task1 = ctx.AddTask("Removing duplicates", new ProgressTaskSettings { MaxValue = fsItems.Count }); var uniqueFiles = new ConcurrentBag<FileSystemInfo>(); Parallel.ForEach(fsItems.GroupBy(x => x.Name[0]), (itemsByFirstLetter, _, _) => { Parallel.ForEach(itemsByFirstLetter, (file, state, index) => { var relevantName = RelevantName(file.Name); var isDuplicate = itemsByFirstLetter.Take((int)index).Any(x => RelevantName(x.Name).Equals(relevantName, StringComparison.InvariantCultureIgnoreCase)); if (isDuplicate) { duplicates++; } else uniqueFiles.Add(file); task1.Increment(1); }); }); task1.StopTask(); var task3 = ctx.AddTask($"Copying files to [bold]{dest}[/]", new ProgressTaskSettings { AutoStart = false, MaxValue = uniqueFiles.Count }); task3.Description = $"{(unpack ? "Unpacking" : "Copying")} {uniqueFiles.Count} files to [bold]{dest}[/]"; task3.StartTask(); foreach(var file in uniqueFiles) { var destination = dest; if (useSubFolders) { var group = Words.Match(file.Name).Value.ToUpperInvariant(); if (Digits.IsMatch(group)) group = "0"; destination = Path.Combine(dest, group); } if (!dryrun) { if (!Directory.Exists(destination)) Directory.CreateDirectory(destination); if (!unpack) { if (file is FileInfo f) f.CopyTo(Path.Combine(destination, file.Name), true); else if (file is DirectoryInfo d) { if (!flattenSubdirs) destination = Directory.CreateDirectory(Path.Combine(destination, d.Name)).FullName; foreach(var fileInDir in d.GetFiles()) fileInDir.CopyTo(Path.Combine(destination, fileInDir.Name)); } } else ZipFile.ExtractToDirectory(file.FullName, destination, true); } task3.Increment(1); } }); timer.Stop(); AnsiConsole.MarkupLine($"Found [red]{duplicates}[/] duplicates in [green]{fsItems.Count}[/] files"); AnsiConsole.MarkupLine($"Time elapsed: [bold]{timer.Elapsed} [/]seconds"); }