Skip to content

[FEATURE] Set console option defaults via guides.xml #587

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions guides.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<guides xmlns="https://www.phpdoc.org/guides"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.phpdoc.org/guides packages/guides-cli/resources/schema/guides.xsd">
xsi:schemaLocation="https://www.phpdoc.org/guides packages/guides-cli/resources/schema/guides.xsd"
input="docs"
output="output"
input-format="rst"
show-progress="true"
theme="bootstrap"
fail-on-log="false"
log-path="php://stder"
>
<project title="phpDocumentor Guides"/>
<theme>bootstrap</theme>
<output-format>html</output-format>
<output-format>intersphinx</output-format>

<extension class="phpDocumentor\Guides\Bootstrap"/>
</guides>
7 changes: 7 additions & 0 deletions packages/guides-cli/resources/schema/guides.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@
<xsd:element name="base-template-path" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="theme" type="theme" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="extension" type="extension" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="output-format" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>

<xsd:attribute name="input" type="xsd:string"/>
<xsd:attribute name="output" type="xsd:string"/>
<xsd:attribute name="input-format" type="xsd:string"/>
<xsd:attribute name="log-path" type="xsd:string"/>
<xsd:attribute name="fail-on-log" type="xsd:string"/>
<xsd:attribute name="show-progress" type="xsd:string"/>
<xsd:attribute name="theme" type="xsd:string"/>
</xsd:complexType>

Expand Down
71 changes: 47 additions & 24 deletions packages/guides-cli/src/Command/Run.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use phpDocumentor\Guides\Handlers\RenderCommand;
use phpDocumentor\Guides\Intersphinx\InventoryRepository;
use phpDocumentor\Guides\Nodes\ProjectNode;
use phpDocumentor\Guides\Settings\ProjectSettings;
use phpDocumentor\Guides\Settings\SettingsManager;
use phpDocumentor\Guides\Twig\Theme\ThemeManager;
use RuntimeException;
Expand Down Expand Up @@ -55,35 +56,30 @@ public function __construct(
'input',
InputArgument::OPTIONAL,
'Directory to read for files',
'docs',
);
$this->addArgument(
'output',
InputArgument::OPTIONAL,
'Directory to read for files',
'output',
);

$this->addOption(
'input-format',
null,
InputOption::VALUE_REQUIRED,
'Format of the input can be RST, or Markdown',
'rst',
);
$this->addOption(
'output-format',
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'Format of the input can be html',
['html'],
'Format of the input can be html and or intersphinx',
);
$this->addOption(
'log-path',
null,
InputOption::VALUE_REQUIRED,
'Write log to this path',
'php://stder',
);
$this->addOption(
'fail-on-log',
Expand All @@ -104,40 +100,70 @@ public function __construct(
null,
InputOption::VALUE_NEGATABLE,
'Whether to show a progress bar',
true,
);
}

