├── .github
├── dependabot.yml
└── workflows
│ └── run-tests.yml
├── .gitignore
├── .phpunit.result.cache
├── .valetrc
├── composer.json
├── composer.lock
├── docs
└── todo.md
├── license
├── phpunit.xml
├── readme.md
├── src
├── CommandInfo.php
├── CommandInput.php
├── Commands
│ └── InstallEnvCommand.php
├── Exceptions
│ └── UnsupportedCommandType.php
├── File.php
├── Files
│ └── MigrationFile.php
├── Listeners
│ └── OpenOnMake.php
├── OpenFile.php
├── Openers
│ └── MigrationFile.php
├── Options.php
├── PathGetters
│ └── FilePath.php
├── Paths.php
├── Providers
│ └── OpenOnMakeServiceProvider.php
├── Testing
│ ├── IsGenerator.php
│ └── NotGenerator.php
└── config
│ └── open-on-make.php
└── tests
└── unit
├── CommandInfoTest.php
├── CommandInputTest.php
├── FileTest.php
├── MigrationFileTest.php
├── OpenFileTest.php
├── OptionsTest.php
└── PathsTest.php
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # Please see the documentation for all configuration options:
2 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
3 |
4 | version: 2
5 | updates:
6 |
7 | - package-ecosystem: "github-actions"
8 | directory: "/"
9 | schedule:
10 | interval: "weekly"
11 | labels:
12 | - "dependencies"
--------------------------------------------------------------------------------
/.github/workflows/run-tests.yml:
--------------------------------------------------------------------------------
1 | name: run-tests
2 |
3 | on:
4 | push:
5 | branches: [master]
6 | pull_request:
7 | branches: [master]
8 |
9 | jobs:
10 | test:
11 |
12 | runs-on: ubuntu-latest
13 | strategy:
14 | fail-fast: true
15 | matrix:
16 | php: [7.4]
17 | dependency-version: [prefer-stable]
18 |
19 | name: P${{ matrix.php }} - ${{ matrix.dependency-version }}
20 |
21 | steps:
22 | - name: Checkout code
23 | uses: actions/checkout@v4
24 |
25 | - name: Setup PHP
26 | uses: shivammathur/setup-php@v2
27 | with:
28 | php-version: ${{ matrix.php }}
29 | extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, xdebug
30 | coverage: xdebug
31 |
32 | - name: Install dependencies
33 | run: composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-suggest
34 |
35 | - name: Execute tests
36 | run: vendor/bin/phpunit
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | tests/report/
3 | .phpunit.result.cache
4 | .idea
5 |
--------------------------------------------------------------------------------
/.phpunit.result.cache:
--------------------------------------------------------------------------------
1 | {"version":1,"defects":[],"times":{"Tests\\CommandInfoTest::it_checks_if_empty_command_is_not_a_make_model_command":0.042,"Tests\\CommandInfoTest::it_checks_if_command_is_make_model_command":0.015,"Tests\\CommandInfoTest::it_checks_if_command_is_make_test_command":0.014,"Tests\\CommandInfoTest::it_checks_if_command_is_make_factory_command":0.014,"Tests\\CommandInfoTest::it_checks_if_command_is_make_command_command":0.016,"Tests\\CommandInfoTest::it_returns_what_is_set_for_input":0.016,"Tests\\CommandInfoTest::it_checks_if_command_is_migration_command_command":0.014,"Tests\\CommandInfoTest::it_checks_if_command_is_artisan_list_command":0.016,"Tests\\CommandInfoTest::it_checks_if_command_is_artisan_list_command_specifically":0.015,"Tests\\CommandInfoTest::it_returns_the_command_string":0.016,"Tests\\CommandInfoTest::it_returns_the_arg_name":0.015,"Tests\\CommandInfoTest::it_says_list_command_is_not_openable":0.014,"Tests\\CommandInfoTest::it_says_help_executions_are_not_openable":0.014,"Tests\\CommandInfoTest::it_says_commands_without_a_name_are_not_openable":0.014,"Tests\\CommandInfoTest::it_creates_a_filename_based_on_name_argument":0.015,"Tests\\CommandInfoTest::it_creates_a_filename_based_on_name_argument_with_namespace":0.014,"Tests\\CommandInfoTest::it_returns_splfile_from_filename":0.014,"Tests\\CommandInfoTest::it_a_does_not_create_a_filename_if_no_name_provided":0.014,"Tests\\CommandInfoTest::it_gets_the_command_class":0.014,"Tests\\CommandInfoTest::it_returns_null_for_command_class_when_unknown_make_command_executed":0.014,"Tests\\CommandInfoTest::it_alerts_user_that_adding_php_to_their_name_arguments_is_bad":0.025,"Tests\\CommandInfoTest::it_says_nothing_is_openable_if_production":0.015,"Tests\\CommandInputTest::it_should_not_have_options_if_none_passed":0.022,"Tests\\CommandInputTest::it_should_have_options_if_passed":0.015,"Tests\\CommandInputTest::it_returns_all_options_in_getCollection":0.015,"Tests\\CommandInputTest::it_returns_all_options_in_getOptions":0.015,"Tests\\CommandInputTest::it_returns_className_from_argument_with_full_qualified_classname":0.015,"Tests\\FileTest::it_adds_php_extension_to_name_of_thing_being_generated":0.017,"Tests\\FileTest::it_adds_php_extension_to_name_of_thing_being_generated_and_replaces_two_backslashes_with_forward_slash":0.015,"Tests\\FileTest::it_calls_open_when_opening_additional_files":0.016,"Tests\\FileTest::it_opens_additional_files_generated_in_addition_to_model":0.015,"Tests\\FileTest::it_delegates_open_to_open_file_class":0.015,"Tests\\MigrationFileTest::it_returns_latest_migration_path":0.021,"Tests\\OpenFileTest::it_opens_files":0.017,"Tests\\OptionsTest::it_returns_the_command_type_from_option":0,"Tests\\OptionsTest::it_checks_if_command_is_resource":0,"Tests\\OptionsTest::it_checks_if_command_is_migration":0,"Tests\\OptionsTest::it_checks_if_command_is_all":0,"Tests\\OptionsTest::it_checks_if_the_passed_option_exists":0,"Tests\\OptionsTest::it_checks_if_the_passed_option_does_not_exists":0,"Tests\\PathsTest::it_returns_an_object_path_for_a_command_key":0.016,"Tests\\PathsTest::it_returns_null_if_command_key_not_exists":0.015,"Tests\\PathsTest::it_returns_the_command_path_from_command_string":0.015,"Tests\\PathsTest::it_returns_null_if_command_string_unknown":0.015,"Tests\\PathsTest::it_returns_path_of_existing_key":0.015}}
--------------------------------------------------------------------------------
/.valetrc:
--------------------------------------------------------------------------------
1 | php=php@7.4
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ahuggins/open-on-make",
3 | "description": "Automatically open files in editor when Artisan make:* is executed",
4 | "license": "MIT",
5 | "authors": [
6 | {
7 | "name": "Andrew Huggins",
8 | "email": "andrewhuggins@gmail.com"
9 | }
10 | ],
11 | "require": {
12 | "php" : "~7.4",
13 | "imliam/laravel-env-set-command": "^1.1",
14 | "symfony/finder": "^5.1",
15 | "laravel/helpers": "^1.2",
16 | "illuminate/support": "^7.19|^8.0",
17 | "illuminate/console": "^7.19|^8.0"
18 | },
19 | "autoload": {
20 | "psr-4": {
21 | "OpenOnMake\\": "src"
22 | }
23 | },
24 | "autoload-dev": {
25 | "psr-4": {
26 | "Tests\\": "tests/"
27 | }
28 | },
29 | "extra": {
30 | "laravel": {
31 | "providers": [
32 | "OpenOnMake\\Providers\\OpenOnMakeServiceProvider"
33 | ]
34 | }
35 | },
36 | "require-dev": {
37 | "phpunit/phpunit": "^8.4",
38 | "orchestra/testbench": "^5.4"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/docs/todo.md:
--------------------------------------------------------------------------------
1 | # Refactor
2 | I really want to refactor this into something more robust that is hopefully a little easier to grok how it works.
3 |
4 | This would make maintaining a little easier, and be a good exercise.
5 |
6 | I intend this to be the 1.0 release.
7 |
8 | ### Refactor Strategy
9 |
10 | Looking at the code, it's rather procedural. Let's OOP it up. Backed by Tests...more better tests. And I think OOPing it, will make the testing ability better and easier.
11 |
12 | To do that, I need a pretty good list of different commands that would be called.
13 |
14 | 1. `null` (if just `artisan`)
15 | 2. `make:model` for Model
16 | 3. `make:cast`
17 | 4.
18 |
19 | [X] Handle if `artisan` with no command is run
20 | [X] First check should be if the command is a `make:` command, and if not, just bail.
21 | - CommandInfo->isOpenable() checks if it's a make: command
22 | - Also checks if it's not just `artisan` meaning no additional command provided
23 |
24 | ## The idea here is to break the code into modular parts.
25 |
26 | [X] Move the code for if the Command is a `make:test` command to its own file.
27 | - CommandInfo ended up being where a lot of code should live. isMakeCommand lives here
28 | [ ] `isSubClassOfGeneratorCommand` to its own file
29 | [X] `Migration handler` to its own file
30 | - Ended up moving to the File class. Better, but might be temporary
31 | [ ] Move `checkForFlags` code to its own file
32 |
33 |
34 | ## New Stuff
35 | [ ] make:component creates a blade file as well, would be cool to open both
--------------------------------------------------------------------------------
/license:
--------------------------------------------------------------------------------
1 | Copyright 2018 Andrew Huggins
2 |
3 | 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:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | 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.
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 | tests/unit
14 |
15 |
16 |
17 | tests/feature
18 |
19 |
20 |
21 |
22 | src
23 |
24 | src/Testing/
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Open On Make
2 |
3 | A package that makes it easy to have the `artisan make:` commands open the newly created file in your editor of choice.
4 |
5 | ## Installation
6 |
7 | `composer require --dev ahuggins/open-on-make`
8 |
9 | This package defaults to VS Code using the `code` command, this can be changed by using the Artisan command:
10 |
11 | `php artisan open:install`
12 |
13 | It will ask you which editor you want, enter the corresponding number and hit enter. It will update your env file with the CLI command.
14 |
15 | > You can still set this manually, this was intended to streamline the process, make it a little faster and one less thing to look up.
16 |
17 | > Feel free to suggest or open a PR with additional editors if anything is missing.
18 |
19 | ## Set env Editor manually
20 |
21 | ```
22 | OPEN_ON_MAKE_EDITOR=nameOfCliCommandForEditor
23 | OPEN_ON_MAKE_FLAGS='-a' // Flags you need passed to the above Command
24 | ```
25 |
26 | > Most people will probably only need to add `OPEN_ON_MAKE_EDITOR` to their .env file.
27 |
28 | #### Publish the config
29 |
30 | - publish the package config with
31 |
32 | `php artisan vendor:publish --tag=open-on-make`
33 |
34 | #### Disable the package
35 |
36 | > Some team members may want to disable this feature.
37 |
38 | You can explicitly disable this package by setting the `OPEN_ON_MAKE_ENABLED` environment variable:
39 |
40 | ```
41 | OPEN_ON_MAKE_ENABLED=false
42 | ```
43 |
44 | ## Example Editor values
45 |
46 | Sublime - `OPEN_ON_MAKE_EDITOR=subl`
47 |
48 | PHPStorm - `OPEN_ON_MAKE_EDITOR=phpstorm` Setup Instructions: https://www.jetbrains.com/help/phpstorm/opening-files-from-command-line.html
49 |
50 | Atom - `OPEN_ON_MAKE_EDITOR=atom` Provided you have shell commands installed: https://user-images.githubusercontent.com/1791228/38758555-814eb602-3f3f-11e8-8071-3c9690bb0374.png
51 |
52 | VS Code = `OPEN_ON_MAKE_EDITOR=code` Provided you have the `code` shell command installed: https://code.visualstudio.com/docs/setup/mac
53 |
54 | ## License
55 |
56 | Licensed under the [MIT](license) license
57 |
--------------------------------------------------------------------------------
/src/CommandInfo.php:
--------------------------------------------------------------------------------
1 | commandString = $commandString;
35 | $this->argName = $argName;
36 | $this->help = $help;
37 | $this->output = $output;
38 | $this->filename = $this->ensurePHPExtension();
39 | $this->splFile = new \SplFileInfo($this->filename);
40 | $this->input = $input;
41 | }
42 |
43 | public function ensurePHPExtension()
44 | {
45 | if (!$this->argName) {
46 | return null;
47 | }
48 |
49 | $this->alertUserNotToAddPHPExtension();
50 |
51 | $name = str_replace('\\', '/', $this->argName);
52 | $name = str_replace('.php', '', $name);
53 | $name = $name . '.php';
54 | return $name;
55 | }
56 |
57 | public function getFilename()
58 | {
59 | return $this->filename;
60 | }
61 |
62 | public function getSplFile()
63 | {
64 | return $this->splFile;
65 | }
66 |
67 | public function getCommandString() : ?string
68 | {
69 | return $this->commandString;
70 | }
71 |
72 | public function getArgName() : ?string
73 | {
74 | return $this->argName;
75 | }
76 |
77 | public function getHelp() : bool
78 | {
79 | return $this->help;
80 | }
81 |
82 | public function isMakeCommand() : bool
83 | {
84 | return is_string($this->getCommandString()) && str_contains($this->getCommandString(), 'make:');
85 | }
86 |
87 | public function isMigrationCommand()
88 | {
89 | return is_string($this->getCommandString()) && str_contains($this->getCommandString(), ':migration');
90 | }
91 |
92 | /**
93 | * You can run artisan without a command..default to Lists
94 | *
95 | * @return boolean
96 | */
97 | public function isListCommand()
98 | {
99 | return $this->getCommandString() === null || $this->getCommandString() === 'list';
100 | }
101 |
102 | public function isCommandHelp() : bool
103 | {
104 | return $this->getHelp() == true;
105 | }
106 |
107 | public function isOpenable() : bool
108 | {
109 | if ($this->envProduction()) {
110 | return false;
111 | }
112 |
113 | if ($this->isListCommand()) {
114 | return false;
115 | }
116 |
117 | if ($this->isCommandHelp()) {
118 | return false;
119 | }
120 |
121 | return
122 | $this->hasName() &&
123 | $this->isMakeCommand() ;
124 | }
125 |
126 | public function envProduction() : bool
127 | {
128 | return config('app.env') == 'production';
129 | }
130 |
131 | /**
132 | * Fetched from `input` so that Openable does not access $argName before set.
133 | *
134 | * @return boolean
135 | */
136 | private function hasName()
137 | {
138 | return isset($this->argName);
139 | }
140 |
141 | /** This is because making a Model is only command you can generate other classes */
142 | public function isMakeModelCommand() : bool
143 | {
144 | return str_contains($this->getCommandString(), ':model');
145 | }
146 |
147 | public function isTestCommand() : bool
148 | {
149 | return str_replace('make:', '', $this->getCommandString()) === 'test';
150 | }
151 |
152 | public function isFactoryCommand() : bool
153 | {
154 | return str_replace('make:', '', $this->getCommandString()) === 'factory';
155 | }
156 |
157 | public function isCommandCommand() : bool
158 | {
159 | return str_replace('make:', '', $this->getCommandString()) === 'command';
160 | }
161 |
162 | private function getEventInput()
163 | {
164 | return $this->input;
165 | }
166 |
167 | public function getInput() : CommandInput
168 | {
169 | return new CommandInput($this->getEventInput());
170 | }
171 |
172 | public function getCommandClass()
173 | {
174 | $key = str_replace('make:', '', $this->getCommandString());
175 | if (!array_key_exists($key, Paths::$commands)) {
176 | return null;
177 | }
178 | return Paths::getCommandPath($key);
179 | }
180 |
181 | public function alertUserNotToAddPHPExtension()
182 | {
183 | if (is_string($this->argName) && str_contains($this->argName, '.php')) {
184 | $this->output->writeln('Open-On-Make: You should not provide .php');
185 | $this->output->writeln('Open-On-Make: When user provides `.php` extension, this results in a file with `.php.php` as extension.');
186 | $this->output->writeln('Open-On-Make: Open-On-Make can not open file.');
187 | return;
188 | }
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/src/CommandInput.php:
--------------------------------------------------------------------------------
1 | input = $input;
16 | $this->setCollection();
17 | }
18 |
19 | public function getCollection() : Collection
20 | {
21 | return $this->collection;
22 | }
23 |
24 | private function setCollection()
25 | {
26 | $this->collection = collect(explode(' ', $this->input));
27 | }
28 |
29 | /**
30 | * First item in collection is comand string (index zero)
31 | * Second item is Class Name w/without namespace (index one)
32 | * Remaining items are just options
33 | *
34 | * @return void
35 | */
36 | public function getOptions() : array
37 | {
38 | return $this->collection->slice(2)->all();
39 | }
40 |
41 | public function getClassNameOfNameArgument() : string
42 | {
43 | $exploded = explode('\\', $this->collection[1]);
44 | $className = trim(array_pop($exploded), "'");
45 | return $className;
46 | }
47 |
48 | public function hasOptions() : bool
49 | {
50 | return $this->collection->count() > 2;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Commands/InstallEnvCommand.php:
--------------------------------------------------------------------------------
1 | 'subl',
36 | 'VSCode' => 'code',
37 | 'Atom' => 'atom',
38 | 'PHPStorm' => 'pstorm',
39 | ];
40 |
41 | /**
42 | * Execute the console command.
43 | *
44 | * @return mixed
45 | */
46 | public function handle()
47 | {
48 |
49 | $choice = $this->choice('What editor do you want to use?', array_keys($this->editors));
50 |
51 | Artisan::call('env:set', [
52 | 'key' => 'OPEN_ON_MAKE_EDITOR',
53 | 'value' => $this->editors[$choice],
54 | ]);
55 |
56 | $this->info('Your OPEN_ON_MAKE_EDITOR has been set to ' . $choice);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Exceptions/UnsupportedCommandType.php:
--------------------------------------------------------------------------------
1 | open = $open;
21 | $this->options = $options;
22 | $this->finder = $finder;
23 | }
24 |
25 | public function openOptionalFiles($option, $name)
26 | {
27 | if ($this->options->exist($option)) {
28 | $this->openFilesGeneratedInAdditionToModel($option, $name);
29 | } elseif ($this->options->isAll($option)) {
30 | $this->openAllTypes($name);
31 | }
32 | }
33 |
34 | public function open($path)
35 | {
36 | $this->open->open($path);
37 | }
38 |
39 | public function getFileName($name)
40 | {
41 | return str_replace('\\', '/', $name . '.php');
42 | }
43 |
44 | public function find(CommandInfo $commandInfo)
45 | {
46 | $this->finder->files()->depth('>= 0')->depth('< 10')->name($commandInfo->getSplFile()->getFileName())->in(base_path());
47 |
48 | $path = '';
49 |
50 | if ($this->finder->hasResults()) {
51 | foreach ($this->finder as $file) {
52 | $path = $file->getRealPath();
53 | break;
54 | }
55 | }
56 |
57 | return $path;
58 | }
59 |
60 | public function openAdditionalFile($path, $name, $option)
61 | {
62 | $this->open->open($path . $name . ucfirst($this->options->getOption($option)) . '.php');
63 | }
64 |
65 | public function openAllTypes($name)
66 | {
67 | foreach ($this->options->getOptions() as $key => $value) {
68 | if (! $this->options->isMigration($value) && ! $this->options->isResource($value)) {
69 | $this->openAdditionalFile(Paths::getPath($value), $name, $key);
70 | } elseif ($this->options->isMigration($value)) {
71 | MigrationFile::open();
72 | }
73 | }
74 | }
75 |
76 | public function openFilesGeneratedInAdditionToModel($option, $name)
77 | {
78 | if ($this->options->isMigration($option)) {
79 | MigrationFile::open();
80 | } else {
81 | $option = $this->options->isResource($option) ? '-c' : $option;
82 | $this->openAdditionalFile(Paths::getPath($this->options->getOption($option)), $name, $option);
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/Files/MigrationFile.php:
--------------------------------------------------------------------------------
1 | getLatestMigration();
10 | }
11 |
12 | public function getLatestMigration()
13 | {
14 | $this->createDiskForAppRoot();
15 |
16 | $newestMigration = collect(
17 | \Storage::disk('easyOpen')->files('database/migrations')
18 | )->pop();
19 |
20 | $this->unsetDiskForAppRoot();
21 |
22 | return base_path($newestMigration);
23 | }
24 |
25 | private function unsetDiskForAppRoot()
26 | {
27 | unset(app()->config['filesystems.disks.easyOpen']);
28 | }
29 |
30 | private function createDiskForAppRoot()
31 | {
32 | app()->config["filesystems.disks.easyOpen"] = [
33 | 'driver' => 'local',
34 | 'root' => base_path(),
35 | ];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Listeners/OpenOnMake.php:
--------------------------------------------------------------------------------
1 | filePath = $filePath;
19 | $this->file = $file;
20 | }
21 |
22 | public function handle($event)
23 | {
24 | $commandInfo = new CommandInfo(
25 | $event->command,
26 | $event->input->hasArgument('name') ? $event->input->getArgument('name') : null,
27 | $event->input,
28 | $event->output,
29 | $event->input->getOption('help')
30 | );
31 | if ($commandInfo->isOpenable()) {
32 | $path = $this->filePath->determine($commandInfo);
33 |
34 | OpenFile::open($path);
35 |
36 | $this->checkForFlags($commandInfo);
37 | }
38 | }
39 |
40 | public function checkForFlags($commandInfo)
41 | {
42 | if (! $commandInfo->isMakeModelCommand()) {
43 | return null;
44 | }
45 |
46 | $input = $commandInfo->getInput();
47 |
48 | if ($input->hasOptions()) {
49 | $name = $input->getClassNameOfNameArgument();
50 | foreach ($input->getOptions() as $option) {
51 | $this->file->openOptionalFiles($option, $name);
52 | }
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/OpenFile.php:
--------------------------------------------------------------------------------
1 | createDiskForAppRoot();
13 |
14 | $newestMigration = collect(
15 | Storage::disk('easyOpen')->files('database/migrations')
16 | )->pop();
17 |
18 | $this->unsetDiskForAppRoot();
19 |
20 | return base_path($newestMigration);
21 | }
22 |
23 | private function unsetDiskForAppRoot()
24 | {
25 | unset(app()->config['filesystems.disks.easyOpen']);
26 | }
27 |
28 | private function createDiskForAppRoot()
29 | {
30 | app()->config["filesystems.disks.easyOpen"] = [
31 | 'driver' => 'local',
32 | 'root' => base_path(),
33 | ];
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Options.php:
--------------------------------------------------------------------------------
1 | "controller",
9 | "--controller" => "controller",
10 | "-f" => "factory",
11 | "--factory" => "factory",
12 | "-m" => "migration",
13 | "--migration" => "migration",
14 | "-r" => "resource",
15 | "--resource" => "resource"
16 | ];
17 |
18 | public function getOptions()
19 | {
20 | return $this->options;
21 | }
22 |
23 | public function getOption($option)
24 | {
25 | return $this->getOptions()[$option];
26 | }
27 |
28 | public function isResource($option)
29 | {
30 | return $option === '-r' || $option === '--resource' || $option === 'resource';
31 | }
32 |
33 | public function isMigration($option)
34 | {
35 | return $option === '-m' || $option === '--migration' || $option === 'migration';
36 | }
37 |
38 | public function isAll($option)
39 | {
40 | return $option === '-a' || $option === '--all';
41 | }
42 |
43 | public function exist($option)
44 | {
45 | return array_key_exists($option, $this->getOptions());
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/PathGetters/FilePath.php:
--------------------------------------------------------------------------------
1 | file = $file;
17 | $this->migration = $migration;
18 | }
19 |
20 | public function determine(CommandInfo $commandInfo)
21 | {
22 | if ($commandInfo->isMigrationCommand()) {
23 | return $this->migration->getLatestMigration();
24 | }
25 | return $this->file->find($commandInfo);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Paths.php:
--------------------------------------------------------------------------------
1 | 'app/Http/Controllers/',
14 | 'factory' => 'database/factories/',
15 | 'migration' => '',
16 | 'resource' => 'app/Http/Controllers/',
17 | ];
18 |
19 | public static $commands = [
20 | 'action' => \Spatie\QueueableAction\ActionMakeCommand::class,
21 | 'channel' => FoundationConsole\ChannelMakeCommand::class,
22 | 'command' => FoundationConsole\ConsoleMakeCommand::class,
23 | 'controller' => RoutingConsole\ControllerMakeCommand::class,
24 | 'event' => FoundationConsole\EventMakeCommand::class,
25 | 'exception' => FoundationConsole\ExceptionMakeCommand::class,
26 | 'factory' => DatabaseConsole\Factories\FactoryMakeCommand::class,
27 | 'job' => FoundationConsole\JobMakeCommand::class,
28 | 'listener' => FoundationConsole\ListenerMakeCommand::class,
29 | 'mail' => FoundationConsole\MailMakeCommand::class,
30 | 'middleware' => RoutingConsole\MiddlewareMakeCommand::class,
31 | 'migration' => DatabaseConsole\Migrations\MigrateMakeCommand::class,
32 | 'model' => FoundationConsole\ModelMakeCommand::class,
33 | 'notification' => FoundationConsole\NotificationMakeCommand::class,
34 | 'observer' => FoundationConsole\ObserverMakeCommand::class,
35 | 'policy' => FoundationConsole\PolicyMakeCommand::class,
36 | 'provider' => FoundationConsole\ProviderMakeCommand::class,
37 | 'request' => FoundationConsole\RequestMakeCommand::class,
38 | 'resource' => FoundationConsole\ResourceMakeCommand::class,
39 | 'rule' => FoundationConsole\RuleMakeCommand::class,
40 | 'seeder' => DatabaseConsole\Seeds\SeederMakeCommand::class,
41 | 'test' => FoundationConsole\TestMakeCommand::class,
42 | 'widget' => \Arrilot\Widgets\Console\WidgetMakeCommand::class,
43 | 'observer' => FoundationConsole\ObserverMakeCommand::class,
44 | 'view' => \Sven\ArtisanView\Commands\MakeView::class,
45 | ];
46 |
47 | public static function getPaths()
48 | {
49 | return array_merge(self::$paths, config('open-on-make.paths'));
50 | }
51 |
52 | public static function getCommandClass(string $commandString)
53 | {
54 | $key = str_replace('make:', '', $commandString);
55 | if (!array_key_exists($key, self::$commands)) {
56 | return null;
57 | }
58 | return self::getCommandPath($key);
59 | }
60 |
61 | public static function getPath(string $key) : string
62 | {
63 | return self::getPaths()[$key];
64 | }
65 |
66 | public static function getCommandPath(string $key) : string
67 | {
68 | if (! isset(self::$commands[$key])) {
69 | throw new UnsupportedCommandType(sprintf('Unknown Make Command: %s', $key));
70 | }
71 | return self::$commands[$key];
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/Providers/OpenOnMakeServiceProvider.php:
--------------------------------------------------------------------------------
1 | mergeConfigFrom(
17 | __DIR__.'../../config/open-on-make.php',
18 | 'open-on-make'
19 | );
20 |
21 | $this->publishes([
22 | __DIR__.'/../config/open-on-make.php' => config_path('open-on-make.php')
23 | ], 'open-on-make');
24 |
25 | if (config('open-on-make.enabled')) {
26 | Event::listen(
27 | 'Illuminate\Console\Events\CommandFinished',
28 | 'OpenOnMake\Listeners\OpenOnMake'
29 | );
30 | }
31 |
32 |
33 | $commands = [
34 | \OpenOnMake\Commands\InstallEnvCommand::class,
35 | ];
36 |
37 | if ($this->app->environment() === 'testing') {
38 | $commands[] = ModelMakeCommand::class;
39 | $commands[] = MigrateMakeCommand::class;
40 | $commands[] = IsGenerator::class;
41 | $commands[] = EnvironmentSetCommand::class;
42 | }
43 |
44 | if ($this->app->runningInConsole()) {
45 | $this->commands($commands);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Testing/IsGenerator.php:
--------------------------------------------------------------------------------
1 | env('OPEN_ON_MAKE_EDITOR', 'code'),
5 | 'flags' => env('OPEN_ON_MAKE_FLAGS', ''),
6 | 'enabled' => env('OPEN_ON_MAKE_ENABLED', true),
7 | /**
8 | * Add here your custom paths.
9 | */
10 | 'paths' => []
11 | ];
12 |
--------------------------------------------------------------------------------
/tests/unit/CommandInfoTest.php:
--------------------------------------------------------------------------------
1 | assertFalse($commandInfo->isMakeCommand());
21 | }
22 |
23 | /** @test */
24 | public function it_checks_if_command_is_make_model_command()
25 | {
26 | $commandInfo = new CommandInfo('make:model');
27 | $this->assertTrue($commandInfo->isMakeModelCommand());
28 | }
29 |
30 | /** @test */
31 | public function it_checks_if_command_is_make_test_command()
32 | {
33 | $commandInfo = new CommandInfo('make:test');
34 | $this->assertTrue($commandInfo->isTestCommand());
35 | }
36 |
37 | /** @test */
38 | public function it_checks_if_command_is_make_factory_command()
39 | {
40 | $commandInfo = new CommandInfo('make:factory');
41 | $this->assertTrue($commandInfo->isFactoryCommand());
42 | }
43 |
44 | /** @test */
45 | public function it_checks_if_command_is_make_command_command()
46 | {
47 | $commandInfo = new CommandInfo('make:command');
48 | $this->assertTrue($commandInfo->isCommandCommand());
49 | }
50 |
51 | /** @test */
52 | public function it_returns_what_is_set_for_input()
53 | {
54 | $testArgs = new ArgvInput(['IgnoredAppName', 'make:command', 'NameOfGeneratedFile', 'firstOption']);
55 | $commandInfo = new CommandInfo('make:command', null, $testArgs);
56 | $this->assertEquals('firstOption', $commandInfo->getInput()->getOptions()[2]);
57 | }
58 |
59 | /** @test */
60 | public function it_checks_if_command_is_migration_command_command()
61 | {
62 | $commandInfo = new CommandInfo('make:migration');
63 | $this->assertTrue($commandInfo->isMigrationCommand());
64 | }
65 |
66 | /** @test */
67 | public function it_checks_if_command_is_artisan_list_command()
68 | {
69 | // If you just run `php artisan`
70 | $commandInfo = new CommandInfo;
71 | $this->assertTrue($commandInfo->isListCommand());
72 | }
73 |
74 | /** @test */
75 | public function it_checks_if_command_is_artisan_list_command_specifically()
76 | {
77 | // If you run `php artisan list`
78 | $commandInfo = new CommandInfo('list');
79 | $this->assertTrue($commandInfo->isListCommand());
80 | }
81 |
82 | /** @test */
83 | public function it_returns_the_command_string()
84 | {
85 | $commandInfo = new CommandInfo('make:controller', 'Something');
86 | $this->assertEquals('make:controller', $commandInfo->getCommandString());
87 | }
88 |
89 | /** @test */
90 | public function it_returns_the_arg_name()
91 | {
92 | $commandInfo = new CommandInfo('make:controller', 'Something');
93 | $this->assertEquals('Something', $commandInfo->getArgName());
94 | }
95 |
96 | /** @test */
97 | public function it_says_list_command_is_not_openable()
98 | {
99 | $commandInfo = new CommandInfo;
100 | $this->assertFalse($commandInfo->isOpenable());
101 | }
102 |
103 | /** @test */
104 | public function it_says_help_executions_are_not_openable()
105 | {
106 | $commandInfo = new CommandInfo('make:model', null, null, null, true);
107 | $this->assertFalse($commandInfo->isOpenable());
108 | }
109 |
110 | /** @test */
111 | public function it_says_commands_without_a_name_are_not_openable()
112 | {
113 | $commandInfo = new CommandInfo('make:model');
114 | $this->assertFalse($commandInfo->isOpenable());
115 | }
116 |
117 | /** @test */
118 | public function it_creates_a_filename_based_on_name_argument()
119 | {
120 | $commandInfo = new CommandInfo('make:model', 'SomeName');
121 | $this->assertEquals('SomeName.php', $commandInfo->getFilename());
122 | }
123 |
124 | /** @test */
125 | public function it_creates_a_filename_based_on_name_argument_with_namespace()
126 | {
127 | $commandInfo = new CommandInfo('make:model', 'App\\Models\\SomeName');
128 | $this->assertEquals('App/Models/SomeName.php', $commandInfo->getFilename());
129 | }
130 |
131 | /** @test */
132 | public function it_returns_splfile_from_filename()
133 | {
134 | $commandInfo = new CommandInfo('make:model', 'SomeName');
135 | $this->assertInstanceOf(SplFileInfo::class, $commandInfo->getSplFile());
136 | }
137 |
138 | /** @test */
139 | public function it_a_does_not_create_a_filename_if_no_name_provided()
140 | {
141 | $commandInfo = new CommandInfo('make:model');
142 | $this->assertNull($commandInfo->getFilename());
143 | }
144 |
145 | /** @test */
146 | public function it_gets_the_command_class()
147 | {
148 | $commandInfo = new CommandInfo('make:model');
149 | $this->assertEquals('Illuminate\Foundation\Console\ModelMakeCommand', $commandInfo->getCommandClass());
150 | }
151 |
152 | /** @test */
153 | public function it_returns_null_for_command_class_when_unknown_make_command_executed()
154 | {
155 | $commandInfo = new CommandInfo('make:thisIsNotAValidModel');
156 | $this->assertNull($commandInfo->getCommandClass());
157 | }
158 |
159 | /** @test */
160 | public function it_alerts_user_that_adding_php_to_their_name_arguments_is_bad()
161 | {
162 | $spy = Mockery::spy(OutputInterface::class);
163 | $commandInfo = new CommandInfo('make:model', 'SomeModel.php', null, $spy);
164 | $spy->shouldHaveReceived('writeln')->times(3);
165 | $this->assertTrue(true);
166 | }
167 |
168 | /** @test */
169 | public function it_says_nothing_is_openable_if_production()
170 | {
171 | Config::set('app.env', 'production');
172 | $commandInfo = new CommandInfo('make:model');
173 | $this->assertFalse($commandInfo->isOpenable());
174 | }
175 |
176 | public function setUp() : void
177 | {
178 | parent::setUp();
179 | }
180 |
181 | protected function tearDown() : void
182 | {
183 | Mockery::close();
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/tests/unit/CommandInputTest.php:
--------------------------------------------------------------------------------
1 | makeCommandInput('make:model SomeName');
25 | $this->assertFalse($commandInput->hasOptions());
26 | }
27 |
28 | /** @test */
29 | public function it_should_have_options_if_passed()
30 | {
31 | $commandInput = $this->makeCommandInput('make:model SomeName -c');
32 | $this->assertTrue($commandInput->hasOptions());
33 | }
34 |
35 | /** @test */
36 | public function it_returns_all_options_in_getCollection()
37 | {
38 | $commandInput = $this->makeCommandInput('make:model SomeName -c');
39 | $this->assertCount(3, $commandInput->getCollection());
40 | }
41 |
42 | /** @test */
43 | public function it_returns_all_options_in_getOptions()
44 | {
45 | $commandInput = $this->makeCommandInput('make:model SomeName -c');
46 | $this->assertCount(1, $commandInput->getOptions());
47 | $this->assertEquals(array_values(['-c']), array_values($commandInput->getOptions()));
48 | }
49 |
50 | /** @test */
51 | public function it_returns_className_from_argument_with_full_qualified_classname()
52 | {
53 | $commandInput = $this->makeCommandInput('make:model App\\\Models\\\SomeName');
54 | $this->assertEquals('SomeName', $commandInput->getClassNameOfNameArgument());
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tests/unit/FileTest.php:
--------------------------------------------------------------------------------
1 | open = Mockery::mock(OpenFile::class);
17 | $this->file = new File($this->open, new Options, new Finder);
18 | parent::setUp();
19 | }
20 |
21 | /** @test */
22 | public function it_adds_php_extension_to_name_of_thing_being_generated()
23 | {
24 | $filename = $this->file->getFileName('NameToGenerate');
25 | $this->assertEquals('NameToGenerate.php', $filename);
26 | }
27 |
28 | /** @test */
29 | public function it_adds_php_extension_to_name_of_thing_being_generated_and_replaces_two_backslashes_with_forward_slash()
30 | {
31 | $filename = $this->file->getFileName('Models\\NameToGenerate');
32 | $this->assertEquals('Models/NameToGenerate.php', $filename);
33 | }
34 |
35 | /** @test */
36 | public function it_calls_open_when_opening_additional_files()
37 | {
38 | $this->open->expects('open')->once();
39 |
40 | $this->file->openAdditionalFile('', 'SomeName', '-c');
41 | }
42 |
43 | /** @test */
44 | public function it_opens_additional_files_generated_in_addition_to_model()
45 | {
46 | $this->open->expects('open')->once();
47 | $this->file->openFilesGeneratedInAdditionToModel('-r', 'SomeModelName');
48 | }
49 |
50 | /** @test */
51 | public function it_delegates_open_to_open_file_class()
52 | {
53 | $this->open->expects('open')->once();
54 | $this->file->open('something');
55 | }
56 |
57 | protected function getPackageProviders($app)
58 | {
59 | return ['OpenOnMake\Providers\OpenOnMakeServiceProvider'];
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/tests/unit/MigrationFileTest.php:
--------------------------------------------------------------------------------
1 | assertStringContainsString('laravel/database/migrations', $path);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/unit/OpenFileTest.php:
--------------------------------------------------------------------------------
1 | open = new OpenFile;
17 | parent::setUp();
18 | }
19 |
20 | /** @test */
21 | public function it_opens_files()
22 | {
23 | $this->assertTrue(OpenFile::open('test'));
24 | }
25 |
26 | protected function getPackageProviders($app)
27 | {
28 | return ['OpenOnMake\Providers\OpenOnMakeServiceProvider'];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/unit/OptionsTest.php:
--------------------------------------------------------------------------------
1 | options = new Options;
15 | }
16 | /** @test */
17 | public function it_returns_the_command_type_from_option()
18 | {
19 | foreach ($this->options->getOptions() as $flag => $type) {
20 | $this->assertEquals($type, $this->options->getOption($flag));
21 | }
22 | }
23 |
24 | /** @test */
25 | public function it_checks_if_command_is_resource()
26 | {
27 | $this->assertTrue($this->options->isResource('-r'));
28 | $this->assertTrue($this->options->isResource('--resource'));
29 | $this->assertTrue($this->options->isResource('resource'));
30 | }
31 |
32 | /** @test */
33 | public function it_checks_if_command_is_migration()
34 | {
35 | $this->assertTrue($this->options->isMigration('-m'));
36 | $this->assertTrue($this->options->isMigration('--migration'));
37 | $this->assertTrue($this->options->isMigration('migration'));
38 | }
39 |
40 | /** @test */
41 | public function it_checks_if_command_is_all()
42 | {
43 | $this->assertTrue($this->options->isAll('-a'));
44 | $this->assertTrue($this->options->isAll('--all'));
45 | }
46 |
47 | /** @test */
48 | public function it_checks_if_the_passed_option_exists()
49 | {
50 | $this->assertTrue($this->options->exist('-c'));
51 | }
52 |
53 | /** @test */
54 | public function it_checks_if_the_passed_option_does_not_exists()
55 | {
56 | $this->assertFalse($this->options->exist('--notExistingOption'));
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/tests/unit/PathsTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('Illuminate\Foundation\Console\ModelMakeCommand', Paths::getCommandPath('model'));
15 | }
16 |
17 | /** @test */
18 | public function it_returns_null_if_command_key_not_exists()
19 | {
20 | $this->expectException(UnsupportedCommandType::class);
21 |
22 | $this->assertNull(Paths::getCommandPath('notACommandKey'));
23 | }
24 |
25 | /** @test */
26 | public function it_returns_the_command_path_from_command_string()
27 | {
28 | $this->assertEquals(
29 | 'Illuminate\Foundation\Console\ModelMakeCommand',
30 | Paths::getCommandClass('make:model')
31 | );
32 | }
33 |
34 | /** @test */
35 | public function it_returns_null_if_command_string_unknown()
36 | {
37 | $this->assertNull(Paths::getCommandClass('make:somethingThatDoesNotExist'));
38 | }
39 |
40 | /** @test */
41 | public function it_returns_path_of_existing_key()
42 | {
43 | $this->assertEquals(
44 | 'app/Http/Controllers/',
45 | Paths::getPath('controller')
46 | );
47 | }
48 |
49 | protected function getPackageProviders($app)
50 | {
51 | return ['OpenOnMake\Providers\OpenOnMakeServiceProvider'];
52 | }
53 | }
--------------------------------------------------------------------------------