diff --git a/example/webdoc.conf.json b/example/webdoc.conf.json index 01d0756c..2769e56f 100644 --- a/example/webdoc.conf.json +++ b/example/webdoc.conf.json @@ -1,6 +1,6 @@ { "source": { - "includePattern": "./src/**/*" + "include": "./src/**/*" }, "plugins": [ "plugins/markdown" diff --git a/packages/webdoc-cli/src/config.js b/packages/webdoc-cli/src/config.js index b097a9ae..5f593eff 100644 --- a/packages/webdoc-cli/src/config.js +++ b/packages/webdoc-cli/src/config.js @@ -9,8 +9,11 @@ type ConfigSchema = { sort?: string }, source?: { + // Declared in order of priority + include?: string | Array, includePattern?: string | Array, - include?: string | Array + excludePattern?: string | Array, + exclude?: string | Array, }, conf?: { tags?: { @@ -52,7 +55,6 @@ const defaultConfig: ConfigSchema = { sort: "type, scope, access, name", // @webdoc/parser{mod:sort} }, source: { - includePattern: "./**/*.js", // @webdoc/cli{main} }, conf: { tags: { @@ -103,30 +105,6 @@ export function loadConfig(file: string): ConfigSchema { return config; } -export function getIncludePattern(config: ConfigSchema): string[] { - const source = config.source; - - if (typeof source !== "undefined") { - if (typeof source.includePattern !== "undefined") { - if (Array.isArray(source.includePattern)) { - return source.includePattern; - } else if (typeof source.includePattern === "string") { - return [source.includePattern]; - } - } - - if (typeof source.include !== "undefined") { - if (Array.isArray(source.include)) { - return source.include; - } else if (typeof source.include === "string") { - return [source.include]; - } - } - } - - return []; -} - export function getTemplate(config: ConfigSchema): string { if (config.opts && config.opts.template) { return config.opts.template; diff --git a/packages/webdoc-cli/src/index.js b/packages/webdoc-cli/src/index.js index 606e9118..c20a85c4 100644 --- a/packages/webdoc-cli/src/index.js +++ b/packages/webdoc-cli/src/index.js @@ -59,7 +59,7 @@ async function main(argv: yargs.Argv) { global.Webdoc = global.Webdoc || {}; registerWebdocParser();// global.Webdoc.Parser - const {loadConfig, getIncludePattern, getTemplate} = require("./config"); + const {loadConfig, getTemplate} = require("./config"); const config = loadConfig(argv.config); const tutorials = loadTutorials(argv.tutorials); @@ -79,13 +79,6 @@ async function main(argv: yargs.Argv) { global.Webdoc.env.conf = config; global.Webdoc.userConfig = config; - // TODO: excludePattern - const includePattern = getIncludePattern(config); - - if (!includePattern) { - console.log("No source.include or source.includePattern found in config file"); - } - if (config.plugins) { for (const pluginPath of config.plugins) { if (pluginPath === "plugins/markdown") { diff --git a/packages/webdoc-cli/src/sources/index.js b/packages/webdoc-cli/src/sources/index.js index 71903141..b4a32894 100644 --- a/packages/webdoc-cli/src/sources/index.js +++ b/packages/webdoc-cli/src/sources/index.js @@ -2,15 +2,76 @@ import type {RootDoc, SourceFile} from "@webdoc/types"; import globby from "globby"; import {packages} from "./packages"; +// Create a filtering callback that returns whether a path passes all +// patterns (if exclude = false) or if it fails all of them (if exclude = true). +function makePatternFilter( + patterns: string | string[], + exclude: boolean = false, +): (path: string) => boolean { + const normalizedFormat = Array.isArray(patterns) ? + patterns : + ((patterns && [patterns]) || []); + + if (normalizedFormat.length === 0) { + // If no patterns to match, then short circuit evaluation. + return () => true; + } + + const regExps = normalizedFormat.map( + (pattern) => { + try { + return new RegExp(pattern, "g"); + } catch (e) { + console.error("Invalid pattern: " + pattern + + "\nPlease make sure the patterns in sources.includePattern or source.excludePattern " + + "defined in your configuration file are valid\n", + ); + } + }, + ); + + return function(path: string): boolean { + for (const regExp of regExps) { + if (path.match(regExp)) { + // If include pattern matched, return true. + // If exclude pattern matched, return false. + return !exclude; + } + } + + // If all include patterns failed, return false. + // If all exclude patterns passed, return true. + return exclude; + }; +} + export function sources(config: Object, documentTree: RootDoc): SourceFile[] { - const includePattern = config.source.includePattern || config.source.include; + const { + include, + includePattern, + exclude, + excludePattern, + } = config.source; - if (!includePattern) { - console.log("No source.include or source.includePattern found in config file"); + if (!include) { + console.error("No input files specified. You must " + + "define source.include in your configuration file."); + + return []; } - const paths = globby.sync(includePattern); - const sources: SourceFile[] = paths.map((file) => ({path: file})); + const paths = globby.sync(include); + const excludePaths = Array.isArray(exclude) ? + exclude : + ((exclude && [exclude]) || []); + + const sources: SourceFile[] = paths + .filter(makePatternFilter(includePattern, false)) + .filter(makePatternFilter(excludePattern, true)) + .filter((path) => !(excludePaths.some( + (excludedPath) => path === excludePaths, + ))) + .map((path) => ({path})); documentTree.packages = packages(sources);