From ffd3c73800baeb4ddb0238c04d21ac2f0971754e Mon Sep 17 00:00:00 2001 From: Frankly George <54015-franklygeorge@users.noreply.gitgud.io> Date: Wed, 7 Feb 2024 18:58:20 +0000 Subject: [PATCH] Updated Gulp build script, compile.bat, and compile.sh --- .eslintrc.json | 10 + .gitignore | 3 + .gitlab-ci.yml | 3 +- CONTRIBUTING.md | 1 - build.config.json | 13 +- compile-legacy.bat | 2 + compile-legacy.sh | 203 +++++++ compile.bat | 144 ++++- compile.sh | 219 ++------ compile_debug.bat | 11 - compile_themes.bat | 29 - gulpfile.js | 502 ++++++++++++++---- package.json | 14 +- ...e_debug+sanityCheck.bat => sanityCheck.bat | 10 +- 14 files changed, 810 insertions(+), 354 deletions(-) create mode 100644 compile-legacy.bat create mode 100755 compile-legacy.sh delete mode 100644 compile_debug.bat delete mode 100644 compile_themes.bat rename compile_debug+sanityCheck.bat => sanityCheck.bat (84%) diff --git a/.eslintrc.json b/.eslintrc.json index 9dbbf5be39e..0306fb66558 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -31,6 +31,16 @@ "impliedStrict": true } }, + "overrides": [ + { + // overrides for helper scripts that are written + // using imports and/or exports + "files": ["gulpfile.js"], + "parserOptions": { + "sourceType": "module" + } + } + ], "settings": { "jsdoc": { "mode": "typescript" diff --git a/.gitignore b/.gitignore index 9ca9221b11e..12190558f14 100644 --- a/.gitignore +++ b/.gitignore @@ -75,3 +75,6 @@ src/002-config/fc-version.js.commitHash.js # legacy devNotes/legacy files/* /.vs + +# mod development +/mods/dev/ \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 621997da4f2..4b7809f8261 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -36,8 +36,7 @@ build: before_script: - npm update --no-audit --no-fund --omit=dev script: - - mkdir bin/ # The minifier cannot create the location for the minified file itself - - npx gulp --minify --release --ci --verbosity 6 + - npx gulp --minify --release --ci html artifacts: paths: - bin/FC_pregmod.html diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ea25f4e8e49..02aa37b799b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,6 @@ To effectively work on the project the following tools are required: * Windows: Open a terminal and execute `cd C:\path\to\project\fc-pregmod` * GNU/Linux: Open a terminal and execute `cd /path/to/project/fc-pregmod/` 3. Run `npm install` in your terminal - * On Windows, you may need to run `npm install --omit-optional` instead. 4. Open the directory in your preferred editor * Make sure you have an extension for ESLint installed to catch formatting errors diff --git a/build.config.json b/build.config.json index 3d84c8e0c54..cf0aea27ddb 100644 --- a/build.config.json +++ b/build.config.json @@ -1,9 +1,10 @@ { "dirs": { "intermediate": "build", - "output": "bin" + "output": "bin", + "modOutput": "bin/mods" }, - "output": "FC_pregmod.html", + "output": "FC_pregmod[extras].html", "gitVersionFile": "src/002-config/fc-version.js.commitHash.js", "sources": { "module": { @@ -11,14 +12,16 @@ "css": ["css/**/*.css"] }, "story": { - "css": ["src/**/*.css"], "js": ["src/**/*.js"], + "css": ["src/**/*.css"], "twee": ["src/**/*.tw"], "media": [ - "src/art/vector/layers", - "src/art/vector_revamp/layers" + "src/art/vector/layers/", + "src/art/vector_revamp/layers/" ] }, + "mods": "mods/dev", + "themes": "themes", "head": "resources/raster/favicon/arcologyVector.html" }, "options": { diff --git a/compile-legacy.bat b/compile-legacy.bat new file mode 100644 index 00000000000..a07be8664a8 --- /dev/null +++ b/compile-legacy.bat @@ -0,0 +1,2 @@ +:: just a shortcut for compile.bat --legacy +call compile.bat --legacy \ No newline at end of file diff --git a/compile-legacy.sh b/compile-legacy.sh new file mode 100755 index 00000000000..b3b903a7461 --- /dev/null +++ b/compile-legacy.sh @@ -0,0 +1,203 @@ +#!/bin/bash + +output=/dev/stdout +name=FC_pregmod + +# displays help text +function displayHelp() { + cat <<HelpText +Usage: compile.sh [OPTION]... + +Options: + -d, --dry Do not compile + -g, --git Add hash of HEAD to filename + -h, --help Show this help text + -s, --sanity Run sanityCheck + -q, --quiet Suppress terminal output + -t, --themes Generate theme files + -m, --minify Minify output files + --ci CI mode + -f, --f Final file name +HelpText +} + +#display an error message +function echoError() { + echo -e "\033[0;31m$*\033[0m" +} + +#display message +function echoMessage() { + echo "$1" >"${output}" +} + +#compile the HTML file +function compile() { + mkdir -p bin/resources + export TWEEGO_PATH=devTools/tweeGo/storyFormats + TWEEGO_EXE="tweego" + + if hash $TWEEGO_EXE 2>/dev/null; then + echoMessage "system tweego binary" + else + case "$(uname -m)" in + x86_64 | amd64) + echoMessage "x64 arch" + if [ "$(uname -s)" = "Darwin" ]; then + TWEEGO_EXE="./devTools/tweeGo/tweego_osx64" + elif [ "$OSTYPE" = "msys" ]; then + TWEEGO_EXE="./devTools/tweeGo/tweego_win64" + else + TWEEGO_EXE="./devTools/tweeGo/tweego_nix64" + fi + ;; + x86 | i[3-6]86) + echoMessage "x86 arch" + if [ "$(uname -s)" = "Darwin" ]; then + TWEEGO_EXE="./devTools/tweeGo/tweego_osx86" + elif [ "$OSTYPE" = "msys" ]; then + TWEEGO_EXE="./devTools/tweeGo/tweego_win86" + else + TWEEGO_EXE="./devTools/tweeGo/tweego_nix86" + fi + ;; + *) + echoError "No system tweego binary found, and no precompiled binary for your platform available." + echoError "Please compile tweego and put the executable in PATH." + exit 2 + ;; + esac + fi + + if [ "$(uname -m)" = "x86_64" ] || [ "$(uname -m)" = "amd64" ]; then + if [ "$(uname -s)" = "Darwin" ]; then + MINIFY_EXE="./devTools/minify/minify_darwin_amd64" + elif [ "$OSTYPE" = "msys" ]; then + MINIFY_EXE="./devTools/minify/minify_win_amd64.exe" + else + MINIFY_EXE="./devTools/minify/minify_linux_amd64" + fi + fi + + file="bin/${name}.html" + + # Find and insert current commit + if [[ "$ci" ]]; then + COMMIT=$CI_COMMIT_SHORT_SHA + elif [[ -d .git ]]; then + COMMIT=$(git rev-parse --short HEAD) + if [[ "$usehash" ]]; then + file="bin/${name}${COMMIT}.html" + fi + fi + if [[ "$minify" ]]; then + final_file=$file + file="bin/tmp.html" + fi + + if [[ "$COMMIT" ]]; then + printf "App.Version.commitHash = '%s';\n" "${COMMIT}" > src/002-config/fc-version.js.commitHash.js + fi + + devTools/concatFiles.sh js/ '*.js' bin/fc.js + devTools/concatFiles.sh css/ '*.css' bin/fc.css + $TWEEGO_EXE -o "$file" --module=bin/fc.js --module=bin/fc.css --head resources/raster/favicon/arcologyVector.html src/ || build_failed="true" + rm -f bin/fc.js + rm -f bin/fc.css + if [ "$build_failed" = "true" ]; then + echoError "Build failed." + exit 1 + fi + + if [[ "$minify" ]]; then + if [[ "$MINIFY_EXE" ]]; then + # SC license is inside an HTML comment, so keep them. + # eval depends on local variables, so don't modify them (Config, Engine, ...) + $MINIFY_EXE --html-keep-comments --js-keep-var-names "$file" > "$final_file" + rm -f "$file" + else + echoError "Minification only available on amd64 systems." + mv "$file" "$final_file" + fi + file=$final_file + fi + + if [[ "$ci" || -d .git ]]; then + rm src/002-config/fc-version.js.commitHash.js + fi + echoMessage "Saved to $file." +} + +if [[ "$1" == "" ]]; then + #tip if no option + echoMessage "For more options see compile.sh -h." +else + #parse options + while [[ "$1" ]]; do + case $1 in + -d | --dry) + dry="true" + ;; + -g | --git) + usehash="true" + ;; + -h | --help) + displayHelp + exit 0 + ;; + -s | --sanity) + sanity="true" + ;; + -q | --quiet) + output=/dev/null + ;; + -t | --themes) + themes="true" + ;; + -m | --minify) + minify="true" + ;; + --ci) + ci="true" + ;; + -f | --file) + name=$2 + shift + ;; + *) + echoError "Unknown argument $1." + displayHelp + exit 1 + ;; + esac + shift + done +fi + +# Run sanity check. +[ -n "$sanity" ] && ./sanityCheck.sh + +if ! [[ -d .git ]]; then + echoMessage "No git repository. Git specific actions disabled." +fi + +#compile +if [[ "$dry" ]]; then + echoMessage "Dry run finished." +else + compile + echoMessage "Compilation finished at $(date +%T)." +fi + +# compile themes +if [[ "$themes" ]]; then + ( + cd themes/ || exit + for D in *; do + if [ -d "${D}" ]; then + ../devTools/concatFiles.sh "${D}"/ '*.css' ../bin/"${D}".css + fi + done + ) + echoMessage "Themes compiled at $(date +%T)" +fi diff --git a/compile.bat b/compile.bat index 869fd26680f..1ec489dd0fe 100644 --- a/compile.bat +++ b/compile.bat @@ -3,15 +3,103 @@ :: Set working directory pushd %~dp0 -SETLOCAL +SET BASEDIR=%~dp0 +SETLOCAL EnableDelayedExpansion -:: If compile is invoked with "extramemory", set SORT_MEM (used by concatFiles.bat) +set "GULP=True" -SET CMD_OPTION=%~1 -IF DEFINED CMD_OPTION IF /I [%CMD_OPTION%]==[EXTRAMEMORY] SET CMD_OPTION=EXTRAMEM -IF DEFINED CMD_OPTION IF /I [%CMD_OPTION%]==[EMEMORY] SET CMD_OPTION=EXTRAMEM -IF DEFINED CMD_OPTION IF /I [%CMD_OPTION%]==[EXTRAMEM] SET SORT_MEM=65535 +:: process arguments from command line +:processargs +SET ARG=%1 +IF DEFINED ARG ( + :: legacy arguments + IF "%ARG%"=="EXTRAMEMORY" SET SORT_MEM=65535 + IF "%ARG%"=="EMEMORY" SET SORT_MEM=65535 + IF "%ARG%"=="EXTRAMEM" SET SORT_MEM=65535 + :: disable building with Gulp + if "%ARG%"=="--legacy" SET "GULP=" + :: create themes using legacy compile + if "%ARG%"=="--themes" SET "THEMES=True" + if "%ARG%"=="--help" GOTO :help + SHIFT + GOTO processargs +) + +:: check if gulp is defined +if DEFINED GULP ( + :: check for git + where /q git + IF ERRORLEVEL 1 ( + ECHO git is not available. + SET "GULP=" + ) + + :: check for node + where /q node + IF ERRORLEVEL 1 ( + ECHO Node is not available. + SET "GULP=" + ) + + :: if gulp is still defined + IF DEFINED GULP ( + :: if the node_modules directory doesn't exist + IF NOT EXIST .\node_modules\ ( + ECHO Node and git are available, but the Node modules are not installed. + CHOICE /C YN /N /M "Would you like us to run 'npm install' to install Node modules, using ~120 MB of disk space [Y/N]?" + IF !errorlevel!==1 ( + ECHO Installing Node modules... + CALL npm install + ) ELSE ( + ECHO Use the '--legacy' flag to remove this prompt or run 'compile-legacy.bat' instead. + SET "GULP=" + ) + ) + ) + + :: if gulp is still defined + if DEFINED GULP ( + ECHO Using Gulp to build FC. + ECHO Pass the '--legacy' flag to use the legacy compiler or run 'compile-legacy.bat' instead. + + if DEFINED THEMES ( + ECHO The '--themes' flag only needed for legacy compiler. Gulp always compiles themes. + ECHO Either remove it or add the '--legacy' flag to use the legacy compiler. + ) + + :: execute gulp command + CALL npx gulp all --color + + :: exit + ENDLOCAL + popd + exit /b 0 + ) +) else ( + :: Using legacy compiler since the '--legacy' flag was set. + GOTO legacybuild +) +:gulpmessage +ECHO. +ECHO Development builds will be more debugable (will include source maps) if you enable Gulp. +ECHO To enable Gulp make sure you have git and Node installed. +ECHO To remove these messages, pass the '--legacy' flag or run 'compile-legacy.bat' instead. +ECHO. + +:legacybuild + +:: if the bin directory doesn't exist, then create it +if NOT EXIST .\bin\ ( + MKDIR .\bin\ +) + +if DEFINED THEMES ( + CALL :compile_themes +) + +ECHO Compiling FC... +ECHO Press Ctrl+C at any time to cancel the build. :: See if we can find a git installation set GITFOUND=no @@ -52,3 +140,47 @@ IF EXIST "%~dp0src\002-config\fc-version.js.commitHash.js" DEL "%~dp0src\002-con ENDLOCAL popd ECHO Done +GOTO :eof + +:compile_themes +ECHO Compiling Themes... + +set back=%cd% +for /d %%i in (%~dp0\themes\*) do ( + CALL :compileDirectory %%i +) +cd %back% + +EXIT /B %ERRORLEVEL% + +:compileDirectory +REM ~1 is an absolute path, get name of directory here +REM https://stackoverflow.com/a/5480568 +set var1=%~1% +set var2=%var1% +set i=0 + +:loopprocess +for /F "tokens=1* delims=\" %%A in ( "%var1%" ) do ( + set /A i+=1 + set var1=%%B + goto loopprocess +) + +for /F "tokens=%i% delims=\" %%G in ( "%var2%" ) do set last=%%G + +REM compile +CALL devTools/concatFiles.bat "%%~1" "*.css" bin\"%last%".css +:: end loopprocess and compileDirectory +GOTO :eof + +:: print help +:help +ECHO compile.bat [flags] +ECHO. +ECHO --legacy: build using legacy compiler (less features, but no extra depenencies) +ECHO --themes: create themes using legacy compiler (automatically created in new compiler) +ECHO EXTRAMEM: passed to the sort script when using legacy compiler +ECHO --npm: install npm modules automatically +:: exit +GOTO :eof \ No newline at end of file diff --git a/compile.sh b/compile.sh index b3b903a7461..254fb9166ac 100755 --- a/compile.sh +++ b/compile.sh @@ -1,203 +1,84 @@ #!/bin/bash -output=/dev/stdout -name=FC_pregmod +# check for git +if command -v git &> /dev/null; then + git="true" +fi + +# check for Node +if command -v node &> /dev/null; then + node="true" +fi + +# check for node_modules +if [[ "$git" && "$node" ]]; then + # if the node_modules directory doesn't exist + if [[ -d node_modules ]]; then + npm="true" + fi +fi # displays help text function displayHelp() { cat <<HelpText -Usage: compile.sh [OPTION]... +Usage: compile.sh [GULP FLAGS] -Options: - -d, --dry Do not compile - -g, --git Add hash of HEAD to filename - -h, --help Show this help text - -s, --sanity Run sanityCheck - -q, --quiet Suppress terminal output - -t, --themes Generate theme files - -m, --minify Minify output files - --ci CI mode - -f, --f Final file name -HelpText -} +Falls back to ./compile-legacy.sh if Gulp's dependencies are missing. -#display an error message -function echoError() { - echo -e "\033[0;31m$*\033[0m" -} +HelpText -#display message -function echoMessage() { - echo "$1" >"${output}" +if [[ $"npm" ]]; then + npx gulp +else + cat <<HelpText +Gulp's dependencies are not installed. +HelpText +fi } -#compile the HTML file -function compile() { - mkdir -p bin/resources - export TWEEGO_PATH=devTools/tweeGo/storyFormats - TWEEGO_EXE="tweego" - - if hash $TWEEGO_EXE 2>/dev/null; then - echoMessage "system tweego binary" - else - case "$(uname -m)" in - x86_64 | amd64) - echoMessage "x64 arch" - if [ "$(uname -s)" = "Darwin" ]; then - TWEEGO_EXE="./devTools/tweeGo/tweego_osx64" - elif [ "$OSTYPE" = "msys" ]; then - TWEEGO_EXE="./devTools/tweeGo/tweego_win64" - else - TWEEGO_EXE="./devTools/tweeGo/tweego_nix64" - fi - ;; - x86 | i[3-6]86) - echoMessage "x86 arch" - if [ "$(uname -s)" = "Darwin" ]; then - TWEEGO_EXE="./devTools/tweeGo/tweego_osx86" - elif [ "$OSTYPE" = "msys" ]; then - TWEEGO_EXE="./devTools/tweeGo/tweego_win86" - else - TWEEGO_EXE="./devTools/tweeGo/tweego_nix86" - fi - ;; - *) - echoError "No system tweego binary found, and no precompiled binary for your platform available." - echoError "Please compile tweego and put the executable in PATH." - exit 2 - ;; - esac - fi - - if [ "$(uname -m)" = "x86_64" ] || [ "$(uname -m)" = "amd64" ]; then - if [ "$(uname -s)" = "Darwin" ]; then - MINIFY_EXE="./devTools/minify/minify_darwin_amd64" - elif [ "$OSTYPE" = "msys" ]; then - MINIFY_EXE="./devTools/minify/minify_win_amd64.exe" - else - MINIFY_EXE="./devTools/minify/minify_linux_amd64" - fi - fi - - file="bin/${name}.html" - - # Find and insert current commit - if [[ "$ci" ]]; then - COMMIT=$CI_COMMIT_SHORT_SHA - elif [[ -d .git ]]; then - COMMIT=$(git rev-parse --short HEAD) - if [[ "$usehash" ]]; then - file="bin/${name}${COMMIT}.html" - fi - fi - if [[ "$minify" ]]; then - final_file=$file - file="bin/tmp.html" - fi - - if [[ "$COMMIT" ]]; then - printf "App.Version.commitHash = '%s';\n" "${COMMIT}" > src/002-config/fc-version.js.commitHash.js - fi - - devTools/concatFiles.sh js/ '*.js' bin/fc.js - devTools/concatFiles.sh css/ '*.css' bin/fc.css - $TWEEGO_EXE -o "$file" --module=bin/fc.js --module=bin/fc.css --head resources/raster/favicon/arcologyVector.html src/ || build_failed="true" - rm -f bin/fc.js - rm -f bin/fc.css - if [ "$build_failed" = "true" ]; then - echoError "Build failed." - exit 1 - fi - - if [[ "$minify" ]]; then - if [[ "$MINIFY_EXE" ]]; then - # SC license is inside an HTML comment, so keep them. - # eval depends on local variables, so don't modify them (Config, Engine, ...) - $MINIFY_EXE --html-keep-comments --js-keep-var-names "$file" > "$final_file" - rm -f "$file" - else - echoError "Minification only available on amd64 systems." - mv "$file" "$final_file" - fi - file=$final_file - fi - - if [[ "$ci" || -d .git ]]; then - rm src/002-config/fc-version.js.commitHash.js - fi - echoMessage "Saved to $file." -} +flags="all" if [[ "$1" == "" ]]; then #tip if no option - echoMessage "For more options see compile.sh -h." + echo "For more options see compile.sh -h." else #parse options while [[ "$1" ]]; do case $1 in - -d | --dry) - dry="true" - ;; - -g | --git) - usehash="true" - ;; -h | --help) displayHelp exit 0 ;; - -s | --sanity) - sanity="true" - ;; - -q | --quiet) - output=/dev/null - ;; - -t | --themes) - themes="true" - ;; - -m | --minify) - minify="true" - ;; - --ci) - ci="true" - ;; - -f | --file) - name=$2 - shift - ;; *) - echoError "Unknown argument $1." - displayHelp - exit 1 - ;; + flags="${flags} $1" esac shift done fi -# Run sanity check. -[ -n "$sanity" ] && ./sanityCheck.sh +echo "" +if [[ ! "$git" ]]; then + echo "git is not available, install it to use Gulp compiler." +fi -if ! [[ -d .git ]]; then - echoMessage "No git repository. Git specific actions disabled." +if [[ ! "$node" ]]; then + echo "Node is not available, install it to use the Gulp compiler." fi -#compile -if [[ "$dry" ]]; then - echoMessage "Dry run finished." -else - compile - echoMessage "Compilation finished at $(date +%T)." +if [[ ! "$npm" ]]; then + echo "Node modules aren't installed, run 'npm install' to install them." fi -# compile themes -if [[ "$themes" ]]; then - ( - cd themes/ || exit - for D in *; do - if [ -d "${D}" ]; then - ../devTools/concatFiles.sh "${D}"/ '*.css' ../bin/"${D}".css - fi - done - ) - echoMessage "Themes compiled at $(date +%T)" +if [[ ! "$git" || ! "$node" || ! "$npm" ]]; then + echo "" + echo "Gulp compiler dependencies not met, falling back to legacy compiler." + echo "The legacy compiler is missing source map generation, but requires no other dependencies." + echo "If you wish to always use the legacy compiler, run './compile-legacy.sh' instead." + echo "" + ./compile-legacy.sh $flags + exit 0 fi + +echo "Compiling using Gulp with these arguments: $flags" +echo "" +npx gulp $flags \ No newline at end of file diff --git a/compile_debug.bat b/compile_debug.bat deleted file mode 100644 index 17d3c9be06d..00000000000 --- a/compile_debug.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo off -:: Free Cities Basic Compiler - Windows - -:: Set working directory -pushd %~dp0 - -:: Compile the game -call "%~dp0compile.bat" - -popd -PAUSE diff --git a/compile_themes.bat b/compile_themes.bat deleted file mode 100644 index 460d1c11704..00000000000 --- a/compile_themes.bat +++ /dev/null @@ -1,29 +0,0 @@ -@echo off - -set back=%cd% -for /d %%i in (%~dp0\themes\*) do ( - CALL :compileDirectory %%i -) -cd %back% - -EXIT /B %ERRORLEVEL% - -:compileDirectory -REM ~1 is an absolute path, get name of directory here -REM https://stackoverflow.com/a/5480568 -set var1=%~1% -set var2=%var1% -set i=0 - -:loopprocess -for /F "tokens=1* delims=\" %%A in ( "%var1%" ) do ( - set /A i+=1 - set var1=%%B - goto loopprocess -) - -for /F "tokens=%i% delims=\" %%G in ( "%var2%" ) do set last=%%G - -REM compile -CALL devTools/concatFiles.bat "%%~1" "*.css" bin\"%last%".css -EXIT /B 0 diff --git a/gulpfile.js b/gulpfile.js index 3f34c4542ee..5141a260448 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,38 +1,119 @@ -import {config as minifyConfig, string as minifyString, file as minifyFile} from '@tdewolff/minify'; -import yargs from 'yargs'; -import {hideBin} from 'yargs/helpers'; +/** + * @file defines the gulp tasks that we use to build FC + */ + +/* globals process */ +// cSpell: words embedsourcemaps, sourcemapsincludecontent, pmodversion, fnames, nothrow, pathcmp, autoprefix + +import yargs from "yargs"; +import {hideBin} from "yargs/helpers"; +import terser from "gulp-terser"; +import cleanCSS from "gulp-clean-css"; import autoprefixer from "autoprefixer"; -import chalk from "chalk"; import gulp from "gulp"; import concat from "gulp-concat"; -import log from 'fancy-log-levels'; +import gulpIgnore from "gulp-ignore"; +import log from "fancy-log-levels"; import noop from "gulp-noop"; import postcss from "gulp-postcss"; import shell from "gulp-shell"; import sort from "gulp-sort"; import sourcemaps from "gulp-sourcemaps"; import stripCssJSComments from "gulp-strip-comments"; -import childProcess from "child_process"; +import {execSync} from "child_process"; import which from "which"; -import fs from "fs"; +import jetpack from "fs-jetpack"; import path from "path"; import os from "os"; -import through from 'through2'; -import cfg from './build.config.json' assert {type: "json"}; - -// defines build options which can be supplied from the command line -// example: npx gulp --minify --verbosity 6 -const args = yargs(hideBin(process.argv)).options({ - verbosity: {type: 'number', default: 1}, - release: {type: 'boolean', default: false}, - ci: {type: 'boolean', default: false}, // assumes gitlab CI environment - minify: {type: 'boolean', default: false}, - embedsourcemaps: {type: 'boolean', default: false}, - sourcemapsincludecontent: {type: 'boolean', default: false} -}).argv; - -minifyConfig({"html-keep-comments": true, "js-keep-var-names": true}); +import {fileURLToPath} from "url"; + +// run `npx gulp` to display help +const args = yargs(hideBin(process.argv)) + .showHelpOnFail(true) + .option('verbosity', { + alias: 'v', + type: 'number', + description: 'Logging verbosity level, 1-6', + default: 6, + }) + .option('release', { + alias: 'r', + type: 'boolean', + description: 'Build source maps if not supplied', + default: false, + }) + .options('ci', { + type: 'boolean', + description: 'Assumes gitlab CI environment', + default: false, + }) + .option('minify', { + alias: 'm', + type: 'boolean', + description: 'Makes builds smaller at the cost of readability and compiling time', + default: false, + }) + .options('embedsourcemaps', { + type: 'boolean', + description: 'Embed source maps into final html file', + default: true, + }) + .options('sourcemapsincludecontent', { + type: 'boolean', + description: 'Add original js and css code to the source maps', + default: true, + }) + .options('debug', { + type: 'boolean', + description: 'Add files that match the *.debug.* pattern, otherwise ignore them', + default: false, + }) + .options('hash', { + type: 'boolean', + description: 'Adds the git commit hash to the output filename', + default: false, + }) + .options('epoch', { + type: 'boolean', + description: 'Adds the current epoch time to the output filename', + default: false, + }) + .options('pmodversion', { + type: 'boolean', + description: 'Adds the current pregmod version number to the output filename', + default: false, + }) + // commands should exist as exported gulp tasks + .command('html', "Build FC") + .command('themes', "Build themes") + .command('mods', "Build mods") + .command('all', "Build FC, themes, and mods") + .demandCommand() + .parse(); + +// load json without using "...assert {type: "json"}" which is still in to proposal stage +// https://github.com/tc39/proposal-json-modules + +const cfg = jetpack.read(fileURLToPath(new URL('./build.config.json', import.meta.url)), "json"); +/** + * Options used to minify js code using terser + * @type {import("terser").MinifyOptions} + */ +const terserMinifyConfig = { + // https://www.npmjs.com/package/terser#minify-options + mangle: true, + // eslint-disable-next-line camelcase + keep_classnames: true, + // eslint-disable-next-line camelcase + keep_fnames: true, +}; +/** + * Options used to minify css code using CleanCSS + */ +const cleanCssMinifyConfig = { + // https://www.npmjs.com/package/clean-css#constructor-options +}; /** Filename for the temporary output. Tweego will write here and then it will be moved into the output dir */ const htmlOut = "tmp.html"; @@ -42,47 +123,56 @@ log(args.verbosity); // -------------- Helper functions ----------------------- /** - * @summary Locates tweego executable. - * - * Looks in the host $PATH, otherwise uses one of the bundled in devTools/tweeGo + * Locates a tweego executable. + * Looks in the host $PATH, otherwise uses one of the bundled executables in devTools/tweeGo + * @returns {string} Returns the path to the tweego executable */ function tweeCompilerExecutable() { - const systemTweego = which.sync('tweego', {nothrow: true}); + const systemTweego = which.sync("tweego", {nothrow: true}); + if (systemTweego) { - log.info('Found system tweego at ', systemTweego); + log.info("Found system tweego at ", systemTweego); return systemTweego; } - const archSuffix = os.arch() === 'x64' ? '64' : '86'; + + const archSuffix = os.arch() === "x64" ? "64" : "86"; const platformSuffix = { - 'Darwin': 'osx', - 'Linux': 'nix', - 'Windows_NT': 'win' + "Darwin": "osx", + "Linux": "nix", + "Windows_NT": "win" }[os.type()]; - const extension = os.type() === 'Windows_NT' ? '.exe' : ''; - const res = path.join('.', 'devTools', 'tweeGo', `tweego_${platformSuffix}${archSuffix}${extension}`); - log.info('Using bundled tweego at ', res); + const extension = os.type() === "Windows_NT" ? ".exe" : ""; + const res = path.join(".", "devTools", "tweeGo", `tweego_${platformSuffix}${archSuffix}${extension}`); + + log.info("Using bundled tweego at ", res); return res; } /** - * @summary Composes tweego invocation command + * Composes tweego invocation command * * Combines paths to tweego and options defined in the build.config.json file to * return a full tweego launch command, which will combine all story elements, pick up modules, - * and generate an HTML file in the intermidiate directory + * and generate an HTML file in the intermediate directory + * @returns {string} Full tweego command string */ function tweeCompileCommand() { - let sources = [path.join(cfg.dirs.intermediate, "story")]; + const sources = [path.join(cfg.dirs.intermediate, "story")]; + sources.push(...cfg.sources.story.media); - let modules = [path.join(cfg.dirs.intermediate, "module")]; - let moduleArgs = modules.map(fn => `--module=${fn}`); - return `${tweeCompilerExecutable()} --head=${cfg.sources.head} -o ${path.join(cfg.dirs.intermediate, htmlOut)} ${moduleArgs.join(' ')} ${sources.join(' ')}`; + const modules = [path.join(cfg.dirs.intermediate, "module")]; + const moduleArgs = modules.map(fn => `--module=${fn}`); + + return `${tweeCompilerExecutable()} --head=${cfg.sources.head} -o ${path.join(cfg.dirs.intermediate, htmlOut)} ${moduleArgs.join(" ")} ${sources.join(" ")}`; } /** * gulp-sort uses String.localeCompare() by default, which may be case-insensitive, * while we require case -sensitive sorting for sources + * @param {Vinyl} a + * @param {Vinyl} b + * @returns {number} */ function pathcmp(a, b) { return (a.path < b.path ? -1 : (a.path > b.path ? 1 : 0)); @@ -90,9 +180,17 @@ function pathcmp(a, b) { /** * Creates a pipeline that sorts and combines files + * @param {string|string[]} srcGlob Glob(s) to combine + * @param {string} destDir destination directory to save to + * @param {string} destFileName the filename to save as + * @returns {NodeJS.ReadWriteStream} */ function concatFiles(srcGlob, destDir, destFileName) { return gulp.src(srcGlob) + .pipe(args.debug + ? noop() + : gulpIgnore.exclude("*.debug.*") + ) .pipe(sort(pathcmp)) .pipe(concat(destFileName)) .pipe(gulp.dest(destDir)); @@ -104,26 +202,34 @@ function concatFiles(srcGlob, destDir, destFileName) { * The pipeline collects sources, sorts them, concatenates and * saves in the destination dir. If no "release" command line switch was * supplied, sourcemaps will be written for the files + * @param {string} srcGlob Glob to process + * @param {string} destDir destination directory to save to + * @param {string} destFileName the filename to save as + * @returns {NodeJS.ReadWriteStream} */ function processScripts(srcGlob, destDir, destFileName) { const addSourcemaps = !args.release; - const prefix = path.relative(destDir, srcGlob.substr(0, srcGlob.indexOf('*'))); + const prefix = path.relative(destDir, srcGlob.substr(0, srcGlob.indexOf("*"))); + return gulp.src(srcGlob) + .pipe(args.debug + ? noop() + : gulpIgnore.exclude("*.debug.*") + ) .pipe(sort(pathcmp)) .pipe(addSourcemaps ? sourcemaps.init() : noop()) .pipe(concat(destFileName)) - .pipe(addSourcemaps ? - sourcemaps.write(args.embedsourcemaps ? undefined : '.', { + .pipe(args.minify + // @ts-expect-error This is correct + ? terser(terserMinifyConfig) + : noop()) + .pipe(addSourcemaps + ? sourcemaps.write(args.embedsourcemaps ? undefined : ".", { includeContent: args.sourcemapsincludecontent, sourceRoot: prefix, sourceMappingURLPrefix: path.relative(cfg.dirs.output, destDir) - }) : - noop()) - // minify JS. Mostly for the src/ directory, which later minifying won't be able to access - .pipe(args.minify ? through.obj((chunk, enc, cb) => { - chunk.contents = new Buffer(minifyString("text/javascript", chunk.contents.toString())); - cb(null, chunk); - }) : noop()) + }) + : noop()) .pipe(gulp.dest(destDir)); } @@ -133,24 +239,37 @@ function processScripts(srcGlob, destDir, destFileName) { * The pipeline collects sources, sorts them, concatenates, pass through * an autoprefixer and saves in the destination dir. If no "release" command * line switch was supplied, sourcemaps will be written for the files + * @param {string} srcGlob Glob to process + * @param {string} destDir destination directory to save to + * @param {string} destFileName the filename to save as + * @returns {NodeJS.ReadWriteStream} */ function processStylesheets(srcGlob, destDir, destFileName) { const addSourcemaps = !args.release; - const prefix = path.relative(destDir, srcGlob.substr(0, srcGlob.indexOf('*'))); + const prefix = path.relative(destDir, srcGlob.substr(0, srcGlob.indexOf("*"))); + return gulp.src(srcGlob) + .pipe(args.debug + ? noop() + : gulpIgnore.exclude("*.debug.*") + ) .pipe(sort(pathcmp)) .pipe(addSourcemaps ? sourcemaps.init() : noop()) .pipe(concat(destFileName)) - .pipe(cfg.options.css.autoprefix ? - postcss([autoprefixer({overrideBrowserslist: ['last 2 versions']})]) : - noop()) - .pipe(addSourcemaps ? - sourcemaps.write(args.embedsourcemaps ? undefined : '.', { + .pipe(cfg.options.css.autoprefix + ? postcss([autoprefixer({overrideBrowserslist: ["last 2 versions"]})]) + : noop()) + // minify css using CleanCSS + .pipe(args.minify + ? cleanCSS(cleanCssMinifyConfig) + : noop()) + .pipe(addSourcemaps + ? sourcemaps.write(args.embedsourcemaps ? undefined : ".", { includeContent: args.sourcemapsincludecontent, sourceRoot: prefix, sourceMappingURLPrefix: path.relative(cfg.dirs.output, destDir) - }) : - noop()) + }) + : noop()) .pipe(gulp.dest(destDir)); } @@ -161,53 +280,113 @@ function processStylesheets(srcGlob, destDir, destFileName) { * for writing sourcemaps we have to process them one by one, because we detect * where to write source maps from each glob pattern in order to make them accessible * from the compiled HTML + * @param {("module-js"|"module-css"|"story-js"|"story-css"|"story-twee"|"story-media")} name + * @param {Function} processorFunc + * @param {string[]} globs + * @param {string} destDir destination directory to save to + * @param {string} destFileName filename to save as + * @param {...any} args extra args to pass to processorFunc + * @returns {import("gulp").TaskFunction} */ function processSrc(name, processorFunc, globs, destDir, destFileName, ...args) { - let tasks = []; + /** @type {import("gulp").TaskFunction[]} */ + const tasks = []; + if (!Array.isArray(globs) || globs.length === 1) { const src = Array.isArray(globs) ? globs[0] : globs; + tasks.push(() => processorFunc(src, destDir, destFileName, args)); tasks[tasks.length - 1].displayName = "process-" + name; } else { // many globs const ext = path.extname(destFileName); const bn = path.basename(destFileName, ext); + for (let i = 0; i < globs.length; ++i) { tasks.push(() => processorFunc(globs[i], destDir, `${bn}-${i}${ext}`, args)); tasks[tasks.length - 1].displayName = `process-${name}-${i}`; } } + const res = gulp.parallel(...tasks); + res.displayName = name; return res; } -/** Returns true if the working directory is a Git repository */ +function gitExecutableExists() { + return which.sync('git', {nothrow: true}) !== null; +} + +/** + * Returns true if the working directory is a Git repository + * @returns {boolean} + */ function isGitCheckout() { - return fs.statSync('.git').isDirectory(); + return jetpack.exists(".git") === "dir"; } -/** Invokes git and writes hash of the head commit to the file, specified in the 'gitVersionFile' build config property */ +let gitHash = "UNKNOWN"; + +/** + * Invokes git and writes the hash of the head commit to the file, specified in the 'gitVersionFile' config property + * @param {Function} cb callback function + */ function injectGitCommit(cb) { // check if we are in CI mode, if yes, just read out the hash from environment variables - const readGitHash = args.ci ? "echo $CI_COMMIT_SHORT_SHA" : 'git rev-parse --short HEAD'; - childProcess.exec(readGitHash, function(error, stdout) { - if (!error) { - log.info('current git hash: ', stdout); - fs.writeFile(cfg.gitVersionFile, `App.Version.commitHash = '${stdout.trimEnd()}';\n`, cb); - } else { - log.error(chalk.red(`Error running git. Error: ${error}`)); - cb(); - } - }); + gitHash = args.ci + ? execSync("echo $CI_COMMIT_SHORT_SHA").toString().trim() + : execSync("git rev-parse --short HEAD").toString().trim(); + + if (gitHash === "$CI_COMMIT_SHORT_SHA" || (gitHash === "" && args.ci === true)) { + // This should only fire if the CI flag is used out of GitLab CI + // If it fires in GitLab CI then $CI_COMMIT_SHORT_SHA is no longer valid or something has gone terribly wrong. + log.warn(`git hash === "${gitHash}"!`); + log.warn("Are you in a GitLab CI environment?"); + log.warn("If not please remove the --ci flag from the commands arguments to remove this message."); + log.warn("Sleeping for 10 seconds and then setting ci to false"); + // sleep for 10 second + Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 10000); + args.ci = false; + return injectGitCommit(cb); + } else if (gitHash === "") { + throw new Error("Failed to get git hash!"); + } + + log.info("current git hash:", gitHash); + jetpack.write(cfg.gitVersionFile, `App.Version.commitHash = '${gitHash}';\n`, {atomic: true}); + cb(); } -/** Ensures the file with the git commit hash does not exists */ +/** + * Ensures the file with the git commit hash does not exists + * @param {Function} cb callback function + */ function cleanupGit(cb) { - if (fs.existsSync(cfg.gitVersionFile)) { - fs.unlink(cfg.gitVersionFile, cb); - } else { - cb(); + jetpack.remove(cfg.gitVersionFile); + cb(); +} + +/** + * Copies a file/directory to a destination + * @param {string} source + * @param {string} destination + * @param {boolean} removeExisting + * @param {Function} callback + */ +function copy(source, destination, removeExisting, callback) { + // if not debug mode filter out *.debug.* files + let matching = "!*.debug.*"; + + if (args.debug === true) { + matching = "*"; + } + + if (removeExisting) { + jetpack.remove(destination); } + + jetpack.copy(source, destination, {overwrite: true, matching: matching}); + callback(); } // --------------- build tasks definitions ----------------- @@ -222,14 +401,15 @@ When all intermediate files are ready, tweego picks them up and assembles the HT */ // Create task to execute tweego -gulp.task('compileStory', shell.task(tweeCompileCommand(), { +gulp.task("compileStory", shell.task(tweeCompileCommand(), { env: {...process.env, ...cfg.options.twee.environment}, verbose: args.verbosity >= 3 })); /** - * Creates tasks for preparing intermidiate files for a component - * @param {*} name "story" or "module" + * Creates tasks for preparing intermediate files for a component + * @param {"story"|"module"} name "story" or "module" + * @returns {import("gulp").TaskFunction} */ function prepareComponent(name) { const processors = { @@ -249,17 +429,24 @@ function prepareComponent(name) { func: null } }; - const c = cfg.sources[name]; const outDir = path.join(cfg.dirs.intermediate, name); const subTasks = []; - for (const srcType in c) { + + /** @type {"css"|"js"|"twee"|"media"} */ + let srcType; + + for (srcType in c) { const proc = processors[srcType]; + if (proc.func) { + // @ts-expect-error ${name}-${srcType} is valid subTasks.push(processSrc(`${name}-${srcType}`, proc.func, c[srcType], outDir, `${name}${proc.output}`, cfg.options[srcType])); } } - let r = gulp.parallel(subTasks); + + const r = gulp.parallel(subTasks); + r.displayName = "prepare-" + name; return r; } @@ -267,77 +454,156 @@ function prepareComponent(name) { /** * Creates a task for compiling a theme * @param {string} themeName theme directory name + * @returns {string} task name */ function makeThemeCompilationTask(themeName) { + // make sure it's a name, not a path + if (themeName.replace(/\/+$/, "").replace(/\\+$/, "").includes(path.sep)) { + // only keep the last path component + themeName = themeName.split(path.sep).pop(); + } + const taskName = `make-theme-${themeName}`; + gulp.task(taskName, function() { - return concatFiles(`themes/${themeName}/**/*.css`, cfg.dirs.output, `${themeName}.css`); + return concatFiles(`${cfg.sources.themes}/${themeName}/**/*.css`, cfg.dirs.output, `${themeName}.css`); }); return taskName; } -/** Moves compiled HTML file from the intermidiate location to the final output */ -function moveHTMLInPlace(cb) { - fs.rename(path.join(cfg.dirs.intermediate, htmlOut), path.join(cfg.dirs.output, cfg.output), cb); -} +/** + * Creates a task for compiling a mod + * @param {string} modName mod directory name + * @returns {string} task name + */ +function makeModCompilationTask(modName) { + // make sure it's a name, not a path + if (modName.replace(/\/+$/, "").replace(/\\+$/, "").includes(path.sep)) { + // only keep the last path component + modName = modName.split(path.sep).pop(); + } -function moveAndMinifyHTML(cb) { - minifyFile('text/html', path.join(cfg.dirs.intermediate, htmlOut), path.join(cfg.dirs.output, cfg.output)); - cb(); + const taskName = `make-mod-${modName}`; + + gulp.task(taskName, function(cb) { + return copy(`${cfg.sources.mods}/${modName}`, `${cfg.dirs.modOutput}/${modName}`, true, cb); + }); + return taskName; } -/** Removes intermediate compilation files if any */ -function removeIntermediateFiles(cb) { - if (fs.existsSync(cfg.dirs.intermediate)) { - fs.rm(cfg.dirs.intermediate, {recursive: true}, cb); - } else { +/** + * Moves compiled HTML file from the intermediate location to the final output + * @param {Function} cb callback function + */ +function moveHTML(cb) { + if (jetpack.exists(path.join(cfg.dirs.intermediate, htmlOut)) === "file") { + let finalPath = path.join(cfg.dirs.output, cfg.output); + let extraString = ""; + + if (args.epoch) { + extraString += "." + String(Math.floor(Date.now() / 1000)); + } + + if (args.pmodversion) { + // open ./src/002-config/fc-version.js + jetpack.read("./src/002-config/fc-version.js").split("\n").forEach(line => { + if (line.trim().includes("pmod: ")) { + // add everything between first and last " to extraString + extraString += "." + line.split("\"")[1].split("\"")[0]; + } + }); + } + + if (args.hash) { + extraString += "." + gitHash; + } + + finalPath = finalPath.replace("[extras]", extraString); + + jetpack.move(path.join(cfg.dirs.intermediate, htmlOut), path.resolve(finalPath), {overwrite: true}); + + log.info("FC saved to \"" + finalPath + "\""); cb(); } } +/** + * Removes intermediate compilation files if any + * @param {Function} cb callback function + */ +function removeIntermediateFiles(cb) { + jetpack.remove(cfg.dirs.intermediate); + cb(); +} + // Creates task to assemble components in the intermediate dir where they are ready for tweego -gulp.task('prepare', gulp.parallel(prepareComponent("module"), prepareComponent("story"))); +gulp.task("prepare", gulp.parallel(prepareComponent("module"), prepareComponent("story"))); + +// Creates theme build task for each subdirectory in the 'themes' dir +const themeTasks = jetpack.find(cfg.sources.themes, {files: false, directories: true, recursive: false}) + .map(entry => makeThemeCompilationTask(entry)); + +// create cfg.sources.mods directory if it doesn't exist +jetpack.dir(cfg.sources.mods); + +// Creates mod build task for each subdirectory in the 'mods' dir +const modTasks = jetpack.find(cfg.sources.mods, {files: false, directories: true, recursive: false}) + .map(entry => makeModCompilationTask(entry)); + +// If modTasks is empty, create a task that does nothing +if (modTasks.length === 0) { + gulp.task("make-mod-empty-folder", function(cb) { + return cb(); + }); + + modTasks.push("make-mod-empty-folder"); +} // Create the main build and clean tasks, which include writing Git commit hash if we are working in a Git repo let cleanOp = noop(); -if (isGitCheckout()) { + +if (isGitCheckout() && gitExecutableExists()) { cleanOp = gulp.parallel(cleanupGit, removeIntermediateFiles); - gulp.task('buildHTML', gulp.series(cleanOp, injectGitCommit, 'prepare', 'compileStory', cleanupGit)); + + gulp.task("buildHTML", gulp.series(cleanOp, injectGitCommit, "prepare", "compileStory", cleanupGit)); } else if (args.ci) { // CI environment is already clean - gulp.task('buildHTML', gulp.series(injectGitCommit, 'prepare', 'compileStory')); + + gulp.task("buildHTML", gulp.series(injectGitCommit, "prepare", "compileStory")); } else { + if (isGitCheckout()) { + log.info("git executable not found."); + } cleanOp = gulp.parallel(removeIntermediateFiles); - gulp.task('buildHTML', gulp.series(cleanOp, 'prepare', 'compileStory')); + gulp.task("buildHTML", gulp.series(cleanOp, "prepare", "compileStory")); } -export const clean = cleanOp; -// Creates theme build task for each subdirectory in the 'themes' dir -const themeTasks = fs.readdirSync('themes') - .filter(entry => fs.statSync(path.join('themes', entry)).isDirectory()) - .map(entry => makeThemeCompilationTask(entry)); +export const clean = cleanOp; // Create user-invocable targets for building HTML and themes -export const html = gulp.series('buildHTML', args.minify ? moveAndMinifyHTML : moveHTMLInPlace); +export const html = gulp.series("buildHTML", moveHTML); export const themes = gulp.parallel(themeTasks); +export const mods = gulp.parallel(modTasks); -// Set the default target which is invoked when no target is explicitly provided by user -export default html; -// Convenient shortcut to build everything (HTML and themes) -export const all = gulp.parallel(html, themes); +// Convenient shortcut to build everything (HTML, themes, and mods) +export const all = gulp.parallel(html, themes, mods); // legacy tasks -gulp.task('twineCSS', function() { - return concatFiles([...cfg.sources.module.css, ...cfg.sources.story.css], 'devNotes', 'twine CSS.txt'); +gulp.task("twineCSS", function() { + return concatFiles([...cfg.sources.module.css, ...cfg.sources.story.css], "devNotes", "twine CSS.txt"); }); -gulp.task('twineJS', function() { - return gulp.src([...cfg.sources.module.js, ...cfg.sources.story.js, '!src/art/assistantArt.js']) +gulp.task("twineJS", function() { + return gulp.src([...cfg.sources.module.js, ...cfg.sources.story.js, "!src/art/assistantArt.js"]) + .pipe(args.debug + ? noop() + : gulpIgnore.exclude("*.debug.*") + ) .pipe(stripCssJSComments({trim: true})) .pipe(sort(pathcmp)) - .pipe(concat('twine JS.txt')) - .pipe(gulp.dest('devNotes')); + .pipe(concat("twine JS.txt")) + .pipe(gulp.dest("devNotes")); }); -export const twine = gulp.parallel('twineCSS', 'twineJS'); +export const twine = gulp.parallel("twineCSS", "twineJS"); diff --git a/package.json b/package.json index db57146c9d8..549a90cb95a 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,10 @@ }, "scripts": { "lint": "eslint src/**/*.js js/**/*.js", - "compile": "sh compile.sh" + "compile": "sh compile.sh", + "build": "npx gulp all", + "build:debug": "npx gulp --debug all", + "build:release": "npx gulp --minify --release all" }, "license": "GPL-3.0-only", "devDependencies": { @@ -26,22 +29,21 @@ }, "dependencies": { "autoprefixer": "^10.0.0", - "chalk": "^5.2.0", "fancy-log-levels": "^1.0.0", + "fs-jetpack": "^5.1.0", "gulp": "^4.0.2", + "gulp-clean-css": "^4.3.0", "gulp-concat": "^2.6.1", + "gulp-ignore": "^3.0.0", "gulp-noop": "^1.0.1", "gulp-postcss": "^9.0.0", "gulp-shell": "^0.8.0", "gulp-sort": "^2.0.0", "gulp-sourcemaps": "^3.0.0", "gulp-strip-comments": "^2.5.2", + "gulp-terser": "^2.1.0", "postcss": "^8.4.21", - "through2": "^4.0.2", "which": "^3.0.0", "yargs": "^17.7.1" - }, - "optionalDependencies": { - "@tdewolff/minify": "^2.20.9" } } diff --git a/compile_debug+sanityCheck.bat b/sanityCheck.bat similarity index 84% rename from compile_debug+sanityCheck.bat rename to sanityCheck.bat index 6091542f890..66eb8252085 100644 --- a/compile_debug+sanityCheck.bat +++ b/sanityCheck.bat @@ -1,5 +1,4 @@ @echo off -:: Free Cities Basic Compiler - Windows :: Set working directory pushd %~dp0 @@ -20,11 +19,8 @@ for %%k in (HKCU HKLM) do ( :FOUND if %GITFOUND% == yes ( set "PATH=%GIT%bin;%PATH%" + echo Running sanityCheck.sh using git bash bash --login -c "./sanityCheck.sh" +) else ( + echo Could not find git installation ) - -:: Compile the game -call "%~dp0compile.bat" - -popd -PAUSE -- GitLab