11import { Compat } from "compute-baseline/browser-compat-data" ;
2- import fs from "node:fs/promises" ;
3- import fsSync from "node:fs" ;
2+ import * as diff from "diff" ;
43import { fdir } from "fdir" ;
5- import Path from "path" ;
4+ import fsSync from "node:fs" ;
5+ import fs from "node:fs/promises" ;
66import { fileURLToPath } from "node:url" ;
7+ import Path from "path" ;
78import webSpecs from "web-specs" assert { type : "json" } ;
9+ import winston from "winston" ;
810import { Document } from "yaml" ;
911import yargs from "yargs" ;
1012
@@ -22,8 +24,24 @@ const argv = yargs(process.argv.slice(2))
2224 . option ( "paths" , {
2325 type : "array" ,
2426 describe : "Draft feature files to update" ,
27+ } )
28+ . option ( "verbose" , {
29+ alias : "v" ,
30+ describe : "Show more information about what files are modified" ,
31+ type : "count" ,
32+ default : 0 ,
33+ defaultDescription : "warn" ,
2534 } ) . argv ;
2635
36+ const logger = winston . createLogger ( {
37+ level : argv . verbose > 0 ? "debug" : "info" ,
38+ format : winston . format . combine (
39+ winston . format . colorize ( ) ,
40+ winston . format . simple ( ) ,
41+ ) ,
42+ transports : new winston . transports . Console ( ) ,
43+ } ) ;
44+
2745function * getPages ( spec ) : Generator < string > {
2846 yield spec . url ;
2947 if ( spec . nightly ?. url ) {
@@ -178,7 +196,43 @@ async function main() {
178196
179197 feature . comment = usedFeaturesComment . trimEnd ( ) ;
180198 }
181- await fs . writeFile ( `features/draft/spec/${ id } .yml` , feature . toString ( ) ) ;
199+
200+ const destination = `features/draft/spec/${ id } .yml` ;
201+ const proposedFile = feature . toString ( ) ;
202+
203+ let originalFile : string ;
204+ try {
205+ originalFile = await fs . readFile ( destination , { encoding : "utf-8" } ) ;
206+ } catch ( err : unknown ) {
207+ // If there's no file for this spec already, write a new one immediately.
208+ if ( typeof err === "object" && "code" in err && err . code === "ENOENT" ) {
209+ await fs . writeFile ( destination , proposedFile ) ;
210+ logger . info ( `${ destination } : new spec file added` ) ;
211+ continue ;
212+ }
213+ throw err ;
214+ }
215+
216+ // If there's a file for this spec already, write updates only if something
217+ // other than the `draft_date` changed. Because changes can be comments, we
218+ // have to check a diff rather than parsing and comparing values.
219+ const changes = diff . diffLines ( originalFile , proposedFile ) ;
220+ const noChanges =
221+ changes . length === 1 && ! changes [ 0 ] . added && ! changes [ 0 ] . removed ;
222+ const onlyDateChanges =
223+ ! noChanges &&
224+ changes . length === 3 &&
225+ changes
226+ . filter ( ( change ) => change . added || change . removed )
227+ . every ( ( change ) => change . value . includes ( "draft_date: " ) ) ;
228+
229+ if ( noChanges || onlyDateChanges ) {
230+ logger . debug ( `${ destination } : no changes, skipped` ) ;
231+ continue ;
232+ }
233+
234+ await fs . writeFile ( destination , proposedFile ) ;
235+ logger . info ( `${ destination } : updated` ) ;
182236 }
183237}
184238
0 commit comments