From 7d44c419c44b03a8c99ade25f60f74a43c66879b Mon Sep 17 00:00:00 2001 From: Inhere Date: Tue, 14 Mar 2023 14:42:50 +0800 Subject: [PATCH] :necktie: up: update some git and doc commands logic --- app/Common/CmdRunner.php | 12 ++ app/Console/Command/DocCommand.php | 23 ++- app/Console/Command/LinuxCommand.php | 2 +- app/Console/Command/ToolCommand.php | 2 + app/Console/Component/Clipboard.php | 181 +----------------- app/Console/Controller/JsonController.php | 28 ++- app/Console/Controller/StringController.php | 90 ++++++--- .../SubCmd/GitlabCmd/ResolveConflictCmd.php | 2 +- .../SubCmd/GitxCmd/AddCommitPushCmd.php | 42 ++-- app/Helper/KiteUtil.php | 25 +++ app/Lib/Parser/Text/TextParser.php | 30 ++- 11 files changed, 209 insertions(+), 228 deletions(-) diff --git a/app/Common/CmdRunner.php b/app/Common/CmdRunner.php index af15ad8..e7e2f3c 100644 --- a/app/Common/CmdRunner.php +++ b/app/Common/CmdRunner.php @@ -3,6 +3,7 @@ namespace Inhere\Kite\Common; use RuntimeException; +use Toolkit\Cli\Cli; use Toolkit\Cli\Color; use Toolkit\Sys\Cmd\AbstractCmdBuilder; use function is_array; @@ -153,6 +154,17 @@ public function batch(array $commands): self return $this; } + /** + * @param string $subCmd + * @param ...$args + * + * @return $this + */ + public function git(string $subCmd, ...$args): self + { + return $this->add(Cli::toCmdline($args, "git $subCmd")); + } + /** * @param string $cmdTpl * @param mixed ...$args diff --git a/app/Console/Command/DocCommand.php b/app/Console/Command/DocCommand.php index 103c668..f7be4ac 100644 --- a/app/Console/Command/DocCommand.php +++ b/app/Console/Command/DocCommand.php @@ -21,7 +21,9 @@ use Toolkit\Cli\Color; use Toolkit\PFlag\FlagType; use Toolkit\Sys\Proc\ProcWrapper; +use function array_keys; use function array_pop; +use function count; use function dirname; use function implode; use function rtrim; @@ -79,6 +81,7 @@ protected function configure(): void $fs->addOpt('lang', '', 'use the language for find topic document', FlagType::STRING, false, $lang); $fs->addOpt('create', '', 'create an new topic document', FlagType::BOOL); + $fs->addOpt('config', '', 'show config for document settings', FlagType::BOOL); $fs->addOpt('cat', '', 'see the document file contents', FlagType::BOOL); $fs->addOpt('edit', 'e', 'edit an topic document', FlagType::BOOL); $fs->addOpt('editor', '', 'editor for edit the topic document', FlagType::STRING, false, 'vim'); @@ -120,7 +123,7 @@ private function prepareManDoc(): Document } /** - * @param Input $input + * @param Input $input * @param Output $output */ protected function execute(Input $input, Output $output): void @@ -135,6 +138,18 @@ protected function execute(Input $input, Output $output): void return; } + $fs = $this->flags; + if ($fs->getOpt('config')) { + $tNames = array_keys($man->getTopicNames()); + $total = count($tNames); + $output->aList([ + 'Language' => $man->getLang(), + 'Docs paths' => $man->getPaths(), + "Topic names(total: $total)" => $tNames, + ]); + return; + } + $this->topName = $this->flags->getArg('top'); $this->subNames = $this->flags->getArg('subs', []); @@ -190,8 +205,8 @@ protected function execute(Input $input, Output $output): void /** * @param Document $doc - * @param Output $output - * @param string $nameString + * @param Output $output + * @param string $nameString */ private function createTopic(Document $doc, Output $output, string $nameString): void { @@ -235,7 +250,7 @@ private function editTopic(DocTopic $topic): void /** * @param Document $man - * @param string $nameString + * @param string $nameString */ private function listTopicInfo(Document $man, string $nameString): void { diff --git a/app/Console/Command/LinuxCommand.php b/app/Console/Command/LinuxCommand.php index b73a47b..7cbbeb2 100644 --- a/app/Console/Command/LinuxCommand.php +++ b/app/Console/Command/LinuxCommand.php @@ -6,7 +6,6 @@ use Inhere\Console\IO\Input; use Inhere\Console\IO\Output; use Toolkit\PFlag\FlagsParser; -use Toolkit\PFlag\Validator\EnumValidator; /** * class LinuxCommand @@ -54,5 +53,6 @@ protected function configFlags(FlagsParser $fs): void protected function execute(Input $input, Output $output) { // TODO: Implement execute() method. + $output->info('TODO'); } } diff --git a/app/Console/Command/ToolCommand.php b/app/Console/Command/ToolCommand.php index 7547512..078c0ac 100644 --- a/app/Console/Command/ToolCommand.php +++ b/app/Console/Command/ToolCommand.php @@ -12,6 +12,7 @@ use Inhere\Console\Command; use Inhere\Console\IO\Input; use Inhere\Console\IO\Output; +use Inhere\Kite\Console\SubCmd\GitxCmd\GitEmojiCmd; use Inhere\Kite\Console\SubCmd\OpenCmd; use Inhere\Kite\Console\SubCmd\ToolCmd\BatchCommand; use Inhere\Kite\Console\SubCmd\ToolCmd\CatCommand; @@ -49,6 +50,7 @@ protected function subCommands(): array CatCommand::class, FindCommand::class, SearchCommand::class, + GitEmojiCmd::class, ]; } diff --git a/app/Console/Component/Clipboard.php b/app/Console/Component/Clipboard.php index 3aada32..9650d59 100644 --- a/app/Console/Component/Clipboard.php +++ b/app/Console/Component/Clipboard.php @@ -2,191 +2,12 @@ namespace Inhere\Kite\Console\Component; -use Toolkit\Stdlib\Obj\AbstractObj; -use Toolkit\Stdlib\OS; -use Toolkit\Sys\Exec; -use function addslashes; -use function file_put_contents; -use function tempnam; - /** * Class Clipboard * * @package Inhere\Kite\Helper */ -class Clipboard extends AbstractObj +class Clipboard extends \Toolkit\Sys\Tool\Clipboard { - public const WRITER_ON_MAC = 'pbcopy'; - public const WRITER_ON_WIN = 'clip'; - public const WRITER_ON_LINUX = 'xsel'; - - public const READER_ON_MAC = 'pbpaste'; - public const READER_ON_WIN = 'clip'; - public const READER_ON_LINUX = 'xclip'; - - /** - * @var string - */ - private string $writerApp; - - /** - * @var string - */ - private string $readerApp; - - /** - * @return string - */ - public static function readAll(): string - { - return (new self())->read(); - } - - /** - * @param string $text - * - * @return bool - */ - public static function writeString(string $text): bool - { - return (new self())->write($text); - } - - public function __construct() - { - parent::__construct(); - - $this->writerApp = $this->getWriterByOS(); - $this->readerApp = $this->getReaderByOS(); - } - - /** - * @param string $contents - * @param bool $addSlashes - * - * @return bool - */ - public function write(string $contents, bool $addSlashes = false): bool - { - $program = $this->writerApp; - if (!$program) { - return false; - } - - // $contents = trim($contents); - if ($addSlashes) { - $contents = addslashes($contents); - } - - // $contents = str_replace("\n", " \\\n", $contents); - $multiLine = str_contains($contents, "\n"); - - // linux: - // # Copy input to clipboard - // echo -n "$input" | xclip -selection c - // Mac: - // echo hello | pbcopy - // pbcopy < tempfile.txt - if ($multiLine) { - $file = tempnam(OS::tempDir(), "tmp_"); - - // File::write($contents, $file); - file_put_contents($file, $contents); - $command = "$program < $file"; - } else { - $command = "echo $contents | $program"; - } - - $result = Exec::auto($command); - return (int)$result['status'] === 0; - } - - /** - * @return string - */ - public function read(): string - { - $program = $this->readerApp; - if (!$program) { - return ''; - } - - $result = Exec::auto($program); - - return $result['output']; - } - - /** - * @param string $file - * - * @return bool - */ - public function readToFile(string $file): bool - { - $program = $this->readerApp; - if (!$program) { - return false; - } - - // Mac: pbpaste >> tasklist.txt - $result = Exec::auto("$program >> $file"); - - return (int)$result['status'] === 0; - } - - /** - * @return string - */ - protected function getWriterByOS(): string - { - if (OS::isWindows()) { - return self::WRITER_ON_WIN; - } - - if (OS::isMac()) { - return self::WRITER_ON_MAC; - } - - if (OS::isLinux()) { - return self::WRITER_ON_LINUX; - } - - return ''; - } - - /** - * @return string - */ - protected function getReaderByOS(): string - { - if (OS::isWindows()) { - return self::READER_ON_WIN; - } - - if (OS::isMac()) { - return self::READER_ON_MAC; - } - - if (OS::isLinux()) { - return self::READER_ON_LINUX; - } - - return ''; - } - - /** - * @return string - */ - public function getReaderApp(): string - { - return $this->readerApp; - } - /** - * @return string - */ - public function getWriterApp(): string - { - return $this->writerApp; - } } diff --git a/app/Console/Controller/JsonController.php b/app/Console/Controller/JsonController.php index e54382e..42c81c5 100644 --- a/app/Console/Controller/JsonController.php +++ b/app/Console/Controller/JsonController.php @@ -33,10 +33,10 @@ use function is_scalar; use function is_string; use function json_decode; +use function preg_replace; use function str_contains; use function str_replace; use function str_starts_with; -use function stripslashes; use function trim; use const JSON_THROW_ON_ERROR; @@ -151,7 +151,7 @@ private function autoReadJSON(string $source): void */ public function loadCommand(FlagsParser $fs, Output $output): void { - $ext = '.json'; + $ext = '.json'; $json = ContentsAutoReader::readFrom($fs->getArg('source'), [ 'suffix' => $ext, ]); @@ -273,6 +273,7 @@ public function searchCommand(FlagsParser $fs, Output $output): void * * @options * --uq, --unquote bool;unquote input string before format. + * --simple bool; simple split to multi line, not use json_decode * * @arguments * json The json text line. allow: @load, @clipboard, @stdin @@ -287,8 +288,29 @@ public function prettyCommand(FlagsParser $fs, Output $output): void 'loadedFile' => $this->dumpfile, ]); + if ($fs->getOpt('simple')) { + $output->writeRaw(str_replace(',', ",\n", $json)); + return; + } + if ($fs->getOpt('unquote')) { - $json = stripslashes($json); + $regexMap = [ + '#"\{"#' => '{"', + '#:"\[#' => ':[', + '#"\[\{"#' => '[{"', + '#\}\]"#' => '}]', + '#\}"#' => '}', + '#\]"#' => ']', + '#\\\\+#' => '', + ]; + $output->aList($regexMap, 'regex map', [ + 'sepChar' => ' => ', + ]); + + foreach ($regexMap as $pattern => $replace) { + $json = preg_replace($pattern, $replace, $json); + } + // $output->writeRaw(str_replace(',', ",\n", $json)); } // $data = json_decode($json, true); diff --git a/app/Console/Controller/StringController.php b/app/Console/Controller/StringController.php index 80f85e7..5047363 100644 --- a/app/Console/Controller/StringController.php +++ b/app/Console/Controller/StringController.php @@ -32,14 +32,17 @@ use Toolkit\Stdlib\Arr; use Toolkit\Stdlib\Json; use Toolkit\Stdlib\Str; +use function array_combine; use function array_pad; use function array_shift; use function count; use function explode; use function implode; use function is_file; +use function preg_replace; use function str_contains; use function str_replace; +use function str_split; use function strlen; use function substr; use function trim; @@ -71,13 +74,13 @@ public static function aliases(): array protected static function commandAliases(): array { return [ - 'join' => ['implode', 'j'], - 'split' => ['s'], - 'process' => ['p', 'filter', 'f'], - 'replace' => ['r'], - 'parse' => ['fields'], - 'length' => ['len', 'ln', 'count'], - ]; + 'join' => ['implode', 'j'], + 'split' => ['s'], + 'process' => ['p', 'filter', 'f'], + 'replace' => ['r'], + 'parse' => ['fields'], + 'length' => ['len', 'ln', 'count'], + ]; } protected function init(): void @@ -181,11 +184,12 @@ public function joinCommand(FlagsParser $fs): void * input '@FILEPATH' - will read from the filepath * * @options - * -s, --sep The separator char. defaults is an SPACE. - * --join-sep The sep char for join all items for output. defaults: NL - * -f, --filter array;apply there filters for each substr. - * allow: - * - wrap eg `wrap:'` wrap char(') for each item + * -s, --sep The separator char. defaults is an SPACE. + * --len, --length int;Split by length. + * --join-sep The sep char for join all items for output. defaults: NL + * -f, --filter array;apply there filters for each substr. + * allow: + * - wrap eg `wrap:'` wrap char(') for each item * * @param FlagsParser $fs * @@ -199,10 +203,16 @@ public function splitCommand(FlagsParser $fs): void $text = trim($fs->getArg('text')); $text = ContentsAutoReader::readFrom($text); - $sep = $fs->getOpt('sep', ' '); - $sep = KiteUtil::resolveSep($sep); + $len = $fs->getOpt('length'); + if ($len > 0) { + $items = str_split($text, $len); + } else { + $sep = $fs->getOpt('sep', ' '); + $sep = KiteUtil::resolveSep($sep); + + $items = explode($sep, $text); + } - $items = explode($sep, $text); if ($filters = $fs->getOpt('filter')) { foreach ($items as &$item) { $item = $this->applyFilters($item, $filters); @@ -390,12 +400,14 @@ public function processCommand(FlagsParser $fs, Output $output): void * input '@FILEPATH' - will read from the filepath * * @options - * -f, -s, --from The replace from chars - * -t, --to The replace to chars + * -f, --from array;The replace from chars + * -t, --to array;The replace to chars * --rm, --remove array;Want remove some chars, allow multi + * --regex bool; mark the from is regex expr string. * * @param FlagsParser $fs * @param Output $output + * * @example * {binWithCmd} -f '"' 'a "abc" "abc"' # Output: a abc abc */ @@ -416,9 +428,26 @@ public function replaceCommand(FlagsParser $fs, Output $output): void return; } - $from = TextParser::resolveSep($from); - $to = TextParser::resolveSep($to); - $output->writeRaw(str_replace($from, $to, $text)); + if ($fs->getOpt('regex')) { + $output->aList(array_combine($from, $to), 'regex map'); + foreach ($from as $i => $pattern) { + $text = preg_replace($pattern, $to[$i] ?? '', $text); + } + + $output->writeRaw($text); + return; + } + + $search = $replace = []; + foreach ($from as $item) { + $search[] = TextParser::resolveSep($item); + } + foreach ($to as $item) { + $replace[] = TextParser::resolveSep($item); + } + + $output->aList(array_combine($search, $replace), 'replace map'); + $output->writeRaw(str_replace($search, $replace, $text)); } /** @@ -471,10 +500,11 @@ public function parseCommand(FlagsParser $fs, Output $output): void $valueSep = $fs->getOpt('value-sep', ' '); $itemParser = TextParser::charSplitParser($valueSep); // $itemParser = TextItemParser::new($valueSep, $indexes); - break; + break; } $p->setItemParser($itemParser); + $p->setFields($fs->getOptStrAsArray('fields')); $p->parse(); $result = ''; @@ -502,11 +532,11 @@ public function parseCommand(FlagsParser $fs, Output $output): void $result = implode("\n", $rows); break; case 'table': - Table::show($p->getData()); + Table::show($p->getData(true)); $doOutput = false; break; default: - $result = Json::pretty($p->getData()); + $result = Json::pretty($p->getData(true)); break; } @@ -544,6 +574,7 @@ public function caseCommand(FlagsParser $fs, Output $output): void * * @options * --nt, --not-trim bool;dont run trim for input + * -s, --sep Split by the sep char, then count elements * * @arguments * source string;The source code for calc. allow: string, @clipboard;true @@ -553,8 +584,17 @@ public function caseCommand(FlagsParser $fs, Output $output): void */ public function lengthCommand(FlagsParser $fs, Output $output): void { - $source = ContentsAutoReader::readFrom($fs->getArg('source'), []); + $source = ContentsAutoReader::readFrom($fs->getArg('source')); + $trimmed = trim($source); + $output->println("INPUT: $source"); + + if ($sep = $fs->getOpt('sep')) { + $list = Str::explode($trimmed, $sep); + $count = count($list); + } else { + $count = strlen($trimmed); + } - $output->colored('Length: ' . strlen(trim($source))); + $output->colored('Length: ' . $count); } } diff --git a/app/Console/SubCmd/GitlabCmd/ResolveConflictCmd.php b/app/Console/SubCmd/GitlabCmd/ResolveConflictCmd.php index 98a5c64..d148f5b 100644 --- a/app/Console/SubCmd/GitlabCmd/ResolveConflictCmd.php +++ b/app/Console/SubCmd/GitlabCmd/ResolveConflictCmd.php @@ -17,7 +17,7 @@ class ResolveConflictCmd extends Command { protected static string $name = 'resolve'; - protected static string $desc = 'create a new branch for git project'; + protected static string $desc = 'Resolve conflicts preparing for current git branch.'; public static function aliases(): array { diff --git a/app/Console/SubCmd/GitxCmd/AddCommitPushCmd.php b/app/Console/SubCmd/GitxCmd/AddCommitPushCmd.php index ce6e8d7..679c3e3 100644 --- a/app/Console/SubCmd/GitxCmd/AddCommitPushCmd.php +++ b/app/Console/SubCmd/GitxCmd/AddCommitPushCmd.php @@ -6,11 +6,12 @@ use Inhere\Console\IO\Input; use Inhere\Console\IO\Output; use Inhere\Kite\Common\CmdRunner; -use Inhere\Kite\Kite; +use Inhere\Kite\Helper\KiteUtil; use PhpGit\Git; -use Toolkit\Stdlib\Obj\DataObject; +use Toolkit\Stdlib\Str; use function implode; use function sprintf; +use function str_contains; use function strlen; use function trim; @@ -34,17 +35,19 @@ public static function aliases(): array * run git add/commit/push at once command * * @options - * -m, --message string;The commit message text - * --nm, --no-message bool;not input message, write message by git interactive shell. - * --np, --not-push bool;Dont execute git push - * --auto-sign bool;Auto add sign string after message. - * --sign-text Custom setting the sign text. + * -m, --message string;The commit message text + * --nm, --no-message bool;not input message, write message by git interactive shell. + * --np, --not-push bool;Dont execute git push + * --auto-sign bool;Auto add sign string after message. + * --sign-text Custom setting the sign text. + * --template template for commit message + * --nt, --no-template bool;disable template for commit message * * @arguments * files... array;Only add special files * * @help - * commit types: + * Commit types: * build "Build system" * chore "Chore" * ci "CI" @@ -56,6 +59,10 @@ public static function aliases(): array * style "Style" * test "Testing" * + * Template Variables: + * branch - Current branch name + * message - Commit message + * * @param Input $input * @param Output $output * @@ -65,7 +72,11 @@ protected function execute(Input $input, Output $output): void { $fs = $this->flags; - $settings = DataObject::new(Kite::config()->getArray('git')); + // command settings. id like: 'cmd:git:acp' 'cmd:gitlab:acp' + $settings = KiteUtil::getCmdConfig($this->getCommandId()); + if (!$settings->isEmpty()) { + $output->aList($settings->toArray(), "Command Settings"); + } $message = ''; $noMessage = $fs->getOpt('no-message'); @@ -90,11 +101,11 @@ protected function execute(Input $input, Output $output): void $signText = $fs->getOpt('sign-text', $settings->getString('sign-text')); $autoSign = $fs->getOpt('auto-sign', $settings->getBool('auto-sign')); + $template = $fs->getOpt('template', $settings->getString('template')); + $git = Git::new(); // will auto fetch user info by git if ($autoSign && !$signText) { - $git = Git::new(); - $username = $git->config->get('user.name'); $userEmail = $git->config->get('user.email'); // eg "Signed-off-by: inhere " @@ -115,6 +126,15 @@ protected function execute(Input $input, Output $output): void $run->do(true); $run->afterOkDo("git add $added"); if ($message) { + if ($template) { + $template = str_contains($template, '{message}') ? $template : "$template {message}"; + $tplVars = [ + 'message' => $message, + 'branch' => $git->getCurrentBranch(), + ]; + $message = Str::renderVars($template, $tplVars, '{%s}'); + } + if ($signText) { $message .= "\n\nSigned-off-by: $signText"; } diff --git a/app/Helper/KiteUtil.php b/app/Helper/KiteUtil.php index 425f3cd..83f8394 100644 --- a/app/Helper/KiteUtil.php +++ b/app/Helper/KiteUtil.php @@ -5,8 +5,10 @@ use Inhere\Kite\Kite; use PhpPkg\EasyTpl\EasyTemplate; use Toolkit\FsUtil\FS; +use Toolkit\Stdlib\Obj\DataObject; use Toolkit\Stdlib\OS; use Toolkit\Stdlib\Str; +use function array_merge; use function defined; use function dirname; use function in_array; @@ -152,4 +154,27 @@ public static function findPhpUnitConfigFile(string $dir): string return $dir; } + + /** + * command settings. id like: 'cmd:git:acp' 'cmd:gitlab:acp' + * + * @param string $commandId + * @param string $parentKey + * + * @return DataObject + */ + public static function getCmdConfig(string $commandId, string $parentKey = ''): DataObject + { + // command settings. id like: 'cmd:git:acp' 'cmd:gitlab:acp' + $confKey = "cmd:$commandId"; + + if ($parentKey) { + $config = Kite::config()->getArray($parentKey); + $config = array_merge($config, Kite::config()->getArray($confKey)); + } else { + $config = Kite::config()->getArray($confKey); + } + + return DataObject::new($config); + } } diff --git a/app/Lib/Parser/Text/TextParser.php b/app/Lib/Parser/Text/TextParser.php index 3449d9d..5e94cb4 100644 --- a/app/Lib/Parser/Text/TextParser.php +++ b/app/Lib/Parser/Text/TextParser.php @@ -30,10 +30,10 @@ class TextParser public const APPEND = 2; public const DISCARD = 3; - public const NL_CHAR = 'NL'; + public const NL_CHAR = 'NL'; public const SPACE_CHAR = 'SPACE'; - public const NL = "\n"; + public const NL = "\n"; public const SPACE = ' '; /** @@ -71,6 +71,11 @@ class TextParser */ public string $headerSep = "\n###\n"; + /** + * @var true replace TAB to SPACE + */ + private bool $tabToSpace = false; + /** * @var bool */ @@ -186,10 +191,15 @@ public static function newWithParser(string $text, callable $itemParser): self * Class constructor. * * @param string $text + * @param callable|null $setFn = function($p TextParser) {} */ - public function __construct(string $text = '') + public function __construct(string $text = '', callable $setFn = null) { $this->text = $text; + + if ($setFn) { + $setFn($this); + } } /** @@ -264,6 +274,9 @@ public function prepare(): self $this->parseHeaderSettings($header); } + if ($this->tabToSpace) { + $text = str_replace("\t", " ", $text); + } $this->textBody = $text; // fallback: init field number from fields list. @@ -762,4 +775,15 @@ public function getCount(): int { return count($this->data); } + + /** + * @param bool $tabToSpace + * + * @return TextParser + */ + public function setTabToSpace(bool $tabToSpace): self + { + $this->tabToSpace = $tabToSpace; + return $this; + } }