@codigodoleo/wp-kit 3.2.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +73 -194
  2. package/lib/core/infer-ci-capabilities.js +17 -0
  3. package/lib/prompts/index.js +64 -4
  4. package/modules/blank-theme/index.js +71 -0
  5. package/modules/blank-theme/lint/.prettierrc.json +12 -0
  6. package/modules/blank-theme/lint/.stylelintrc.json +7 -0
  7. package/modules/{lint → blank-theme/lint}/eslint.config.mjs +2 -8
  8. package/modules/blank-theme/lint/pint.json +11 -0
  9. package/modules/blank-theme/prompts.js +33 -0
  10. package/modules/blank-theme/templates/.lando.yml.hbs +26 -0
  11. package/modules/blank-theme/templates/functions.php.hbs +46 -0
  12. package/modules/blank-theme/templates/package.json.hbs +16 -0
  13. package/modules/blank-theme/templates/style.css.hbs +7 -0
  14. package/modules/blank-theme/templates/vite.config.js.hbs +23 -0
  15. package/modules/deploy/.github/workflows/deploy-docker.yml +2 -0
  16. package/modules/deploy/.github/workflows/deploy-ssh.yml +2 -0
  17. package/modules/deploy/.github/workflows/release.yml +2 -0
  18. package/modules/deploy/index.js +38 -0
  19. package/modules/deploy/templates/.github/workflows/ci.yml.hbs +29 -1
  20. package/modules/deploy/templates/.gitlab/ci/lint-blank-theme.yml.hbs +35 -0
  21. package/modules/deploy/templates/.gitlab/ci/lint-mu-plugin.yml.hbs +19 -0
  22. package/modules/deploy/templates/.gitlab/ci/lint-plugin.yml.hbs +19 -0
  23. package/modules/deploy/templates/.gitlab/ci/lint-sage.yml.hbs +47 -0
  24. package/modules/git/templates/workspace.json.hbs +1 -1
  25. package/modules/lint/.commitlintrc.json +21 -0
  26. package/modules/lint/.prettierignore +15 -25
  27. package/modules/lint/.prettierrc.json +5 -16
  28. package/modules/lint/index.js +75 -8
  29. package/modules/lint/prompts.js +1 -8
  30. package/modules/lint/templates/.lando.yml.hbs +3 -8
  31. package/modules/lint/templates/workspace.json.hbs +3 -3
  32. package/modules/mu-plugin/index.js +49 -0
  33. package/modules/mu-plugin/lint/.prettierrc.json +7 -0
  34. package/modules/mu-plugin/lint/eslint.config.mjs +30 -0
  35. package/modules/mu-plugin/lint/pint.json +11 -0
  36. package/modules/mu-plugin/prompts.js +23 -0
  37. package/modules/mu-plugin/templates/.lando.yml.hbs +15 -0
  38. package/modules/mu-plugin/templates/composer.json.hbs +14 -0
  39. package/modules/mu-plugin/templates/plugin.php.hbs +15 -0
  40. package/modules/php/templates/composer.json.hbs +15 -1
  41. package/modules/plugin/index.js +45 -0
  42. package/modules/plugin/lint/.prettierrc.json +7 -0
  43. package/modules/plugin/lint/eslint.config.mjs +30 -0
  44. package/modules/plugin/lint/pint.json +11 -0
  45. package/modules/plugin/prompts.js +23 -0
  46. package/modules/plugin/templates/.lando.yml.hbs +15 -0
  47. package/modules/plugin/templates/composer.json.hbs +14 -0
  48. package/modules/plugin/templates/plugin.php.hbs +15 -0
  49. package/modules/sage/index.js +25 -0
  50. package/modules/sage/lint/.prettierrc.json +12 -0
  51. package/modules/sage/lint/.stylelintrc.json +7 -0
  52. package/modules/sage/lint/eslint.config.mjs +30 -0
  53. package/modules/sage/lint/pint.json +11 -0
  54. package/modules/sage/prompts.js +22 -7
  55. package/modules/sage/templates/.devcontainer/docker-compose.override.yml.hbs +1 -3
  56. package/modules/sage/templates/.lando.yml.hbs +17 -5
  57. package/modules/sage/templates/theme/vite.config.js.hbs +4 -4
  58. package/package.json +7 -1
  59. package/templates/.devcontainer/docker-compose.yml.hbs +3 -0
  60. package/templates/.gitignore.hbs +84 -13
  61. package/templates/.lando.yml.hbs +2 -0
  62. package/templates/composer.json.hbs +60 -13
  63. package/templates/workspace.json.hbs +1 -1
  64. package/modules/lint/.eslintignore +0 -36
  65. package/modules/lint/.eslintrc.json +0 -8
  66. package/modules/lint/.stylelintignore +0 -19
  67. package/modules/lint/.stylelintrc.json +0 -9
  68. package/modules/lint/pint.json +0 -26