private function getSettingsOverridenWithInput(InputInterface $input): ProjectSettings
{
$settings = $this->settingsManager->getProjectSettings();
if ($input->getArgument('input')) {
$settings->setInput((string) $input->getArgument('input'));
}

if ($input->getArgument('output')) {
$settings->setOutput((string) $input->getArgument('output'));
}

if ($input->getOption('log-path')) {
$settings->setLogPath((string) $input->getOption('log-path'));
}

if ($input->getOption('fail-on-log')) {
$settings->setFailOnError(true);
}

if ($input->getOption('input-format')) {
$settings->setInputFormat((string) $input->getOption('input-format'));
}

if (count($input->getOption('output-format')) > 0) {
$settings->setOutputFormats($input->getOption('output-format'));
}

if ($input->getOption('theme')) {
$settings->setTheme((string) $input->getOption('theme'));
}

return $settings;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$inputDir = $this->getAbsolutePath((string) ($input->getArgument('input') ?? ''));
$settings = $this->getSettingsOverridenWithInput($input);
$inputDir = $this->getAbsolutePath($settings->getInput());
if (!is_dir($inputDir)) {
throw new RuntimeException(sprintf('Input directory "%s" was not found! ' . "\n" .
'Run "vendor/bin/guides -h" for information on how to configure this command.', $inputDir));
}

$settings = $this->settingsManager->getProjectSettings();

$projectNode = new ProjectNode(
$settings->getTitle() === '' ? null : $settings->getTitle(),
$settings->getVersion() === '' ? null : $settings->getVersion(),
);
$this->inventoryRepository->initialize($settings->getInventories());

$outputDir = $this->getAbsolutePath((string) ($input->getArgument('output') ?? ''));
$sourceFileSystem = new Filesystem(new Local($input->getArgument('input')));
$outputDir = $this->getAbsolutePath($settings->getOutput());
$sourceFileSystem = new Filesystem(new Local($settings->getInput()));
$sourceFileSystem->addPlugin(new Finder());
$logPath = $input->getOption('log-path') ?? 'php://stder';
$logPath = $settings->getLogPath();
if ($logPath === 'php://stder') {
$this->logger->pushHandler(new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, Logger::WARNING));
} else {
$this->logger->pushHandler(new StreamHandler($logPath . '/warning.log', Logger::WARNING));
$this->logger->pushHandler(new StreamHandler($logPath . '/error.log', Logger::ERROR));
}

$failOnLog = $input->getOption('fail-on-log') ?? false;

if ($failOnLog) {
if ($settings->isFailOnError()) {
$spyProcessor = new SpyProcessor();
$this->logger->pushProcessor($spyProcessor);
}
Expand All @@ -146,28 +172,25 @@ protected function execute(InputInterface $input, OutputInterface $output): int
new ParseDirectoryCommand(
$sourceFileSystem,
'',
$input->getOption('input-format'),
$settings->getInputFormat(),
$projectNode,
),
);

$theme = $input->getOption('theme');
if ($theme) {
$settings->setTheme($theme);
}


$this->themeManager->useTheme($settings->getTheme());

$documents = $this->commandBus->handle(new CompileDocumentsCommand($documents, new CompilerContext($projectNode)));

$destinationFileSystem = new Filesystem(new Local($outputDir));

$outputFormats = $input->getOption('output-format');
$outputFormats = $settings->getOutputFormats();

