From 32f955d9caf4d4b79277ec5e2289f5c1abd73cec Mon Sep 17 00:00:00 2001 From: Jordan LeDoux Date: Fri, 16 Jul 2021 19:04:12 -0700 Subject: [PATCH] [#10] Making paths work for Windows --- roster-config-schema.config.json | 4 + src/Samsara/Roster/Roster.php | 104 +++++++++++++++---------- src/Samsara/Roster/TemplateFactory.php | 4 +- 3 files changed, 69 insertions(+), 43 deletions(-) diff --git a/roster-config-schema.config.json b/roster-config-schema.config.json index e1bcc26..6e5378b 100644 --- a/roster-config-schema.config.json +++ b/roster-config-schema.config.json @@ -13,6 +13,10 @@ "type": "string", "description": "The version to export the documentation as; omit for auto-detection behavior" }, + "export-path": { + "type": "string", + "description": "The export path to write the finished documentation files to" + }, "templates": { "type": "string", "description": "The path to the template files" diff --git a/src/Samsara/Roster/Roster.php b/src/Samsara/Roster/Roster.php index 91eb14f..b49f86c 100644 --- a/src/Samsara/Roster/Roster.php +++ b/src/Samsara/Roster/Roster.php @@ -45,6 +45,7 @@ class Roster extends Command private SymfonyStyle $io; private bool $verbose = false; + private string $docsExportPath; public function __construct($rootDir) { @@ -91,6 +92,12 @@ protected function configure(): void 'mode' => InputOption::VALUE_OPTIONAL, 'description' => "What roster.json config file to use (if any)" ], + 'export-path' => [ + 'default' => 'docs'.DIRECTORY_SEPARATOR.'roster', + 'shortcut' => null, + 'mode' => InputOption::VALUE_OPTIONAL, + 'description' => "The export path to write the finished documentation files to." + ], 'templates' => [ 'default' => null, 'shortcut' => 't', @@ -175,12 +182,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int /* * All the setup and config values and options values setting */ - if (empty($this->rootRosterDir)) { + if (empty($this->rootRosterDir) || !is_dir($this->rootRosterDir)) { $this->io->error('Cannot find Roster root directory'); return self::FAILURE; } - $configPathRoot = $this->rootDir.'/'.$opts['config-file']; + $configPathRoot = $this->rootDir.DIRECTORY_SEPARATOR.$opts['config-file']; if (!is_file($configPathRoot)) { ConfigBag::setRosterConfig(new Config("{}", new Json(), true)); @@ -240,7 +247,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int if ($opts['templates']) { ConfigBag::getRosterConfig()->set('templates', $opts['templates']); } elseif (!ConfigBag::getRosterConfig()->has('templates')) { - ConfigBag::getRosterConfig()->set('templates', 'doc-templates/roster-templates'); + ConfigBag::getRosterConfig()->set('templates', 'doc-templates'.DIRECTORY_SEPARATOR.'roster-templates'); } if ($opts['prefer-source'] || !ConfigBag::getRosterConfig()->has('prefer-source')) { @@ -256,11 +263,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int if (ConfigBag::getRosterConfig()->has('mkdocs')) { $this->io->section('Gathering MkDocs Config Info'); - $existingMkDocsYml = is_file($this->rootDir . '/mkdocs.yml'); + $existingMkDocsYml = is_file($this->rootDir . DIRECTORY_SEPARATOR.'mkdocs.yml'); if ($existingMkDocsYml) { $oldConfig = Config::load( - file_get_contents($this->rootDir . '/mkdocs.yml'), + file_get_contents($this->rootDir . DIRECTORY_SEPARATOR. 'mkdocs.yml'), new YamlReader(), true ); @@ -363,10 +370,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int ConfigBag::getRosterConfig()->set('mkdocs.nav-key', $baseKey); } - $baseExportPath = $this->rootDir. - '/docs/roster/'. - ConfigBag::getRosterConfig()->get('with-version', 'latest'); - $python = exec('which pip'); $python3 = exec('which pip3'); @@ -384,24 +387,43 @@ protected function execute(InputInterface $input, OutputInterface $output): int } } - if (ConfigBag::getRosterConfig()->get('templates') == 'doc-templates/roster-templates') { - ConfigBag::getRosterConfig()->set('templates', 'doc-templates/roster-templates-mkdocs'); + if (ConfigBag::getRosterConfig()->get('templates') == 'doc-templates'.DIRECTORY_SEPARATOR.'roster-templates') { + ConfigBag::getRosterConfig()->set('templates', 'doc-templates'.DIRECTORY_SEPARATOR.'roster-templates-mkdocs'); + } + } + + + if (ConfigBag::getRosterConfig()->has('export-path')) { + if ($opts['export-path'] == 'docs'.DIRECTORY_SEPARATOR.'roster') { + $baseExportPath = ConfigBag::getRosterConfig()->get('export-path'); + } else { + $baseExportPath = $opts['export-path']; } } else { - $baseExportPath = $this->rootDir. - '/docs/roster-export/'. - $version; + $baseExportPath = $opts['export-path']; + } + + if (!str_starts_with(DIRECTORY_SEPARATOR, $baseExportPath) && !preg_match('/^[A-Z]?:\\\\/ism', $baseExportPath)) { + $baseExportPath = realpath($this->rootDir.DIRECTORY_SEPARATOR.$baseExportPath.DIRECTORY_SEPARATOR.$version); + } + + if (!is_string($baseExportPath)) { + $baseExportPath = $this->rootDir.DIRECTORY_SEPARATOR.'docs'; } $this->baseExportPath = $baseExportPath; + $this->docsExportPath = 'roster'.DIRECTORY_SEPARATOR.$version; - $baseExportPathParts = explode('/', $baseExportPath); + $baseExportPathParts = explode(DIRECTORY_SEPARATOR, $baseExportPath); $pathSum = ''; $this->io->section('Initialization'); foreach ($baseExportPathParts as $exportPathPart) { - $pathSum .= '/'.$exportPathPart; + if (str_contains(':', $exportPathPart)) { + continue; + } + $pathSum .= DIRECTORY_SEPARATOR.$exportPathPart; if (!is_dir($pathSum)) { $createDir = mkdir($pathSum); @@ -440,7 +462,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } if (!empty($autoloader)) { - $autoloader = realpath($this->rootDir.'/'.$autoloader); + $autoloader = realpath($this->rootDir.DIRECTORY_SEPARATOR.$autoloader); require_once $autoloader; } @@ -452,7 +474,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int ConfigBag::getRosterConfig()->set('visibility-level', $visibilityLevel); - $fileList = $this->traverseDirectories(realpath($this->rootDir.'/'.$sourcePath)); + $fileList = $this->traverseDirectories(realpath($this->rootDir.DIRECTORY_SEPARATOR.$sourcePath)); $this->classes = []; foreach ($fileList as $file) { @@ -515,7 +537,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->io->success('Templates Compiled To Documents'); $this->io->section('Writing Documentation to Output Directory'); - $ok = TemplateFactory::writeToDocs($baseExportPath, $this->io); + $ok = TemplateFactory::writeToDocs($this->baseExportPath.DIRECTORY_SEPARATOR.$this->docsExportPath, $this->io); if ($ok) { $this->io->success('Documentation Written To Output Directory'); @@ -532,8 +554,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int if ($choice && isset($oldConfig)) { $extraCss = $oldConfig->get('extra_css'); - if (!in_array('css/'.$cssFileName.'.css', $extraCss)) { - $extraCss[] = 'css/'.$cssFileName.'.css'; + if (!in_array('css'.DIRECTORY_SEPARATOR.$cssFileName.'.css', $extraCss)) { + $extraCss[] = 'css'.DIRECTORY_SEPARATOR.$cssFileName.'.css'; } $appendOrMerge = ConfigBag::getRosterConfig()->get('mkdocs.merge-nav-mode'); @@ -577,8 +599,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $mkDocsConfig = (new YamlDumper(4))->dump($oldConfig->all(), 50, 0, Yaml::DUMP_OBJECT_AS_MAP); } else { if (isset($oldConfig) && !$choice) { - $oldMkdocs = file_get_contents($this->rootDir . '/mkdocs.yml'); - $ok = file_put_contents($this->rootDir . '/mkdocs.yml.old', $oldMkdocs); + $oldMkdocs = file_get_contents($this->rootDir . DIRECTORY_SEPARATOR. 'mkdocs.yml'); + $ok = file_put_contents($this->rootDir . DIRECTORY_SEPARATOR. 'mkdocs.yml.old', $oldMkdocs); } $configBase = Config::load( @@ -588,8 +610,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int ); $extraCss = $configBase->get('extra_css'); - if (!in_array('css/'.$cssFileName.'.css', $extraCss)) { - $extraCss[] = 'css/'.$cssFileName.'.css'; + if (!in_array('css'.DIRECTORY_SEPARATOR.$cssFileName.'.css', $extraCss)) { + $extraCss[] = 'css'.DIRECTORY_SEPARATOR.$cssFileName.'.css'; } $configBase->set('site_name', ConfigBag::getRosterConfig()->get('mkdocs.site-name')); @@ -601,8 +623,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $mkDocsConfig = (new YamlDumper(4))->dump($configBase->all(), 50, 0, Yaml::DUMP_OBJECT_AS_MAP); } - if (!is_dir($this->rootDir.'/docs/css')) { - $ok = $ok && mkdir($this->rootDir . '/docs/css'); + if (!is_dir($this->baseExportPath.DIRECTORY_SEPARATOR.'css')) { + $ok = $ok && mkdir($this->baseExportPath.DIRECTORY_SEPARATOR.'css'); } if ($ok) { @@ -613,15 +635,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int return self::FAILURE; } - TemplateFactory::queueCompile('docs/css/'.$cssFileName, TemplateFactory::getTemplate($cssFileName), 'css'); - TemplateFactory::queueCompile('docs/requirements', TemplateFactory::getTemplate('requirements'), 'txt'); + TemplateFactory::queueCompile('css'.DIRECTORY_SEPARATOR.$cssFileName, TemplateFactory::getTemplate($cssFileName), 'css'); + TemplateFactory::queueCompile('requirements', TemplateFactory::getTemplate('requirements'), 'txt'); $this->io->newLine(); $this->io->writeln('Exporting Additional Files'); $this->io->newLine(); TemplateFactory::compileAll($this->io); - $ok = TemplateFactory::writeToDocs($this->rootDir, $this->io); + $ok = TemplateFactory::writeToDocs($this->baseExportPath, $this->io); if ($ok) { $this->io->success('Supporting Files Exported'); @@ -632,7 +654,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->io->newLine(); $this->io->writeln('Writing MkDocs Config'); $this->io->newLine(); - $ok = file_put_contents($this->rootDir.'/mkdocs.yml', $mkDocsConfig); + $ok = file_put_contents($this->rootDir.DIRECTORY_SEPARATOR.'mkdocs.yml', $mkDocsConfig); if ($ok) { $this->io->success('MkDocs Config File Updated'); @@ -716,9 +738,9 @@ protected function buildMkdocsNav(string $baseExportPath): array $pathParts = []; foreach ($list as $path) { - $path = str_replace($baseExportPath.'/', '', $path); + $path = str_replace($baseExportPath.DIRECTORY_SEPARATOR, '', $path); // Get the alias stuff - $pathParts[] = explode('/', $path); + $pathParts[] = explode(DIRECTORY_SEPARATOR, $path); } $navArray = []; @@ -766,7 +788,7 @@ protected function formatNavArrayRecursive(array $nav): array if (is_string($value)) { $formattedNav[$i] = [$key => $value]; } else { - $formattedNav[$i] = [$key => $this->formatNavArrayRecursive($value, $i)]; + $formattedNav[$i] = [$key => $this->formatNavArrayRecursive($value)]; } $i++; } @@ -802,16 +824,16 @@ protected function formatNavArrayRecursive(array $nav): array protected function buildNavArrayRecursive(array $parts, int $depth = 0, string $builtString = ''): array { $navArray = []; - $diffedPath = str_replace($this->rootDir.'/docs/', '', $this->baseExportPath); + $diffedPath = str_replace($this->rootDir.DIRECTORY_SEPARATOR.'docs'.DIRECTORY_SEPARATOR, '', $this->baseExportPath); if (isset($parts[$depth+1])) { - $navArray[$parts[$depth]] = $this->buildNavArrayRecursive($parts, $depth+1, $builtString.$parts[$depth].'/'); + $navArray[$parts[$depth]] = $this->buildNavArrayRecursive($parts, $depth+1, $builtString.$parts[$depth].DIRECTORY_SEPARATOR); return $navArray; } $name = str_replace('.md', '', $parts[$depth]); - return [$name => $diffedPath.'/'.$builtString.$parts[$depth]]; + return [$name => $diffedPath.DIRECTORY_SEPARATOR.$builtString.$parts[$depth]]; } protected function traverseDirectories(string $dir): array @@ -946,10 +968,10 @@ protected function processTemplates(string $templatePath): bool { if (!is_dir($templatePath)) { - if (is_dir($this->rootDir.'/'.$templatePath)) { - $templatePath = $this->rootDir . '/' . $templatePath; - } elseif (is_dir($this->rootDir.'/vendor/samsara/roster/'.$templatePath)) { - $templatePath = $this->rootDir.'/vendor/samsara/roster/'.$templatePath; + if (is_dir($this->rootDir.DIRECTORY_SEPARATOR.$templatePath)) { + $templatePath = $this->rootDir .DIRECTORY_SEPARATOR. $templatePath; + } elseif (is_dir($this->rootDir.str_replace('/', DIRECTORY_SEPARATOR, '/vendor/samsara/roster/').$templatePath)) { + $templatePath = $this->rootDir.str_replace('/', DIRECTORY_SEPARATOR, '/vendor/samsara/roster/').$templatePath; } else { $this->io->error('Cannot find Roster templates.'); $this->io->info('Please provide a path to the templates directory using the --templates option.'); diff --git a/src/Samsara/Roster/TemplateFactory.php b/src/Samsara/Roster/TemplateFactory.php index e4a7c13..4a268d4 100644 --- a/src/Samsara/Roster/TemplateFactory.php +++ b/src/Samsara/Roster/TemplateFactory.php @@ -103,13 +103,13 @@ public static function writeToDocs(string $writePath, SymfonyStyle $io): bool $pathSum = ''; $filename = array_pop($pathPart); foreach ($pathPart as $part) { - $pathSum .= '/'.$part; + $pathSum .= DIRECTORY_SEPARATOR.$part; if (!is_dir($writePath.$pathSum)) { $ok = $ok && mkdir($writePath.$pathSum); } } - $finalPath = $writePath.$pathSum.'/'.$filename.'.'.self::$compileExtensions[$path]; + $finalPath = $writePath.$pathSum.DIRECTORY_SEPARATOR.$filename.'.'.self::$compileExtensions[$path]; self::$writtenFiles[] = $finalPath; if (self::$compileExtensions[$path] == 'md') {