function UnknownPathExcluder::getExcludedPaths

Returns the paths to exclude from stage operations.

Return value

string[] The paths that should be excluded from stage operations, relative to the project root.

Throws

\Exception See \Drupal\package_manager\ComposerInspector::validate().

File

core/modules/package_manager/src/PathExcluder/UnknownPathExcluder.php, line 76

Class

UnknownPathExcluder
Excludes unknown paths from stage operations.

Namespace

Drupal\package_manager\PathExcluder

Code

private function getExcludedPaths() : array {
    // If this excluder is disabled, or the project root and web root are the
    // same, we are not excluding any paths.
    $is_disabled = $this->configFactory
        ->get('package_manager.settings')
        ->get('include_unknown_files_in_project_root');
    $web_root = $this->pathLocator
        ->getWebRoot();
    if ($is_disabled || empty($web_root)) {
        return [];
    }
    // To determine the files to include, the installed packages must be known,
    // and that requires Composer commands to be able to run. This intentionally
    // does not catch exceptions: failed Composer validation in the project root
    // implies that this excluder cannot function correctly. In such a case, the
    // call to ComposerInspector::getConfig() would also have triggered an
    // exception, but explicitness is preferred here.
    // @see \Drupal\package_manager\StatusCheckTrait::runStatusCheck()
    $project_root = $this->pathLocator
        ->getProjectRoot();
    $this->composerInspector
        ->validate($project_root);
    // The vendor directory and web root are always included in staging
    // operations, along with `composer.json`, `composer.lock`, and any scaffold
    // files provided by Drupal core.
    $always_include = [
        $this->composerInspector
            ->getConfig('vendor-dir', $project_root),
        $web_root,
        'composer.json',
        'composer.lock',
    ];
    foreach ($this->getScaffoldFiles() as $scaffold_file_path) {
        // The web root is always included in staging operations, so we don't need
        // to do anything special for scaffold files that live in it.
        if (str_starts_with($scaffold_file_path, '[web-root]')) {
            continue;
        }
        $always_include[] = ltrim($scaffold_file_path, '/');
    }
    // Find any path repositories located inside the project root. These need
    // to be included or Composer will break in the staging area.
    $repositories = $this->composerInspector
        ->getConfig('repositories', $project_root);
    $repositories = Json::decode($repositories);
    foreach ($repositories as $repository) {
        if ($repository['type'] !== 'path') {
            continue;
        }
        try {
            // Ensure $path is relative to the project root, even if it's written as
            // an absolute path in `composer.json`.
            $path = Path::makeRelative($repository['url'], $project_root);
            // Strip off everything except the top-level directory name. For
            // example, if the repository path is `custom/module/foo`, always
            // include `custom`.
            $always_include[] = dirname($path, substr_count($path, '/') ?: 1);
        } catch (InvalidArgumentException) {
            // The repository path is not relative to the project root, so we don't
            // need to worry about it.
        }
    }
    // Search for all files (including hidden ones) in the project root. We need
    // to use readdir() and friends here, rather than glob(), since certain
    // glob() flags aren't supported on all systems. We also can't use
    // \Drupal\Core\File\FileSystemInterface::scanDirectory(), because it
    // unconditionally ignores hidden files and directories.
    $files_in_project_root = [];
    $handle = opendir($project_root);
    if (empty($handle)) {
        throw new \RuntimeException("Could not scan for files in the project root.");
    }
    while ($entry = readdir($handle)) {
        $files_in_project_root[] = $entry;
    }
    closedir($handle);
    return array_diff($files_in_project_root, $always_include, [
        '.',
        '..',
    ]);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.