From c0715563db5993a52874a27a7f39cf6e131f186d Mon Sep 17 00:00:00 2001 From: Pedro Nauck Date: Tue, 28 May 2019 22:15:03 -0300 Subject: [PATCH] feat: dynamic src and root path --- core/docz-core/src/config/argv.ts | 10 ++++-- core/docz-core/src/config/docz.ts | 3 +- core/docz-core/src/config/paths.ts | 15 +++++++- core/docz-core/src/index.ts | 1 - core/docz-core/src/lib/Bundler.ts | 3 +- core/docz-core/src/lib/Entries.ts | 36 ++++++++++++------- core/docz-core/src/lib/Entry.ts | 14 ++++---- core/docz-core/src/lib/Plugin.ts | 3 +- .../devServer/services/createResources.ts | 6 +++- core/docz-core/src/states/entries.ts | 12 ++----- core/docz-core/src/states/props.ts | 23 ++++++------ core/docz-core/src/utils/docgen/index.ts | 3 +- core/docz-core/src/utils/docgen/javascript.ts | 5 ++- core/docz-core/src/utils/repo-info.ts | 7 ++-- core/gatsby-theme-docz/gatsby-config.js | 6 ++-- .../src/node/onCreateBabelConfig.js | 8 ++++- core/gatsby-theme-docz/src/node/onPreInit.js | 5 ++- examples/basic/doczrc.js | 1 - .../babel-plugin-export-metadata/src/index.js | 3 +- 19 files changed, 102 insertions(+), 62 deletions(-) diff --git a/core/docz-core/src/config/argv.ts b/core/docz-core/src/config/argv.ts index fde7c8615..762a99b42 100644 --- a/core/docz-core/src/config/argv.ts +++ b/core/docz-core/src/config/argv.ts @@ -6,9 +6,15 @@ import titleize from 'titleize' import { get } from 'lodash/fp' import { Plugin } from '../lib/Plugin' -import { BabelRC } from '../config/babel' import * as paths from '../config/paths' +export interface BabelRC { + presets: any[] + plugins: any[] + cacheDirectory?: boolean + babelrc?: boolean +} + const getEnv = (val: string | string[], defaultValue: any = null): any => envDotProp.get(val, defaultValue, { parse: true }) @@ -89,7 +95,7 @@ export interface Argv { } export interface Config extends Argv { - paths: Record + paths: paths.Paths plugins: Plugin[] mdPlugins: any[] hastPlugins: any[] diff --git a/core/docz-core/src/config/docz.ts b/core/docz-core/src/config/docz.ts index e371cd3e0..1c23e77a7 100644 --- a/core/docz-core/src/config/docz.ts +++ b/core/docz-core/src/config/docz.ts @@ -6,8 +6,7 @@ import { merge } from 'lodash/fp' import detectPort from 'detect-port' import * as paths from '../config/paths' -import { BabelRC } from '../config/babel' -import { Config, Argv } from '../config/argv' +import { BabelRC, Config, Argv } from '../config/argv' import { Plugin } from '../lib/Plugin' const toOmit = ['_', '$0', 'version', 'help'] diff --git a/core/docz-core/src/config/paths.ts b/core/docz-core/src/config/paths.ts index 0828bcc50..0c705fb53 100644 --- a/core/docz-core/src/config/paths.ts +++ b/core/docz-core/src/config/paths.ts @@ -18,6 +18,15 @@ export const root = fs.realpathSync(process.cwd()) export const resolveApp = (to: string) => path.resolve(root, to) export const resolveOwn = (to: string) => path.resolve(__dirname, '../', to) +export const checkIsDoczProject = (config: any) => { + return path.parse(config.root || root).base === '.docz' +} + +export const getRootDir = (config: any) => { + const isDoczProject = checkIsDoczProject(config) + return isDoczProject ? path.resolve(root, '../') : root +} + export interface Paths { root: string templates: string @@ -33,6 +42,8 @@ export interface Paths { appYarnLock: string ownNodeModules: string + checkIsDoczProject: (config: any) => boolean + getRootDir: (config: any) => string getDist: (dest: string) => string distPublic: (dest: string) => string @@ -48,7 +59,9 @@ export const templates = path.join(resolve.sync('docz-core'), '../templates') export const packageJson = resolveApp('package.json') export const servedPath = (base: string) => ensureSlash(base, true) -export const docz = resolveApp('.docz') +const IS_DOCZ_PROJECT = path.parse(root).base === '.docz' + +export const docz = resolveApp(IS_DOCZ_PROJECT ? './' : '.docz') export const app = path.resolve(docz, 'app/') export const cache = path.resolve(docz, 'cache/') export const appPublic = path.resolve(docz, 'public/') diff --git a/core/docz-core/src/index.ts b/core/docz-core/src/index.ts index e80b29189..469f9fa41 100644 --- a/core/docz-core/src/index.ts +++ b/core/docz-core/src/index.ts @@ -4,7 +4,6 @@ export { cli } from './cli' /** config exports */ export { parseConfig, getBaseConfig } from './config/docz' export { Config, setArgs } from './config/argv' -export { BabelRC } from './config/babel' /** states */ import * as states from './states' diff --git a/core/docz-core/src/lib/Bundler.ts b/core/docz-core/src/lib/Bundler.ts index 02268511f..e6fbfdecf 100644 --- a/core/docz-core/src/lib/Bundler.ts +++ b/core/docz-core/src/lib/Bundler.ts @@ -82,8 +82,9 @@ export class Bundler { public async build(config: C): Promise { const dist = paths.getDist(this.args.dest) + const root = paths.getRootDir(config) - if (paths.root === path.resolve(dist)) { + if (root === path.resolve(dist)) { logger.fatal( new Error( 'Unexpected option: "dest" cannot be set to the current working directory.' diff --git a/core/docz-core/src/lib/Entries.ts b/core/docz-core/src/lib/Entries.ts index b68028a9a..5aedb5d8f 100644 --- a/core/docz-core/src/lib/Entries.ts +++ b/core/docz-core/src/lib/Entries.ts @@ -5,8 +5,6 @@ import { isRegExp, isString } from 'lodash/fp' import minimatch from 'minimatch' import glob from 'fast-glob' -import * as paths from '../config/paths' - import { Entry, EntryObj } from './Entry' import { Plugin } from './Plugin' import { Config } from '../config/argv' @@ -18,9 +16,21 @@ const mapToObj = (map: Map) => {} ) -const matchFilesWithSrc = (config: Config) => (files: string[]) => { - const src = path.relative(paths.root, config.src) - return files.map(file => (file.startsWith(src) ? file : path.join(src, file))) +export const matchFilesWithSrc = (config: Config) => (files: string[]) => { + const { paths, src } = config + const rootDir = paths.getRootDir(config) + const srcDir = path.resolve(rootDir, src) + const prefix = path.relative(rootDir, srcDir) + return files.map(file => + file.startsWith(prefix) ? file : path.join(prefix, file) + ) +} + +export const getFilesToMatch = (config: Config) => { + const { files: pattern } = config + const arr = Array.isArray(pattern) ? pattern : [pattern] + const toMatch = matchFilesWithSrc(config) + return toMatch(arr) } export type EntryMap = Record @@ -31,17 +41,15 @@ export class Entries { public repoEditUrl: string | null constructor(config: Config) { - this.repoEditUrl = getRepoEditUrl(config.src, config.editBranch) + this.repoEditUrl = getRepoEditUrl(config) this.all = new Map() this.get = async () => this.getMap(config) } private async getMap(config: Config): Promise { - const { src, files: pattern, ignore, plugins, mdPlugins } = config - const arr = Array.isArray(pattern) ? pattern : [pattern] - const toMatch = matchFilesWithSrc(config) - - const initialFiles = await glob(toMatch(arr), { + const { paths, ignore, plugins, mdPlugins } = config + const initialFiles = await glob(getFilesToMatch(config), { + cwd: paths.getRootDir(config), ignore: ['**/node_modules/**'], onlyFiles: true, matchBase: false, @@ -57,10 +65,12 @@ export class Entries { }) }) + const rootDir = paths.getRootDir(config) const createEntry = async (file: string) => { try { - const ast = await parseMdx(file, mdPlugins) - const entry = new Entry(ast, file, src, config) + const fullpath = path.resolve(rootDir, file) + const ast = await parseMdx(fullpath, mdPlugins) + const entry = new Entry(ast, file, config) if (this.repoEditUrl) entry.setLink(this.repoEditUrl) const { settings, ...rest } = entry diff --git a/core/docz-core/src/lib/Entry.ts b/core/docz-core/src/lib/Entry.ts index 1b2b3acb0..6f8d65dec 100644 --- a/core/docz-core/src/lib/Entry.ts +++ b/core/docz-core/src/lib/Entry.ts @@ -56,14 +56,15 @@ export class Entry { [key: string]: any } - constructor(ast: any, file: string, src: string, config: Config) { - const filepath = this.getFilepath(file, src) + constructor(ast: any, file: string, config: Config) { + const filepath = this.getFilepath(config, file) const parsed = getParsedData(ast) const name = this.getName(filepath, parsed) + const root = paths.getRootDir(config) this.id = createId(file) this.filepath = filepath - this.fullpath = path.resolve(config.root, file) + this.fullpath = path.resolve(root, file) this.link = '' this.slug = this.slugify(filepath, config.separator) this.route = this.getRoute(parsed, config.base) @@ -79,9 +80,10 @@ export class Entry { } } - private getFilepath(file: string, src: string): string { - const srcPath = path.resolve(paths.root, src) - const filepath = path.relative(srcPath, file) + private getFilepath(config: Config, file: string): string { + const root = paths.getRootDir(config) + const fullpath = path.resolve(root, config.src, file) + const filepath = path.relative(root, fullpath) if (process.platform === 'win32') { return filepath.split('\\').join('/') diff --git a/core/docz-core/src/lib/Plugin.ts b/core/docz-core/src/lib/Plugin.ts index a6a07becc..b6f2d95ea 100644 --- a/core/docz-core/src/lib/Plugin.ts +++ b/core/docz-core/src/lib/Plugin.ts @@ -1,7 +1,6 @@ import { get, isFunction } from 'lodash/fp' -import { Config } from '../config/argv' -import { BabelRC } from '../config/babel' +import { Config, BabelRC } from '../config/argv' import { pReduce } from '../utils/p-reduce' export type SetConfig = (config: Config) => Config | Promise diff --git a/core/docz-core/src/machines/devServer/services/createResources.ts b/core/docz-core/src/machines/devServer/services/createResources.ts index 12f738d26..ab46346cc 100644 --- a/core/docz-core/src/machines/devServer/services/createResources.ts +++ b/core/docz-core/src/machines/devServer/services/createResources.ts @@ -104,9 +104,13 @@ const writeEslintRc = async ({ isDoczRepo }: ServerMachineCtx) => { const writeConfigFile = async ({ args, isDoczRepo }: ServerMachineCtx) => { const outputPath = path.join(paths.docz, 'gatsby-config.js') + await outputFileFromTemplate('gatsby-config.tpl.js', outputPath, { isDoczRepo, - config: JSON.stringify({ ...args, root: paths.docz }), + config: JSON.stringify({ + ...args, + root: paths.docz, + }), }) } diff --git a/core/docz-core/src/states/entries.ts b/core/docz-core/src/states/entries.ts index b134d5bfd..9dea7c3e9 100644 --- a/core/docz-core/src/states/entries.ts +++ b/core/docz-core/src/states/entries.ts @@ -1,11 +1,10 @@ -import * as path from 'path' import chokidar from 'chokidar' import equal from 'fast-deep-equal' import { get } from 'lodash/fp' import { WATCH_IGNORE } from './config' import { Params, State } from '../lib/DataServer' -import { Entries } from '../lib/Entries' +import { Entries, getFilesToMatch } from '../lib/Entries' import { Config } from '../config/argv' import * as paths from '../config/paths' @@ -28,16 +27,11 @@ export const state = ( config: Config, dev?: boolean ): State => { - const src = path.relative(paths.root, config.src) - const files = Array.isArray(config.files) - ? config.files.map(filePath => path.join(src, filePath)) - : path.join(src, config.files) - const ignored = config.watchIgnore || WATCH_IGNORE - const watcher = chokidar.watch(files, { - cwd: paths.root, + const watcher = chokidar.watch(getFilesToMatch(config), { ignored, persistent: true, + cwd: paths.getRootDir(config), }) watcher.setMaxListeners(Infinity) diff --git a/core/docz-core/src/states/props.ts b/core/docz-core/src/states/props.ts index effb087a8..c923dc60a 100644 --- a/core/docz-core/src/states/props.ts +++ b/core/docz-core/src/states/props.ts @@ -1,4 +1,4 @@ -import { join, relative } from 'path' +import * as path from 'path' import chokidar from 'chokidar' import fastglob from 'fast-glob' import { State, Params } from '../lib/DataServer' @@ -17,18 +17,19 @@ const getPattern = (config: Config) => { docgenConfig: docgenConfig, } = config - const src = relative( - paths.root, - docgenConfig.searchPath ? docgenConfig.searchPath : source - ) + const searchPath = docgenConfig.searchPath ? docgenConfig.searchPath : source + const root = paths.getRootDir(config) + const srcDir = path.resolve(root, searchPath) + const src = path.relative(root, srcDir) return ignore - .map(entry => `!**/${entry}`) + .map(entry => typeof entry === 'string' && `!**/${entry}`) + .filter(Boolean) .concat([ - join(src, ts ? '**/*.{ts,tsx}' : '**/*.{js,jsx,mjs}'), + path.join(src, ts ? '**/*.{ts,tsx}' : '**/*.{js,jsx,mjs}'), '!**/node_modules', '!**/doczrc.js', - ]) + ]) as string[] } const removeFilepath = (items: any[], filepath: string) => @@ -36,7 +37,8 @@ const removeFilepath = (items: any[], filepath: string) => const initial = (config: Config, pattern: string[]) => async (p: Params) => { const { filterComponents } = config - const files = await fastglob(pattern, { cwd: paths.root }) + const cwd = paths.getRootDir(config) + const files = await fastglob(pattern, { cwd }) const filtered = filterComponents ? filterComponents(files) : files const metadata = await docgen(filtered, config) p.setState('props', metadata) @@ -59,8 +61,9 @@ const remove = (p: Params) => async (filepath: string) => { export const state = (config: Config, dev?: boolean): State => { const pattern = getPattern(config) const ignored = config.watchIgnore || WATCH_IGNORE + const cwd = paths.getRootDir(config) const watcher = chokidar.watch(pattern, { - cwd: paths.root, + cwd, ignored, persistent: true, }) diff --git a/core/docz-core/src/utils/docgen/index.ts b/core/docz-core/src/utils/docgen/index.ts index 6e629d2e7..b3cc67897 100644 --- a/core/docz-core/src/utils/docgen/index.ts +++ b/core/docz-core/src/utils/docgen/index.ts @@ -6,7 +6,8 @@ import { jsParser } from './javascript' import { tsParser } from './typescript' export const docgen = async (files: string[], config: Config) => { - const tsconfig = await findUp('tsconfig.json', { cwd: paths.root }) + const cwd = paths.getRootDir(config) + const tsconfig = await findUp('tsconfig.json', { cwd }) return config.typescript ? tsParser(files, config, tsconfig) : jsParser(files, config) diff --git a/core/docz-core/src/utils/docgen/javascript.ts b/core/docz-core/src/utils/docgen/javascript.ts index 50fd5ee6e..fb970df48 100644 --- a/core/docz-core/src/utils/docgen/javascript.ts +++ b/core/docz-core/src/utils/docgen/javascript.ts @@ -6,6 +6,7 @@ import actualNameHandler from 'react-docgen-actual-name-handler' import reactDocgen from 'react-docgen' import { Config } from '../../config/argv' +import { getRootDir } from '../../config/paths' const throwError = (err: any) => { logger.fatal(`Error parsing static types`) @@ -17,14 +18,16 @@ export const jsParser = (files: string[], config: Config) => { config.docgenConfig.resolver || reactDocgen.resolver.findAllExportedComponentDefinitions + const root = getRootDir(config) const parseFilepathProps = (filepath: string) => { + const fullpath = path.resolve(root, filepath) const handlers = reactDocgen.defaultHandlers.concat([ externalProptypesHandler(filepath), actualNameHandler, ]) try { - const code = fs.readFileSync(filepath, 'utf-8') + const code = fs.readFileSync(fullpath, { encoding: 'utf-8' }) const props = reactDocgen.parse(code, resolver, handlers) return { key: path.normalize(filepath), value: props } } catch (err) { diff --git a/core/docz-core/src/utils/repo-info.ts b/core/docz-core/src/utils/repo-info.ts index 426c79a25..a8d9cfdb5 100644 --- a/core/docz-core/src/utils/repo-info.ts +++ b/core/docz-core/src/utils/repo-info.ts @@ -4,6 +4,7 @@ import getPkgRepo from 'get-pkg-repo' import findup from 'find-up' import * as paths from '../config/paths' +import { Config } from '../config/argv' // TODO: type repo object returned from get-pkg-repo export const parseRepo = (): any => { @@ -44,13 +45,13 @@ const getTree = (repo: any, branch: string, relative: string) => { return defaultPath } -export const getRepoEditUrl = (src: string, branch: string): string | null => { +export const getRepoEditUrl = (config: Config): string | null => { try { const repo = parseRepo() const project = path.parse(findup.sync('.git')).dir - const root = path.join(paths.root, src) + const root = path.join(paths.getRootDir(config), config.src) const relative = path.relative(project, root) - const tree = getTree(repo, branch, relative) + const tree = getTree(repo, config.editBranch, relative) return ( repo && diff --git a/core/gatsby-theme-docz/gatsby-config.js b/core/gatsby-theme-docz/gatsby-config.js index ac93160e0..25fa963f6 100644 --- a/core/gatsby-theme-docz/gatsby-config.js +++ b/core/gatsby-theme-docz/gatsby-config.js @@ -33,10 +33,10 @@ const getHastPlugins = rootPath => { } module.exports = opts => { - const { paths, ...config } = getDoczConfig(opts) + const config = getDoczConfig(opts) + const { paths } = config const mdPlugins = getMdPlugins() const hastPlugins = getHastPlugins(paths.root) - const appPath = path.relative(paths.root, paths.app) return { plugins: [ @@ -53,7 +53,7 @@ module.exports = opts => { ? config.hastPlugins.concat(hastPlugins) : hastPlugins, defaultLayouts: { - default: path.join(config.root, appPath, 'components/Layout.js'), + default: path.join(paths.app, 'components/Layout.js'), }, }, }, diff --git a/core/gatsby-theme-docz/src/node/onCreateBabelConfig.js b/core/gatsby-theme-docz/src/node/onCreateBabelConfig.js index 66db390fb..2d9c8451e 100644 --- a/core/gatsby-theme-docz/src/node/onCreateBabelConfig.js +++ b/core/gatsby-theme-docz/src/node/onCreateBabelConfig.js @@ -1,5 +1,11 @@ -module.exports = ({ actions }) => { +const { getBaseConfig } = require('docz-core') + +module.exports = ({ actions }, opts = {}) => { + const config = getBaseConfig(opts) + const { paths } = config + actions.setBabelPlugin({ name: 'babel-plugin-export-metadata', + options: { root: paths.getRootDir(config) }, }) } diff --git a/core/gatsby-theme-docz/src/node/onPreInit.js b/core/gatsby-theme-docz/src/node/onPreInit.js index 73435ee23..d6406ec96 100644 --- a/core/gatsby-theme-docz/src/node/onPreInit.js +++ b/core/gatsby-theme-docz/src/node/onPreInit.js @@ -6,9 +6,8 @@ const { parseConfig } = require('../utils/parseConfig') const fromTemplates = filepath => path.resolve(__dirname, '../../templates', filepath) -const mountComponentPath = ({ paths, ...config }) => component => { - const appPath = path.relative(paths.root, paths.app) - return path.join(config.root, appPath, 'components', component || '') +const mountComponentPath = ({ paths }) => component => { + return path.resolve(paths.app, 'components', component || '') } const touchTemplateWithPaths = config => async (filepath, opts) => { diff --git a/examples/basic/doczrc.js b/examples/basic/doczrc.js index 893eb9684..42c5dee67 100644 --- a/examples/basic/doczrc.js +++ b/examples/basic/doczrc.js @@ -1,4 +1,3 @@ export default { - src: '../', menu: ['Getting Started', 'Components'], } diff --git a/other-packages/babel-plugin-export-metadata/src/index.js b/other-packages/babel-plugin-export-metadata/src/index.js index 1d5c5f174..d8bc19457 100644 --- a/other-packages/babel-plugin-export-metadata/src/index.js +++ b/other-packages/babel-plugin-export-metadata/src/index.js @@ -21,8 +21,9 @@ const replaceExportDefault = template(` `) const getFilename = state => { + const rootDir = get(state, 'opts.root', process.cwd()) const filename = get(state, 'file.opts.filename') - return filename && path.relative(process.cwd(), filename) + return filename && path.relative(rootDir, filename) } const findPathToInsert = path =>