@@ -0,0 +1,46 @@
1
+ <?php
2
+ /**
3
+ * Theme functions and definitions.
4
+ *
5
+ * @package {{blank_theme_name}}
6
+ */
7
+
8
+ if (!defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ define('{{blank_theme_name}}_VERSION', '{{projectVersion}}');
13
+ define('{{blank_theme_name}}_DIR', get_template_directory());
14
+ define('{{blank_theme_name}}_URI', get_template_directory_uri());
15
+
16
+ /**
17
+ * Enqueue Vite-compiled assets.
18
+ */
19
+ add_action('wp_enqueue_scripts', function () {
20
+ $manifest = {{blank_theme_name}}_DIR . '/dist/.vite/manifest.json';
21
+
22
+ if (!file_exists($manifest)) {
23
+ return;
24
+ }
25
+
26
+ $data = json_decode(file_get_contents($manifest), true);
27
+
28
+ if (isset($data['src/js/app.js']['file'])) {
29
+ wp_enqueue_script(
30
+ '{{blank_theme_name}}-app',
31
+ {{blank_theme_name}}_URI . '/dist/' . $data['src/js/app.js']['file'],
32
+ [],
33
+ null,
34
+ true
35
+ );
36
+ }
37
+
38
+ if (isset($data['src/scss/app.scss']['file'])) {
39
+ wp_enqueue_style(
40
+ '{{blank_theme_name}}-app',
41
+ {{blank_theme_name}}_URI . '/dist/' . $data['src/scss/app.scss']['file'],
42
+ [],
43
+ null
44
+ );
45
+ }
46
+ });
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "{{blank_theme_name}}",
3
+ "version": "{{projectVersion}}",
4
+ "description": "{{projectDescription}}",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "lint": "eslint src/js --ext .js,.ts",
10
+ "lint:css": "stylelint \"src/scss/**/*.scss\""
11
+ },
12
+ "devDependencies": {
13
+ "vite": "^6.0.0",
14
+ "sass-embedded": "^1.77.0"
15
+ }
16
+ }
@@ -0,0 +1,7 @@
1
+ /*
2
+ Theme Name: {{blank_theme_name}}
3
+ Description: {{projectDescription}}
4
+ Version: {{projectVersion}}
5
+ Author: {{author}}
6
+ Text Domain: {{blank_theme_name}}
7
+ */
@@ -0,0 +1,23 @@
1
+ import { defineConfig } from 'vite';
2
+
3
+ export default defineConfig({
4
+ base: '/app/content/themes/{{blank_theme_name}}/dist/',
5
+ build: {
6
+ outDir: 'dist',
7
+ rollupOptions: {
8
+ input: {
9
+ app: 'src/js/app.js',
10
+ styles: 'src/scss/app.scss',
11
+ },
12
+ },
13
+ manifest: true,
14
+ emptyOutDir: true,
15
+ },
16
+ css: {
17
+ preprocessorOptions: {
18
+ scss: {
19
+ api: 'modern-compiler',
20
+ },
21
+ },
22
+ },
23
+ });
@@ -56,6 +56,8 @@ jobs:
56
56
  build-push:
57
57
  name: Build & Push
58
58
  runs-on: ubuntu-latest
59
+ env:
60
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
59
61
  steps:
60
62
  - name: Checkout
61
63
  uses: actions/checkout@v4
@@ -72,6 +72,8 @@ jobs:
72
72
  build-and-deploy:
73
73
  name: Build & Deploy via SSH
74
74
  runs-on: ubuntu-latest
75
+ env:
76
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
75
77
  steps:
76
78
  - name: Checkout
77
79
  uses: actions/checkout@v4
@@ -32,6 +32,8 @@ jobs:
32
32
  release:
33
33
  name: Semantic Release
34
34
  runs-on: ubuntu-latest
35
+ env:
36
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
35
37
  steps:
36
38
  - name: Checkout
37
39
  uses: actions/checkout@v4
