Detect whether the project is a Drupal project and resolve the web root. Returns `Some(web_root)` if one of the canonical Drupal core packages is listed in `require` or `require-dev`, and we can determine the web root. Web-root resolution order: 1. `extra.drupal-scaffold.locations.web-root` in `composer.json`. 2. Filesystem fallback: the first of `web/`, `docroot/`, `public/`, `html/` that conta
(
workspace_root: &Path,
package: &ComposerPackage,
)
| 825 | /// 2. Filesystem fallback: the first of `web/`, `docroot/`, `public/`, |
| 826 | /// `html/` that contains `core/lib/Drupal.php`. |
| 827 | pub(crate) fn detect_drupal_web_root( |
| 828 | workspace_root: &Path, |
| 829 | package: &ComposerPackage, |
| 830 | ) -> Option<PathBuf> { |
| 831 | const DRUPAL_PACKAGES: &[&str] = &["drupal/core", "drupal/core-recommended", "drupal/core-dev"]; |
| 832 | |
| 833 | let is_drupal = DRUPAL_PACKAGES |
| 834 | .iter() |
| 835 | .any(|pkg| package.require.contains_key(*pkg) || package.require_dev.contains_key(*pkg)); |
| 836 | |
| 837 | if !is_drupal { |
| 838 | return None; |
| 839 | } |
| 840 | |
| 841 | // 1. Read from extra.drupal-scaffold.locations.web-root |
| 842 | if let Some(ComposerPackageExtra::Object(extra_map)) = &package.extra |
| 843 | && let Some(scaffold) = extra_map.get("drupal-scaffold") |
| 844 | && let Some(web_root_str) = scaffold |
| 845 | .get("locations") |
| 846 | .and_then(|l| l.get("web-root")) |
| 847 | .and_then(|v| v.as_str()) |
| 848 | { |
| 849 | let path = workspace_root.join(web_root_str.trim_end_matches('/')); |
| 850 | return Some(path); |
| 851 | } |
| 852 | |
| 853 | // 2. Filesystem fallback: find which common dir contains core/lib/Drupal.php |
| 854 | for candidate in &["web", "docroot", "public", "html"] { |
| 855 | let path = workspace_root.join(candidate); |
| 856 | if path.join("core/lib/Drupal.php").exists() { |
| 857 | return Some(path); |
| 858 | } |
| 859 | } |
| 860 | |
| 861 | None |
| 862 | } |
| 863 | |
| 864 | #[cfg(test)] |
| 865 | mod tests { |