import * as cli from "cli" ; import { default as chalk } from "chalk" ; import { readFileSync , existsSync , statSync , readdirSync , PathLike } from "fs" ; import { join , resolve } from "path" ; import * as rubber from './rubber' ; import { getUserDir } from "./utils/preferences_grab" ; cli . setUsage ( "rubber [options] path/to/project.yyp [output file]" ) ; /**
 * Preform basic checks to see if a .yyp is actually valid.
 */ function validateYYP ( path ) { let projectRead ; try { projectRead = JSON . parse ( readFileSync ( path ) . toString ( ) . replace ( /\,\s*\}/gi , "}" ) . replace ( /\,\s*\]/gi , "]" ) ) ; } catch ( e ) { projectRead = { } ; } return ( ( "IsDnDProject" in projectRead ) && ( "id" in projectRead ) && ( "mvc" in projectRead ) && ( "resources" in projectRead ) && ( projectRead . modelName === "GMProject" ) ) || ( ( "resources" in projectRead ) && ( "MetaData" in projectRead ) && ( "resourceVersion" in projectRead ) && ( "name" in projectRead ) && ( "tags" in projectRead ) && ( projectRead . resourceType === "GMProject" ) ) ; } const options = cli . parse ( { zip : [ "Z" , "Creates a zip archive" ] , installer : [ "I" , "Creates a installer package" ] , yyc : [ "y" , "Compiles with YYC" ] , config : [ "c" , "Sets the configuration" , "string" ] , version : [ "v" , "Display the current version" ] , clear : [ "" , "Clears cache for project and exits." ] , "clear_remote" : [ "" , "Clears the remote client cache." ] , "gms-dir" : [ "" , "Alternative GMS installation directory" , "path" ] , "export-platform" : [ "p" , "Export platform" , "string" ] , "device-config-dir" : [ "" , "Target device config file directory" , "path" ] , "target-device-name" : [ "" , "Target device name" , "string" ] , "runtime" : [ "" , "The runtime to use" , "string" ] , "ea" : [ "" , "Toggle whether to use Early Access version" ] } ) ; cli . main ( async ( args , options ) => { if ( options . version ) { const packagejson = JSON . parse ( readFileSync ( join ( __dirname , "../package.json" ) ) . toString ( ) ) ; console . log ( `Rubber ` + chalk . green ( `v${ packagejson . version }` ) ) ; return ; } if ( args . length == 0 ) { cli . fatal ( "Missing project path. Exiting" ) ; } let path = resolve ( args [ 0 ] ) ; if ( statSync ( path ) . isDirectory ( ) ) { for ( const name of readdirSync ( path ) ) { if ( ! statSync ( join ( path , name ) ) . isDirectory ( ) ) { if ( validateYYP ( join ( path , name ) ) ) { path = join ( path , name ) ; break ; } } } } if ( ! existsSync ( path ) ) { cli . fatal ( "Project does not exist at " + chalk . yellow ( path ) + ". Exiting" ) ; return ; } if ( ! validateYYP ( path ) ) { cli . fatal ( "Project invalid, or in a newer format. Exiting" ) ; } let buildType = "test" ; if ( options . zip && options . installer ) { cli . fatal ( "Cannot make a zip and installer :)   Use two different cli calls. Exiting" ) ; } if ( options . zip ) { buildType = "zip" ; } if ( options . installer ) { buildType = "installer" ; } let gamemakerLocation = "" ; if ( options [ "gms-dir" ] ) { gamemakerLocation = options [ "gms-dir" ] ; } let deviceConfigFileLocation = "" ; if ( options [ "device-config-dir" ] ) { deviceConfigFileLocation = options [ "device-config-dir" ] ; } let targetDeviceName = "" ; if ( options [ "target-device-name" ] ) { targetDeviceName = options [ "target-device-name" ] ; } let platform = "windows" ; if ( options [ "export-platform" ] ) { platform = options [ "export-platform" ] ; } let theRuntime = "" ; if ( options [ "runtime" ] ) { theRuntime = options [ "runtime" ] ; } let rubberOptions = { projectPath : path , build : buildType , outputPath : args [ 1 ] || "" , yyc : options . yyc , config : options . config || "default" , verbose : options . debug , gamemakerLocation , platform , deviceConfigFileLocation , targetDeviceName , theRuntime , ea : options . ea } ; if ( options . clear ) { rubber . clearCache ( path ) . then ( ( ) => { cli . info ( "Cleared Project Cache." ) ; } ) ; return ; } const build = options [ "clear_remote" ] ? rubber . clearCacheRemote ( rubberOptions ) : rubber . compile ( rubberOptions , false ) ; build . on ( "compileStatus" , ( data ) => { if ( data . toLowerCase ( ) . startsWith ( "error" ) ) { data = chalk . redBright ( data ) ; } process . stdout . write ( data ) ; } ) ; build . on ( "gameStatus" , ( data ) => { process . stdout . write ( data ) ; } ) ; build . on ( "gameStarted" , ( ) => { console . log ( "\n" ) ; } ) ; let igorErrors = false ; build . on ( "compileFinished" , ( errors ) => { if ( errors . length > 0 ) { igorErrors = true ; console . log ( chalk . redBright ( "Compile Errors:" ) ) ; errors . forEach ( err => { console . log ( "  " + chalk . redBright ( err ) ) ; } ) ; } } ) ; build . on ( "allFinished" , ( ) => { if ( ! igorErrors ) console . log ( chalk . green ( "Compile Finished" ) ) ; } ) ; build . on ( "error" , ( error ) => { if ( ! igorErrors ) cli . fatal ( error . message ) ; } ) ; } ) ;