Skip to content

Commit f983e53

Browse files
committed
feat: Add editorconfig, gitignore, and CLI commands
- Added .editorconfig for coding style unification - Included .gitignore for system and editor files - Implemented CLI commands for installation, options, roots, routes, template - Created classes for Command, Install, Options, Roots, Routes, Template
1 parent e012917 commit f983e53

File tree

19 files changed

+703
-1
lines changed

19 files changed

+703
-1
lines changed

.editorconfig

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This file is for unifying the coding style for different editors and IDEs
2+
# editorconfig.org
3+
4+
# PHP PSR-12 Coding Standards
5+
# https://www.php-fig.org/psr/psr-12/
6+
7+
root = true
8+
9+
[*.{css,scss,less,js,json,ts,sass,html,hbs,mustache,phtml,html.twig,md,yml}]
10+
charset = utf-8
11+
indent_style = space
12+
indent_size = 2
13+
end_of_line = lf
14+
insert_final_newline = true
15+
trim_trailing_whitespace = true
16+
17+
[*.php]
18+
charset = utf-8
19+
end_of_line = lf
20+
indent_style = tab
21+
indent_size = 4
22+
trim_trailing_whitespace = true
23+
24+
[*.md]
25+
indent_size = 4
26+
trim_trailing_whitespace = false
27+
28+
[package.json,.{babelrc,editorconfig,eslintrc,lintstagedrc,stylelintrc}]
29+
indent_style = space
30+
indent_size = 2

.gitignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# System files
2+
# ------------
3+
4+
Icon
5+
.DS_Store
6+
7+
# Editors
8+
# (sensitive workspace files)
9+
# ---------------------------
10+
*.sublime-workspace
11+
/.vscode
12+
/.idea
13+
.php-cs-fixer.cache
14+
15+
## Composer
16+
# ---------------
17+
/vendor
18+
19+
## Frontend
20+
# ---------------
21+
.sass-cache
22+
node_modules
23+
npm-debug.log