foreach ($outputFormats as $format) {
$progressBar = null;

if ($output instanceof ConsoleOutputInterface && $input->getOption('progress')) {
if ($output instanceof ConsoleOutputInterface && $settings->isShowProgressBar()) {
$progressBar = new ProgressBar($output->section());
}

Expand Down Expand Up @@ -195,7 +218,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
'Successfully placed ' . (is_countable($documents) ? count($documents) : 0) . ' rendered ' . $formatsText . ' files into ' . $outputDir,
);

if ($failOnLog && $spyProcessor->hasBeenCalled()) {
if ($settings->isFailOnError() && $spyProcessor->hasBeenCalled()) {
return Command::FAILURE;
}

Expand Down
48 changes: 40 additions & 8 deletions packages/guides/src/DependencyInjection/GuidesExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ public function getConfigTreeBuilder(): TreeBuilder
->end()
->end()
->scalarNode('theme')->end()
->scalarNode('input')->end()
->scalarNode('output')->end()
->scalarNode('input_format')->end()
->arrayNode('output_format')
->defaultValue([])
->scalarPrototype()->end()
->end()
->scalarNode('log_path')->end()
->scalarNode('fail_on_log')->end()
->scalarNode('show_progress')->end()
->arrayNode('base_template_paths')
->defaultValue([])
->scalarPrototype()->end()
Expand Down Expand Up @@ -91,28 +101,50 @@ public function load(array $configs, ContainerBuilder $container): void
$loader->load('command_bus.php');
$loader->load('guides.php');

$projectSettings = [];
$projectSettings = new ProjectSettings();
if (isset($config['project'])) {
if (isset($config['project']['version'])) {
$config['project']['version'] = (string) $config['project']['version'];
$projectSettings->setVersion((string) $config['project']['version']);
}

$projectSettings = $config['project'];
$projectSettings->setTitle((string) $config['project']['title']);
}

if (isset($config['inventories'])) {
$projectSettings['inventories'] = $config['inventories']['inventory'];
$projectSettings->setInventories($config['inventories']['inventory']);
}

if (isset($config['theme'])) {
$projectSettings['theme'] = (string) $config['theme'];
$projectSettings->setTheme((string) $config['theme']);
}

if (isset($config['input'])) {
$projectSettings->setInput((string) $config['input']);
}

if (isset($config['output'])) {
$projectSettings->setOutput((string) $config['output']);
}

if ($projectSettings) {
$container->getDefinition(SettingsManager::class)
->addMethodCall('setProjectSettings', [new ProjectSettings($projectSettings)]);
if (isset($config['input_format'])) {
$projectSettings->setInputFormat((string) $config['input_format']);
}

if (isset($config['output_format']) && is_array($config['output_format'])) {
$projectSettings->setOutputFormats($config['output_format']);
}

if (isset($config['show_progress'])) {
$projectSettings->setShowProgressBar((bool) $config['show_progress']);
}

if (isset($config['fail_on_log'])) {
$projectSettings->setFailOnError((bool) $config['show_progress']);
}

$container->getDefinition(SettingsManager::class)
->addMethodCall('setProjectSettings', [$projectSettings]);

$config['base_template_paths'][] = dirname(__DIR__, 2) . '/resources/template/html';
$container->setParameter('phpdoc.guides.base_template_paths', $config['base_template_paths']);

Expand Down
100 changes: 84 additions & 16 deletions packages/guides/src/Settings/ProjectSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,21 @@

namespace phpDocumentor\Guides\Settings;

use function is_array;
use function is_string;

class ProjectSettings
{
/** @var array<string, string> */
private array $inventories;
private string $title;
private string $version;
private string $theme;

/** @param array<string, string|array<string, string>> $settingsArray */
public function __construct(array $settingsArray)
{
$this->title = isset($settingsArray['title']) && is_string($settingsArray['title']) ? $settingsArray['title'] : '';
$this->version = isset($settingsArray['version']) && is_string($settingsArray['version']) ? $settingsArray['version'] : '';
$this->inventories = isset($settingsArray['inventories']) && is_array($settingsArray['inventories']) ? $settingsArray['inventories'] : [];
$this->theme = isset($settingsArray['theme']) && is_string($settingsArray['theme']) ? $settingsArray['theme'] : 'default';
}
private array $inventories = [];
private string $title = '';
private string $version = '';
private string $theme = 'default';
private string $input = 'docs';
private string $output = 'output';
private string $inputFormat = 'rst';
/** @var string[] */
private array $outputFormats = ['html'];
private string $logPath = 'php://stder';
private bool $failOnError = false;
private bool $showProgressBar = true;

public function getTitle(): string
{
Expand Down Expand Up @@ -65,4 +61,76 @@ public function setTheme(string $theme): void
{
$this->theme = $theme;
}

public function getInput(): string
{
return $this->input;
}

public function setInput(string $input): void
{
$this->input = $input;
}

public function getOutput(): string
{
return $this->output;
}

public function setOutput(string $output): void
{
$this->output = $output;
}

public function getInputFormat(): string
{
return $this->inputFormat;
}

public function setInputFormat(string $inputFormat): void
{
$this->inputFormat = $inputFormat;
}

public function getLogPath(): string
{
return $this->logPath;
}

public function setLogPath(string $logPath): void
{
$this->logPath = $logPath;
}

public function isFailOnError(): bool
{
return $this->failOnError;
}

public function setFailOnError(bool $failOnError): void
{
$this->failOnError = $failOnError;
}

public function isShowProgressBar(): bool
{
return $this->showProgressBar;
}

public function setShowProgressBar(bool $showProgressBar): void
{
$this->showProgressBar = $showProgressBar;
}

/** @return string[] */
public function getOutputFormats(): array
{
return $this->outputFormats;
}

/** @param string[] $outputFormats */
public function setOutputFormats(array $outputFormats): void
{
$this->outputFormats = $outputFormats;
}
}
Loading