Skip to content

Instantly share code, notes, and snippets.

@willvincent
Last active February 9, 2020 08:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save willvincent/c24ddd327603394832eeb3d161fc7a9d to your computer and use it in GitHub Desktop.
Save willvincent/c24ddd327603394832eeb3d161fc7a9d to your computer and use it in GitHub Desktop.
Bash script to setup a reasonable base install of laravel with inertiajs + vue
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Usage: laravel-init app_name"
exit 1
fi
### GLOBAL COMPOSER PACKAGES
composer global require hirak/prestissimo friendsofphp/php-cs-fixer
### CREATE PROJECT
composer create-project laravel/laravel $1 --no-progress --prefer-dist
cd $1
### INSTALL PACKAGES
composer require fruitcake/laravel-cors \
laravel/telescope \
laravel/scout \
inertiajs/inertia-laravel \
pmatseykanets/laravel-scout-postgres \
mpociot/laravel-apidoc-generator
### INSTALL DEV PACKAGES
composer require barryvdh/laravel-debugbar \
barryvdh/laravel-ide-helper \
beyondcode/laravel-dump-server \
friendsofphp/php-cs-fixer --dev
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
php artisan vendor:publish --provider="Facade\Ignition\IgnitionServiceProvider"
php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider"
php artisan vendor:publish --provider="Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider"
php artisan vendor:publish --provider="Mpociot\ApiDoc\ApiDocGeneratorServiceProvider"
php artisan vendor:publish --provider="Fruitcake\Cors\CorsServiceProvider"
php artisan vendor:publish --provider="BeyondCode\DumpServer\DumpServerServiceProvider"
php artisan telescope:install
### INITIALIZE GIT REPO
git init
### JS PACKAGES
# Ensure we have the json tool globally available so we can update our package.json file in a moment
npm add json --global
# Install relevant dependencies
npm add @inertiajs/inertia @inertiajs/inertia-vue
npm add @commitlint/cli @commitlint/config-conventional eslint eslint-config-prettier eslint-plugin-prettier git-authors-cli lint-staged prettier standard-version sass sass-loader vue yorkie --save-dev
### UPDATE PACKAGE.JSON
json -I -f package.json -e "
this.version = '0.0.0'
this['lint-staged'] = {
'resources/**/*.{css,js,vue}': [ 'prettier --write' ],
'*.php': [ 'php ./vendor/bin/php-cs-fixer fix --config .php_cs' ]
}
this.gitHooks = {
'pre-commit': 'lint-staged',
'commit-msg': 'commitlint -E GIT_PARAMS'
}
this['standard-version'] = {
'scripts': { 'prerelease': 'git-authors-cli && git add package.json' }
}
this.scripts.release = './.scripts/release'
this.scripts.hotfix = './.scripts/hotfix'
"
### UPDATE COMPOSER.JSON
json -I -f composer.json -e "
this.version = '0.0.0'
this.name = '$1'
this.description = 'A laravel based project.'
this.license = 'private'
this.scripts['post-update-cmd'] = [
'Illuminate\\Foundation\\ComposerScripts::postUpdate',
'@php artisan ide-helper:generate',
'@php artisan ide-helper:meta'
]
"
### GENERATE IDE HELPER FILES
php artisan clear-compiled
php artisan ide-helper:generate
php artisan ide-helper:meta
###########################################################################################
### FILE SETUP
## git ignore ##
rm .gitignore
cat <<'EOF' > .gitignore
/.idea
/node_modules
/public/hot
/public/storage
/public/docs
/storage/*.key
/vendor
.env
.env.backup
.phpunit.result.cache
.php_cs.cache
.vscode
.DS_Store
**/.DS_Store
_ide_helper.php
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
EOF
## Editor Config ##
rm .editorconfig
cat <<'EOF' > .editorconfig
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.{js,vue}]
indent_size = 2
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
EOF
## eslint ignore ##
cat <<'EOF' > .eslintignore
node_modules
public
EOF
## eslintrc ##
cat <<'EOF' > .eslintrc.js
module.exports = {
root: true,
parserOptions: {
ecmaVersion: 2018,
},
globals: {
use: true,
},
env: {
node: true,
es6: true,
},
// globals: {
// },
extends: [
'eslint:recommended',
'plugin:prettier/recommended',
],
rules: {
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'comma-dangle': ['error', 'always-multiline'],
semi: ['error', 'never'],
'no-var': 'error',
'no-const-assign': 'error',
'no-unused-vars': 'warn',
// 'no-await-in-loop': 'warn',
'default-case': 'error',
eqeqeq: 'warn',
'linebreak-style': ['error', 'unix'],
'no-alert': 'warn',
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-unreachable': 'warn',
'no-else-return': 'warn',
'no-empty': 'warn',
'no-multi-spaces': 'warn',
'no-useless-return': 'warn',
'no-case-declarations': 'error',
yoda: 'error',
'no-use-before-define': 'warn',
'no-mixed-spaces-and-tabs': 'error',
'no-duplicate-imports': 'error',
'prefer-const': 'warn',
// indent: 'off',
'require-atomic-updates': 'warn',
'space-before-function-paren': 0,
'standard/computed-property-even-spacing': 'off',
'no-constant-condition': 'warn',
},
};
EOF
## php cs ##
cat <<'EOF' > .php_cs
<?php
$finder = PhpCsFixer\Finder::create()
->in(__DIR__)
->exclude(['bootstrap', 'storage', 'vendor', 'public', 'node_modules'])
->name('*.php')
->name('_ide_helper')
->notName('*.blade.php')
->ignoreDotFiles(true)
->ignoreVCS(true);
return PhpCsFixer\Config::create()
->setRules([
'@PSR2' => true,
'array_syntax' => ['syntax' => 'short'],
'array_indentation' => true,
'binary_operator_spaces' => ['default' => 'align_single_space'],
'list_syntax' => ['syntax' => 'short'],
'no_extra_blank_lines' => true,
'no_trailing_comma_in_list_call' => true,
'no_unused_imports' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'normalize_index_brace' => true,
'ordered_imports' => ['sortAlgorithm' => 'alpha'],
'trailing_comma_in_multiline_array' => true,
'whitespace_after_comma_in_array' => true,
])
->setFinder($finder);
EOF
## prettier ignore ##
cat <<'EOF' > .prettierignore
node_modules/
public/
EOF
## prettier rc ##
cat <<'EOF' > .prettierrc
{
"singleQuote": true,
"trailingComma": "es5",
"semi": false,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true
}
EOF
## commit lint ##
cat <<'EOF' > commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
// [LEVEL, APPLICABLE, VALUE]
//
// Level [0..2]: 0 disables the rule. For 1 it will be considered a warning for 2 an error.
// Applicable always|never: never inverts the rule.
// Value: value to use for this rule.
'scope-case': [2, 'always', 'start-case'],
'subject-case': [2, 'always', 'sentence-case'],
'subject-full-stop': [1, 'always', '.'],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
},
}
EOF
## init script ##
mkdir .scripts
cat <<'EOF' > .scripts/init
#!/bin/bash
set -ex
# Make composer faster
composer global require hirak/prestissimo
# Ensure git-authors-cli is globally available
npm install git-authors-cli --global
# Install nodejs packages
npm install
# Install composer packages
composer update
EOF
chmod +x .scripts/init
## release script ##
cat <<'EOF' > .scripts/release
#!/bin/sh
set -ex
git checkout master
git pull -r
node_modules/.bin/standard-version # bump version, update CHANGELOG
git push --follow-tags origin master
# Get this latest tag we just created (version)
VERSION=$(git describe)
# Move the production branch to this new release
git branch -f production $VERSION
# Push production (triggers drone deploy)
git push -f origin production
EOF
chmod +x .scripts/release
## hotfix script ##
cat <<'EOF' > .scripts/hotfix
#!/bin/sh
set -e
# Important note: this will add a new patch release AND deploy
if [ $# -lt 2 ]; then
# Interactively get info
echo "Enter the version to patch, in the format vX.Y.Z: \c"
read VERSION
COMMITS=""
echo "Enter a single commit to cherry-pick (you'll be able to enter more): \c"
while read -r COMMIT
do
[ -z $COMMIT ] && break
COMMITS="$COMMITS$COMMIT "
echo "Another commit (or ENTER if you're done): \c"
done
else
VERSION=$1
COMMITS=${@:2}
fi
if [[ $VERSION != v* ]]; then
echo "Version should be in the format vX.Y.Z"
exit 1
fi
set -x
git checkout $VERSION
# Cherry-pick the bugfix commit to this version
git cherry-pick $COMMITS
# Version bump, update CHANGELOG
node_modules/.bin/standard-version
# Get the new patch version, push tags
NEW_VERSION=$(git describe)
git push --follow-tags origin $NEW_VERSION
# Move the production branch to this new release
git branch -f production $NEW_VERSION
# Push production
git push -f origin production
git checkout master
EOF
chmod +x .scripts/hotfix
## versionrc.js
cat <<'EOF' > .versionrc.js
const config = {};
config.bumpFiles = [
"package.json",
"composer.json"
];
module.exports = config;
EOF
## readme ##
rm README.md
cat <<'EOF' > README.md
# Base Laravel Starter
## Changelog
[CHANGELOG.md](CHANGELOG.md)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)
## Installation
NOTE: You _must_ have node and PHP installed on your _local_ machine, not just within homestead to use the various tooling around git commit linting, style checking, etc.
1. Clone this repo
1. `cd` into directory for this repo
1. run `.scripts/init`
1. In your copy of .env file edit/change default settings as necessary.
1. Any .env changes that need to be shared should be added to the .env.example file as well.
1. Refresh/generate api docs for yourself as needed: `composer make-docs`
Recommend using either [Valet](https://laravel.com/docs/6.x/valet#installation) or [Laravel Homestead](https://laravel.com/docs/6.x/homestead#installation-and-setup)
## API Documentation
The codebase automatically generates its own documentation through docblock comments on controller methods. This documentation is available to be reviewed via web browser at the `/docs` route.
Review the [documenting your api](https://laravel-apidoc-generator.readthedocs.io/en/latest/documenting.html#) section of the laravel apidoc package for complete details on implementing appropriate docblock comments for api documentation generation.
**NOTE:** As this exists in the `/public` folder, it is world-viewable, and will either need alternate config and/or custom webserver config if it is to be included outside of local environments!
## Development workflow
1. Each new feature should be built within a dedicated feature branch, named according to its function: ie: `feature/user-permissions`
1. Ideally, each new feature should also include a test suite of unit and/or functional tests, or browser-tests when applicable
1. As routes are added, or changed controller docblocks should be updated to keep api documentation accurate
1. When the feature is completed a pull request to the master branch will be created, features should only be merged in after review, and not prior to completion of that feature.
1. The master branch will always be maintained in a "ready for deployment" state.
1. PHP & Javascript files will automatically be linted and reformatted during commits, if lint errors are present that cannot be resolved, the commit will be disallowed.
1. Commit messages must adhere to the [conventional-changelog standard](https://www.conventionalcommits.org/en/v1.0.0/), with messages in the following format:
`type(Feature Name): Sentence describing what was done.`
Where `type` is one of: fix, feat, docs, test, chore -- all lowercase
Feature Name is optional, if omitted, also omit the parenthesis. If included it should be in _Title Case_
The sentence should be properly capitalized with a period at the end.
**Important** If the change includes a _breaking_ change, that must be noted in the body of the commit message (two lines below the description). For example:
```
feat(Ham Sandwich): Adds a delicious ham sandwich feature.
BREAKING CHANGE: Causes pumpernickel bread to become unavailable.
```
This allows automated changelog generation from git commit history, and keeps commit messages from becoming irrelevant/useless. Only `feat` and `fix` commit messages will be populated into the changelog.
EOF
### Run PHP CS FIXER
php vendor/bin/php-cs-fixer fix --config .php_cs
### INITIAL COMMIT
git add .
git commit -m "Initial commit" --no-verify
### DONE!
echo ""
echo ""
echo ""
echo "#############################"
echo "## INSTALLATION COMPLETE ##"
echo "#############################"
echo ""
echo "cd into [$1] and build something awesome!"
echo ""
echo "Reminders:"
echo " - Update config files [$1/config]"
echo " - Review server and client install instructions for inertiajs: https://inertiajs.com"
echo ""
echo ""
@willvincent
Copy link
Author

willvincent commented Feb 5, 2020

Also installs and configures php_cs_fixer, eslint, prettier, commit lint, lint (and fix) of staged php / js / vue files, larvel scout & scout postgres driver, debugbar, telescope, ide helper, etc.

Also provides some starting points for init, release and hotfix scripts.

Assumes you have a working installation of composer and npm, of course php with all the necessary extensions for laravel, and are on a linux/mac os.. may work with bash on windows, but no guarantee..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment