Some checks failed
		
		
	
	Build Test Deploy / docs (push) Has been cancelled
				
			Build Test Deploy / deploy (push) Has been cancelled
				
			Build Test Deploy / build-test (push) Has been cancelled
				
			Build Test Deploy / authority-container (push) Has been cancelled
				
			Docs CI / lint-and-preview (push) Has been cancelled
				
			
		
			
				
	
	
		
			129 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.CommandLine;
 | |
| using System.IO;
 | |
| using System.Threading;
 | |
| using System.Threading.Tasks;
 | |
| using Microsoft.Extensions.DependencyInjection;
 | |
| using Microsoft.Extensions.Logging;
 | |
| using StellaOps.Auth.Client;
 | |
| using StellaOps.Cli.Commands;
 | |
| using StellaOps.Cli.Configuration;
 | |
| using StellaOps.Cli.Services;
 | |
| using StellaOps.Cli.Telemetry;
 | |
| 
 | |
| namespace StellaOps.Cli;
 | |
| 
 | |
| internal static class Program
 | |
| {
 | |
|     internal static async Task<int> Main(string[] args)
 | |
|     {
 | |
|         var (options, configuration) = CliBootstrapper.Build(args);
 | |
| 
 | |
|         var services = new ServiceCollection();
 | |
|         services.AddSingleton(configuration);
 | |
|         services.AddSingleton(options);
 | |
| 
 | |
|         var verbosityState = new VerbosityState();
 | |
|         services.AddSingleton(verbosityState);
 | |
| 
 | |
|         services.AddLogging(builder =>
 | |
|         {
 | |
|             builder.ClearProviders();
 | |
|             builder.AddSimpleConsole(logOptions =>
 | |
|             {
 | |
|                 logOptions.TimestampFormat = "HH:mm:ss ";
 | |
|                 logOptions.SingleLine = true;
 | |
|             });
 | |
|             builder.AddFilter((category, level) => level >= verbosityState.MinimumLevel);
 | |
|         });
 | |
| 
 | |
|         if (!string.IsNullOrWhiteSpace(options.Authority.Url))
 | |
|         {
 | |
|             services.AddStellaOpsAuthClient(clientOptions =>
 | |
|             {
 | |
|                 clientOptions.Authority = options.Authority.Url;
 | |
|                 clientOptions.ClientId = options.Authority.ClientId ?? string.Empty;
 | |
|                 clientOptions.ClientSecret = options.Authority.ClientSecret;
 | |
|                 clientOptions.DefaultScopes.Clear();
 | |
|                 clientOptions.DefaultScopes.Add(string.IsNullOrWhiteSpace(options.Authority.Scope)
 | |
|                     ? StellaOps.Auth.Abstractions.StellaOpsScopes.FeedserJobsTrigger
 | |
|                     : options.Authority.Scope);
 | |
| 
 | |
|                 var resilience = options.Authority.Resilience ?? new StellaOpsCliAuthorityResilienceOptions();
 | |
|                 clientOptions.EnableRetries = resilience.EnableRetries ?? true;
 | |
| 
 | |
|                 if (resilience.RetryDelays is { Count: > 0 })
 | |
|                 {
 | |
|                     clientOptions.RetryDelays.Clear();
 | |
|                     foreach (var delay in resilience.RetryDelays)
 | |
|                     {
 | |
|                         if (delay > TimeSpan.Zero)
 | |
|                         {
 | |
|                             clientOptions.RetryDelays.Add(delay);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (resilience.AllowOfflineCacheFallback.HasValue)
 | |
|                 {
 | |
|                     clientOptions.AllowOfflineCacheFallback = resilience.AllowOfflineCacheFallback.Value;
 | |
|                 }
 | |
| 
 | |
|                 if (resilience.OfflineCacheTolerance.HasValue && resilience.OfflineCacheTolerance.Value >= TimeSpan.Zero)
 | |
|                 {
 | |
|                     clientOptions.OfflineCacheTolerance = resilience.OfflineCacheTolerance.Value;
 | |
|                 }
 | |
|             });
 | |
| 
 | |
|             var cacheDirectory = options.Authority.TokenCacheDirectory;
 | |
|             if (!string.IsNullOrWhiteSpace(cacheDirectory))
 | |
|             {
 | |
|                 Directory.CreateDirectory(cacheDirectory);
 | |
|                 services.AddStellaOpsFileTokenCache(cacheDirectory);
 | |
|             }
 | |
| 
 | |
|             services.AddHttpClient<IAuthorityRevocationClient, AuthorityRevocationClient>(client =>
 | |
|             {
 | |
|                 client.Timeout = TimeSpan.FromMinutes(2);
 | |
|                 if (Uri.TryCreate(options.Authority.Url, UriKind.Absolute, out var authorityUri))
 | |
|                 {
 | |
|                     client.BaseAddress = authorityUri;
 | |
|                 }
 | |
|             });
 | |
|         }
 | |
| 
 | |
|         services.AddHttpClient<IBackendOperationsClient, BackendOperationsClient>(client =>
 | |
|         {
 | |
|             client.Timeout = TimeSpan.FromMinutes(5);
 | |
|             if (!string.IsNullOrWhiteSpace(options.BackendUrl) &&
 | |
|                 Uri.TryCreate(options.BackendUrl, UriKind.Absolute, out var backendUri))
 | |
|             {
 | |
|                 client.BaseAddress = backendUri;
 | |
|             }
 | |
|         });
 | |
| 
 | |
|         services.AddSingleton<IScannerExecutor, ScannerExecutor>();
 | |
|         services.AddSingleton<IScannerInstaller, ScannerInstaller>();
 | |
| 
 | |
|         await using var serviceProvider = services.BuildServiceProvider();
 | |
|         using var cts = new CancellationTokenSource();
 | |
|         Console.CancelKeyPress += (_, eventArgs) =>
 | |
|         {
 | |
|             eventArgs.Cancel = true;
 | |
|             cts.Cancel();
 | |
|         };
 | |
| 
 | |
|         var rootCommand = CommandFactory.Create(serviceProvider, options, cts.Token);
 | |
|         var commandConfiguration = new CommandLineConfiguration(rootCommand);
 | |
|         var commandExit = await commandConfiguration.InvokeAsync(args, cts.Token).ConfigureAwait(false);
 | |
| 
 | |
|         var finalExit = Environment.ExitCode != 0 ? Environment.ExitCode : commandExit;
 | |
|         if (cts.IsCancellationRequested && finalExit == 0)
 | |
|         {
 | |
|             finalExit = 130; // Typical POSIX cancellation exit code
 | |
|         }
 | |
| 
 | |
|         return finalExit;
 | |
|     }
 | |
| }
 |