function _legacyFindFiles_getMatchingItems()

in node/task.ts [1138:1227]


function _legacyFindFiles_getMatchingItems(
    includePatterns: string[],
    excludePatterns: RegExp[],
    includeFiles: boolean,
    includeDirectories: boolean) {

    debug('getMatchingItems()');
    for (let pattern of includePatterns) {
        debug(`includePattern: '${pattern}'`);
    }

    for (let pattern of excludePatterns) {
        debug(`excludePattern: ${pattern}`);
    }

    debug('includeFiles: ' + includeFiles);
    debug('includeDirectories: ' + includeDirectories);

    let allFiles = {} as { [k: string]: string };
    for (let pattern of includePatterns) {
        // determine the directory to search
        //
        // note, getDirectoryName removes redundant path separators
        let findPath: string;
        let starIndex = pattern.indexOf('*');
        let questionIndex = pattern.indexOf('?');
        if (starIndex < 0 && questionIndex < 0) {
            // if no wildcards are found, use the directory name portion of the path.
            // if there is no directory name (file name only in pattern or drive root),
            // this will return empty string.
            findPath = im._getDirectoryName(pattern);
        }
        else {
            // extract the directory prior to the first wildcard
            let index = Math.min(
                starIndex >= 0 ? starIndex : questionIndex,
                questionIndex >= 0 ? questionIndex : starIndex);
            findPath = im._getDirectoryName(pattern.substring(0, index));
        }

        // note, due to this short-circuit and the above usage of getDirectoryName, this
        // function has the same limitations regarding drive roots as the powershell
        // implementation.
        //
        // also note, since getDirectoryName eliminates slash redundancies, some additional
        // work may be required if removal of this limitation is attempted.
        if (!findPath) {
            continue;
        }

        let patternRegex: RegExp = im._legacyFindFiles_convertPatternToRegExp(pattern);

        // find files/directories
        let items = find(findPath, <FindOptions>{ followSymbolicLinks: true })
            .filter((item: string) => {
                if (includeFiles && includeDirectories) {
                    return true;
                }

                let isDir = fs.statSync(item).isDirectory();
                return (includeFiles && !isDir) || (includeDirectories && isDir);
            })
            .forEach((item: string) => {
                let normalizedPath = process.platform == 'win32' ? item.replace(/\\/g, '/') : item; // normalize separators
                // **/times/** will not match C:/fun/times because there isn't a trailing slash
                // so try both if including directories
                let alternatePath = `${normalizedPath}/`;   // potential bug: it looks like this will result in a false
                // positive if the item is a regular file and not a directory

                let isMatch = false;
                if (patternRegex.test(normalizedPath) || (includeDirectories && patternRegex.test(alternatePath))) {
                    isMatch = true;

                    // test whether the path should be excluded
                    for (let regex of excludePatterns) {
                        if (regex.test(normalizedPath) || (includeDirectories && regex.test(alternatePath))) {
                            isMatch = false;
                            break;
                        }
                    }
                }

                if (isMatch) {
                    allFiles[item] = item;
                }
            });
    }

    return Object.keys(allFiles).sort();
}