@@ -2,8 +2,7 @@ import { lifecycleHooks } from './hooks.js';
22import { Types } from '@graphql-codegen/plugin-helpers' ;
33import { executeCodegen } from './codegen.js' ;
44import { createWatcher } from './utils/watcher.js' ;
5- import { fileExists , readFile , writeFile , unlinkFile } from './utils/file-system.js' ;
6- import mkdirp from 'mkdirp' ;
5+ import { readFile , writeFile , unlinkFile , mkdirp } from './utils/file-system.js' ;
76import { dirname , join , isAbsolute } from 'path' ;
87import { debugLog } from './utils/debugging.js' ;
98import { CodegenContext , ensureContext } from './config.js' ;
@@ -57,41 +56,49 @@ export async function generate(
5756 ( ) =>
5857 Promise . all (
5958 generationResult . map ( async ( result : Types . FileOutput ) => {
60- const exists = await fileExists ( result . filename ) ;
59+ const previousHash = recentOutputHash . get ( result . filename ) || ( await hashFile ( result . filename ) ) ;
60+ const exists = previousHash !== null ;
61+
62+ // Store previous hash to avoid reading from disk again
63+ if ( previousHash ) {
64+ recentOutputHash . set ( result . filename , previousHash ) ;
65+ }
6166
6267 if ( ! shouldOverwrite ( config , result . filename ) && exists ) {
6368 return ;
6469 }
6570
6671 const content = result . content || '' ;
6772 const currentHash = hash ( content ) ;
68- let previousHash = recentOutputHash . get ( result . filename ) ;
69-
70- if ( ! previousHash && exists ) {
71- previousHash = hash ( await readFile ( result . filename ) ) ;
72- }
7373
7474 if ( previousHash && currentHash === previousHash ) {
7575 debugLog ( `Skipping file (${ result . filename } ) writing due to indentical hash...` ) ;
7676 return ;
77- } else if ( context . checkMode ) {
77+ }
78+
79+ // skip updating file in dry mode
80+ if ( context . checkMode ) {
7881 context . checkModeStaleFiles . push ( result . filename ) ;
79- return ; // skip updating file in dry mode
82+ return ;
8083 }
8184
8285 if ( content . length === 0 ) {
8386 return ;
8487 }
8588
86- recentOutputHash . set ( result . filename , currentHash ) ;
87- const basedir = dirname ( result . filename ) ;
8889 await lifecycleHooks ( result . hooks ) . beforeOneFileWrite ( result . filename ) ;
8990 await lifecycleHooks ( config . hooks ) . beforeOneFileWrite ( result . filename ) ;
90- await mkdirp ( basedir ) ;
91+
9192 const absolutePath = isAbsolute ( result . filename )
9293 ? result . filename
9394 : join ( input . cwd || process . cwd ( ) , result . filename ) ;
94- await writeFile ( absolutePath , result . content ) ;
95+
96+ const basedir = dirname ( absolutePath ) ;
97+ await mkdirp ( basedir ) ;
98+
99+ await writeFile ( absolutePath , content ) ;
100+ recentOutputHash . set ( result . filename , currentHash ) ;
101+
95102 await lifecycleHooks ( result . hooks ) . afterOneFileWrite ( result . filename ) ;
96103 await lifecycleHooks ( config . hooks ) . afterOneFileWrite ( result . filename ) ;
97104 } )
@@ -143,3 +150,16 @@ function shouldOverwrite(config: Types.Config, outputPath: string): boolean {
143150function isConfiguredOutput ( output : any ) : output is Types . ConfiguredOutput {
144151 return typeof output . plugins !== 'undefined' ;
145152}
153+
154+ async function hashFile ( filePath : string ) : Promise < string | null > {
155+ try {
156+ return hash ( await readFile ( filePath ) ) ;
157+ } catch ( err ) {
158+ if ( err && err . code === 'ENOENT' ) {
159+ // return null if file does not exist
160+ return null ;
161+ }
162+ // rethrow unexpected errors
163+ throw err ;
164+ }
165+ }
0 commit comments