diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..157ff0c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +vendor/ +composer.lock diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..14ad34e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 minicli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ac6b2c5 --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# commit-calendar + +Display a list of dates and commits from public GitHub repositories. +You will display the list in the terminal, and you can choose to save it to a CSV file (";" separated) and display into a browser (thanks to [itty.bitty](https://itty.bitty.site)) + +Commit Calendar is a CLI utility based on [Minicli](https://github.com/minicli/minicli). + +## Installation + +Requirements: +- `php-cli` >= 7.3 +- Composer + +Installation: + +1. Clone this repository +2. Run `composer install` + +## How to use + +In a terminal, in the project folder: + +```bash +./commit-calendar display owner=OWNER name=NAME [number=NUMBER] +``` + +- OWNER: is the repository owner +- NAME: is the repository name +- NUMBER: the number of commits you want to extract + +For example: from this url https://github.com/dottxado/pico-macro-pad the OWNER is "dottxado" and the name is "pico-macro-pad", resulting in +```bash +./commit-calendar display owner=dottxado name=pico-macro-pad +``` + +While OWNER and NAME are required, and if not given they will be queried by the CLI, NUMBER has a default value of 30. + +## Help +In a terminal, in the project folder: + +```bash +./commit-calendar help +``` +will display the available commands, and + +```bash +./commit-calendar help display +``` +will display the help for the display command. diff --git a/app/.gitkeep b/app/.gitkeep new file mode 100644 index 0000000..9c558e3 --- /dev/null +++ b/app/.gitkeep @@ -0,0 +1 @@ +. diff --git a/app/Command/Display/DefaultController.php b/app/Command/Display/DefaultController.php new file mode 100644 index 0000000..f5fb584 --- /dev/null +++ b/app/Command/Display/DefaultController.php @@ -0,0 +1,182 @@ +numberOfResults = 30; + $this->perPage = 30; + $this->userInput = new Input('CommitCalendar$> '); + } + + public function handle(): void + { + $owner = $this->owner(); + $name = $this->name(); + $this->number(); + + $pages = ceil($this->numberOfResults / $this->perPage); + + $this->getPrinter()->info(sprintf('Your input -> OWNER %s and NAME %s', $owner, $name)); + $this->getPrinter()->info(sprintf('Total number of results to get: %s', $this->numberOfResults)); + + $output = []; + for ($i = 1; $i <= $pages; $i++) { + $numberOfResults = ($this->perPage * $i) <= $this->numberOfResults + ? $this->perPage + : $this->numberOfResults % $this->perPage; + $this->getPrinter()->info(sprintf('Querying GitHub for %s results...', $numberOfResults)); + /** + * @var GithubService + */ + $githubService = $this->getApp()->github; + $output = array_merge($output, $githubService->getCommitList($owner, $name, $i, $numberOfResults) ?? []); + } + + if (is_null($output)) { + $this->getPrinter()->error('Ooooops, something has gone bad'); + exit; + } elseif (empty($output)) { + $this->getPrinter()->error('Ooooops, the result is empty!'); + exit; + } + + $this->displayTable($output); + $this->saveToFile($output); + $this->displayInBrowser($output, $owner, $name); + + $this->getPrinter()->success('Bye!'); + $this->getPrinter()->newline(); + } + + private function owner(): string + { + if ($this->hasParam('owner')) { + $owner = $this->getParam('owner'); + } else { + $this->getPrinter()->info('Provide the owner of the repository:'); + $owner = $this->userInput->read(); + } + return $owner; + } + + private function name(): string + { + if ($this->hasParam('name')) { + $name = $this->getParam('name'); + } else { + $this->getPrinter()->info('Provide the name of the repository:'); + $name = $this->userInput->read(); + } + return $name; + } + + private function number() + { + if ($this->hasParam('number') && ! is_null($this->getParam('number'))) { + $this->numberOfResults = (int)$this->getParam('number'); + } + } + + private function displayTable(array $list): void + { + $table = new TableHelper(); + $table->addHeader(['Date', 'Message']); + foreach ($list as $element) { + $date = $element->commit->author->date ?? ''; + $message = isset($element->commit->message) + ? str_replace("\n", ' ', trim($element->commit->message)) + : ''; + $table->addRow([$date, $message]); + } + $this->getPrinter()->newline(); + $this->getPrinter()->rawOutput($table->getFormattedTable(new ColorOutputFilter())); + $this->getPrinter()->newline(); + } + + private function saveToFile(array $list): void + { + $this->getPrinter()->display('Do you want it saved to a CSV file?[Y/n]', true); + $logToFile = $this->userInput->read(); + if (strtolower($logToFile) === 'y' || $logToFile === '') { + $this->getPrinter()->display('Full path and filename?[./commitcalendar.csv]', true); + $filePath = $this->userInput->read(); + if ($filePath === '') { + $filePath = 'commitcalendar.csv'; + } + $backupOutput = $this->getApp()->getPrinter(); + $this->getApp()->setOutputHandler(new OutputHandler(new FilePrinterAdapter($filePath))); + $content = $this->generateCsv($list); + $this->getPrinter()->rawOutput($content); + $this->getApp()->setOutputHandler($backupOutput); + } + } + + private function displayInBrowser(array $list, string $owner, string $name): void + { + $this->getPrinter()->display('Do you want to see it in a browser? (It may not work if the data are > 2Kb)[Y/n]', true); + $generateHtml = $this->userInput->read(); + if (strtolower($generateHtml) === 'y' || $generateHtml === '') { + $link = shell_exec( + 'echo -n "' + .$this->generateHtml($list, $owner, $name) + .'" | lzma -9 | base64 | xargs -0 printf "https://itty.bitty.site/#/%s\n"' + ); + $this->getPrinter()->info('Copy this link to your browser'); + $this->getPrinter()->rawOutput($link); + } + } + + private function generateHtml(array $list, string $owner, string $name): string + { + $pageTemplate = '
Date | Message |
---|