README.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,29 @@
1-
# kx-devutils
1+
# Kirby devutils plugin
2+
3+
Some handy Kirby commands to help during Kirby development.
4+
5+
## License
6+
7+
MIT
8+
9+
## Installation
10+
11+
### Download
12+
13+
Download and copy this repository to `/site/plugins/kx-devutils`.
14+
15+
### Git submodule
16+
17+
```
18+
git submodule add https://github.com/genxbe/kx-devutils.git site/plugins/kx-devutils
19+
```
20+
21+
### Composer
22+
23+
```
24+
composer require genxbe/kx-devutils
25+
```
26+
27+
## Credits
28+
29+
- [Sam Serrien](https://sam.serrien.be) @ [GeNx](https://genx.be)

classes/Commands/Command.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace X\Commands\Commands;
4+
5+
use Kirby\Cms\App;
6+
use Kirby\CLI\CLI;
7+
8+
class Command
9+
{
10+
protected CLI $cli;
11+
protected App $kirby;
12+
13+
public function __construct(CLI $cli)
14+
{
15+
$this->cli = $cli;
16+
$this->kirby = App::instance();
17+
}
18+
}

classes/Commands/Install.php

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
namespace X\Commands\Commands;
4+
5+
use Kirby\CLI\CLI;
6+
use Kirby\Filesystem\F;
7+
use X\Commands\Lib\Shell;
8+
9+
use function Laravel\Prompts\info;
10+
use function Laravel\Prompts\alert;
11+
use function Laravel\Prompts\error;
12+
use function Laravel\Prompts\warning;
13+
use function Laravel\Prompts\spin;
14+
use function Laravel\Prompts\progress;
15+
16+
class Install extends Command
17+
{
18+
public function __construct(CLI $cli)
19+
{
20+
parent::__construct($cli);
21+
22+
$this->checkEnv();
23+
24+
if(empty($cli->arg('--nophp'))) {
25+
$this->composerInstall();
26+
}
27+
28+
if(empty($cli->arg('--nojs'))) {
29+
$this->jsInstall();
30+
}
31+
}
32+
33+
private function jsInstall(): void
34+
{
35+
if(F::exists($this->kirby->root().'/yarn.lock')) {
36+
$framework = 'yarn';
37+
}
38+
39+
if(F::exists($this->kirby->root().'/package.json')) {
40+
$framework = 'npm';
41+
}
42+
43+
if(empty($framework)) {
44+
error('❌ JS Framework not installed, package.json and yarn.lock not found.');
45+
return;
46+
}
47+
48+
$success = progress(
49+
label: "Running {$framework} install...",
50+
steps: 1,
51+
callback: function() use($framework) {
52+
return Shell::run("{$framework} install");
53+
},
54+
);
55+
56+
if($success[0] === false) {
57+
error('❌ npm install failed.');
58+
return;
59+
}
60+
61+
info("🚀 {$framework} installed");
62+
}
63+
64+
private function composerInstall(): void
65+
{
66+
if(!F::exists($this->kirby->root().'/composer.json')) {
67+
error('❌ Composer not installed, composer.json not found.');
68+
return;
69+
}
70+
71+
$success = progress(
72+
label: 'Running composer install...',
73+
steps: 1,
74+
callback: function() {
75+
Shell::run('composer install');
76+
},
77+
);
78+
79+
if($success[0] === false) {
80+
error('❌ composer install failed.');
81+
return;
82+
}
83+
84+
info('🚀 Composer installed');
85+
}
86+
87+
private function checkEnv(): void
88+
{
89+
$env = $this->kirby->root().'/.env';
90+
$envExample = $this->kirby->root('root').'/.env.example';
91+
92+
if(!F::exists($env) && F::exists($envExample)) {
93+
error('❌ .env file not found.');
94+
info('🚀 Copying .env.example to .env...');
95+
96+
F::copy($envExample, $env);
97+
}
98+
99+
if(!F::exists($env) && !F::exists($envExample)) {
100+
alert('❌ .env & .env.example file not found.');
101+
info('🚀 Creating new basic .env file...');
102+
103+
$envContent = <<<'ENV'
104+
# APP_ENV = local|staging|production
105+
APP_ENV=local
106+
APP_DEBUG=false
107+
ENV;
108+
109+
F::write($env, $envContent);
110+
}
111+
112+
info('🚀 .env file is correctly installed.');
113+
}
114+
115+
}

classes/Commands/Options.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
namespace X\Commands\Commands;
4+
5+
use Kirby\CLI\CLI;
6+
use Kirby\Toolkit\Str;
7+
use X\Commands\Lib\Toolkit;
8+
9+
use function Laravel\Prompts\info;
10+
use function Laravel\Prompts\table;
11+
use function Laravel\Prompts\error;
12+
use function Laravel\Prompts\suggest;
13+
14+
class Options extends Command
15+
{
16+
public function __construct(CLI $cli)
17+
{
18+
parent::__construct($cli);
19+
20+
if($cli->arg('--all')) {
21+
return $this->getOptions();
22+
}
23+
24+
$this->selectPlugin();
25+
}
26+
27+
private function selectPlugin()
28+
{
29+
$plugins = $this->kirby->plugins();
30+
$fullPluginNames = array_keys(array_map(function($plugin) {
31+
return $plugin->name();
32+
}, $plugins));
33+
34+
foreach($fullPluginNames as $plugin) {
35+
$pluginParts = explode('/', $plugin);
36+
$pluginNames[] = $pluginParts[1]." ({$plugin})";
37+
}
38+
39+
$safePluginNames = array_merge($fullPluginNames, $pluginNames);
40+
41+
$selectedPlugin = suggest(
42+
label: 'Do you want options for a specific plugin? (Leavy empty for all)',
43+
options: $safePluginNames,
44+
placeholder: 'E.g. ray or bnomei/...',
45+
);
46+
47+
return $this->getOptions($selectedPlugin);
48+
}
49+
50+
private function getOptions(string $plugin = null)
51+
{
52+
$allOptions = $this->kirby->options();
53+
54+
if(!empty($plugin)) {
55+
if(Str::contains($plugin, '(')) {
56+
$plugin = Str::between($plugin, '(', ')');
57+
}
58+
59+
60+
if(!empty($allOptions[Str::replace($plugin, '/', '.')])) {
61+
$pluginOptions = $allOptions[Str::replace($plugin, '/', '.')];
62+
return $this->printOptions($plugin, $pluginOptions);
63+
}
64+
65+
return error('❌ Plugin not found.');
66+
}
67+
68+
return $this->printAllOptions($allOptions);
69+
}
70+
71+
private function printOptions(string $plugin, array $pluginOptions)
72+
{
73+
$pluginOptions = Toolkit::flattenArray($pluginOptions);
74+
75+
$table = [];
76+
foreach($pluginOptions as $option => $default)
77+
{
78+
$default = Toolkit::stringify($default);
79+
80+
array_push($table, [
81+
'option' => $option,
82+
'default' => $default,
83+
]);
84+
}
85+
86+
table(
87+
headers: ['Option', 'Default'],
88+
rows: $table,
89+
);
90+
}
91+
92+
private function printAllOptions(array $allOptions)
93+
{
94+
foreach($allOptions as $group => $options) {
95+
$groupOptions = Toolkit::flattenArray($options);
96+
97+
if(is_array($groupOptions)) {
98+
$table = [];
99+
100+
foreach($groupOptions as $option => $default) {
101+
array_push($table, [
102+
'group' => $group,
103+
'option' => $option,
104+
'default' => $default,
105+
]);
106+
}
107+
108+
if(empty($table)) {
109+
continue;
110+
}
111+
112+
info($group);
113+
114+
table(
115+
headers: ['Option', 'Default'],
116+
rows: array_map(function($item) {
117+
return [
118+
$item['option'],
119+
Str::short(Toolkit::stringify($item['default']), 50),
120+
];
121+
}, $table),
122+
);
123+
}
124+
125+
if(!is_array($groupOptions)) {
126+
if($groupOptions instanceof \Closure) {
127+
$groupOptions = '-- Closure --';
128+
}
129+
130+
info($group);
131+
132+
table(
133+
headers: ['Option', 'Default'],
134+
rows: [
135+
[$group, Toolkit::stringify($groupOptions)],
136+
],
137+
);
138+
}
139+
}
140+
}
141+
}

classes/Commands/Roots.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace X\Commands\Commands;
4+
5+
use Kirby\CLI\CLI;
6+
7+
use function Laravel\Prompts\table;
8+
9+
class Roots extends Command
10+
{
11+
public function __construct(CLI $cli)
12+
{
13+
parent::__construct($cli);
14+
15+
$roots = $cli->roots();
16+
ksort($roots);
17+
18+
table(
19+
headers: ['Root', 'Path'],
20+
rows: array_map(
21+
static function ($root, $path) {
22+
return [$root, $path];
23+
},
24+
array_keys($roots),
25+
array_values($roots)
26+
)
27+
);
28+
}
29+
}

0 commit comments

Comments
 (0)