Skip to content

Commit

Permalink
[2.x] Add option to install ESLint with Prettier (#412)
Browse files Browse the repository at this point in the history
* add stub for eslint config

* add stub for prettier config

* add option to install eslint with prettier

* fix lint errors

* add CI workflow to fix code styling

* delete style ci config

* replace prettier.config.cjs with .prettierrc

* Pint: fix code styling

* ESLint: fix code styling

* format

---------

Co-authored-by: avosalmon <[email protected]>
  • Loading branch information
avosalmon and avosalmon authored Sep 17, 2024
1 parent 79f0661 commit 6f41572
Show file tree
Hide file tree
Showing 130 changed files with 2,159 additions and 708 deletions.
68 changes: 68 additions & 0 deletions .github/workflows/coding-standards.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: fix code styling

on: [push]

jobs:
pint:
uses: laravel/.github/.github/workflows/coding-standards.yml@main
with:
message: "Pint: fix code styling"

eslint:
name: Lint stubs for Inertia stacks
runs-on: ubuntu-latest
needs: pint

steps:
- name: Checkout code
uses: actions/checkout@v4

# We need to pull the latest changes because the `pint` job might have pushed changes
- name: Pull Remote Changes
run: git pull

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Install NPM packages
run: |
# Common packages
npm install \
eslint@^8.57.0 \
prettier@^3.3.0 \
prettier-plugin-organize-imports@^4.0.0 \
prettier-plugin-tailwindcss@^0.6.5
# React
npm install \
react@^18.2.0 \
eslint-plugin-react@^7.34.4 \
eslint-plugin-react-hooks@^4.6.2 \
eslint-plugin-prettier@^5.1.3 \
eslint-config-prettier@^9.1.0 \
@typescript-eslint/eslint-plugin@^7.16.0 \
@typescript-eslint/parser@^7.16.0
# Vue
npm install \
eslint-plugin-vue@^9.23.0 \
@rushstack/eslint-patch@^1.8.0 \
@vue/eslint-config-prettier@^9.0.0 \
@vue/eslint-config-typescript@^13.0.0
- name: Run ESLint
run: |
cp stubs/inertia-common/.prettierrc .
npx eslint --config stubs/inertia-react/.eslintrc.json stubs/inertia-react/resources/js --ext .js,.jsx --fix
npx eslint --config stubs/inertia-react-ts/.eslintrc.json stubs/inertia-react-ts/resources/js --ext .js,.jsx,.ts,.tsx --fix
npx eslint --config stubs/inertia-vue/.eslintrc.cjs stubs/inertia-vue/resources/js --ext .js,.vue --fix
npx eslint --config stubs/inertia-vue-ts/.eslintrc.cjs stubs/inertia-vue-ts/resources/js --ext .js,.ts,.vue --fix
- name: Clean up
run: rm -rf node_modules package.json package-lock.json .prettierrc

- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "ESLint: fix code styling"
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:

jobs:
stub-tests:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest

strategy:
fail-fast: true
Expand Down
8 changes: 0 additions & 8 deletions .styleci.yml

This file was deleted.

35 changes: 27 additions & 8 deletions src/Console/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class InstallCommand extends Command implements PromptsForMissingInput
{--pest : Indicate that Pest should be installed}
{--ssr : Indicates if Inertia SSR support should be installed}
{--typescript : Indicates if TypeScript is preferred for the Inertia stack}
{--eslint : Indicates if ESLint with Prettier should be installed}
{--composer=global : Absolute path to the Composer binary which should be used to install packages}';

/**
Expand Down Expand Up @@ -181,7 +182,6 @@ protected function hasComposerPackage($package)
/**
* Installs the given Composer Packages into the application.
*
* @param array $packages
* @param bool $asDev
* @return bool
*/
Expand Down Expand Up @@ -209,7 +209,6 @@ protected function requireComposerPackages(array $packages, $asDev = false)
/**
* Removes the given Composer Packages from the application.
*
* @param array $packages
* @param bool $asDev
* @return bool
*/
Expand All @@ -235,9 +234,8 @@ protected function removeComposerPackages(array $packages, $asDev = false)
}

/**
* Update the "package.json" file.
* Update the dependencies in the "package.json" file.
*
* @param callable $callback
* @param bool $dev
* @return void
*/
Expand All @@ -264,6 +262,29 @@ protected static function updateNodePackages(callable $callback, $dev = true)
);
}

/**
* Update the scripts in the "package.json" file.
*
* @return void
*/
protected static function updateNodeScripts(callable $callback)
{
if (! file_exists(base_path('package.json'))) {
return;
}

$content = json_decode(file_get_contents(base_path('package.json')), true);

$content['scripts'] = $callback(
array_key_exists('scripts', $content) ? $content['scripts'] : []
);

file_put_contents(
base_path('package.json'),
json_encode($content, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT).PHP_EOL
);
}

/**
* Delete the "node_modules" directory and remove the associated lock files.
*
Expand Down Expand Up @@ -302,7 +323,7 @@ protected function replaceInFile($search, $replace, $path)
*/
protected function phpBinary()
{
return (new PhpExecutableFinder())->find(false) ?: 'php';
return (new PhpExecutableFinder)->find(false) ?: 'php';
}

