From ed73ee487e493943f6d0f4665787725531b34dbd Mon Sep 17 00:00:00 2001 From: Soichi Takamura Date: Tue, 4 May 2021 17:10:48 +0900 Subject: [PATCH] Silent (#469) * wip: test stdout for load logs * wip: refact to "basic" from "usual" * wip: add an option `silent` * wip: add a failing test * Add `silent` option * fix: Compare `silent` as some output or no output --- .../loader/{usual => basic}/.graphql-let.yml | 0 .../loader/{usual => basic}/pages/index.tsx | 0 .../{usual => basic}/pages/partial.graphql | 0 .../{usual => basic}/pages/viewer.graphql | 0 .../{usual => basic}/pages/viewer2.graphql | 0 .../schema/type-defs.graphqls | 0 src/__fixtures/loader/silent/.graphql-let.yml | 11 ++++++ src/__fixtures/loader/silent/pages/index.tsx | 18 +++++++++ .../loader/silent/pages/partial.graphql | 4 ++ .../loader/silent/pages/viewer.graphql | 6 +++ .../loader/silent/pages/viewer2.graphql | 6 +++ .../loader/silent/schema/type-defs.graphqls | 9 +++++ src/gen.ts | 19 ++++++---- src/lib/__snapshots__/config.test.ts.snap | 2 + src/lib/codegen.ts | 5 ++- src/lib/config.ts | 2 + src/loader.test.ts | 38 +++++++++++++------ src/loader.ts | 29 ++++++++------ 18 files changed, 118 insertions(+), 31 deletions(-) rename src/__fixtures/loader/{usual => basic}/.graphql-let.yml (100%) rename src/__fixtures/loader/{usual => basic}/pages/index.tsx (100%) rename src/__fixtures/loader/{usual => basic}/pages/partial.graphql (100%) rename src/__fixtures/loader/{usual => basic}/pages/viewer.graphql (100%) rename src/__fixtures/loader/{usual => basic}/pages/viewer2.graphql (100%) rename src/__fixtures/loader/{usual => basic}/schema/type-defs.graphqls (100%) create mode 100644 src/__fixtures/loader/silent/.graphql-let.yml create mode 100644 src/__fixtures/loader/silent/pages/index.tsx create mode 100644 src/__fixtures/loader/silent/pages/partial.graphql create mode 100644 src/__fixtures/loader/silent/pages/viewer.graphql create mode 100644 src/__fixtures/loader/silent/pages/viewer2.graphql create mode 100644 src/__fixtures/loader/silent/schema/type-defs.graphqls diff --git a/src/__fixtures/loader/usual/.graphql-let.yml b/src/__fixtures/loader/basic/.graphql-let.yml similarity index 100% rename from src/__fixtures/loader/usual/.graphql-let.yml rename to src/__fixtures/loader/basic/.graphql-let.yml diff --git a/src/__fixtures/loader/usual/pages/index.tsx b/src/__fixtures/loader/basic/pages/index.tsx similarity index 100% rename from src/__fixtures/loader/usual/pages/index.tsx rename to src/__fixtures/loader/basic/pages/index.tsx diff --git a/src/__fixtures/loader/usual/pages/partial.graphql b/src/__fixtures/loader/basic/pages/partial.graphql similarity index 100% rename from src/__fixtures/loader/usual/pages/partial.graphql rename to src/__fixtures/loader/basic/pages/partial.graphql diff --git a/src/__fixtures/loader/usual/pages/viewer.graphql b/src/__fixtures/loader/basic/pages/viewer.graphql similarity index 100% rename from src/__fixtures/loader/usual/pages/viewer.graphql rename to src/__fixtures/loader/basic/pages/viewer.graphql diff --git a/src/__fixtures/loader/usual/pages/viewer2.graphql b/src/__fixtures/loader/basic/pages/viewer2.graphql similarity index 100% rename from src/__fixtures/loader/usual/pages/viewer2.graphql rename to src/__fixtures/loader/basic/pages/viewer2.graphql diff --git a/src/__fixtures/loader/usual/schema/type-defs.graphqls b/src/__fixtures/loader/basic/schema/type-defs.graphqls similarity index 100% rename from src/__fixtures/loader/usual/schema/type-defs.graphqls rename to src/__fixtures/loader/basic/schema/type-defs.graphqls diff --git a/src/__fixtures/loader/silent/.graphql-let.yml b/src/__fixtures/loader/silent/.graphql-let.yml new file mode 100644 index 00000000..21f11260 --- /dev/null +++ b/src/__fixtures/loader/silent/.graphql-let.yml @@ -0,0 +1,11 @@ +schema: schema/type-defs.graphqls +documents: + - "**/*.graphql" + - "**/*.tsx" +plugins: + - typescript + - typescript-operations + - typescript-react-apollo +respectGitIgnore: true +cacheDir: __generated__ +silent: true \ No newline at end of file diff --git a/src/__fixtures/loader/silent/pages/index.tsx b/src/__fixtures/loader/silent/pages/index.tsx new file mode 100644 index 00000000..64abdf8d --- /dev/null +++ b/src/__fixtures/loader/silent/pages/index.tsx @@ -0,0 +1,18 @@ +import { gql, load } from 'graphql-let'; + +const { useViewerQuery } = load('./viewer.graphql'); +useViewerQuery().data.viewer.name as string; +// @ts-expect-error +useViewerQuery() as number; + +const { useViewerYQuery } = gql(` + # import Partial from './partial.graphql' + query ViewerY { + viewer { + ...Partial + } + } +`); +useViewerYQuery().data.viewer.name as string; +// @ts-expect-error +useViewerYQuery() as number; diff --git a/src/__fixtures/loader/silent/pages/partial.graphql b/src/__fixtures/loader/silent/pages/partial.graphql new file mode 100644 index 00000000..78cafe70 --- /dev/null +++ b/src/__fixtures/loader/silent/pages/partial.graphql @@ -0,0 +1,4 @@ +fragment Partial on User { + id + name +} diff --git a/src/__fixtures/loader/silent/pages/viewer.graphql b/src/__fixtures/loader/silent/pages/viewer.graphql new file mode 100644 index 00000000..2b8e2500 --- /dev/null +++ b/src/__fixtures/loader/silent/pages/viewer.graphql @@ -0,0 +1,6 @@ +# import Partial from './partial.graphql' +query Viewer { + viewer { + ...Partial + } +} diff --git a/src/__fixtures/loader/silent/pages/viewer2.graphql b/src/__fixtures/loader/silent/pages/viewer2.graphql new file mode 100644 index 00000000..6247a2aa --- /dev/null +++ b/src/__fixtures/loader/silent/pages/viewer2.graphql @@ -0,0 +1,6 @@ +# import Partial from './partial.graphql' +query Viewer2 { + viewer { + ...Partial + } +} diff --git a/src/__fixtures/loader/silent/schema/type-defs.graphqls b/src/__fixtures/loader/silent/schema/type-defs.graphqls new file mode 100644 index 00000000..aed22561 --- /dev/null +++ b/src/__fixtures/loader/silent/schema/type-defs.graphqls @@ -0,0 +1,9 @@ +type User { + id: ID! + name: String! + status: String! +} + +type Query { + viewer: User +} diff --git a/src/gen.ts b/src/gen.ts index 04db3cb7..300a4d39 100644 --- a/src/gen.ts +++ b/src/gen.ts @@ -95,9 +95,11 @@ export async function gen({ cwd, configFilePath, }: CommandOpts): Promise { - updateLog('Scanning...'); - const [config, configHash] = await loadConfig(cwd, configFilePath); + const { silent } = config; + + if (!silent) updateLog('Scanning...'); + const execContext = createExecContext(cwd, config, configHash); const codegenContext: CodegenContext[] = []; @@ -120,28 +122,29 @@ export async function gen({ ); if (isAllSkip(codegenContext)) { - updateLog( - `Nothing to do. Caches for ${codegenContext.length} GraphQL documents are fresh.`, - ); + if (!silent) + updateLog( + `Nothing to do. Caches for ${codegenContext.length} GraphQL documents are fresh.`, + ); } else { const numToProcess = codegenContext.reduce( (i, { skip }) => (skip ? i : i + 1), 0, ); - updateLog(`Processing ${numToProcess} codegen...`); + if (!silent) updateLog(`Processing ${numToProcess} codegen...`); writeTiIndexForContext(execContext, codegenContext); await processCodegenForContext(execContext, codegenContext); - updateLog(`Generating ${numToProcess} d.ts...`); + if (!silent) updateLog(`Generating ${numToProcess} d.ts...`); await processDtsForContext(execContext, codegenContext); const displayNum = numToProcess === codegenContext.length ? numToProcess : `${numToProcess}/${codegenContext.length}`; - updateLog(`Done processing ${displayNum} GraphQL documents.`); + if (!silent) updateLog(`Done processing ${displayNum} GraphQL documents.`); } await removeObsoleteFiles(execContext, codegenContext, graphqlRelPaths); diff --git a/src/lib/__snapshots__/config.test.ts.snap b/src/lib/__snapshots__/config.test.ts.snap index 475beec3..02d88f36 100644 --- a/src/lib/__snapshots__/config.test.ts.snap +++ b/src/lib/__snapshots__/config.test.ts.snap @@ -47,6 +47,7 @@ Array [ }, ], "schemaEntrypoint": "", + "silent": false, "typeInjectEntrypoint": "node_modules/@types/graphql-let/index.d.ts", }, "6134bbfa2c25f64acb7c526097ecc4e4014c2aa4", @@ -67,6 +68,7 @@ Object { "respectGitIgnore": false, "schema": "**/*.graphql", "schemaEntrypoint": "yeah.graphqls", + "silent": false, "typeInjectEntrypoint": "typings/yeah.d.ts;", } `; diff --git a/src/lib/codegen.ts b/src/lib/codegen.ts index 94130e61..202453df 100644 --- a/src/lib/codegen.ts +++ b/src/lib/codegen.ts @@ -51,8 +51,11 @@ export function buildCodegenConfig( } return { - silent: true, ...config, + // Regardless of `silent` value in config, + // we always suppress GraphQL code generator logs + silent: true, + // @ts-ignore cwd, diff --git a/src/lib/config.ts b/src/lib/config.ts index 1620d34d..08137e3e 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -18,6 +18,7 @@ export type GraphQLLetAdditionalOptions = { // gqlDtsEntrypoint?: string; typeInjectEntrypoint?: string; generateOptions?: Types.ConfiguredOutput; + silent?: boolean; }; export type UserConfigTypes = PartialGraphqlCodegenOptions & @@ -64,6 +65,7 @@ export function buildConfig(raw: UserConfigTypes): ConfigTypes { raw.typeInjectEntrypoint || 'node_modules/@types/graphql-let/index.d.ts', generateOptions: raw.generateOptions || Object.create(null), schemaEntrypoint: raw.schemaEntrypoint || '', + silent: raw.silent || false, }; } diff --git a/src/loader.test.ts b/src/loader.test.ts index ca132eb5..5839f0f0 100644 --- a/src/loader.test.ts +++ b/src/loader.test.ts @@ -8,15 +8,17 @@ import { join as pathJoin } from 'path'; import { promisify } from 'util'; import waitOn from 'wait-on'; import { Stats } from 'webpack'; +import * as print from './lib/print'; import compiler from './lib/__tools/compile'; import { prepareFixtures } from './lib/__tools/file'; const unlink = promisify(fs.unlink); -let flatProjFixtureDir: string; +let basicFixtureDir: string; let monorepoFixtureDir: string; +let silentFixtureDir: string; -const flatProjEntrypoints = ['pages/index.tsx', 'pages/viewer.graphql']; +const basicEntrypoints = ['pages/index.tsx', 'pages/viewer.graphql']; function getOutputInfo(stats: Stats) { const { modules } = stats.toJson()!; @@ -32,22 +34,22 @@ function getOutputInfo(stats: Stats) { describe('graphql-let/loader', () => { beforeAll(async () => { - [flatProjFixtureDir] = await prepareFixtures( + [basicFixtureDir] = await prepareFixtures( __dirname, - '__fixtures/loader/usual', + '__fixtures/loader/basic', ); [monorepoFixtureDir] = await prepareFixtures( __dirname, '__fixtures/loader/monorepo', ); + [silentFixtureDir] = await prepareFixtures( + __dirname, + '__fixtures/loader/silent', + ); }); test('generates .tsx and .d.ts', async () => { - const stats = await compiler( - flatProjFixtureDir, - flatProjEntrypoints, - 'node', - ); + const stats = await compiler(basicFixtureDir, basicEntrypoints, 'node'); const outputs = getOutputInfo(stats); expect(outputs).toHaveLength(4); @@ -72,7 +74,7 @@ describe('graphql-let/loader', () => { ]; const results = await Promise.all( expectedTargets.map(([file, target]) => - compiler(flatProjFixtureDir, [file], target), + compiler(basicFixtureDir, [file], target), ), ); for (const [i, stats] of results.entries()) { @@ -82,11 +84,25 @@ describe('graphql-let/loader', () => { expect(output).toMatchSnapshot(); } const globResults = await glob('**/*.graphql.d.ts', { - cwd: flatProjFixtureDir, + cwd: basicFixtureDir, }); strictEqual(globResults.length, 2); }); + test('The option "silent" suppresses standard output logs', async () => { + let messages = ''; + const mockFn = (m: any) => (messages += m + '\n'); + jest.spyOn(print, 'printInfo').mockImplementation(mockFn); + jest.spyOn(print, 'updateLog').mockImplementation(mockFn); + + await compiler(basicFixtureDir, basicEntrypoints, 'node'); + expect(messages).not.toHaveLength(0); + + messages = ''; + await compiler(silentFixtureDir, basicEntrypoints, 'node'); + expect(messages).toHaveLength(0); + }); + describe('options', () => { async function acceptsConfigPathInOptionsConfigFile( configFilePath: string, diff --git a/src/loader.ts b/src/loader.ts index fc6a1754..d819352d 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -57,10 +57,11 @@ const processLoaderForSources = memoize( options: GraphQLLetLoaderOptions, ): Promise => { const [config, configHash] = await loadConfig(cwd, options.configFile); + const { silent } = config; const execContext = createExecContext(cwd, config, configHash); const codegenContext: CodegenContext[] = []; const sourceRelPath = pathRelative(cwd, sourceFullPath); - updateLog(`Processing ${sourceRelPath}...`); + if (!silent) updateLog(`Processing ${sourceRelPath}...`); const { schemaHash } = await appendFileSchemaContext( execContext, @@ -78,12 +79,12 @@ const processLoaderForSources = memoize( if (!codegenContext.length) return sourceContent; if (isAllSkip(codegenContext)) { - updateLog(`Nothing to do. Cache was fresh.`); + if (!silent) updateLog(`Nothing to do. Cache was fresh.`); const [{ tsxFullPath }] = codegenContext; return await readFile(tsxFullPath, 'utf-8'); } - updateLog(`Processing codegen for ${sourceRelPath}...`); + if (!silent) updateLog(`Processing codegen for ${sourceRelPath}...`); const [[fileNode, programPath, callExpressionPathPairs]] = paths; // Add dependencies so editing dependent GraphQL emits HMR. @@ -107,12 +108,15 @@ const processLoaderForSources = memoize( ); writeTiIndexForContext(execContext, codegenContext); await processCodegenForContext(execContext, codegenContext); - updateLog(`Generating d.ts for ${sourceRelPath}...`); + if (!silent) updateLog(`Generating d.ts for ${sourceRelPath}...`); await processDtsForContext(execContext, codegenContext); const { code } = generator(fileNode); - updateLog(`Done processing ${sourceRelPath}.`); + if (!silent) { + updateLog(`Done processing ${sourceRelPath}.`); + updateLogDone(); + } return code; }, (gqlFullPath: string) => gqlFullPath, @@ -127,10 +131,11 @@ const processLoaderForDocuments = memoize( options: GraphQLLetLoaderOptions, ): Promise => { const [config, configHash] = await loadConfig(cwd, options.configFile); + const { silent } = config; const execContext = createExecContext(cwd, config, configHash); const codegenContext: FileSchemaCodegenContext[] = []; const graphqlRelPath = pathRelative(cwd, gqlFullPath); - updateLog(`Processing ${graphqlRelPath}...`); + if (!silent) updateLog(`Processing ${graphqlRelPath}...`); // Add dependencies so editing dependent GraphQL emits HMR. const { dependantFullPaths } = resolveGraphQLDocument( @@ -156,19 +161,22 @@ const processLoaderForDocuments = memoize( const { skip, tsxFullPath } = fileContext; if (skip) { - updateLog(`Nothing to do. Cache was fresh.`); + if (!silent) updateLog(`Nothing to do. Cache was fresh.`); return await readFile(tsxFullPath, 'utf-8'); } - updateLog(`Processing codegen for ${graphqlRelPath}...`); + if (!silent) updateLog(`Processing codegen for ${graphqlRelPath}...`); const [{ content }] = await processCodegenForContext(execContext, [ fileContext, ]); - updateLog(`Generating d.ts for ${graphqlRelPath}...`); + if (!silent) updateLog(`Generating d.ts for ${graphqlRelPath}...`); await processDtsForContext(execContext, [fileContext]); - updateLog(`Done processing ${graphqlRelPath}.`); + if (!silent) { + updateLog(`Done processing ${graphqlRelPath}.`); + updateLogDone(); + } return content; }, (gqlFullPath: string) => gqlFullPath, @@ -212,7 +220,6 @@ const graphQLLetLoader: loader.Loader = function (resourceContent) { promise .then((tsxContent) => { - updateLogDone(); callback(undefined, tsxContent); }) .catch((e) => {