jenkins-design-language/bin/import-material-icons.js
function findSourceFiles(sourceIconsRoot) {
    let visitedDirectories = [];
    let allSourceFiles = [];

    function recurseDir(dir, depth) {
        // Don't get in any loops
        if (visitedDirectories.indexOf(dir) !== -1) {
            return;
        }

        if (depth > 3) {
            throw new Error('findSourceFiles() - directory tree too deep');
        }

        visitedDirectories.push(dir);

        return fs.readdirAsync(dir)
            .then(filenames => {
                // Turn the list of filenames into paths
                const paths = filenames
                    .filter(filename => filename[0] !== '.' && filename !== 'index.js') // Ignore index, hidden, '.' and '..'
                    .map(filename => pathUtils.resolve(dir, filename));

                // For each path...
                const statPromises = paths.map(filePath => {
                    return fs.statAsync(filePath) // ... get stats
                        .then(stats => ({ filePath, stats })); // ... and associate with path
                });

                // Turn the array of promises into a promise of arrays.
                return Promise.all(statPromises);
            })
            .then(filePathsAndStats => {
                // Pick out all the JS files in dir, while collecting the list of subdirectories

                let subDirPaths = [];

                for (const { filePath, stats } of filePathsAndStats) {
                    if (stats.isDirectory()) {
                        subDirPaths.push(filePath);
                    }
                    else if (stats.isFile() && pathUtils.extname(filePath).toLowerCase() === '.js') {
                        allSourceFiles.push(filePath);
                    }
                }

                if (subDirPaths.length === 0) {
                    return;
                }

                // Recurse
                return Promise.all(subDirPaths.map(path => recurseDir(path, depth + 1)));
            });
    }

    return recurseDir(sourceIconsRoot, 0).then(() => allSourceFiles);
}
function findSourceFiles(sourceIconsRoot) {
    let visitedDirectories = [];
    let allSourceFiles = [];

    function recurseDir(dir, depth) {
        // Don't get in any loops
        if (visitedDirectories.indexOf(dir) !== -1) {
            return;
        }

        if (depth > 3) {
            throw new Error('findSourceFiles() - directory tree too deep');
        }

        visitedDirectories.push(dir);

        return fs.readdirAsync(dir)
            .then(filenames => {
                // Turn the list of filenames into paths
                const paths = filenames
                    .filter(filename => filename[0] !== '.' && filename !== 'index.js') // Ignore index, hidden, '.' and '..'
                    .map(filename => pathUtils.resolve(dir, filename));

                // For each path...
                const statPromises = paths.map(filePath => {
                    return fs.statAsync(filePath) // ... get stats
                        .then(stats => ({ filePath, stats })); // ... and associate with path
                });

                // Turn the array of promises into a promise of arrays.
                return Promise.all(statPromises);
            })
            .then(filePathsAndStats => {
                // Pick out all the JS files in dir, while collecting the list of subdirectories

                let subDirPaths = [];

                for (const { filePath, stats } of filePathsAndStats) {
                    if (stats.isDirectory()) {
                        subDirPaths.push(filePath);
                    }
                    else if (stats.isFile() && pathUtils.extname(filePath).toLowerCase() === '.js') {
                        allSourceFiles.push(filePath);
                    }
                }

                if (subDirPaths.length === 0) {
                    return;
                }

                // Recurse
                return Promise.all(subDirPaths.map(path => recurseDir(path, depth + 1)));
            });
    }

    return recurseDir(sourceIconsRoot, 0).then(() => allSourceFiles);
}
function findSourceFiles ( sourceIconsRoot ) { let visitedDirectories = [ ] ; let allSourceFiles = [ ] ; function recurseDir ( dir , depth ) { // Don't get in any loops if ( visitedDirectories . indexOf ( dir ) !== - 1 ) { return ; } if ( depth > 3 ) { throw new Error ( 'findSourceFiles() - directory tree too deep' ) ; } visitedDirectories . push ( dir ) ; return fs . readdirAsync ( dir ) . then ( filenames => { // Turn the list of filenames into paths const paths = filenames . filter ( filename => filename [ 0 ] !== '.' && filename !== 'index.js' ) // Ignore index, hidden, '.' and '..' . map ( filename => pathUtils . resolve ( dir , filename ) ) ; // For each path... const statPromises = paths . map ( filePath => { return fs . statAsync ( filePath ) // ... get stats . then ( stats => ( { filePath , stats } ) ) ; // ... and associate with path } ) ; // Turn the array of promises into a promise of arrays. return Promise . all ( statPromises ) ; } ) . then ( filePathsAndStats => { // Pick out all the JS files in dir, while collecting the list of subdirectories let subDirPaths = [ ] ; for ( const { filePath , stats } of filePathsAndStats ) { if ( stats . isDirectory ( ) ) { subDirPaths . push ( filePath ) ; } else if ( stats . isFile ( ) && pathUtils . extname ( filePath ) . toLowerCase ( ) === '.js' ) { allSourceFiles . push ( filePath ) ; } } if ( subDirPaths . length === 0 ) { return ; } // Recurse return Promise . all ( subDirPaths . map ( path => recurseDir ( path , depth + 1 ) ) ) ; } ) ; } return recurseDir ( sourceIconsRoot , 0 ) . then ( ( ) => allSourceFiles ) ; }
Traverse the tree starting at sourcePath, and find all the .js files.

Only goes 3 levels deep, will throw if it gives up due to tree depth.

Kind of ugly, but better than pulling in some npm module with 45 transitive dependencies.  Please let me know if
there's a nicer way to do this! - JM
Traverse the tree starting at sourcePath and find all the . js files .