import fg from "fast-glob" ;
import fs from "fs" ;
import assert from "assert" ;
import { log } from "./logging.js" ;
import Path from "path" ;
import { execSync } from "child_process" ;
/ *
Fixes some common problems with fast - glob on windows .
* /
export const glob = ( path ) => {
if ( process . platform === "win32" ) {
// fast-glob doesn't understand \\ or C:\
const fixed _path = path . replace ( "C:" , "" ) . replaceAll ( '\\' , '/' )
return fg . sync ( fixed _path ) ;
} else {
return fg . sync ( path ) ;
}
}
export const changed = ( source , target ) => {
// we want the source to error if it doesn't exist
const s _stat = fs . statSync ( source ) ;
// but target might not exist, which would mean it's a change
const t _stat = fs . statSync ( target , { throwIfNoEntry : false } ) ;
return ! t _stat || s _stat . mtimeMs > t _stat . mtimeMs ;
}
/* Makes a directory recursively. */
export const mkdir = ( dir ) => {
if ( ! fs . existsSync ( dir ) ) {
log . debug ( ` making dir ${ dir } ` ) ;
fs . mkdirSync ( dir , { recursive : true } ) ;
}
}
/ *
Given any path to a file , makes sure all its directories are in place .
Example :
` ` ` javascript
console . log ( "PRINT" ) ;
` ` `
- ` param string ` -- path to file
* /
export const mkdir _to = ( target ) => {
let dirs = Path . parse ( target ) ;
mkdir ( dirs . dir ) ;
}
/* Convenience function that makes sure the dir is there then writes the data. */
export const write = ( target , data ) => {
mkdir _to ( target ) ;
fs . writeFileSync ( target , data ) ;
}
/ *
Like write but does an OS copy after making the target dir . When given a
filter it will give the filter function the arguments , let it return contents ,
then write those instead of a copy .
* /
export const copy = ( src , dest , filter = null ) => {
mkdir _to ( dest ) ;
if ( filter ) {
try {
let raw _data = fs . readFileSync ( src ) ;
let data = filter ( src , dest , raw _data ) ;
write ( dest , data ) ;
} catch ( error ) {
log . error ( error , "Problem with filter write in copy" ) ;
}
} else {
fs . copyFileSync ( src , dest ) ;
}
}
export const rm = ( file _name , ignore = false ) => {
log . warn ( "Deleting file" , file _name ) ;
try {
fs . unlinkSync ( file _name ) ;
} catch ( error ) {
if ( ignore ) {
log . debug ( ` Requested delete file ${ file _name } doesn't exist, but ignored. ` ) ;
} else {
log . error ( error , file _name ) ;
throw error ;
}
}
}
export const index _rollup = ( src _index , target _index , contents , key ) => {
let index = JSON . parse ( fs . readFileSync ( src _index ) ) ;
index [ key ] = glob ( contents ) . map ( f => JSON . parse ( fs . readFileSync ( f ) ) ) ;
assert ( index [ key ] !== undefined , ` Attempt to load contents into ${ key } for ${ src _index } failed with undefined. ` ) ;
write ( target _index , JSON . stringify ( index ) ) ;
return index ;
}
export const exec = ( cmd , opts ) => {
log . info ( ` EXEC ${ cmd } ` ) ;
return execSync ( cmd , opts ) ;
}
export const exec _i = ( cmd , opts = { } ) => {
return exec ( cmd , { stdio : [ process . stdout , process . stderr , process . stdin ] , ... opts } ) ;
}
export default {
index _rollup , rm , exec , changed , mkdir , mkdir _to , write , copy , exec _i , glob
}