/**
Expand Down Expand Up @@ -331,7 +352,6 @@ protected function runCommands($commands)
/**
* Remove Tailwind dark classes from the given files.
*
* @param \Symfony\Component\Finder\Finder $finder
* @return void
*/
protected function removeDarkClasses(Finder $finder)
Expand Down Expand Up @@ -367,8 +387,6 @@ protected function promptForMissingArgumentsUsing()
/**
* Interact further with the user if they were prompted for missing arguments.
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return void
*/
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)
Expand All @@ -382,6 +400,7 @@ protected function afterPromptingForMissingArguments(InputInterface $input, Outp
'dark' => 'Dark mode',
'ssr' => 'Inertia SSR',
'typescript' => 'TypeScript',
'eslint' => 'ESLint with Prettier',
]
))->each(fn ($option) => $input->setOption($option, true));
} elseif (in_array($stack, ['blade', 'livewire', 'livewire-functional'])) {
Expand Down
82 changes: 82 additions & 0 deletions src/Console/InstallsInertiaStacks.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,46 @@ protected function installInertiaVueStack()
});
}

if ($this->option('eslint')) {
$this->updateNodePackages(function ($packages) {
return [
'eslint' => '^8.57.0',
'eslint-plugin-vue' => '^9.23.0',
'@rushstack/eslint-patch' => '^1.8.0',
'@vue/eslint-config-prettier' => '^9.0.0',
'prettier' => '^3.3.0',
'prettier-plugin-organize-imports' => '^4.0.0',
'prettier-plugin-tailwindcss' => '^0.6.5',
] + $packages;
});

if ($this->option('typescript')) {
$this->updateNodePackages(function ($packages) {
return [
'@vue/eslint-config-typescript' => '^13.0.0',
] + $packages;
});

$this->updateNodeScripts(function ($scripts) {
return $scripts + [
'lint' => 'eslint resources/js --ext .js,.ts,.vue --ignore-path .gitignore --fix',
];
});

copy(__DIR__.'/../../stubs/inertia-vue-ts/.eslintrc.cjs', base_path('.eslintrc.cjs'));
} else {
$this->updateNodeScripts(function ($scripts) {
return $scripts + [
'lint' => 'eslint resources/js --ext .js,.vue --ignore-path .gitignore --fix',
];
});

copy(__DIR__.'/../../stubs/inertia-vue/.eslintrc.cjs', base_path('.eslintrc.cjs'));
}

copy(__DIR__.'/../../stubs/inertia-common/.prettierrc', base_path('.prettierrc'));
}

// Providers...
(new Filesystem)->copyDirectory(__DIR__.'/../../stubs/inertia-common/app/Providers', app_path('Providers'));

Expand Down Expand Up @@ -216,6 +256,48 @@ protected function installInertiaReactStack()
});
}

if ($this->option('eslint')) {
$this->updateNodePackages(function ($packages) {
return [
'eslint' => '^8.57.0',
'eslint-plugin-react' => '^7.34.4',
'eslint-plugin-react-hooks' => '^4.6.2',
'eslint-plugin-prettier' => '^5.1.3',
'eslint-config-prettier' => '^9.1.0',
'prettier' => '^3.3.0',
'prettier-plugin-organize-imports' => '^4.0.0',
'prettier-plugin-tailwindcss' => '^0.6.5',
] + $packages;
});

if ($this->option('typescript')) {
$this->updateNodePackages(function ($packages) {
return [
'@typescript-eslint/eslint-plugin' => '^7.16.0',
'@typescript-eslint/parser' => '^7.16.0',
] + $packages;
});

$this->updateNodeScripts(function ($scripts) {
return $scripts + [
'lint' => 'eslint resources/js --ext .js,.jsx,.ts,.tsx --ignore-path .gitignore --fix',
];
});

copy(__DIR__.'/../../stubs/inertia-react-ts/.eslintrc.json', base_path('.eslintrc.json'));
} else {
$this->updateNodeScripts(function ($scripts) {
return $scripts + [
'lint' => 'eslint resources/js --ext .js,.jsx --ignore-path .gitignore --fix',
];
});

copy(__DIR__.'/../../stubs/inertia-react/.eslintrc.json', base_path('.eslintrc.json'));
}

copy(__DIR__.'/../../stubs/inertia-common/.prettierrc', base_path('.prettierrc'));
}

// Providers...
(new Filesystem)->copyDirectory(__DIR__.'/../../stubs/inertia-common/app/Providers', app_path('Providers'));

Expand Down
28 changes: 14 additions & 14 deletions stubs/api/routes/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,29 @@
use Illuminate\Support\Facades\Route;

Route::post('/register', [RegisteredUserController::class, 'store'])
->middleware('guest')
->name('register');
->middleware('guest')
->name('register');

Route::post('/login', [AuthenticatedSessionController::class, 'store'])
->middleware('guest')
->name('login');
->middleware('guest')
->name('login');

Route::post('/forgot-password', [PasswordResetLinkController::class, 'store'])
->middleware('guest')
->name('password.email');
->middleware('guest')
->name('password.email');

Route::post('/reset-password', [NewPasswordController::class, 'store'])
->middleware('guest')
->name('password.store');
->middleware('guest')
->name('password.store');

Route::get('/verify-email/{id}/{hash}', VerifyEmailController::class)
->middleware(['auth', 'signed', 'throttle:6,1'])
->name('verification.verify');
->middleware(['auth', 'signed', 'throttle:6,1'])
->name('verification.verify');

Route::post('/email/verification-notification', [EmailVerificationNotificationController::class, 'store'])
->middleware(['auth', 'throttle:6,1'])
->name('verification.send');
->middleware(['auth', 'throttle:6,1'])
->name('verification.send');

Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])
->middleware('auth')
->name('logout');
->middleware('auth')
->name('logout');
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ function ($user) use ($request) {
return $status == Password::PASSWORD_RESET
? redirect()->route('login')->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
->withErrors(['email' => __($status)]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ public function store(Request $request): RedirectResponse
return $status == Password::RESET_LINK_SENT
? back()->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
->withErrors(['email' => __($status)]);
}
}
Loading

0 comments on commit 6f41572

Please sign in to comment.