From d918cc2c28f6877a6d7906e498896e1437761701 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 6 Apr 2026 13:15:05 -0300 Subject: [PATCH] feat: add first-class theme support for slic here and slic run MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When `slic here` is run from a themes directory (without wp-config.php), slic previously entered "plugins directory mode" and set SLIC_PLUGINS_DIR to the themes directory. This caused plugins like WooCommerce to be cloned and installed inside wp-content/themes/, and Docker mounted the themes dir as wp-content/plugins/ in the container. This commit introduces proper theme-directory mode: - Add `slic_here_is_themes()`: returns true when SLIC_HERE_DIR matches SLIC_THEMES_DIR, indicating slic was pointed at a themes directory. - Update `get_valid_targets()`: include themes as valid `slic use` targets when in themes-directory mode (previously only included when slic_here_is_site()). - Fix `run.php`: replace `slic_plugins_dir(slic_target())` with `get_project_local_path()` so the host-side Codeception config lookup resolves to SLIC_THEMES_DIR/ for theme targets instead of always falling back to SLIC_PLUGINS_DIR. - Fix `using.php`: same path resolution fix for the displayed target path. - Fix `build_command_pool()` and `maybe_build_install_command_pool()` in slic.php: use `get_project_local_path()` for composer/npm build file detection so these commands work correctly for theme targets. `get_project_local_path()` and `get_project_container_path()` in project.php already handled the 'theme' project type correctly — this change ensures the rest of the codebase uses them consistently. - Update README: document the themes directory as a first-class `slic here` option (option 2, before the WordPress root option), including the correct WPLoader suite config pattern for activating a theme under test. Co-Authored-By: Claude Sonnet 4.6 --- README.md | 36 ++++++++++++++++++++++++++++++++++-- src/commands/run.php | 9 +++------ src/commands/using.php | 2 +- src/slic.php | 28 ++++++++++++++++++++++++---- 4 files changed, 62 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 1bbebd3..990704e 100644 --- a/README.md +++ b/README.md @@ -118,9 +118,41 @@ slic here ![slic here](docs/images/slic-here.gif) -#### 2. WordPress Directory +#### 2. Themes Directory -The second option is to navigate to the root of your site (likely where `wp-config.php` lives) and run the `slic here` +If you are developing a **theme**, run `slic here` from your themes directory. `slic` will detect that it is pointed at a themes directory and correctly: + +- Mount the directory as `wp-content/themes/` in the Docker stack so your theme is available to WordPress as a real theme. +- Keep a separate plugins directory (`SLIC_PLUGINS_DIR`) so dependencies like WooCommerce install into `wp-content/plugins/` and not into your themes directory. +- Run Codeception from within the correct `wp-content/themes/` path inside the container. + +Example: + +```bash +# Change to your themes directory +cd /path/to/your/wp-content/themes + +slic here +slic use my-theme +slic run wpunit +``` + +> **WPLoader suite config:** When testing a theme, activate it via the WPLoader `theme:` key rather than listing it under `plugins`/`activatePlugins`. WordPress will then load the theme (including its `functions.php`) automatically. +> +> ```yaml +> modules: +> config: +> WPLoader: +> plugins: +> - woocommerce/woocommerce.php +> activatePlugins: +> - woocommerce/woocommerce.php +> theme: my-theme # ← activates the theme under test +> ``` + +#### 3. WordPress Directory + +The third option is to navigate to the root of your site (likely where `wp-config.php` lives) and run the `slic here` command. > Note: This is an opinionated option and there are some assumptions that are made: diff --git a/src/commands/run.php b/src/commands/run.php index f56799d..56e4051 100644 --- a/src/commands/run.php +++ b/src/commands/run.php @@ -54,12 +54,9 @@ maybe_generate_htaccess(); // Run the command in the Codeception container. -$root = slic_plugins_dir( slic_target( true ) ); - -// If target is site, set the root to the wp dir. -if ( 'site' === slic_target() ) { - $root = slic_wp_dir(); -} +// Use get_project_local_path() so that theme targets resolve to SLIC_THEMES_DIR +// rather than always falling back to SLIC_PLUGINS_DIR. +$root = get_project_local_path(); // Object-cache is disruptive in the context of tests; remove the object cache drop-in before running the tests. $object_cache_dropin = slic_wp_dir( 'wp-content/object-cache.php' ); diff --git a/src/commands/using.php b/src/commands/using.php index da5d919..d4c5faa 100644 --- a/src/commands/using.php +++ b/src/commands/using.php @@ -24,7 +24,7 @@ } $using = slic_target(); -$target_path = slic_plugins_dir( $using ); +$target_path = get_project_local_path(); if ( empty( $using ) ) { echo magenta( "Currently not using any target, commands requiring a target will fail." . PHP_EOL ); return; diff --git a/src/slic.php b/src/slic.php index 2d59231..d12cfd3 100644 --- a/src/slic.php +++ b/src/slic.php @@ -100,12 +100,26 @@ function get_cwd_dir_name() { return ''; } +/** + * Returns true when slic here was run from a themes directory (SLIC_HERE_DIR matches SLIC_THEMES_DIR). + * In this mode themes are valid targets even though slic_here_is_site() is false. + * + * @return bool + */ +function slic_here_is_themes() { + $here_dir = realpath( getenv( 'SLIC_HERE_DIR' ) ); + $themes_dir = realpath( getenv( 'SLIC_THEMES_DIR' ) ); + + return $here_dir && $themes_dir && $here_dir === $themes_dir; +} + /** * Gets all valid targets. * * Valid targets are: * - Anything in the plugins directory. - * - If slic here was done on the site level, "site" is also a valid target. + * - If slic here was done at the site level, "site" is also a valid target and themes are included. + * - If slic here was done at the themes directory level, themes are also valid targets. * * @param bool $as_array Whether to output as an array. If falsy, will output as a formatted string, including * headings, line breaks, and indentation. @@ -121,12 +135,16 @@ function get_valid_targets( $as_array = true ) { $themes = array_keys( dev_themes() ); sort( $themes, SORT_NATURAL ); + $include_themes = slic_here_is_site() || slic_here_is_themes(); + $targets = $plugins; if ( slic_here_is_site() ) { $targets = array_merge( [ 'site' ], $plugins, $themes ); $targets_str .= PHP_EOL . ' Site:' . PHP_EOL; $targets_str .= ' - site'; + } elseif ( slic_here_is_themes() ) { + $targets = array_merge( $themes, $plugins ); } $targets_str .= PHP_EOL . " Plugins:" . PHP_EOL; @@ -138,7 +156,7 @@ static function ( $target ) { ) ); - if ( slic_here_is_site() && $themes ) { + if ( $include_themes && $themes ) { $targets_str .= PHP_EOL . " Themes:" . PHP_EOL; $targets_str .= implode( PHP_EOL, array_map( @@ -1226,7 +1244,8 @@ function dir_has_req_build_file( $base_command, $path ) { */ function maybe_build_install_command_pool( $base_command, $target, array $sub_directories = [] ) { // Only prompt if the target itself has has been identified as available to build. If any subs need to build, will auto-try. - if ( dir_has_req_build_file( $base_command, slic_plugins_dir( $target ) ) ) { + // Use get_project_local_path() so that theme targets resolve to SLIC_THEMES_DIR instead of SLIC_PLUGINS_DIR. + if ( dir_has_req_build_file( $base_command, get_project_local_path() ) ) { $run = ask( PHP_EOL . yellow( $target . ':' ) . " Would you like to run the {$base_command} install processes for this plugin?", 'yes' @@ -1271,7 +1290,8 @@ function build_command_pool( $base_command, array $command, array $sub_directori $targets = []; // If applicable, include target plugin before subdirectory plugins. - $path = $using === 'site' ? slic_wp_dir() : slic_plugins_dir( slic_target() ); + // Use get_project_local_path() so that theme targets resolve to SLIC_THEMES_DIR. + $path = get_project_local_path(); if ( dir_has_req_build_file( $base_command, $path ) ) { $targets[] = 'target'; }