@@ -22,13 +22,24 @@ import fs from 'node:fs';
2222import os from 'node:os' ;
2323import path from 'node:path' ;
2424import { glob } from 'tinyglobby' ;
25+ import { parseArgs } from 'node:util' ;
2526
2627// Do not remove `.git` as we use Git for comparisons later.
2728// Also preserve `uniqueId` as it's irrelevant for the diff and not included via Bazel.
2829// The `README.md` is also put together outside of Bazel, so ignore it too.
2930const SKIP_FILES = [ / ^ R E A D M E \. m d $ / , / ^ u n i q u e I d $ / , / \. m a p $ / ] ;
3031
31- const packageName = process . argv [ 2 ] ;
32+ const { positionals, values : flags } = parseArgs ( {
33+ options : {
34+ write : {
35+ type : 'boolean' ,
36+ short : 'w' ,
37+ default : false ,
38+ } ,
39+ } ,
40+ allowPositionals : true ,
41+ } ) ;
42+ const packageName = positionals [ 0 ] ;
3243if ( ! packageName ) {
3344 console . error ( 'Expected package name to be specified.' ) ;
3445 process . exit ( 1 ) ;
@@ -145,10 +156,17 @@ async function main(packageName: string) {
145156
146157 // Add all files so that new untracked files are also visible in the diff.
147158 git . run ( [ 'add' , '-A' ] , { cwd : tmpDir } ) ;
148- const diff = git . run ( [ 'diff' , 'HEAD' , '--color' ] , { cwd : tmpDir } ) . stdout ;
149-
150- console . info ( '\n\n----- Diff ------' ) ;
151- console . info ( diff ) ;
159+ const diff = git . run ( [ 'diff' , 'HEAD' , flags . write ? '--no-color' : '--color' ] , {
160+ cwd : tmpDir ,
161+ } ) . stdout ;
162+ if ( flags . write ) {
163+ const outputFilePath = path . join ( process . cwd ( ) , `${ packageName } .diff` ) ;
164+ fs . writeFileSync ( outputFilePath , diff , 'utf-8' ) ;
165+ console . info ( `Saved diff to: ${ outputFilePath } ` ) ;
166+ } else {
167+ console . info ( '\n\n----- Diff ------' ) ;
168+ console . info ( diff ) ;
169+ }
152170 } finally {
153171 await deleteDir ( tmpDir ) ;
154172 }
@@ -160,14 +178,19 @@ async function deleteDir(dirPath: string) {
160178 }
161179
162180 // Needed as Bazel artifacts are readonly and cannot be deleted otherwise.
163- recursiveChmod ( dirPath , 'u+w' ) ;
181+ recursiveChmod ( dirPath ) ;
164182 await fs . promises . rm ( dirPath , { recursive : true , force : true , maxRetries : 3 } ) ;
165183}
166184
167- function recursiveChmod ( dirPath : string , permissions : fs . Mode ) {
168- fs . chmodSync ( dirPath , permissions ) ;
185+ function recursiveChmod ( dirPath : string ) {
186+ const stats = fs . statSync ( dirPath ) ;
169187
170- for ( const file of fs . readdirSync ( dirPath ) ) {
171- recursiveChmod ( path . join ( dirPath , file ) , permissions ) ;
188+ // Add user write permission to existing permissions.
189+ fs . chmodSync ( dirPath , stats . mode | 0o200 ) ;
190+
191+ if ( stats . isDirectory ( ) ) {
192+ for ( const file of fs . readdirSync ( dirPath ) ) {
193+ recursiveChmod ( path . join ( dirPath , file ) ) ;
194+ }
172195 }
173196}
0 commit comments