Exemple #1
0
        public sealed override async Task <int> ExecuteAsync(CommandContext context, TSettings settings)
        {
            // Set verbose tracing
            if (settings.LogLevel != LogLevel.Information)
            {
                _serviceCollection.Configure <LoggerFilterOptions>(options => options.MinLevel = settings.LogLevel);
            }

            // File logging
            if (!string.IsNullOrEmpty(settings.LogFile))
            {
                // Add the log provider (adding it to the service collection will get picked up by the logger factory)
                _serviceCollection.AddSingleton <ILoggerProvider, FileLoggerProvider>();
                _serviceCollection.Configure <FileLoggerOptions>(options =>
                {
                    options.FileName     = settings.LogFile;
                    options.LogDirectory = string.Empty;
                });
            }

            // Build a temporary service provider so we can log
            IServiceProvider services = _serviceCollection.BuildServiceProvider();

            // Log pending messages
            ILogger logger = services.GetRequiredService <ILogger <Bootstrapper> >();

            logger.LogInformation($"Statiq version {Engine.Version}");
            ClassCatalog classCatalog = services.GetService <ClassCatalog>();

            if (classCatalog != null)
            {
                classCatalog.LogDebugMessages(logger);
            }

            // Attach
            if (settings.Attach)
            {
                logger.LogInformation($"Waiting for a debugger to attach to process {Process.GetCurrentProcess().Id} (or press a key to continue)...");
                while (!Debugger.IsAttached && !Console.KeyAvailable)
                {
                    Thread.Sleep(100);
                }
                if (Console.KeyAvailable)
                {
                    Console.ReadKey(true);
                    logger.LogInformation("Key pressed, continuing execution");
                }
                else
                {
                    logger.LogInformation("Debugger attached, continuing execution");
                }
            }

            return(await ExecuteCommandAsync(_serviceCollection, context, settings));
        }
Exemple #2
0
        public sealed override async Task <int> ExecuteAsync(CommandContext context, TSettings commandSettings)
        {
            // Set verbose tracing
            if (commandSettings.LogLevel != LogLevel.Information)
            {
                ServiceCollection.Configure <LoggerFilterOptions>(options => options.MinLevel = commandSettings.LogLevel);
            }

            // File logging
            if (!string.IsNullOrEmpty(commandSettings.LogFile))
            {
                // Add the log provider (adding it to the service collection will get picked up by the logger factory)
                ServiceCollection.AddSingleton <ILoggerProvider, FileLoggerProvider>();
                ServiceCollection.Configure <FileLoggerOptions>(options =>
                {
                    options.FileName     = commandSettings.LogFile;
                    options.LogDirectory = string.Empty;
                });
            }

            // Build a temporary service provider so we can log
            // Make sure to place it in it's own scope so transient services get correctly disposed
            IServiceProvider services     = ServiceCollection.BuildServiceProvider();
            ClassCatalog     classCatalog = services.GetService <ClassCatalog>();

            using (IServiceScope serviceScope = services.CreateScope())
            {
                // Log pending messages
                ILogger logger = serviceScope.ServiceProvider.GetRequiredService <ILogger <Bootstrapper> >();
                logger.LogInformation($"Statiq version {Engine.Version}");
                classCatalog?.LogDebugMessages(logger);

                // Attach
                if (commandSettings.Attach)
                {
                    logger.LogInformation($"Waiting for a debugger to attach to process {Process.GetCurrentProcess().Id} (or press a key to continue)...");
                    while (!Debugger.IsAttached && !Console.KeyAvailable)
                    {
                        Thread.Sleep(100);
                    }
                    if (Console.KeyAvailable)
                    {
                        Console.ReadKey(true);
                        logger.LogInformation("Key pressed, continuing execution");
                    }
                    else
                    {
                        logger.LogInformation("Debugger attached, continuing execution");
                    }
                }
            }

            // Add settings
            if (commandSettings.Settings?.Length > 0)
            {
                foreach (KeyValuePair <string, string> setting in SettingsParser.Parse(commandSettings.Settings))
                {
                    ConfigurationSettings[setting.Key] = setting.Value;
                }
            }

            // Configure settings after other configuration so they can use the values
            ConfigurableSettings configurableSettings = new ConfigurableSettings(ConfigurationSettings);

            Configurators.Configure(configurableSettings);

            return(await ExecuteCommandAsync(context, commandSettings));
        }
Exemple #3
0
        /// <inheritdoc/>
        public async Task <int> RunAsync()
        {
            // Remove the synchronization context
            await default(SynchronizationContextRemover);

            // Populate the class catalog (if we haven't already)
            ClassCatalog.Populate();

            // Run bootstrapper configurators first
            Configurators.Configure <IBootstrapper>(this);
            Configurators.Configure(this);

            // Run the configuration configurator and get the configuration root
            IConfigurationBuilder     configurationBuilder      = new ConfigurationBuilder();
            ConfigurableConfiguration configurableConfiguration = new ConfigurableConfiguration(configurationBuilder);

            Configurators.Configure(configurableConfiguration);
            IConfigurationRoot    configurationRoot     = configurationBuilder.Build();
            ConfigurationSettings configurationSettings = new ConfigurationSettings(configurationRoot);

            // Create the service collection
            IServiceCollection serviceCollection = CreateServiceCollection() ?? new ServiceCollection();

            serviceCollection.TryAddSingleton(this);
            serviceCollection.TryAddSingleton <IBootstrapper>(this);
            serviceCollection.TryAddSingleton(ClassCatalog);  // The class catalog is retrieved later for deferred logging once a service provider is built
            serviceCollection.TryAddSingleton <IConfiguration>(configurationRoot);

            // Run configurators on the service collection
            ConfigurableServices configurableServices = new ConfigurableServices(serviceCollection, configurationRoot);

            Configurators.Configure(configurableServices);

            // Add simple logging to make sure it's available in commands before the engine adds in,
            // but add it after the configurators have a chance to configure logging
            serviceCollection.AddLogging();

            // Create the stand-alone command line service container and register a few types needed for the CLI
            CommandServiceTypeRegistrar registrar = new CommandServiceTypeRegistrar();

            registrar.RegisterInstance(typeof(IConfigurationSettings), configurationSettings);
            registrar.RegisterInstance(typeof(IConfigurationRoot), configurationRoot);
            registrar.RegisterInstance(typeof(IServiceCollection), serviceCollection);
            registrar.RegisterInstance(typeof(IConfiguratorCollection), Configurators);
            registrar.RegisterInstance(typeof(Bootstrapper), this);

            // Create the command line parser and run the command
            ICommandApp app = _getCommandApp(registrar);

            app.Configure(commandConfigurator =>
            {
                commandConfigurator.ValidateExamples();
                ConfigurableCommands configurableCommands = new ConfigurableCommands(commandConfigurator);
                Configurators.Configure(configurableCommands);
            });
            int exitCode = await app.RunAsync(Arguments);

            // Dispose all instances of the console logger to flush the message queue and stop the listening thread
            ConsoleLoggerProvider.DisposeAll();

            return(exitCode);
        }