├── .editorconfig ├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── anonfiles ├── app ├── Anonfiles │ └── Anonfiles.php ├── Commands │ ├── .gitkeep │ ├── DownloadCommand.php │ └── UploadCommand.php └── Providers │ └── AppServiceProvider.php ├── bootstrap └── app.php ├── box.json ├── builds └── anonfiles ├── composer.json ├── composer.lock ├── config ├── anonfiles.php ├── app.php ├── commands.php ├── logo.php └── updater.php ├── phpstan.neon ├── phpunit.xml.dist └── tests ├── CreatesApplication.php ├── Feature └── InspiringCommandTest.php ├── Pest.php ├── TestCase.php └── Unit └── ExampleTest.php /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.yml] 15 | indent_style = space 16 | indent_size = 2 17 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | /.github export-ignore 3 | .styleci.yml export-ignore 4 | .scrutinizer.yml export-ignore 5 | BACKERS.md export-ignore 6 | CONTRIBUTING.md export-ignore 7 | CHANGELOG.md export-ignore 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | /.idea 3 | /.vscode 4 | /.vagrant 5 | .phpunit.result.cache 6 | test/ 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Albin Varghese 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Anonfiles CLI


2 |

3 | 4 | logo 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 |

13 | 14 | ## Table of Contents 15 | 16 | - [Introduction](#introduction) 17 | - [Features](#features) 18 | - [Installation](#installation) 19 | - [Contributing](#contributing) 20 | - [License](#license) 21 | 22 | ## Introduction 23 | 24 | Anon Files CLI can upload and download files from anonfiles.com API within your command line interface. 25 | 26 | ## Features 27 | 28 | - Upload your files directly from CLI. 29 | - Rename before uploading. 30 | - Download your files directly to a specified folder. 31 | 32 | ## Installation 33 | 34 | - download the phar file to your machine. 35 | 36 | ##### using CURL 37 | 38 | ```curl 39 | curl -s https://github.com/albinvar/anonfiles-cli/raw/main/builds/anonfiles -o anonfiles 40 | 41 | ``` 42 | ##### using wget 43 | ```wget 44 | wget https://github.com/albinvar/anonfiles-cli/raw/main/builds/anonfiles -O anonfiles 45 | ``` 46 | 47 | ##### composer 48 | Remember, installing with composer requires each and every libraries to be downloaded first. 49 | 50 | ``` 51 | composer global require albinvar/anonfiles-cli 52 | ``` 53 | 54 | ## Usage 55 | 56 | Using anonfiles CLI is very simple. 57 | 58 | its better to include the cli to your bin of your specified OS. 59 | 60 | ``` 61 | php anonfiles 62 | ``` 63 | 64 | ##### Upload a file 65 | 66 | ``` 67 | php anonfiles upload image.jpeg 68 | ``` 69 | 70 | you can also upload your files through socks5 proxy. by default its configured at `socks5h://127.0.0.1:9050`. It will be customisable in future updates. 71 | 72 | you may now upload the files using `--tor` option. 73 | 74 | ``` 75 | php anonfiles upload folder/image.jpeg --tor 76 | ``` 77 | 78 | 79 | ##### Download a file 80 | 81 | downloading a file is simple, 82 | 83 | ``` 84 | php anonfiles download https://anonfiles.com/u1C0ebc4b0 85 | ``` 86 | 87 | - the link should be only from anonfiles.com 88 | 89 | you may use `--path` option to change your download path. 90 | 91 | ``` 92 | php anonfiles download https://anonfiles.com/u1C0ebc4b0 --path="/sdcard/downloads" 93 | ``` 94 | 95 | similarly, you can also download your files using tor socks proxy using `--tor` option. 96 | 97 | ``` 98 | php anonfiles download https://anonfiles.com/u1C0ebc4b0 --tor 99 | ``` 100 | 101 | ## Contributing 102 | 103 | Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. 104 | 105 | Please make sure to update tests as appropriate. 106 | 107 | ## License 108 | 109 | The project is certified using [MIT License](LICENSE) 110 | -------------------------------------------------------------------------------- /anonfiles: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 34 | 35 | $status = $kernel->handle( 36 | $input = new Symfony\Component\Console\Input\ArgvInput, 37 | new Symfony\Component\Console\Output\ConsoleOutput 38 | ); 39 | 40 | /* 41 | |-------------------------------------------------------------------------- 42 | | Shutdown The Application 43 | |-------------------------------------------------------------------------- 44 | | 45 | | Once Artisan has finished running, we will fire off the shutdown events 46 | | so that any final work may be done by the application before we shut 47 | | down the process. This is the last thing to happen to the request. 48 | | 49 | */ 50 | 51 | $kernel->terminate($input, $status); 52 | 53 | exit($status); 54 | -------------------------------------------------------------------------------- /app/Anonfiles/Anonfiles.php: -------------------------------------------------------------------------------- 1 | output = new \Symfony\Component\Console\Output\ConsoleOutput(); 38 | } 39 | 40 | public function logo($name = 'Anonfiles CLI', $type = null, $font = null): void 41 | { 42 | $name = is_null($name) ? config('logo.name') : $name; 43 | $font = is_null($font) ? config('logo.font') : $font; 44 | $figlet = new Figlet(); 45 | $logo = $figlet->setFont($font)->render($name); 46 | 47 | switch ($type) { 48 | case 'info': 49 | $this->info($logo); 50 | break; 51 | case 'error': 52 | $this->error($logo); 53 | break; 54 | case 'comment': 55 | $this->comment($logo); 56 | break; 57 | case 'question': 58 | $this->question($logo); 59 | break; 60 | default: 61 | $this->line($logo); 62 | break; 63 | 64 | } 65 | } 66 | 67 | public function clear(): mixed 68 | { 69 | return system('clear'); 70 | } 71 | 72 | public function setFile($file): void 73 | { 74 | $this->file = $file; 75 | $this->path = $this->disk->path($file); 76 | $this->getMetaData(); 77 | } 78 | 79 | public function createDisk() 80 | { 81 | try { 82 | $this->disk = Storage::build(['driver' => 'local', 'root' => getcwd()]); 83 | return true; 84 | } catch (\Exception $e) { 85 | return false; 86 | } 87 | } 88 | 89 | public function getFilename() 90 | { 91 | if (! is_null($this->newFilename)) { 92 | return $this->newFilename; 93 | } 94 | return basename($this->path); 95 | } 96 | 97 | public function validate(): void 98 | { 99 | } 100 | 101 | public function getSize() 102 | { 103 | return $this->diffForHumans($this->fileSize); 104 | } 105 | 106 | public function getLastModified() 107 | { 108 | return date('m/d/Y H:i:s', $this->fileLastModified); 109 | } 110 | 111 | public function checkIfFileExists($pathToFile) 112 | { 113 | if ($this->disk->exists($pathToFile)) { 114 | return true; 115 | } 116 | 117 | return false; 118 | } 119 | 120 | public function diffForHumans($bytes, $dec = 2) 121 | { 122 | $size = config('anonfiles.STORAGE_UNITS'); 123 | 124 | $factor = floor((strlen(strval($bytes)) - 1) / 3); 125 | return sprintf("%.{$dec}f", $bytes / pow(1024, $factor)) . @$size[$factor]; 126 | } 127 | 128 | public function checkIfCanConnectToSocksProxy(): bool 129 | { 130 | try { 131 | $this->client->request('GET', 'http://checkip.amazonaws.com/', $this->getSettings(true)); 132 | return true; 133 | } catch (\Exception $e) { 134 | return false; 135 | } 136 | } 137 | 138 | public function getSettings($proxy = false) 139 | { 140 | return $proxy === true ? ['proxy' => static::$proxy] 141 | : []; 142 | } 143 | 144 | public function upload($filename = null, $proxy = false): void 145 | { 146 | $this->newFilename = $filename; 147 | 148 | $this->client = new Client(['http_error' => false, 'progress' => function ( 149 | $downloadTotal, 150 | $downloadedBytes, 151 | $uploadTotal, 152 | $uploadedBytes 153 | ): void { 154 | $res = curl_getinfo($downloadTotal); 155 | echo "\033[5D"; 156 | $msg = $this->diffForHumans($res['size_upload']) . ' / ' . $this->diffForHumans($res['upload_content_length']); 157 | echo " 📂 Progress : {$msg} \r"; 158 | }, 159 | ]); 160 | 161 | if ($proxy === true && $this->checkIfCanConnectToSocksProxy() === false) { 162 | $this->error('Cannot connect to tor proxy, please start tor on your device.'); 163 | exit(1); 164 | } 165 | 166 | try { 167 | $resource = $this->disk->get($this->file); 168 | 169 | $stream = Psr7\stream_for($resource); 170 | 171 | $request = new Request( 172 | 'POST', 173 | config('anonfiles.UPLOAD_ENDPOINT'), 174 | $this->getSettings($proxy), 175 | new Psr7\MultipartStream( 176 | [ 177 | [ 178 | 'name' => 'file', 179 | 'contents' => $stream, 180 | 'filename' => $this->getFilename(), 181 | ], 182 | ] 183 | ) 184 | ); 185 | 186 | $this->response = $this->client->send($request, $this->getSettings($proxy)); 187 | } catch (\GuzzleHttp\Exception\RequestException $e) { 188 | } 189 | } 190 | 191 | public function download($link = null, $pathToFile = null, $proxy = false): mixed 192 | { 193 | try { 194 | $this->client = new Client(['http_error' => false, 'progress' => function ( 195 | $downloadTotal, 196 | $downloadedBytes, 197 | $uploadTotal, 198 | $uploadedBytes 199 | ): void { 200 | echo "\033[5D"; 201 | $msg = $this->diffForHumans($uploadTotal) . ' / ' . $this->diffForHumans($downloadedBytes); 202 | echo " 📥 Progress : {$msg} \r"; 203 | }, 204 | ]); 205 | 206 | if ($proxy === true && $this->checkIfCanConnectToSocksProxy() === false) { 207 | $this->error('Cannot connect to tor proxy, please start tor on your device.'); 208 | exit(1); 209 | } 210 | 211 | $resource = fopen($pathToFile, 'w'); 212 | 213 | $stream = Psr7\stream_for($resource); 214 | 215 | $array = ['save_to' => $stream]; 216 | $array += $this->getSettings($proxy); 217 | 218 | $this->response = $this->client->request('GET', $link, $array); 219 | } catch (\Exception $e) { 220 | return false; 221 | } 222 | return true; 223 | } 224 | 225 | public function getResponse() 226 | { 227 | return isset($this->response) ? json_decode($this->response->getBody()->getContents()) : null; 228 | } 229 | 230 | public function getDownloadLink($link = null) 231 | { 232 | $dom = new DOMDocument(); 233 | $dom->loadHTML(file_get_contents($link)); 234 | return $dom->getElementById('download-url')->getAttribute('href'); 235 | } 236 | 237 | private function getMetadata(): void 238 | { 239 | $this->fileLastModified = $this->disk->lastModified($this->file); 240 | $this->fileSize = $this->disk->size($this->file); 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /app/Commands/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/albinvar/anonfiles-cli/20c1a1e1f5325497124f45a4abbcb6598ef4be68/app/Commands/.gitkeep -------------------------------------------------------------------------------- /app/Commands/DownloadCommand.php: -------------------------------------------------------------------------------- 1 | anonfiles = new Anonfiles(); 57 | } 58 | 59 | /** 60 | * Execute the console command. 61 | */ 62 | public function handle(): void 63 | { 64 | // show logo. 65 | $this->anonfiles->logo('Anonfiles', 'comment'); 66 | 67 | // create new disk instance. 68 | $this->anonfiles->createDisk(); 69 | 70 | $this->link = $this->argument('link'); 71 | 72 | $this->downloadPath = is_null($this->option('path')) ? getcwd() : $this->option('path'); 73 | 74 | $this->info(" Selected URL : {$this->link}"); 75 | 76 | $this->newLine(); 77 | 78 | if (! $this->validate()) { 79 | $this->showMetaData(); 80 | } 81 | } 82 | 83 | public function getMetaData() 84 | { 85 | $code = $this->getUniqueCode(); 86 | $response = Http::acceptJson()->get("https://api.anonfiles.com/v2/file/{$code}/info"); 87 | return $response->object(); 88 | } 89 | 90 | public function showMetaData() 91 | { 92 | $this->fileData = $this->parseUrl()->getMetaData(); 93 | 94 | if ($this->fileData->status === false) { 95 | $this->newLine(); 96 | $this->error('File Not Found..!!!'); 97 | return 1; 98 | } 99 | 100 | $headers = ['Properties', 'Values']; 101 | 102 | $data = [ 103 | ['filename', $this->fileData->data->file->metadata->name], 104 | ['url', $this->fileData->data->file->url->full], 105 | ['size', $this->fileData->data->file->metadata->size->readable], 106 | ]; 107 | 108 | $this->table($headers, $data); 109 | 110 | if ($this->confirm('Are you sure you want to Download this file?', true)) { 111 | $this->downloadLink = $this->anonfiles->getDownloadLink($this->link); 112 | 113 | $this->parseDownloadLink(); 114 | 115 | $status = $this->anonfiles->download($this->downloadLink, $this->downloadPath .'/'. $this->downloadFilename, $this->option('tor')); 116 | 117 | if ($status) { 118 | $this->newline(); 119 | $this->newline(); 120 | $this->comment(' File downloaded ✅'); 121 | $this->newline(); 122 | return 0; 123 | } 124 | $this->error = ' Downloading failed...'; 125 | return 1; 126 | } 127 | } 128 | 129 | /** 130 | * Define the command's schedule. 131 | */ 132 | public function schedule(Schedule $schedule): void 133 | { 134 | // $schedule->command(static::class)->everyMinute(); 135 | } 136 | 137 | private function validate() 138 | { 139 | $this->status = []; 140 | 141 | $this->task('checking if url is valid', function () { 142 | $url = filter_var($this->link, FILTER_SANITIZE_URL); 143 | 144 | if (filter_var($url, FILTER_VALIDATE_URL) !== false && strpos($this->link, 'anonfiles.com') !== false) { 145 | $this->status[] = true; 146 | return true; 147 | } 148 | $this->status[] = false; 149 | return false; 150 | }); 151 | 152 | //end process 153 | return in_array(false, $this->status) ? 1 : 0; 154 | } 155 | 156 | private function parseUrl() 157 | { 158 | $this->parsed = parse_url($this->link); 159 | $this->parsed['params'] = explode('/', $this->parsed['path']); 160 | return $this; 161 | } 162 | 163 | private function parseDownloadLink() 164 | { 165 | $this->parsedDownloadLink = parse_url($this->downloadLink); 166 | $this->parsedDownloadLink['params'] = explode('/', $this->parsedDownloadLink['path']); 167 | $keyOfLastElement = key(array_slice($this->parsedDownloadLink['params'], -1, 1, true)); 168 | $this->downloadFilename = $this->parsedDownloadLink['params'][$keyOfLastElement]; 169 | return $this; 170 | } 171 | 172 | private function getUniqueCode() 173 | { 174 | return $this->parsed['params'][1] ?? null; 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /app/Commands/UploadCommand.php: -------------------------------------------------------------------------------- 1 | anonfiles = new Anonfiles(); 42 | } 43 | 44 | /** 45 | * Execute the console command. 46 | */ 47 | public function handle(): mixed 48 | { 49 | // show logo. 50 | $this->anonfiles->logo('Anonfiles', 'comment'); 51 | 52 | // create new disk instance. 53 | $this->anonfiles->createDisk(); 54 | 55 | $this->file = $this->argument('filename'); 56 | 57 | // validate the file before uploading. 58 | $this->validate(); 59 | 60 | $this->showFileMetaData(); 61 | 62 | if ($this->confirm('Do you want to rename file before uploading?')) { 63 | $this->setNewFileName(); 64 | } 65 | 66 | if ($this->confirm('Do you want to upload file?', true)) { 67 | try { 68 | $this->anonfiles->upload($this->newFilename, $this->option('tor')); 69 | } catch (\GuzzleHttp\Exception\ConnectException $e) { 70 | $this->error($e->getMessage()); 71 | } catch (\Exception $e) { 72 | $this->error($e->getMessage()); 73 | } 74 | } else { 75 | $this->error('aborting...'); 76 | return 0; 77 | } 78 | 79 | return $this->showResponse(); 80 | } 81 | 82 | public function showResponse(): mixed 83 | { 84 | $json = $this->anonfiles->getResponse(); 85 | 86 | if (! is_null($json) && $json->status) { 87 | $this->comment(' File uploaded ✅'); 88 | $this->newline(); 89 | $this->info(' link : '. $json->data->file->url->full); 90 | $this->newline(); 91 | exit(0); 92 | } 93 | if (! is_null($json) && ! $json->status) { 94 | $this->error("({$json->error->code}) {$json->error->message})"); 95 | exit(1); 96 | } 97 | 98 | $this->error('Uploading failed due to a client-side error...'); 99 | exit(1); 100 | } 101 | 102 | private function setNewFileName(): void 103 | { 104 | $this->newFilename = $this->ask('Enter your new file name'); 105 | } 106 | 107 | private function showFileMetaData(): void 108 | { 109 | $headers = ['Properties', 'Values']; 110 | 111 | $data = [ 112 | ['filename', $this->anonfiles->getFileName()], 113 | ['path', $this->anonfiles->path], 114 | ['size', $this->anonfiles->getSize()], 115 | ['last modified', $this->anonfiles->getLastModified()], 116 | ]; 117 | 118 | $this->table($headers, $data); 119 | } 120 | 121 | private function validate(): void 122 | { 123 | if (! $this->anonfiles->checkIfFileExists($this->file)) { 124 | $this->error("File doesn't exist."); 125 | exit(1); 126 | } 127 | 128 | $this->anonfiles->setFile($this->file); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Console\Kernel::class, 31 | LaravelZero\Framework\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Debug\ExceptionHandler::class, 36 | Illuminate\Foundation\Exceptions\Handler::class 37 | ); 38 | 39 | /* 40 | |-------------------------------------------------------------------------- 41 | | Return The Application 42 | |-------------------------------------------------------------------------- 43 | | 44 | | This script returns the application instance. The instance is given to 45 | | the calling script so we can separate the building of the instances 46 | | from the actual running of the application and sending responses. 47 | | 48 | */ 49 | 50 | return $app; 51 | -------------------------------------------------------------------------------- /box.json: -------------------------------------------------------------------------------- 1 | { 2 | "chmod": "0755", 3 | "directories": [ 4 | "app", 5 | "bootstrap", 6 | "config", 7 | "vendor" 8 | ], 9 | "files": [ 10 | "composer.json" 11 | ], 12 | "exclude-dev-files": false, 13 | "exclude-composer-files": false, 14 | "compression": "GZ", 15 | "compactors": [ 16 | "KevinGH\\Box\\Compactor\\Php", 17 | "KevinGH\\Box\\Compactor\\Json" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /builds/anonfiles: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/albinvar/anonfiles-cli/20c1a1e1f5325497124f45a4abbcb6598ef4be68/builds/anonfiles -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "albinvar/anonfiles-cli", 3 | "description": "The Anonfiles CLI tool", 4 | "keywords": ["anonfiles", "anonfiles-cli", "laravel zero", "console", "cli"], 5 | "homepage": "https://github.com/albinvar/anonfiles-cli", 6 | "type": "project", 7 | "license": "MIT", 8 | "support": { 9 | "issues": "https://github.com/albinvar/anonfiles-cli/issues", 10 | "source": "https://github.com/albinvar/anonfiles-cli" 11 | }, 12 | "authors": [ 13 | { 14 | "name": "Albin Varghese", 15 | "email": "me@albinvar.in" 16 | } 17 | ], 18 | "require": { 19 | "php": "^7.3|^8.0", 20 | "guzzlehttp/guzzle": "^6.5.5", 21 | "illuminate/http": "^8.0", 22 | "laminas/laminas-text": "^2.8", 23 | "laravel-zero/phar-updater": "^1.0.6" 24 | }, 25 | "require-dev": { 26 | "laravel-zero/framework": "^8.8", 27 | "mockery/mockery": "^1.4.3", 28 | "nunomaduro/phpinsights": "^2.0", 29 | "pestphp/pest": "^1.3" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "App\\": "app/", 34 | "Anonfiles\\": "app/Anonfiles/" 35 | } 36 | }, 37 | "autoload-dev": { 38 | "psr-4": { 39 | "Tests\\": "tests/" 40 | } 41 | }, 42 | "config": { 43 | "preferred-install": "dist", 44 | "sort-packages": true, 45 | "optimize-autoloader": true, 46 | "allow-plugins": { 47 | "dealerdirect/phpcodesniffer-composer-installer": true, 48 | "pestphp/pest-plugin": true 49 | } 50 | }, 51 | "minimum-stability": "dev", 52 | "prefer-stable": true, 53 | "bin": ["builds/anonfiles"] 54 | } 55 | -------------------------------------------------------------------------------- /config/anonfiles.php: -------------------------------------------------------------------------------- 1 | 'https://api.anonfiles.com/upload', 15 | 16 | /* 17 | |-------------------------------------------------------------------------- 18 | | Storage units 19 | |-------------------------------------------------------------------------- 20 | | 21 | | The endpoint which the file should be uploaded. 22 | | 23 | */ 24 | 25 | 'STORAGE_UNITS' => [' B', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'], 26 | 27 | ]; 28 | -------------------------------------------------------------------------------- /config/app.php: -------------------------------------------------------------------------------- 1 | 'Anonfiles', 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Application Version 21 | |-------------------------------------------------------------------------- 22 | | 23 | | This value determines the "version" your application is currently running 24 | | in. You may want to follow the "Semantic Versioning" - Given a version 25 | | number MAJOR.MINOR.PATCH when an update happens: https://semver.org. 26 | | 27 | */ 28 | 29 | 'version' => app('git.version'), 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Application Environment 34 | |-------------------------------------------------------------------------- 35 | | 36 | | This value determines the "environment" your application is currently 37 | | running in. This may determine how you prefer to configure various 38 | | services the application utilizes. This can be overridden using 39 | | the global command line "--env" option when calling commands. 40 | | 41 | */ 42 | 43 | 'env' => 'development', 44 | 45 | /* 46 | |-------------------------------------------------------------------------- 47 | | Autoloaded Service Providers 48 | |-------------------------------------------------------------------------- 49 | | 50 | | The service providers listed here will be automatically loaded on the 51 | | request to your application. Feel free to add your own services to 52 | | this array to grant expanded functionality to your applications. 53 | | 54 | */ 55 | 56 | 'providers' => [ 57 | App\Providers\AppServiceProvider::class, 58 | ], 59 | 60 | ]; 61 | -------------------------------------------------------------------------------- /config/commands.php: -------------------------------------------------------------------------------- 1 | NunoMaduro\LaravelConsoleSummary\SummaryCommand::class, 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Commands Paths 21 | |-------------------------------------------------------------------------- 22 | | 23 | | This value determines the "paths" that should be loaded by the console's 24 | | kernel. Foreach "path" present on the array provided below the kernel 25 | | will extract all "Illuminate\Console\Command" based class commands. 26 | | 27 | */ 28 | 29 | 'paths' => [app_path('Commands')], 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Added Commands 34 | |-------------------------------------------------------------------------- 35 | | 36 | | You may want to include a single command class without having to load an 37 | | entire folder. Here you can specify which commands should be added to 38 | | your list of commands. The console's kernel will try to load them. 39 | | 40 | */ 41 | 42 | 'add' => [ 43 | // .. 44 | ], 45 | 46 | /* 47 | |-------------------------------------------------------------------------- 48 | | Hidden Commands 49 | |-------------------------------------------------------------------------- 50 | | 51 | | Your application commands will always be visible on the application list 52 | | of commands. But you can still make them "hidden" specifying an array 53 | | of commands below. All "hidden" commands can still be run/executed. 54 | | 55 | */ 56 | 57 | 'hidden' => [ 58 | NunoMaduro\LaravelConsoleSummary\SummaryCommand::class, 59 | Symfony\Component\Console\Command\HelpCommand::class, 60 | Illuminate\Console\Scheduling\ScheduleRunCommand::class, 61 | Illuminate\Console\Scheduling\ScheduleFinishCommand::class, 62 | Illuminate\Foundation\Console\VendorPublishCommand::class, 63 | ], 64 | 65 | /* 66 | |-------------------------------------------------------------------------- 67 | | Removed Commands 68 | |-------------------------------------------------------------------------- 69 | | 70 | | Do you have a service provider that loads a list of commands that 71 | | you don't need? No problem. Laravel Zero allows you to specify 72 | | below a list of commands that you don't to see in your app. 73 | | 74 | */ 75 | 76 | 'remove' => [ 77 | // .. 78 | ], 79 | 80 | ]; 81 | -------------------------------------------------------------------------------- /config/logo.php: -------------------------------------------------------------------------------- 1 | true, 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Logo Name 21 | |-------------------------------------------------------------------------- 22 | | 23 | | This value determines the text that is rendered for the logo. 24 | | It defaults to the app name, but it can be any other text 25 | | value if the logo should be different to the app name. 26 | | 27 | */ 28 | 'name' => config('app.name'), 29 | 30 | /* 31 | |-------------------------------------------------------------------------- 32 | | Default Font 33 | |-------------------------------------------------------------------------- 34 | | 35 | | This option defines the font which should be used for rendering. 36 | | By default, one default font is shipped. However, you are free 37 | | to download and use additional fonts: http://www.figlet.org. 38 | | 39 | */ 40 | 41 | 'font' => \LaravelZero\Framework\Components\Logo\FigletString::DEFAULT_FONT, 42 | 43 | /* 44 | |-------------------------------------------------------------------------- 45 | | Output Width 46 | |-------------------------------------------------------------------------- 47 | | 48 | | This option defines the maximum width of the output string. This is 49 | | used for word-wrap as well as justification. Be careful when using 50 | | small values, because they may result in an undefined behavior. 51 | | 52 | */ 53 | 54 | 'outputWidth' => 80, 55 | 56 | /* 57 | |-------------------------------------------------------------------------- 58 | | Justification 59 | |-------------------------------------------------------------------------- 60 | | 61 | | This option defines the justification of the logo text. By default, 62 | | justification is provided, which will work well on most of your 63 | | console apps. Of course, you are free to change this value. 64 | | 65 | */ 66 | 67 | 'justification' => null, 68 | 69 | /* 70 | |-------------------------------------------------------------------------- 71 | | Right To Left 72 | |-------------------------------------------------------------------------- 73 | | 74 | | This option defines the option in which the text is written. By, default 75 | | the setting of the font-file is used. When justification is not defined, 76 | | a text written from right-to-left is automatically right-aligned. 77 | | 78 | | Possible values: "right-to-left", "left-to-right", null 79 | | 80 | */ 81 | 82 | 'rightToLeft' => null, 83 | 84 | ]; 85 | -------------------------------------------------------------------------------- /config/updater.php: -------------------------------------------------------------------------------- 1 | GithubStrategy::class, 19 | 20 | ]; 21 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: 2 3 | paths: 4 | - app 5 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests/Feature 14 | 15 | 16 | ./tests/Unit 17 | 18 | 19 | 20 | 21 | ./app 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Feature/InspiringCommandTest.php: -------------------------------------------------------------------------------- 1 | artisan('inspiring') 5 | ->expectsOutput('Simplicity is the ultimate sophistication.') 6 | ->assertExitCode(0); 7 | }); 8 | -------------------------------------------------------------------------------- /tests/Pest.php: -------------------------------------------------------------------------------- 1 | in('Feature'); 15 | 16 | /* 17 | |-------------------------------------------------------------------------- 18 | | Expectations 19 | |-------------------------------------------------------------------------- 20 | | 21 | | When you're writing tests, you often need to check that values meet certain conditions. The 22 | | "expect()" function gives you access to a set of "expectations" methods that you can use 23 | | to assert different things. Of course, you may extend the Expectation API at any time. 24 | | 25 | */ 26 | 27 | expect()->extend('toBeOne', function () { 28 | return $this->toBe(1); 29 | }); 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Functions 34 | |-------------------------------------------------------------------------- 35 | | 36 | | While Pest is very powerful out-of-the-box, you may have some testing code specific to your 37 | | project that you don't want to repeat in every file. Here you can also expose helpers as 38 | | global functions to help you to reduce the number of lines of code in your test files. 39 | | 40 | */ 41 | 42 | function something() 43 | { 44 | // .. 45 | } 46 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | toBeTrue(); 5 | }); 6 | --------------------------------------------------------------------------------