mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 08:52:39 +01:00
Make diviner documentation generation book-oriented
Summary: I want to allow a single project to generate multiple "books" of documentation, so we can separate user-facing documentation from technical documentation and such. Generalize the ".divinerconfig" file into a "diviner book" configuration file. Since only the "generate" workflow actually reads any of this stuff, move it all down into the generate workflow. Also, namespace the cache. Test Plan: Ran `bin/diviner generate --book src/docs/user.book`, saw appropriate output. Verified cache generated in a namespace in `.divinercache/`. Reviewers: btrahan, indiefan Reviewed By: btrahan CC: aran Maniphest Tasks: T988 Differential Revision: https://secure.phabricator.com/D4857
This commit is contained in:
parent
6e5d8d4577
commit
51947ac332
3 changed files with 75 additions and 27 deletions
|
@ -2,6 +2,9 @@
|
|||
|
||||
final class DivinerGenerateWorkflow extends DivinerWorkflow {
|
||||
|
||||
private $config;
|
||||
private $atomCache;
|
||||
|
||||
public function didConstruct() {
|
||||
$this
|
||||
->setName('generate')
|
||||
|
@ -12,10 +15,37 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow {
|
|||
'name' => 'clean',
|
||||
'help' => 'Clear the caches before generating documentation.',
|
||||
),
|
||||
array(
|
||||
'name' => 'book',
|
||||
'param' => 'path',
|
||||
'help' => 'Path to a Diviner book configuration.',
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
protected function getConfig($key, $default = null) {
|
||||
return idx($this->config, $key, $default);
|
||||
}
|
||||
|
||||
protected function getAtomCache() {
|
||||
if (!$this->atomCache) {
|
||||
$book_root = $this->getConfig('root');
|
||||
$book_name = $this->getConfig('name');
|
||||
$cache_directory = $book_root.'/.divinercache/'.$book_name;
|
||||
$this->atomCache = new DivinerAtomCache($cache_directory);
|
||||
}
|
||||
return $this->atomCache;
|
||||
}
|
||||
|
||||
protected function log($message) {
|
||||
$console = PhutilConsole::getConsole();
|
||||
$console->getServer()->setEnableLog(true);
|
||||
$console->writeLog($message."\n");
|
||||
}
|
||||
|
||||
public function execute(PhutilArgumentParser $args) {
|
||||
$this->readBookConfiguration($args);
|
||||
|
||||
if ($args->getArg('clean')) {
|
||||
$this->log(pht('CLEARING CACHES'));
|
||||
$this->getAtomCache()->delete();
|
||||
|
@ -170,7 +200,7 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow {
|
|||
|
||||
|
||||
private function findFilesInProject() {
|
||||
$file_hashes = id(new FileFinder($this->getRoot()))
|
||||
$file_hashes = id(new FileFinder($this->getConfig('root')))
|
||||
->excludePath('*/.*')
|
||||
->withType('f')
|
||||
->setGenerateChecksums(true)
|
||||
|
@ -222,11 +252,11 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow {
|
|||
foreach ($atomizers as $class => $files) {
|
||||
foreach (array_chunk($files, 32) as $chunk) {
|
||||
$future = new ExecFuture(
|
||||
'%s atomize --atomizer %s -- %Ls',
|
||||
'%s atomize --ugly --atomizer %s -- %Ls',
|
||||
dirname(phutil_get_library_root('phabricator')).'/bin/diviner',
|
||||
$class,
|
||||
$chunk);
|
||||
$future->setCWD($this->getRoot());
|
||||
$future->setCWD($this->getConfig('root'));
|
||||
|
||||
$futures[] = $future;
|
||||
}
|
||||
|
@ -381,4 +411,42 @@ final class DivinerGenerateWorkflow extends DivinerWorkflow {
|
|||
return md5(serialize($inputs)).'G';
|
||||
}
|
||||
|
||||
private function readBookConfiguration(PhutilArgumentParser $args) {
|
||||
$book_path = $args->getArg('book');
|
||||
if ($book_path === null) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
"Specify a Diviner book configuration file with --book.");
|
||||
}
|
||||
|
||||
$book_data = Filesystem::readFile($book_path);
|
||||
$book = json_decode($book_data, true);
|
||||
if (!is_array($book)) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
"Book configuration '{$book_path}' is not in JSON format.");
|
||||
}
|
||||
|
||||
// If the book specifies a "root", resolve it; otherwise, use the directory
|
||||
// the book configuration file lives in.
|
||||
$full_path = dirname(Filesystem::resolvePath($book_path));
|
||||
if (empty($book['root'])) {
|
||||
$book['root'] = '.';
|
||||
}
|
||||
$book['root'] = Filesystem::resolvePath($book['root'], $full_path);
|
||||
|
||||
// Make sure we have a valid book name.
|
||||
if (!isset($book['name'])) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
"Book configuration '{$book_path}' is missing required ".
|
||||
"property 'name'.");
|
||||
}
|
||||
|
||||
if (!preg_match('/^[a-z][a-z-]*$/', $book['name'])) {
|
||||
$name = $book['name'];
|
||||
throw new PhutilArgumentUsageException(
|
||||
"Book configuration '{$book_path}' has name '{$name}', but book names ".
|
||||
"must include only lowercase letters and hyphens.");
|
||||
}
|
||||
|
||||
$this->config = $book;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,32 +2,8 @@
|
|||
|
||||
abstract class DivinerWorkflow extends PhutilArgumentWorkflow {
|
||||
|
||||
private $atomCache;
|
||||
|
||||
public function isExecutable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getRoot() {
|
||||
return getcwd();
|
||||
}
|
||||
|
||||
protected function getConfig($key, $default = null) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
protected function getAtomCache() {
|
||||
if (!$this->atomCache) {
|
||||
$cache_directory = $this->getRoot().'/.divinercache';
|
||||
$this->atomCache = new DivinerAtomCache($cache_directory);
|
||||
}
|
||||
return $this->atomCache;
|
||||
}
|
||||
|
||||
protected function log($message) {
|
||||
$console = PhutilConsole::getConsole();
|
||||
$console->getServer()->setEnableLog(true);
|
||||
$console->writeLog($message."\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
4
src/docs/book/user.book
Normal file
4
src/docs/book/user.book
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name" : "phabricator",
|
||||
"root" : "../../../"
|
||||
}
|
Loading…
Reference in a new issue