@@ -33,6 +33,44 @@ export async function setupModule(context, generator) {
33
33
  '.gitlab/ci/deploy-ssh.yml'
34
34
  );
35
35
  log(color.green, '[deploy] Jobs reutilizáveis GitLab gerados em .gitlab/ci/');
36
+
37
+ // Lint jobs condicionais por módulo
38
+ if (context.ci?.lint?.sage) {
39
+ await generator.generateFile(
40
+ '.gitlab/ci/lint-sage.yml',
41
+ context,
42
+ 'deploy',
43
+ '.gitlab/ci/lint-sage.yml'
44
+ );
45
+ log(color.green, '[deploy] GitLab lint job para Sage gerado.');
46
+ }
47
+ if (context.ci?.lint?.mu_plugin) {
48
+ await generator.generateFile(
49
+ '.gitlab/ci/lint-mu-plugin.yml',
50
+ context,
51
+ 'deploy',
52
+ '.gitlab/ci/lint-mu-plugin.yml'
53
+ );
54
+ log(color.green, '[deploy] GitLab lint job para MU Plugin gerado.');
55
+ }
56
+ if (context.ci?.lint?.plugin) {
57
+ await generator.generateFile(
58
+ '.gitlab/ci/lint-plugin.yml',
59
+ context,
60
+ 'deploy',
61
+ '.gitlab/ci/lint-plugin.yml'
62
+ );
63
+ log(color.green, '[deploy] GitLab lint job para Plugin gerado.');
64
+ }
65
+ if (context.ci?.lint?.blank_theme) {
66
+ await generator.generateFile(
67
+ '.gitlab/ci/lint-blank-theme.yml',
68
+ context,
69
+ 'deploy',
70
+ '.gitlab/ci/lint-blank-theme.yml'
71
+ );
72
+ log(color.green, '[deploy] GitLab lint job para Blank Theme gerado.');
73
+ }
36
74
  }
