Skip to content

Commit

Permalink
Merge pull request #66 from CornellCustomDev/updates
Browse files Browse the repository at this point in the history
Installer can be used for updates
  • Loading branch information
woodseowl authored Oct 31, 2024
2 parents bc4f73c + 58a5829 commit 68e3a8e
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 102 deletions.
37 changes: 23 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A Cornell University CIT Custom Development starter kit and library for Laravel.

The Starter Kit can be used as a starter kit for a new site or as a library for an existing site.

### Starter Kit
### As a Starter Kit for a New Site

Used as a starter kit, this package deploys the cwd_framework_lite infrastructure and standard configuration files. The
steps below get from a fresh Laravel install to a working site.
Expand Down Expand Up @@ -43,12 +43,16 @@ steps below get from a fresh Laravel install to a working site.
```shell
php artisan starterkit:install
```
This will publish `README.md`, `.env.example`, `.gitignore`, and `.lando.yml` files to the base directory, configured on the project settings and update the `composer.json` file to match. It will also publish HTML/CSS/JS assets from [cwd_framework_lite](https://github.com/CU-CommunityApps/cwd_framework_lite) and a set of [view components](https://laravel.com/docs/10.x/blade#layouts-using-components) that can be used to begin a layout (see `views/cd-index.blade.php` for example usage).
> **NOTE**: The install step updates `.gitignore` so that the vendor directory is no longer excluded. The next commit will be large because it includes everything in the vendor directory.
>```shell
> git add . && git commit -m "Starter Kit install"
> git push
>```
The `starterkit:install` command prompts for a set of install options:
- publish configured [project files](project) to the base directory and update the `composer.json` file to match
- publish HTML/CSS/JS theme assets from [cwd_framework_lite](https://github.com/CU-CommunityApps/cwd_framework_lite)
- publish a set of [view components](https://laravel.com/docs/10.x/blade#layouts-using-components) that can be used to begin a layout
- publish [example blade files](resources/views/examples) to see usage of the layout
> **NOTE**: The "project files" option updates `.gitignore` so that the vendor directory is no longer excluded. The next commit will be large because it includes everything in the vendor directory.
> ```shell
> git add . && git commit -m "Starter Kit install"
> git push
> ```
4. Testing the site<br>
You can confirm the site is working with Lando, since the Starter Kit install process adds a `.lando.yml` file.
Expand All @@ -60,15 +64,20 @@ steps below get from a fresh Laravel install to a working site.
@include('cd-index')
```
### Existing Site
### As a Library for an Existing Site
For an existing Laravel site, this package can be composer-required to provide the library of classes. In this case, you
will not need to run the full Starter Kit install.
For an existing Laravel site, this package can be composer-required to provide the library of classes and optionally install some components.
```php
composer require --update-no-dev cornell-custom-dev/laravel-starter-kit
```
1. Composer require the LaravelStarterKit
```shell
composer require cornell-custom-dev/laravel-starter-kit
```
2. Install the Starter Kit
```shell
php artisan starterkit:install
```
Note: When using as a library or updating an installation, you will not want to install the project files. You may still want to install the theme assets, view components, and possibly example files. Be aware that these will overwrite existing files.
## Libraries
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
"type": "library",
"require": {
"php": "^8.2",
"livewire/livewire": "^3.3",
"livewire/livewire": "^3.5",
"spatie/laravel-package-tools": "^1.16",
"cubear/cwd_framework_lite": "^3.0",
"propaganistas/laravel-phone": "^5.3",
"giggsey/locale": "^2.6"
},
"require-dev": {
"orchestra/testbench": "^8.22",
"orchestra/testbench": "^8.24",
"phpunit/phpunit": "^10.5",
"laravel/pint": "^1.15"
"laravel/pint": "^1.17"
},
"autoload": {
"psr-4": {
Expand Down
28 changes: 24 additions & 4 deletions project/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@ APP_NAME=":project_name"
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_TIMEZONE=America/New_York
APP_URL=https://:project_slug

APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US

APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=database

BCRYPT_ROUNDS=12

LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug

Expand All @@ -15,12 +26,19 @@ DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=laravel

BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=null

BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync

CACHE_DRIVER=file
# CACHE_STORE=database
# CACHE_PREFIX=

MAIL_MAILER=log
MAIL_HOST=mailpit
Expand All @@ -30,3 +48,5 @@ MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="[email protected]"
MAIL_FROM_NAME="${APP_NAME}"

VITE_APP_NAME="${APP_NAME}"
1 change: 1 addition & 0 deletions project/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
.env
.env.backup
.env.production
.phpactor.json
.phpunit.result.cache
Homestead.json
Homestead.yaml
Expand Down
File renamed without changes.
File renamed without changes.
131 changes: 92 additions & 39 deletions src/StarterKitServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@

namespace CornellCustomDev\LaravelStarterKit;

use Illuminate\Support\Arr;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Spatie\LaravelPackageTools\Commands\InstallCommand;
use Spatie\LaravelPackageTools\Package;
use Spatie\LaravelPackageTools\PackageServiceProvider;

use function Laravel\Prompts\confirm;
use function Laravel\Prompts\info;
use function Laravel\Prompts\multiselect;
use function Laravel\Prompts\suggest;
use function Laravel\Prompts\text;

class StarterKitServiceProvider extends PackageServiceProvider
{
const PACKAGE_NAME = 'starterkit';
Expand All @@ -24,7 +29,8 @@ class StarterKitServiceProvider extends PackageServiceProvider
'.env.example',
'.gitignore',
'.lando.yml',
'public/.htaccess',
// Comment this out until we need to include mod_shib config
// 'public/.htaccess',
];

public const ASSET_FILES = [
Expand All @@ -35,29 +41,44 @@ class StarterKitServiceProvider extends PackageServiceProvider
'favicon.ico',
];

public const EXAMPLE_FILES = [
'resources/views/examples/cd-index.blade.php',
// Comment this out until we have better form components and form example
// 'resources/views/examples/form-example.blade.php',
];

public function boot()
{
parent::boot();

$themeDir = '/vendor/cubear/cwd_framework_lite';
$themeAssetsPath = File::isDirectory(base_path().$themeDir) ? base_path() : __DIR__.'/..';
$filesSourcePath = __DIR__.'/..';

if ($this->app->runningInConsole()) {
foreach (self::INSTALL_FILES as $installFileName) {
$this->publishes([
__DIR__."/../project/{$installFileName}" => base_path($installFileName),
], self::PACKAGE_NAME.'-install');
], self::PACKAGE_NAME.':files');
}

foreach (self::ASSET_FILES as $asset_file) {
$this->publishes([$themeAssetsPath.$themeDir.'/'.$asset_file => public_path(self::THEME_NAME.'/'.$asset_file),
], self::THEME_NAME.'-assets');
$this->publishes([
$themeAssetsPath.$themeDir.'/'.$asset_file => public_path(self::THEME_NAME.'/'.$asset_file),
], self::THEME_NAME.':assets');
}
$exampleFile = 'cd-index.blade.php';

$this->publishes([
__DIR__.'/../resources/views/components/cd' => resource_path('/views/components/cd'),
__DIR__."/../resources/views/$exampleFile" => resource_path("/views/$exampleFile"),
], self::PACKAGE_NAME.'-install');
"$filesSourcePath/resources/views/components/cd/layout" => resource_path('/views/components/cd/layout'),
// Comment this out until we have better form components
// "$filesSourcePath/resources/views/components/cd/form" => resource_path('/views/components/cd/form'),
], self::PACKAGE_NAME.':components');

foreach (self::EXAMPLE_FILES as $exampleFile) {
$this->publishes([
"$filesSourcePath/$exampleFile" => base_path($exampleFile),
], self::PACKAGE_NAME.':examples');
}
}
}

Expand All @@ -72,39 +93,83 @@ public function configurePackage(Package $package): void

private function install(InstallCommand $command)
{
$command->info('Installing StarterKit...');
info('Installing StarterKit...');

$install = collect(multiselect(
label: 'What would you like to install or update?',
options: [
'files' => 'Basic project files (README, .env.example, etc.) and update composer.json',
'assets' => 'Theme assets from CWD Framework Lite',
'components' => 'View components (/resources/views/components/cd)',
'examples' => 'Example blade files',
],
default: ['files', 'assets', 'components'],
required: true,
hint: 'Note: Any existing files will be replaced for the selected options.',
));

$installFiles = $install->contains('files');
$installExamples = $install->contains('examples');

if ($installFiles || $installExamples) {
$basePathTitle = Str::title(File::basename(base_path()));
$composerConfig = json_decode(File::get(base_path('composer.json')), true);
// Turn something like "cornell-custom-dev/laravel-demo" into "Laravel Demo"
$composerTitle = Str::title(str_replace('-', ' ', Str::after($composerConfig['name'], '/')));
$projectName = suggest(
label: 'Project name',
options: array_filter([$basePathTitle, $composerTitle]),
required: true,
hint: 'This is used in the README and slugified for use in .env, composer.json, etc.',
);

$projectName = $command->ask('Project name', Str::title(File::basename(base_path())));
$projectDescription = $command->ask('Project description', self::PROJECT_DESCRIPTION);
$projectDescription = text(
label: 'Project description',
default: self::PROJECT_DESCRIPTION,
required: true,
hint: 'This is used in the README and composer.json.',
);
}

$file_list = Arr::join(self::INSTALL_FILES, ', ');
$shouldInstallFiles = $command->confirm(
question: 'Install Starter Kit assets and files?',
default: true,
);
if ($shouldInstallFiles) {
$this->publishAssets($command);
$this->publishFiles($command, $projectName);
// Confirm before proceeding
if (! confirm('Proceed with installation?')) {
info('Installation aborted.');

return;
}

if ($installFiles) {
$this->publishTag($command, self::PACKAGE_NAME.':files');
$this->populatePlaceholders(self::INSTALL_FILES, $projectName, $projectDescription);
$this->updateComposerJson($projectName, $projectDescription);
}

$command->info('File installation complete.');
if ($install->contains('assets')) {
$this->publishTag($command, self::THEME_NAME.':assets');
}

if ($install->contains('components')) {
$this->publishTag($command, self::PACKAGE_NAME.':components');
}

if ($installExamples) {
$this->publishTag($command, self::PACKAGE_NAME.':examples');
$this->populatePlaceholders(self::EXAMPLE_FILES, $projectName);
}

info('Installation complete.');
}

private function publishFiles(InstallCommand $command, string $projectName)
private function publishTag(InstallCommand $command, string $tag): void
{
$command->call(
command: 'vendor:publish',
arguments: [
'--provider' => StarterKitServiceProvider::class,
'--tag' => self::PACKAGE_NAME.'-install',
'--tag' => $tag,
'--force' => true,
]
);
$this->populatePlaceholders([
'resources/views/cd-index.blade.php',
], $projectName);
}

public static function populatePlaceholders($files, string $projectName, ?string $projectDescription = null): void
Expand All @@ -128,19 +193,7 @@ public static function populatePlaceholders($files, string $projectName, ?string
}
}

private function publishAssets(InstallCommand $command)
{
$command->call(
command: 'vendor:publish',
arguments: [
'--provider' => StarterKitServiceProvider::class,
'--tag' => self::THEME_NAME.'-assets',
'--force' => true,
]
);
}

private function updateComposerJson(string $projectName, string $projectDescription)
private function updateComposerJson(string $projectName, string $projectDescription): void
{
$composerFile = base_path('composer.json');
$composerConfig = json_decode(File::get($composerFile), true);
Expand Down
Loading

0 comments on commit 68e3a8e

Please sign in to comment.