1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-22 06:42:41 +01:00

Show some "arc" help pages through a configurable pager, like "less"

Summary:
Fixes T5420. Some "arc help ..." is long and most similar commands send this kind of output through a pager.

Use a pager in at least some cases.

Test Plan: Ran "arc help land", got pager output. Ran "arc help land | cat", got raw output.

Maniphest Tasks: T5420

Differential Revision: https://secure.phabricator.com/D21327
This commit is contained in:
epriestley 2020-06-07 10:40:17 -07:00
parent a30378a34a
commit b62919f7e4
6 changed files with 86 additions and 7 deletions

View file

@ -125,6 +125,18 @@ final class ArcanistArcConfigurationEngineExtension
array( array(
'["master"]', '["master"]',
)), )),
id(new ArcanistStringListConfigOption())
->setKey('pager')
->setDefaultValue(array())
->setSummary(pht('Default pager command.'))
->setHelp(
pht(
'Specify the pager command to use when displaying '.
'documentation.'))
->setExamples(
array(
'["less", "-R", "--"]',
)),
id(new ArcanistStringConfigOption()) id(new ArcanistStringConfigOption())
->setKey('arc.land.onto-remote') ->setKey('arc.land.onto-remote')
->setSummary(pht('Default list of "onto" remote for "arc land".')) ->setSummary(pht('Default list of "onto" remote for "arc land".'))

View file

@ -20,6 +20,12 @@
*/ */
final class PhutilExecPassthru extends PhutilExecutableFuture { final class PhutilExecPassthru extends PhutilExecutableFuture {
private $stdinData;
public function write($data) {
$this->stdinData = $data;
return $this;
}
/* -( Executing Passthru Commands )---------------------------------------- */ /* -( Executing Passthru Commands )---------------------------------------- */
@ -34,7 +40,15 @@ final class PhutilExecPassthru extends PhutilExecutableFuture {
public function execute() { public function execute() {
$command = $this->getCommand(); $command = $this->getCommand();
$spec = array(STDIN, STDOUT, STDERR); $is_write = ($this->stdinData !== null);
if ($is_write) {
$stdin_spec = array('pipe', 'r');
} else {
$stdin_spec = STDIN;
}
$spec = array($stdin_spec, STDOUT, STDERR);
$pipes = array(); $pipes = array();
$unmasked_command = $command->getUnmaskedString(); $unmasked_command = $command->getUnmaskedString();
@ -81,6 +95,11 @@ final class PhutilExecPassthru extends PhutilExecutableFuture {
$errors)); $errors));
} }
} else { } else {
if ($is_write) {
fwrite($pipes[0], $this->stdinData);
fclose($pipes[0]);
}
$err = proc_close($proc); $err = proc_close($proc);
} }

View file

@ -2,6 +2,17 @@
final class PhutilHelpArgumentWorkflow extends PhutilArgumentWorkflow { final class PhutilHelpArgumentWorkflow extends PhutilArgumentWorkflow {
private $workflow;
public function setWorkflow($workflow) {
$this->workflow = $workflow;
return $this;
}
public function getWorkflow() {
return $this->workflow;
}
protected function didConstruct() { protected function didConstruct() {
$this->setName('help'); $this->setName('help');
$this->setExamples(<<<EOHELP $this->setExamples(<<<EOHELP
@ -29,16 +40,26 @@ EOHELP
$with = $args->getArg('help-with-what'); $with = $args->getArg('help-with-what');
if (!$with) { if (!$with) {
// TODO: Update this to use a pager, too.
$args->printHelpAndExit(); $args->printHelpAndExit();
} else { } else {
$out = array();
foreach ($with as $thing) { foreach ($with as $thing) {
echo phutil_console_format( $out[] = phutil_console_format(
"**%s**\n\n", "**%s**\n\n",
pht('%s WORKFLOW', strtoupper($thing))); pht('%s WORKFLOW', strtoupper($thing)));
echo $args->renderWorkflowHelp($thing, $show_flags = true); $out[] = $args->renderWorkflowHelp($thing, $show_flags = true);
echo "\n"; $out[] = "\n";
}
$out = implode('', $out);
$workflow = $this->getWorkflow();
if ($workflow) {
$workflow->writeToPager($out);
} else {
echo $out;
} }
exit(PhutilArgumentParser::PARSE_ERROR_CODE);
} }
} }

View file

@ -8,7 +8,8 @@ final class ArcanistHelpWorkflow
} }
public function newPhutilWorkflow() { public function newPhutilWorkflow() {
return new PhutilHelpArgumentWorkflow(); return id(new PhutilHelpArgumentWorkflow())
->setWorkflow($this);
} }
public function supportsToolset(ArcanistToolset $toolset) { public function supportsToolset(ArcanistToolset $toolset) {

View file

@ -122,7 +122,7 @@ EOTEXT
return $this->newWorkflowInformation() return $this->newWorkflowInformation()
->setSynopsis(pht('Publish reviewed changes.')) ->setSynopsis(pht('Publish reviewed changes.'))
->addExample(pht('**land** [__options__] [__ref__ ...]')) ->addExample(pht('**land** [__options__] -- [__ref__ ...]'))
->setHelp($help); ->setHelp($help);
} }

View file

@ -2451,4 +2451,30 @@ abstract class ArcanistWorkflow extends Phobject {
return $raw_uri; return $raw_uri;
} }
final public function writeToPager($corpus) {
$is_tty = (function_exists('posix_isatty') && posix_isatty(STDOUT));
if (!$is_tty) {
echo $corpus;
} else {
$pager = $this->getConfig('pager');
if (!$pager) {
$pager = array('less', '-R', '--');
}
// Try to show the content through a pager.
$err = id(new PhutilExecPassthru('%Ls', $pager))
->write($corpus)
->resolve();
// If the pager exits with an error, print the content normally.
if ($err) {
echo $corpus;
}
}
return $this;
}
} }