37
75
  if (context.gitProvider === 'github') {
38
76
  await generator.generateFile(
@@ -26,6 +26,34 @@ env.NODE_VERSION
26
26
  não encontrado em $THEME — pulando build do tema" fi
27
27
  {{/if}}
28
28
 
29
+ {{#if ci.lint.sage}}
30
+ lint-sage: name: Lint Sage Theme runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version: ${{'{{'}}
31
+ env.NODE_VERSION
32
+ {{'}}'}}
33
+ - name: Lint Sage run: | cd {{ci.theme.paths.themeRoot}} && npm ci && npx eslint resources/ --config eslint.config.mjs --fix-dry-run && npx stylelint "resources/**/*.{css,scss}"
34
+ {{/if}}
35
+
36
+ {{#if ci.lint.mu_plugin}}
37
+ lint-mu-plugin: name: Lint MU Plugin runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{'{{'}}
38
+ env.PHP_VERSION
39
+ {{'}}'}}
40
+ - name: Lint MU Plugin PHP run: | cd content/mu-plugins/{{mu_plugin_name}} && composer install --no-dev && ./vendor/bin/pint --test
41
+ {{/if}}
42
+
43
+ {{#if ci.lint.plugin}}
44
+ lint-plugin: name: Lint Plugin runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{'{{'}}
45
+ env.PHP_VERSION
46
+ {{'}}'}}
47
+ - name: Lint Plugin PHP run: | cd content/plugins/{{plugin_name}} && composer install --no-dev && ./vendor/bin/pint --test
48
+ {{/if}}
49
+
50
+ {{#if ci.lint.blank_theme}}
51
+ lint-blank-theme: name: Lint Blank Theme runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version: ${{'{{'}}
52
+ env.NODE_VERSION
53
+ {{'}}'}}
54
+ - name: Lint Blank Theme run: | cd content/themes/{{blank_theme_name}} && npm ci && npx eslint src/js/ --config eslint.config.mjs --fix-dry-run && npx stylelint "src/scss/**/*.scss"
55
+ {{/if}}
56
+
29
57
  test-basic: name: Tests runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 -
30
58
  name: Setup Node uses: actions/setup-node@v4 with: node-version: ${{'{{'}}
31
59
  env.NODE_VERSION
@@ -46,4 +74,4 @@ env.NODE_VERSION
46
74
  {{/if}}
47
75
 
48
76
  env: PHP_VERSION: "{{phpVersion}}" NODE_VERSION: "{{ci.nodeVersion}}" WORDPRESS_VERSION: "{{wpCoreVersion}}"
49
- PROJECT_NAME: "{{projectName}}"
77
+ PROJECT_NAME: "{{projectName}}"
@@ -0,0 +1,35 @@
1
+ {{#if ci.lint.blank_theme}}
2
+ lint:blank-theme:eslint:
3
+ stage: lint
4
+ image: node:${NODE_VERSION}-alpine
5
+ variables:
6
+ THEME_DIR: content/themes/{{blank_theme_name}}
7
+ before_script:
8
+ - apk add --no-cache git
9
+ script:
10
+ - cd $THEME_DIR
11
+ - npm ci --cache .npm --prefer-offline
12
+ - npx eslint src/js/ --config eslint.config.mjs --fix-dry-run
13
+ rules:
14
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
15
+ - if: $CI_COMMIT_BRANCH == "main"
16
+ - if: $CI_COMMIT_BRANCH == "staging"
17
+ - if: $CI_COMMIT_BRANCH == "develop"
18
+
19
+ lint:blank-theme:stylelint:
20
+ stage: lint
21
+ image: node:${NODE_VERSION}-alpine
22
+ variables:
23
+ THEME_DIR: content/themes/{{blank_theme_name}}
24
+ before_script:
25
+ - apk add --no-cache git
26
+ script:
27
+ - cd $THEME_DIR
28
+ - npm ci --cache .npm --prefer-offline
29
+ - npx stylelint "src/scss/**/*.scss"
30
+ rules:
31
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
32
+ - if: $CI_COMMIT_BRANCH == "main"
33
+ - if: $CI_COMMIT_BRANCH == "staging"
34
+ - if: $CI_COMMIT_BRANCH == "develop"
35
+ {{/if}}
@@ -0,0 +1,19 @@
1
+ {{#if ci.lint.mu_plugin}}
2
+ lint:mu-plugin:pint:
3
+ stage: lint
4
+ image: php:${PHP_VERSION}-cli
5
+ variables:
6
+ PLUGIN_DIR: content/mu-plugins/{{mu_plugin_name}}
7
+ before_script:
8
+ - apt-get update -qq && apt-get install -qq --no-install-recommends git unzip
9
+ - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
10
+ script:
11
+ - cd $PLUGIN_DIR
12
+ - composer install --no-dev
13
+ - ./vendor/bin/pint --test
14
+ rules:
15
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
16
+ - if: $CI_COMMIT_BRANCH == "main"
17
+ - if: $CI_COMMIT_BRANCH == "staging"
18
+ - if: $CI_COMMIT_BRANCH == "develop"
19
+ {{/if}}
@@ -0,0 +1,19 @@
1
+ {{#if ci.lint.plugin}}
2
+ lint:plugin:pint:
3
+ stage: lint
4
+ image: php:${PHP_VERSION}-cli
5
+ variables:
6
+ PLUGIN_DIR: content/plugins/{{plugin_name}}
7
+ before_script:
8
+ - apt-get update -qq && apt-get install -qq --no-install-recommends git unzip
9
+ - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
10
+ script:
11
+ - cd $PLUGIN_DIR
12
+ - composer install --no-dev
13
+ - ./vendor/bin/pint --test
14
+ rules:
15
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
16
+ - if: $CI_COMMIT_BRANCH == "main"
17
+ - if: $CI_COMMIT_BRANCH == "staging"
18
+ - if: $CI_COMMIT_BRANCH == "develop"
19
+ {{/if}}
@@ -0,0 +1,47 @@
1
+ {{#if ci.lint.sage}}
2
+ lint:sage:eslint:
3
+ stage: lint
4
+ image: node:${NODE_VERSION}-alpine
5
+ before_script:
6
+ - apk add --no-cache git
7
+ script:
8
+ - cd {{ci.theme.paths.themeRoot}}
9
+ - npm ci --cache .npm --prefer-offline
10
+ - npx eslint resources/ --config eslint.config.mjs --fix-dry-run
11
+ rules:
12
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
13
+ - if: $CI_COMMIT_BRANCH == "main"
14
+ - if: $CI_COMMIT_BRANCH == "staging"
15
+ - if: $CI_COMMIT_BRANCH == "develop"
16
+
17
+ lint:sage:stylelint:
18
+ stage: lint
19
+ image: node:${NODE_VERSION}-alpine
20
+ before_script:
21
+ - apk add --no-cache git
22
+ script:
23
+ - cd {{ci.theme.paths.themeRoot}}
24
+ - npm ci --cache .npm --prefer-offline
25
+ - npx stylelint "resources/**/*.{css,scss}"
26
+ rules:
27
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
28
+ - if: $CI_COMMIT_BRANCH == "main"
29
+ - if: $CI_COMMIT_BRANCH == "staging"
30
+ - if: $CI_COMMIT_BRANCH == "develop"
31
+
32
+ lint:sage:pint:
33
+ stage: lint
34
+ image: php:${PHP_VERSION}-cli
35
+ before_script:
36
+ - apt-get update -qq && apt-get install -qq --no-install-recommends git unzip
37
+ - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
38
+ script:
39
+ - cd {{ci.theme.paths.themeRoot}}
40
+ - composer install --no-dev --optimize-autoloader
41
+ - ./vendor/bin/pint --test
42
+ rules:
43
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
44
+ - if: $CI_COMMIT_BRANCH == "main"
45
+ - if: $CI_COMMIT_BRANCH == "staging"
46
+ - if: $CI_COMMIT_BRANCH == "develop"
47
+ {{/if}}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "settings": {
3
- "git.inputValidation": "always",
3
+ "git.inputValidation": true,
4
4
  "git.inputValidationSubjectLength": 72,
5
5
  "git.inputValidationLength": 72,
6
6
  "git.verboseCommit": true,
@@ -0,0 +1,21 @@
1
+ {
2
+ "extends": ["@commitlint/config-conventional"],
3
+ "rules": {
4
+ "type-enum": [
5
+ 2,
6
+ "always",
7
+ ["feat", "fix", "docs", "style", "refactor", "perf", "test", "chore", "ci", "build", "revert"]
8
+ ],
9
+ "type-case": [2, "always", "lower-case"],
10
+ "type-empty": [2, "never"],
11
+ "scope-case": [2, "always", "lower-case"],
12
+ "subject-case": [2, "never", ["sentence-case", "start-case", "pascal-case", "upper-case"]],
13
+ "subject-empty": [2, "never"],
14
+ "subject-full-stop": [2, "never", "."],
15
+ "header-max-length": [2, "always", 72],
16
+ "body-leading-blank": [1, "always"],
17
+ "body-max-line-length": [2, "always", 100],
18
+ "footer-leading-blank": [1, "always"],
19
+ "footer-max-line-length": [2, "always", 100]
20
+ }
21
+ }
@@ -1,36 +1,26 @@
1
- # Ignore node_modules and build directories
1
+ # Node & Composer
2
2
  node_modules/
3
- dist/
4
- build/
5
-
6
- # Ignore WordPress core
7
- wp/
8
- wp-content/plugins/
9
- wp-content/mu-plugins/
10
- wp-content/uploads/
11
- wp-content/upgrade/
3
+ vendor/
12
4
 
13
- content/plugins/
5
+ # Development module folders — each has its own lint config
6
+ content/themes/
14
7
  content/mu-plugins/
8
+ content/plugins/
9
+
10
+ # WordPress core and uploads
11
+ wp/
15
12
  content/uploads/
16
13
  content/upgrade/
14
+ content/cache/
17
15
 
18
- # Ignore Composer dependencies
19
- vendor/
16
+ # Build outputs
17
+ public/build/
18
+ dist/
19
+ .lando/
20
20
 
21
- # Ignore logs and environment
22
- *.log
21
+ # Env and logs
23
22
  .env
24
23
  .env.*
25
-
26
- # Ignore IDE and system files
27
- .DS_Store
28
- Thumbs.db
29
-
30
- # Ignore Lando config cache
31
- .lando/
32
-
33
- # Ignore anything temporary
24
+ *.log
34
25
  *.tmp
35
- *.temp
36
26
  *.bak
@@ -1,29 +1,18 @@
1
1
  {
2
2
  "semi": true,
3
3
  "singleQuote": true,
4
- "trailingComma": "es5",
5
4
  "tabWidth": 2,
6
5
  "printWidth": 100,
6
+ "trailingComma": "es5",
7
7
  "bracketSpacing": true,
8
- "arrowParens": "avoid",
9
8
  "overrides": [
10
9
  {
11
- "files": ["*.scss", "*.css", "*.sass"],
12
- "options": {
13
- "singleQuote": false
14
- }
15
- },
16
- {
17
- "files": ["*.json", "*.yml", "*.yaml"],
18
- "options": {
19
- "tabWidth": 2
20
- }
10
+ "files": ["*.yml", "*.yaml"],
11
+ "options": { "tabWidth": 2 }
21
12
  },
22
13
  {
23
- "files": "*.html",
24
- "options": {
25
- "htmlWhitespaceSensitivity": "ignore"
26
- }
14
+ "files": "*.md",
15
+ "options": { "proseWrap": "always" }
27
16
  }
28
17
  ]
29
18
  }
@@ -1,14 +1,81 @@
1
+ import path from 'path';
2
+
3
+ import fs from 'fs-extra';
4
+
5
+ /**
6
+ * Builds the lint-staged entries object from active development modules.
7
+ * Each dev module contributes globs pointing to its own directory.
8
+ */
9
+ function buildLintStagedEntries(context) {
10
+ const entries = {};
11
+
12
+ // Infra: YAML, JSON, Markdown at root (never touching module folders)
13
+ entries['*.{yml,yaml}'] = ['prettier --write'];
14
+ entries['*.{json,md}'] = ['prettier --write'];
15
+
16
+ // Sage
17
+ if (context.enable_sage) {
18
+ const dir = `content/themes/${context.projectName}`;
19
+ if (context.sage_lint_eslint !== false) {
20
+ entries[`${dir}/resources/**/*.{js,ts,vue,mjs}`] = ['eslint --fix'];
21
+ }
22
+ if (context.sage_lint_stylelint !== false) {
23
+ entries[`${dir}/resources/**/*.{css,scss}`] = ['stylelint --fix'];
24
+ }
25
+ if (context.sage_lint_pint !== false) {
26
+ entries[`${dir}/app/**/*.php`] = ['pint'];
27
+ }
28
+ }
29
+
30
+ // MU-Plugin
31
+ if (context.enable_mu_plugin) {
32
+ const dir = `content/mu-plugins/${context.mu_plugin_name || `${context.projectName}-core`}`;
33
+ if (context.mu_plugin_lint_eslint !== false) {
34
+ entries[`${dir}/resources/**/*.{js,ts}`] = ['eslint --fix'];
35
+ }
36
+ if (context.mu_plugin_lint_pint !== false) {
37
+ entries[`${dir}/src/**/*.php`] = ['pint'];
38
+ }
39
+ }
40
+
41
+ // Plugin
42
+ if (context.enable_plugin) {
43
+ const dir = `content/plugins/${context.plugin_name || `${context.projectName}-plugin`}`;
44
+ if (context.plugin_lint_eslint !== false) {
45
+ entries[`${dir}/resources/**/*.{js,ts}`] = ['eslint --fix'];
46
+ }
47
+ if (context.plugin_lint_pint !== false) {
48
+ entries[`${dir}/src/**/*.php`] = ['pint'];
49
+ }
50
+ }
51
+
52
+ // Blank Theme
53
+ if (context.enable_blank_theme) {
54
+ const dir = `content/themes/${context.blank_theme_name || `${context.projectName}-theme`}`;
55
+ if (context.blank_theme_lint_eslint !== false) {
56
+ entries[`${dir}/src/**/*.{js,ts}`] = ['eslint --fix'];
57
+ }
58
+ if (context.blank_theme_lint_stylelint !== false) {
59
+ entries[`${dir}/src/**/*.{css,scss}`] = ['stylelint --fix'];
60
+ }
61
+ if (context.blank_theme_lint_pint !== false) {
62
+ entries[`${dir}/src/**/*.php`] = ['pint'];
63
+ }
64
+ }
65
+
66
+ return entries;
67
+ }
68
+
1
69
  export async function setupModule(context, generator) {
2
- await generator.copyFile('eslint.config.mjs', 'lint');
3
- await generator.copyFile('.prettierrc.json', 'lint');
70
+ if (!context.enable_lint) return;
4
71
 
72
+ // Root developer tooling (always present when lint is enabled)
73
+ await generator.copyFile('.commitlintrc.json', 'lint');
5
74
  await generator.copyFile('.prettierrc.json', 'lint');
6
75
  await generator.copyFile('.prettierignore', 'lint');
7
76
 
8
- await generator.copyFile('pint.json', 'lint');
9
-
10
- if (context.enable_stylelint) {
11
- await generator.copyFile('.stylelintrc.json', 'lint');
12
- await generator.copyFile('.stylelintignore', 'lint');
13
- }
77
+ // Compose .lintstagedrc.json from active modules
78
+ const entries = buildLintStagedEntries(context);
79
+ const lintStagedPath = path.join(generator.cwd, '.lintstagedrc.json');
80
+ await fs.outputFile(lintStagedPath, JSON.stringify(entries, null, 2) + '\n');
14
81
  }
@@ -3,14 +3,7 @@ export default [
3
3
  {
4
4
  type: 'confirm',
5
5
  name: 'enable_lint',
6
- message: 'Enable linting and formatting tools (ESLint + Prettier)?',
6
+ message: 'Enable developer tooling (Husky, commitlint, Prettier for infra files)?',
7
7
  default: true,
8
8
  },
9
- {
10
- type: 'confirm',
11
- name: 'enable_stylelint',
12
- message: 'Include Stylelint config?',
13
- default: true,
14
- when: answers => answers.enable_lint,
15
- },
16
9
  ];
@@ -1,10 +1,5 @@
1
1
  tooling:
2
- eslint:
2
+ commitlint:
3
3
  service: appserver
4
- cmd: yarn eslint
5
- prettier:
6
- service: appserver
7
- cmd: yarn prettier
8
- stylelint:
9
- service: appserver
10
- cmd: yarn stylelint **/*.{css,scss,vue}
4
+ description: Validate commit message format
5
+ cmd: npx commitlint --edit
@@ -3,9 +3,9 @@
3
3
  "editor.defaultFormatter": "esbenp.prettier-vscode",
4
4
  "editor.formatOnSave": false,
5
5
  "editor.codeActionsOnSave": {
6
- "source.fixAll": true,
7
- "source.fixAll.eslint": true,
8
- "source.organizeImports": true
6
+ "source.fixAll": "explicit",
7
+ "source.fixAll.eslint": "explicit",
8
+ "source.organizeImports": "explicit"
9
9
  },
10
10
  "prettier.requireConfig": true,
11
11
  "prettier.useEditorConfig": true,
@@ -0,0 +1,49 @@
1
+ import path from 'path';
2
+
3
+ import fs from 'fs-extra';
4
+
5
+ import { log, color } from '../../lib/utils/logger.js';
6
+
7
+ export async function setupModule(context, generator) {
8
+ const pluginName = context.mu_plugin_name || `${context.projectName}-core`;
9
+ const pluginDir = `content/mu-plugins/${pluginName}`;
10
+ const absolutePluginDir = path.join(generator.cwd, pluginDir);
11
+
12
+ log(color.blue, `[mu-plugin] 📂 Scaffolding MU plugin: ${pluginDir}`);
13
+
14
+ // 1. Ensure directory exists
15
+ await fs.ensureDir(absolutePluginDir);
16
+
17
+ // 2. Generate main plugin entry file
18
+ await generator.generateFile(
19
+ 'plugin.php',
20
+ { ...context, mu_plugin_name: pluginName },
21
+ 'mu-plugin',
22
+ `${pluginDir}/${pluginName}.php`
23
+ );
24
+
25
+ // 3. Generate composer.json
26
+ await generator.generateFile(
27
+ 'composer.json',
28
+ { ...context, mu_plugin_name: pluginName },
29
+ 'mu-plugin',
30
+ `${pluginDir}/composer.json`
31
+ );
32
+
33
+ // 4. Create src/ scaffold
34
+ await fs.ensureFile(path.join(absolutePluginDir, 'src', '.gitkeep'));
35
+
36
+ // 5. Lint configs co-located in plugin — always installed (IDE/editor support)
37
+ log(color.blue, '[mu-plugin] 🔧 Installing lint configurations...');
38
+ await generator.copyFile('lint/.prettierrc.json', 'mu-plugin', `${pluginDir}/.prettierrc.json`);
39
+ await generator.copyFile('lint/pint.json', 'mu-plugin', `${pluginDir}/pint.json`);
40
+ if (context.mu_plugin_lint_eslint === true) {
41
+ await generator.copyFile(
42
+ 'lint/eslint.config.mjs',
43
+ 'mu-plugin',
44
+ `${pluginDir}/eslint.config.mjs`
45
+ );
46
+ }
47
+
48
+ log(color.green, `[mu-plugin] ✅ MU plugin scaffolded: ${pluginDir}`);
49
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": true,
4
+ "trailingComma": "es5",
5
+ "printWidth": 100,
6
+ "tabWidth": 2
7
+ }