mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-08-29 16:19:36 +01:00
Juke build system port (#7186)
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
## Enforce text mode and LF line breaks
|
||||
*.cjs text eol=lf
|
||||
*.css text eol=lf
|
||||
*.js text eol=lf
|
||||
*.jsx text eol=lf
|
||||
*.scss text eol=lf
|
||||
*.ts text eol=lf
|
||||
*.tsx text eol=lf
|
||||
|
||||
## Enforce binary mode
|
||||
*.dll binary
|
||||
*.exe binary
|
||||
|
||||
@@ -32,7 +32,8 @@ jobs:
|
||||
- name: Run Tests
|
||||
run: |
|
||||
tools/ci/validate_files.sh
|
||||
tools/ci/build_tgui.sh
|
||||
- name: Run TGUI Checks
|
||||
run: tools/build/build --ci lint tgui-test
|
||||
|
||||
dreamchecker:
|
||||
name: DreamChecker
|
||||
|
||||
+144
-80
@@ -1,80 +1,144 @@
|
||||
#ignore misc BYOND files
|
||||
vchat.db
|
||||
vchat.db*
|
||||
*.log
|
||||
*.int
|
||||
*.rsc
|
||||
*.dmb
|
||||
*.lk
|
||||
*.backup
|
||||
*.before
|
||||
*.pyc
|
||||
*.pid
|
||||
cfg/
|
||||
|
||||
#Ignore everything in datafolder and subdirectories
|
||||
/data/**/*
|
||||
/tmp/**/*
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
### https://raw.github.com/github/gitignore/cc542de017c606138a87ee4880e5f06b3a306def/Python.gitignore
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-*.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.cache
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# dotenv
|
||||
.env
|
||||
|
||||
### https://raw.github.com/github/gitignore/cc542de017c606138a87ee4880e5f06b3a306def/Global/Windows.gitignore
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
### https://raw.github.com/github/gitignore/cc542de017c606138a87ee4880e5f06b3a306def/Global/OSX.gitignore
|
||||
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
#Visual studio stuff
|
||||
*.vscode/*
|
||||
!/.vscode/launch.json
|
||||
!/.vscode/extensions.json
|
||||
!/.vscode/settings.json
|
||||
!/.vscode/tasks.json
|
||||
|
||||
temp.dmi
|
||||
|
||||
node_modules/
|
||||
package-lock.json
|
||||
|
||||
config/jobwhitelist.txt
|
||||
###Files and folders specified here will never be tracked.
|
||||
|
||||
#ignore misc VOREStation specified files
|
||||
vchat.db
|
||||
vchat.db*
|
||||
*.before
|
||||
*.pid
|
||||
|
||||
#Ignore everything in datafolder and subdirectories
|
||||
/data/**/*
|
||||
/tmp/**/*
|
||||
|
||||
#Ignore byond config folder.
|
||||
/cfg/**/*
|
||||
|
||||
#Ignore IDE files we don't need in the repo.
|
||||
/.vs/**/*
|
||||
/tgstation/FileContentIndex/**/*
|
||||
/FileContentIndex/**/*
|
||||
/v17/**/*
|
||||
/v18/**/*
|
||||
/v19/**/*
|
||||
/v20/**/*
|
||||
/v21/**/*
|
||||
/v22/**/*
|
||||
|
||||
# Ignore compiled linux libs in the root folder, e.g. librust_g.so
|
||||
/*.so
|
||||
|
||||
#Ignore compiled files and other files generated during compilation.
|
||||
*.mdme
|
||||
*.mdme.*
|
||||
*.dmb
|
||||
*.rsc
|
||||
*.m.dme
|
||||
*.test.dme
|
||||
*.lk
|
||||
*.int
|
||||
*.backup
|
||||
### https://raw.github.com/github/gitignore/cc542de017c606138a87ee4880e5f06b3a306def/Global/Linux.gitignore
|
||||
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
|
||||
### https://raw.github.com/github/gitignore/cc542de017c606138a87ee4880e5f06b3a306def/Global/Vim.gitignore
|
||||
|
||||
# swap
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
# session
|
||||
Session.vim
|
||||
# temporary
|
||||
.netrwhist
|
||||
*~
|
||||
# auto-generated tag files
|
||||
tags
|
||||
|
||||
|
||||
### https://raw.github.com/github/gitignore/cc542de017c606138a87ee4880e5f06b3a306def/Python.gitignore
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-*.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.cache
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# dotenv
|
||||
.env
|
||||
|
||||
# IntelliJ IDEA / PyCharm (with plugin)
|
||||
.idea
|
||||
|
||||
### https://raw.github.com/github/gitignore/cc542de017c606138a87ee4880e5f06b3a306def/Global/Windows.gitignore
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
### https://raw.github.com/github/gitignore/cc542de017c606138a87ee4880e5f06b3a306def/Global/OSX.gitignore
|
||||
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
#Sublime
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
#Visual studio stuff
|
||||
*.vscode/*
|
||||
!/.vscode/launch.json
|
||||
!/.vscode/extensions.json
|
||||
!/.vscode/settings.json
|
||||
!/.vscode/tasks.json
|
||||
|
||||
#GitHub Atom
|
||||
.atom-build.json
|
||||
|
||||
#KDevelop and Kate
|
||||
*.kdev4*
|
||||
*.kate-swp
|
||||
|
||||
temp.dmi
|
||||
|
||||
# JavaScript tools
|
||||
**/node_modules
|
||||
package-lock.json
|
||||
|
||||
# named byond versions config
|
||||
/tools/build/dm_versions.json
|
||||
|
||||
config/jobwhitelist.txt
|
||||
|
||||
Vendored
+2
-2
@@ -8,9 +8,9 @@
|
||||
"type": "byond",
|
||||
"request": "launch",
|
||||
"name": "Launch DreamDaemon",
|
||||
"preLaunchTask": "dm: build - ${command:CurrentDME}",
|
||||
"preLaunchTask": "Build All",
|
||||
"dmb": "${workspaceFolder}/${command:CurrentDMB}",
|
||||
"dreamDaemon": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+67
-16
@@ -1,6 +1,29 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "process",
|
||||
"command": "tools/build/build",
|
||||
"windows": {
|
||||
"command": ".\\tools\\build\\build.bat"
|
||||
},
|
||||
"options": {
|
||||
"env": {
|
||||
"DM_EXE": "${config:dreammaker.byondPath}"
|
||||
}
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$dreammaker",
|
||||
"$tsc",
|
||||
"$eslint-stylish"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"dependsOn": "dm: reparse",
|
||||
"label": "Build All"
|
||||
},
|
||||
{
|
||||
"type": "dreammaker",
|
||||
"dme": "vorestation.dme",
|
||||
@@ -12,9 +35,9 @@
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"command": "tgui/bin/tgui",
|
||||
"command": "bin/tgui-build",
|
||||
"windows": {
|
||||
"command": ".\\tgui\\bin\\tgui.bat"
|
||||
"command": ".\\bin\\tgui-build.cmd"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc",
|
||||
@@ -25,27 +48,55 @@
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"command": "yarn build",
|
||||
"options": {
|
||||
"cwd": "tgui/packages/tgfont/",
|
||||
},
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"label": "tgui: build tgfont",
|
||||
"detail": "node mkdist.cjs && fantasticon --config config.cjs"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"command": "tgui/bin/tgui",
|
||||
"command": "bin/tgui-dev",
|
||||
"windows": {
|
||||
"command": ".\\tgui\\bin\\tgui-prettybuild.bat"
|
||||
"command": ".\\bin\\tgui-dev.cmd"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc",
|
||||
"$eslint-stylish"
|
||||
],
|
||||
"group": "build",
|
||||
"label": "tgui: prettybuild"
|
||||
"label": "tgui: dev server"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"command": "bin/tgui-bench",
|
||||
"windows": {
|
||||
"command": ".\\bin\\tgui-bench.cmd"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc",
|
||||
"$eslint-stylish"
|
||||
],
|
||||
"group": "build",
|
||||
"label": "tgui: bench"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"command": "bin/tgui-sonar",
|
||||
"windows": {
|
||||
"command": ".\\bin\\tgui-sonar.cmd"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc",
|
||||
"$eslint-stylish"
|
||||
],
|
||||
"group": "build",
|
||||
"label": "tgui: sonar"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"command": "bin/tgfont",
|
||||
"windows": {
|
||||
"command": ".\\bin\\tgfont.cmd"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc",
|
||||
"$eslint-stylish"
|
||||
],
|
||||
"group": "build",
|
||||
"label": "tgui: rebuild tgfont"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ export BYOND_MINOR=1589
|
||||
export MACRO_COUNT=4
|
||||
|
||||
# node version
|
||||
export NODE_VERSION=16
|
||||
export NODE_VERSION=20
|
||||
export NODE_VERSION_PRECISE=20.9.0
|
||||
|
||||
# SpacemanDMM git tag
|
||||
export SPACEMAN_DMM_VERSION=suite-1.7
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
call "%~dp0\..\tools\build\build.bat" --wait-on-error build %*
|
||||
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
call "%~dp0\..\tools\build\build.bat" --wait-on-error clean-all %*
|
||||
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
call "%~dp0\..\tools\build\build.bat" --wait-on-error server %*
|
||||
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
call "%~dp0\..\tools\build\build.bat" --wait-on-error dm-test %*
|
||||
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
call "%~dp0\..\tools\build\build.bat" --wait-on-error tg-font %*
|
||||
@@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
call "%~dp0\..\tools\build\build.bat" --wait-on-error tgui-bench %*
|
||||
pause
|
||||
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
call "%~dp0\..\tools\build\build.bat" --wait-on-error tgui tgui-lint tgui-test %*
|
||||
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
call "%~dp0\..\tools\build\build.bat" --wait-on-error tgui-dev %*
|
||||
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
call "%~dp0\..\tools\build\build.bat" --wait-on-error tgui-sonar %*
|
||||
@@ -10,6 +10,7 @@
|
||||
/public
|
||||
/packages/tgui-polyfill
|
||||
/packages/tgfont/static
|
||||
/packages/tgfont/dist
|
||||
**/*.json
|
||||
**/*.yml
|
||||
**/*.md
|
||||
|
||||
+70
-115
@@ -4,34 +4,24 @@
|
||||
|
||||
tgui is a robust user interface framework of /tg/station.
|
||||
|
||||
tgui is very different from most UIs you will encounter in BYOND programming.
|
||||
It is heavily reliant on Javascript and web technologies as opposed to DM.
|
||||
If you are familiar with NanoUI (a library which can be found on almost
|
||||
every other SS13 codebase), tgui should be fairly easy to pick up.
|
||||
tgui is very different from most UIs you will encounter in BYOND programming. It is heavily reliant on Javascript and web technologies as opposed to DM. If you are familiar with NanoUI (a library which can be found on almost every other SS13 codebase), tgui should be fairly easy to pick up.
|
||||
|
||||
## Learn tgui
|
||||
|
||||
People come to tgui from different backgrounds and with different
|
||||
learning styles. Whether you prefer a more theoretical or a practical
|
||||
approach, we hope you’ll find this section helpful.
|
||||
People come to tgui from different backgrounds and with different learning styles. Whether you prefer a more theoretical or a practical approach, we hope you’ll find this section helpful.
|
||||
|
||||
### Practical Tutorial
|
||||
|
||||
If you are completely new to frontend and prefer to **learn by doing**,
|
||||
start with our [practical tutorial](docs/tutorial-and-examples.md).
|
||||
If you are completely new to frontend and prefer to **learn by doing**, start with our [practical tutorial](docs/tutorial-and-examples.md).
|
||||
|
||||
### Guides
|
||||
|
||||
This project uses **Inferno** - a very fast UI rendering engine with a similar
|
||||
API to React. Take your time to read these guides:
|
||||
This project uses **Inferno** - a very fast UI rendering engine with a similar API to React. Take your time to read these guides:
|
||||
|
||||
- [React guide](https://reactjs.org/docs/hello-world.html)
|
||||
- [Inferno documentation](https://infernojs.org/docs/guides/components) -
|
||||
highlights differences with React.
|
||||
- [Inferno documentation](https://infernojs.org/docs/guides/components) - highlights differences with React.
|
||||
|
||||
If you were already familiar with an older, Ractive-based tgui, and want
|
||||
to translate concepts between old and new tgui, read this
|
||||
[interface conversion guide](docs/converting-old-tgui-interfaces.md).
|
||||
If you were already familiar with an older, Ractive-based tgui, and want to translate concepts between old and new tgui, read this [interface conversion guide](docs/converting-old-tgui-interfaces.md).
|
||||
|
||||
### Other Documentation
|
||||
|
||||
@@ -42,97 +32,83 @@ to translate concepts between old and new tgui, read this
|
||||
|
||||
## Pre-requisites
|
||||
|
||||
You will need these programs to start developing in tgui:
|
||||
If you are using the tooling provided in this repo, everything is included! Feel free to skip this step.
|
||||
|
||||
However, if you want finer control over the installation or build process, you will need these:
|
||||
|
||||
- [Node v16.13+](https://nodejs.org/en/download/)
|
||||
- **LTS** release is recommended instead of latest
|
||||
- [Yarn v1.22.4+](https://yarnpkg.com/getting-started/install) (optional)
|
||||
- **DO NOT install Chocolatey if Node installer asks you to!**
|
||||
- [Yarn v1.22.4+](https://yarnpkg.com/getting-started/install)
|
||||
- You can run `npm install -g yarn` to install it.
|
||||
- [Git Bash](https://git-scm.com/downloads)
|
||||
or [MSys2](https://www.msys2.org/) (optional)
|
||||
|
||||
**DO NOT install Chocolatey if Node installer asks you to!**
|
||||
|
||||
## Usage
|
||||
|
||||
**For Git Bash, MSys2, WSL, Linux or macOS users:**
|
||||
**Via provided cmd scripts (Windows)**:
|
||||
|
||||
Change your directory to `tgui`.
|
||||
- `bin/tgui-build` - Build tgui in production mode and run a full suite of code checks.
|
||||
- `bin/tgui-dev` - Launch a development server.
|
||||
- `bin/tgui-dev --reload` - Reload byond cache once.
|
||||
- `bin/tgui-dev --debug` - Run server with debug logging enabled.
|
||||
- `bin/tgui-dev --no-hot` - Disable hot module replacement (helps when doing development on IE8).
|
||||
- `bin/tgui-sonar` - Analyze code with SonarQube.
|
||||
- `bin/tgui-bench` - Run benchmarks.
|
||||
|
||||
Run `bin/tgui --install-git-hooks` to install merge drivers which will
|
||||
assist you in conflict resolution when rebasing your branches. Only has
|
||||
to be done once.
|
||||
> To open a CMD or PowerShell window in any open folder, right click **while holding Shift** on any free space in the folder, then click on either `Open command window here` or `Open PowerShell window here`.
|
||||
|
||||
Run `bin/tgui` with any of the options listed below.
|
||||
**Via Juke Build (cross-platform)**:
|
||||
|
||||
**For Windows CMD or PowerShell users:**
|
||||
- `tools/build/build tgui` - Build tgui in production mode.
|
||||
- `tools/build/build tgui-dev` - Build tgui in production mode.
|
||||
- `tools/build/build tgui-dev --reload` - Reload byond cache once.
|
||||
- `tools/build/build tgui-dev --debug` - Run server with debug logging enabled.
|
||||
- `tools/build/build tgui-dev --no-hot` - Disable hot module replacement (helps when doing development on IE8).
|
||||
- `tools/build/build tgui-lint` - Show (and auto-fix) problems with the code.
|
||||
- `tools/build/build tgui-sonar` - Analyze code with SonarQube.
|
||||
- `tools/build/build tgui-test` - Run unit and integration tests.
|
||||
- `tools/build/build tgui-analyze` - Run a bundle analyzer.
|
||||
- `tools/build/build tgui-bench` - Run benchmarks.
|
||||
- `tools/build/build tgui-clean` - Clean up tgui folder.
|
||||
|
||||
If you haven't opened the console already, you can do that by holding
|
||||
Shift and right clicking on the `tgui` folder, then pressing
|
||||
either `Open command window here` or `Open PowerShell window here`.
|
||||
> With Juke Build, you can run multiple targets together, e.g.:
|
||||
> ```
|
||||
> tools/build/build tgui tgui-lint tgui-tsc tgui-test
|
||||
> ```
|
||||
|
||||
Run `.\bin\tgui.bat` with any of the options listed below.
|
||||
**Via Yarn (cross-platform)**:
|
||||
|
||||
> If using PowerShell, you will receive errors if trying to run
|
||||
> `.\bin\tgui.ps1`, because default Windows policy does not allow direct
|
||||
> execution of PS1 scripts. Run `.\bin\tgui.bat` instead.
|
||||
Run `yarn install` once to install tgui dependencies.
|
||||
|
||||
**Available commands:**
|
||||
- `yarn tgui:build` - Build tgui in production mode.
|
||||
- `yarn tgui:build [options]` - Build tgui with custom webpack options.
|
||||
- `yarn tgui:dev` - Launch a development server.
|
||||
- `yarn tgui:dev --reload` - Reload byond cache once.
|
||||
- `yarn tgui:dev --debug` - Run server with debug logging enabled.
|
||||
- `yarn tgui:dev --no-hot` - Disable hot module replacement (helps when doing development on IE8).
|
||||
- `yarn tgui:lint` - Show (and auto-fix) problems with the code.
|
||||
- `yarn tgui:sonar` - Analyze code with SonarQube.
|
||||
- `yarn tgui:tsc` - Check code with TypeScript compiler.
|
||||
- `yarn tgui:test` - Run unit and integration tests.
|
||||
- `yarn tgui:analyze` - Run a bundle analyzer.
|
||||
- `yarn tgui:bench` - Run benchmarks.
|
||||
- `yarn tgfont:build` - Build icon fonts.
|
||||
- `yarn tgui-polyfill:build` - Build polyfills. You need to run it when updating any of the static (numbered) polyfills.
|
||||
|
||||
- `bin/tgui` - (Recommended build option) Build the project in production mode.
|
||||
- `bin/tgui --pretty` - Check/Prettify all files inside of the packages folder (Mainly Interfaces/Components). Build the project in production mode afterwards.
|
||||
- `bin/tgui --dev` - Launch a development server.
|
||||
- tgui development server provides you with incremental compilation,
|
||||
hot module replacement and logging facilities in all running instances
|
||||
of tgui. In short, this means that you will instantly see changes in the
|
||||
game as you code it. Very useful, highly recommended.
|
||||
- In order to use it, you should start the game server first, connect to it
|
||||
and wait until the world has been properly loaded and you are no longer
|
||||
in the lobby. Start tgui dev server, and once it has finished building,
|
||||
press F5 on any tgui window. You'll know that it's hooked correctly if
|
||||
you see a green bug icon in titlebar and data gets dumped to the console.
|
||||
- `bin/tgui --dev --reload` - Reload byond cache once.
|
||||
- `bin/tgui --dev --debug` - Run server with debug logging enabled.
|
||||
- `bin/tgui --dev --no-hot` - Disable hot module replacement (helps when
|
||||
doing development on IE8).
|
||||
- `bin/tgui --lint` - Show problems with the code.
|
||||
- `bin/tgui --fix` - Auto-fix problems with the code.
|
||||
- `bin/tgui --test` - Run tests.
|
||||
- `bin/tgui --analyze` - Run a bundle analyzer.
|
||||
- `bin/tgui --clean` - Clean up project repo.
|
||||
- `bin/tgui [webpack options]` - Build the project with custom webpack
|
||||
options.
|
||||
## Important Memo
|
||||
|
||||
**For virgins:**
|
||||
|
||||
You can double-click these batch files to achieve the same thing:
|
||||
|
||||
- `bin\tgui.bat` - (Recommended build option) Build the project in production mode.
|
||||
- `bin\tgui-prettybuild.bat` - Prettify all the files inside the packages folder. Build the project in production mode afterwards.
|
||||
- `bin\tgui-dev-server.bat` - Launch a development server.
|
||||
|
||||
> Remember to always run a full build before submitting a PR. It creates
|
||||
> a compressed javascript bundle which is then referenced from DM code.
|
||||
> We prefer to keep it version controlled, so that people could build the
|
||||
> game just by using Dream Maker.
|
||||
Remember to always run a full build of tgui before submitting a PR, because it comes with the full suite of CI checks, and runs much faster on your computer than on GitHub servers. It will save you some time and possibly a few broken commits! Address the issues that are reported by the tooling as much as possible, because maintainers will beat you with a ruler and force you to address them anyway (unless it's a false positive or something unfixable).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Development server is crashing**
|
||||
|
||||
Make sure path to your working directory does not contain spaces or special
|
||||
unicode characters. If so, move codebase to a location which does not contain
|
||||
spaces or unicode characters.
|
||||
Make sure path to your working directory does not contain spaces, special unicode characters, exclamation marks or any other special symbols. If so, move codebase to a location which does not contain these characters.
|
||||
|
||||
This is a known issue with Yarn Berry, and fix is going to happen someday.
|
||||
This is a known issue with Yarn (and some other tools, like Webpack), and fix is going to happen eventually.
|
||||
|
||||
**Development server doesn't find my BYOND cache!**
|
||||
|
||||
This happens if your Documents folder in Windows has a custom location, for
|
||||
example in `E:\Libraries\Documents`. Development server tries its best to find
|
||||
this non-standard location (searches for a Windows Registry key), but it can
|
||||
fail. You have to run the dev server with an additional environmental
|
||||
variable, with a full path to BYOND cache.
|
||||
This happens if your Documents folder in Windows has a custom location, for example in `E:\Libraries\Documents`. Development server tries its best to find this non-standard location (searches for a Windows Registry key), but it can fail. You have to run the dev server with an additional environmental variable, with a full path to BYOND cache.
|
||||
|
||||
```
|
||||
BYOND_CACHE="E:/Libraries/Documents/BYOND/cache"
|
||||
@@ -142,14 +118,11 @@ BYOND_CACHE="E:/Libraries/Documents/BYOND/cache"
|
||||
|
||||
> Example: `No template for dependency: PureExpressionDependency`
|
||||
|
||||
Webpack stores its cache on disk since tgui 4.3, and it is very sensitive
|
||||
to build configuration. So if you update webpack, or share the same cache
|
||||
directory between development and production build, it will start
|
||||
hallucinating.
|
||||
Webpack stores its cache on disk since tgui 4.3, and it is very sensitive to build configuration. So if you update webpack, or share the same cache directory between development and production build, it will start hallucinating.
|
||||
|
||||
To fix this kind of problem, run `bin/tgui --clean` and try again.
|
||||
|
||||
## Developer Tools
|
||||
## Dev Server Tools
|
||||
|
||||
When developing with `tgui-dev-server`, you will have access to certain
|
||||
development only features.
|
||||
@@ -160,7 +133,7 @@ logs and time spent on rendering. Use this information to optimize your
|
||||
code, and try to keep re-renders below 16ms.
|
||||
|
||||
**Kitchen Sink.**
|
||||
Press `F12` to open the KitchenSink interface. This interface is a
|
||||
Press `F12` or click the green bug to open the KitchenSink interface. This interface is a
|
||||
playground to test various tgui components.
|
||||
|
||||
**Layout Debugger.**
|
||||
@@ -188,42 +161,24 @@ so you'll need to restart it if it disconnects from the window.
|
||||
## Project Structure
|
||||
|
||||
- `/packages` - Each folder here represents a self-contained Node module.
|
||||
- `/packages/common` - Helper functions
|
||||
- `/packages/common` - Helper functions that are used throughout all packages.
|
||||
- `/packages/tgui/index.js` - Application entry point.
|
||||
- `/packages/tgui/components` - Basic UI building blocks.
|
||||
- `/packages/tgui/interfaces` - Actual in-game interfaces.
|
||||
Interface takes data via the `state` prop and outputs an html-like stucture,
|
||||
which you can build using existing UI components.
|
||||
- `/packages/tgui/layouts` - Root level UI components, that affect the final
|
||||
look and feel of the browser window. They usually hold various window
|
||||
elements, like the titlebar and resize handlers, and control the UI theme.
|
||||
- `/packages/tgui/routes.js` - This is where tgui decides which interface to
|
||||
pull and render.
|
||||
- `/packages/tgui/layout.js` - A root-level component, holding the
|
||||
window elements, like the titlebar, buttons, resize handlers. Calls
|
||||
`routes.js` to decide which component to render.
|
||||
- `/packages/tgui/layouts` - Root level UI components, that affect the final look and feel of the browser window. These hold various window elements, like the titlebar and resize handlers, and control the UI theme.
|
||||
- `/packages/tgui/routes.js` - This is where tgui decides which interface to pull and render.
|
||||
- `/packages/tgui/styles/main.scss` - CSS entry point.
|
||||
- `/packages/tgui/styles/functions.scss` - Useful SASS functions.
|
||||
Stuff like `lighten`, `darken`, `luminance` are defined here.
|
||||
- `/packages/tgui/styles/atomic` - Atomic CSS classes.
|
||||
These are very simple, tiny, reusable CSS classes which you can use and
|
||||
combine to change appearance of your elements. Keep them small.
|
||||
- `/packages/tgui/styles/components` - CSS classes which are used
|
||||
in UI components. These stylesheets closely follow the
|
||||
[BEM](https://en.bem.info/methodology/) methodology.
|
||||
- `/packages/tgui/styles/interfaces` - Custom stylesheets for your interfaces.
|
||||
Add stylesheets here if you really need a fine control over your UI styles.
|
||||
- `/packages/tgui/styles/functions.scss` - Useful SASS functions. Stuff like `lighten`, `darken`, `luminance` are defined here.
|
||||
- `/packages/tgui/styles/atomic` - Atomic CSS classes. These are very simple, tiny, reusable CSS classes which you can use and combine to change appearance of your elements. Keep them small.
|
||||
- `/packages/tgui/styles/components` - CSS classes which are used in UI components. These stylesheets closely follow the [BEM](https://en.bem.info/methodology/) methodology.
|
||||
- `/packages/tgui/styles/interfaces` - Custom stylesheets for your interfaces. Add stylesheets here if you really need a fine control over your UI styles.
|
||||
- `/packages/tgui/styles/layouts` - Layout-related styles.
|
||||
- `/packages/tgui/styles/themes` - Contains all the various themes you can
|
||||
use in tgui. Each theme must be registered in `webpack.config.js` file.
|
||||
- `/packages/tgui/styles/themes` - Contains themes that you can use in tgui. Each theme must be registered in `/packages/tgui/index.js` file.
|
||||
|
||||
## License
|
||||
|
||||
Source code is covered by /tg/station's parent license - **AGPL-3.0**
|
||||
(see the main [README](../README.md)), unless otherwise indicated.
|
||||
Source code is covered by CHOMPStation's parent license - **AGPL-3.0** (see the main [README](../README.md)), unless otherwise indicated.
|
||||
|
||||
Some files are annotated with a copyright header, which explicitly states
|
||||
the copyright holder and license of the file. Most of the core tgui
|
||||
source code is available under the **MIT** license.
|
||||
Some files are annotated with a copyright header, which explicitly states the copyright holder and license of the file. Most of the core tgui source code is available under the **MIT** license.
|
||||
|
||||
The Authors retain all copyright to their respective work here submitted.
|
||||
|
||||
-235
@@ -1,235 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
## Copyright (c) 2020 Aleksej Komarov
|
||||
## SPDX-License-Identifier: MIT
|
||||
|
||||
set -e
|
||||
shopt -s globstar
|
||||
shopt -s expand_aliases
|
||||
|
||||
## Initial set-up
|
||||
## --------------------------------------------------------
|
||||
|
||||
## Returns an absolute path to file
|
||||
alias tgui-realpath="readlink -f"
|
||||
|
||||
## Fallbacks for GNU readlink
|
||||
## Detecting GNU coreutils http://stackoverflow.com/a/8748344/319952
|
||||
if ! readlink --version >/dev/null 2>&1; then
|
||||
if hash greadlink 2>/dev/null; then
|
||||
alias tgui-realpath="greadlink -f"
|
||||
else
|
||||
alias tgui-realpath="perl -MCwd -le 'print Cwd::abs_path(shift)'"
|
||||
fi
|
||||
fi
|
||||
|
||||
## Find a canonical path to project root
|
||||
base_dir="$(dirname "$(tgui-realpath "${0}")")/.."
|
||||
base_dir="$(tgui-realpath "${base_dir}")"
|
||||
|
||||
## Make use of nvm if it exists
|
||||
if [[ -e "${HOME}/.nvm/nvm.sh" ]]; then
|
||||
source "${HOME}/.nvm/nvm.sh"
|
||||
fi
|
||||
|
||||
## Fall back to running Yarn from the repo
|
||||
if ! hash yarn 2>/dev/null; then
|
||||
yarn_releases=("${base_dir}"/.yarn/releases/yarn-*.cjs)
|
||||
yarn_release="${yarn_releases[0]}"
|
||||
yarn() {
|
||||
node "${yarn_release}" "${@}"
|
||||
}
|
||||
fi
|
||||
|
||||
|
||||
## Functions
|
||||
## --------------------------------------------------------
|
||||
|
||||
## Installs node modules
|
||||
task-install() {
|
||||
cd "${base_dir}"
|
||||
yarn install
|
||||
}
|
||||
|
||||
## Runs webpack
|
||||
task-webpack() {
|
||||
cd "${base_dir}"
|
||||
yarn run webpack-cli "${@}"
|
||||
}
|
||||
|
||||
## Runs a development server
|
||||
task-dev-server() {
|
||||
cd "${base_dir}"
|
||||
yarn node --experimental-modules packages/tgui-dev-server/index.js "${@}"
|
||||
}
|
||||
|
||||
## Run a linter through all packages
|
||||
task-lint() {
|
||||
cd "${base_dir}"
|
||||
yarn run tsc
|
||||
echo "tgui: type check passed"
|
||||
yarn run eslint packages --ext .js,.cjs,.ts,.tsx "${@}"
|
||||
echo "tgui: eslint check passed"
|
||||
}
|
||||
|
||||
task-test() {
|
||||
cd "${base_dir}"
|
||||
yarn run jest
|
||||
}
|
||||
|
||||
## Mr. Proper
|
||||
task-clean() {
|
||||
cd "${base_dir}"
|
||||
## Build artifacts
|
||||
rm -rf public/.tmp
|
||||
rm -f public/*.map
|
||||
rm -f public/*.chunk.*
|
||||
rm -f public/*.bundle.*
|
||||
rm -f public/*.hot-update.*
|
||||
## Yarn artifacts
|
||||
rm -rf .yarn/cache
|
||||
rm -rf .yarn/unplugged
|
||||
rm -rf .yarn/webpack
|
||||
rm -f .yarn/build-state.yml
|
||||
rm -f .yarn/install-state.gz
|
||||
rm -f .yarn/install-target
|
||||
rm -f .pnp.*
|
||||
## NPM artifacts
|
||||
rm -rf **/node_modules
|
||||
rm -f **/package-lock.json
|
||||
}
|
||||
|
||||
## Validates current build against the build stored in git
|
||||
## VOREStation Addition Start
|
||||
task-validate-build() {
|
||||
cd "${base_dir}"
|
||||
local diff
|
||||
diff="$(git diff packages/tgui/public/tgui.bundle.*)"
|
||||
if [[ -n ${diff} ]]; then
|
||||
echo "Error: our build differs from the build committed into git."
|
||||
echo "Please rebuild tgui."
|
||||
exit 1
|
||||
fi
|
||||
echo "tgui: build is ok"
|
||||
}
|
||||
## VOREStation Addition End
|
||||
|
||||
## Installs merge drivers and git hooks
|
||||
task-install-git-hooks() {
|
||||
cd "${base_dir}"
|
||||
local git_root
|
||||
local git_base_dir
|
||||
git_root="$(git rev-parse --show-toplevel)"
|
||||
git_base_dir="${base_dir/${git_root}/.}"
|
||||
git config --replace-all merge.tgui-merge-bundle.driver \
|
||||
"${git_base_dir}/bin/tgui --merge=bundle %O %A %B %L"
|
||||
echo "tgui: Merge drivers have been successfully installed!"
|
||||
}
|
||||
|
||||
## Bundle merge driver
|
||||
task-merge-bundle() {
|
||||
local file_ancestor="${1}"
|
||||
local file_current="${2}"
|
||||
local file_other="${3}"
|
||||
local conflict_marker_size="${4}"
|
||||
echo "tgui: Discarding a local tgui build"
|
||||
## Do nothing (file_current will be merged and is what we want to keep).
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
## Main
|
||||
## --------------------------------------------------------
|
||||
|
||||
if [[ ${1} == "--merge"* ]]; then
|
||||
if [[ ${1} == "--merge=bundle" ]]; then
|
||||
shift 1
|
||||
task-merge-bundle "${@}"
|
||||
fi
|
||||
echo "Unknown merge strategy: ${1}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ${1} == "--install-git-hooks" ]]; then
|
||||
shift 1
|
||||
task-install-git-hooks
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ${1} == "--clean" ]]; then
|
||||
task-clean
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ${1} == "--dev" ]]; then
|
||||
shift
|
||||
task-install
|
||||
task-dev-server "${@}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
## VOREStation Addition Start
|
||||
## Continuous integration scenario
|
||||
if [[ ${1} == "--ci" ]]; then
|
||||
task-clean
|
||||
task-install
|
||||
task-lint
|
||||
task-test
|
||||
task-webpack --mode=production
|
||||
task-validate-build
|
||||
exit 0
|
||||
fi
|
||||
## VOREStation Addition End
|
||||
|
||||
if [[ ${1} == '--lint' ]]; then
|
||||
shift 1
|
||||
task-install
|
||||
task-lint "${@}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ${1} == '--lint-harder' ]]; then
|
||||
shift 1
|
||||
task-install
|
||||
task-lint -c .eslintrc-harder.yml "${@}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ${1} == '--fix' ]]; then
|
||||
shift 1
|
||||
task-install
|
||||
task-lint --fix "${@}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ${1} == '--test' ]]; then
|
||||
shift 1
|
||||
task-install
|
||||
task-test "${@}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
## Analyze the bundle
|
||||
if [[ ${1} == '--analyze' ]]; then
|
||||
task-install
|
||||
task-webpack --mode=production --analyze
|
||||
exit 0
|
||||
fi
|
||||
|
||||
## Make a production webpack build
|
||||
if [[ ${1} == '--build' ]]; then
|
||||
task-install
|
||||
task-webpack --mode=production
|
||||
exit 0
|
||||
fi
|
||||
|
||||
## Make a production webpack build + Run eslint
|
||||
if [[ -z ${1} ]]; then
|
||||
task-install
|
||||
task-lint --fix
|
||||
task-webpack --mode=production
|
||||
exit 0
|
||||
fi
|
||||
|
||||
## Run webpack with custom flags
|
||||
task-install
|
||||
task-webpack "${@}"
|
||||
@@ -1,9 +0,0 @@
|
||||
@echo off
|
||||
rem Copyright (c) 2020 Aleksej Komarov
|
||||
rem SPDX-License-Identifier: MIT
|
||||
call powershell.exe -NoLogo -ExecutionPolicy Bypass -File "%~dp0\tgui_.ps1" --bench %*
|
||||
rem Pause if launched in a separate shell unless initiated from powershell
|
||||
echo %PSModulePath% | findstr %USERPROFILE% >NUL
|
||||
if %errorlevel% equ 0 exit 0
|
||||
echo %cmdcmdline% | find /i "/c"
|
||||
if %errorlevel% equ 0 pause
|
||||
@@ -1,9 +0,0 @@
|
||||
@echo off
|
||||
rem Copyright (c) 2020 Aleksej Komarov
|
||||
rem SPDX-License-Identifier: MIT
|
||||
call powershell.exe -NoLogo -ExecutionPolicy Bypass -File "%~dp0\tgui_.ps1" --dev %*
|
||||
rem Pause if launched in a separate shell unless initiated from powershell
|
||||
echo %PSModulePath% | findstr %USERPROFILE% >NUL
|
||||
if %errorlevel% equ 0 exit 0
|
||||
echo %cmdcmdline% | find /i "/c"
|
||||
if %errorlevel% equ 0 pause
|
||||
@@ -1,9 +0,0 @@
|
||||
@echo off
|
||||
rem Copyright (c) 2020 Aleksej Komarov
|
||||
rem SPDX-License-Identifier: MIT
|
||||
call powershell.exe -NoLogo -ExecutionPolicy Bypass -File "%~dp0\tgui_.ps1" --pretty %*
|
||||
rem Pause if launched in a separate shell unless initiated from powershell
|
||||
echo %PSModulePath% | findstr %USERPROFILE% >NUL
|
||||
if %errorlevel% equ 0 exit 0
|
||||
echo %cmdcmdline% | find /i "/c"
|
||||
if %errorlevel% equ 0 pause
|
||||
@@ -1,9 +0,0 @@
|
||||
@echo off
|
||||
rem Copyright (c) 2020 Aleksej Komarov
|
||||
rem SPDX-License-Identifier: MIT
|
||||
call powershell.exe -NoLogo -ExecutionPolicy Bypass -File "%~dp0\tgui_.ps1" %*
|
||||
rem Pause if launched in a separate shell unless initiated from powershell
|
||||
echo %PSModulePath% | findstr %USERPROFILE% >NUL
|
||||
if %errorlevel% equ 0 exit 0
|
||||
echo %cmdcmdline% | find /i "/c"
|
||||
if %errorlevel% equ 0 pause
|
||||
@@ -1,177 +0,0 @@
|
||||
## Copyright (c) 2020 Aleksej Komarov
|
||||
## SPDX-License-Identifier: MIT
|
||||
|
||||
## Initial set-up
|
||||
## --------------------------------------------------------
|
||||
|
||||
## Enable strict mode and stop of first cmdlet error
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = "Stop"
|
||||
$PSDefaultParameterValues['*:ErrorAction'] = 'Stop'
|
||||
|
||||
## Validates exit code of external commands
|
||||
function Throw-On-Native-Failure {
|
||||
if (-not $?) {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
## Normalize current directory
|
||||
$basedir = Split-Path $MyInvocation.MyCommand.Path
|
||||
$basedir = Resolve-Path "$($basedir)\.."
|
||||
Set-Location $basedir
|
||||
[Environment]::CurrentDirectory = $basedir
|
||||
|
||||
|
||||
## Functions
|
||||
## --------------------------------------------------------
|
||||
|
||||
function yarn {
|
||||
$YarnRelease = Get-ChildItem -Filter ".yarn\releases\yarn-*.cjs" | Select-Object -First 1
|
||||
node ".yarn\releases\$YarnRelease" @Args
|
||||
Throw-On-Native-Failure
|
||||
}
|
||||
|
||||
function Remove-Quiet {
|
||||
Remove-Item -ErrorAction SilentlyContinue @Args
|
||||
}
|
||||
|
||||
function task-install {
|
||||
yarn install
|
||||
}
|
||||
|
||||
## Runs webpack
|
||||
function task-webpack {
|
||||
yarn run webpack-cli @Args
|
||||
}
|
||||
|
||||
## Runs a development server
|
||||
function task-dev-server {
|
||||
yarn node --experimental-modules "packages/tgui-dev-server/index.js" @Args
|
||||
}
|
||||
|
||||
function task-bench {
|
||||
yarn tgui:bench @Args
|
||||
}
|
||||
|
||||
function task-prettier {
|
||||
yarn tgui:prettier @Args
|
||||
}
|
||||
|
||||
function task-prettify {
|
||||
yarn prettierx --write packages @Args
|
||||
}
|
||||
|
||||
## Run a linter through all packages
|
||||
function task-lint {
|
||||
yarn run tsc
|
||||
Write-Output "tgui: type check passed"
|
||||
yarn run eslint packages --ext ".js,.cjs,.ts,.tsx" @Args
|
||||
Write-Output "tgui: eslint check passed"
|
||||
}
|
||||
|
||||
function task-test {
|
||||
yarn run jest
|
||||
}
|
||||
|
||||
## Mr. Proper
|
||||
function task-clean {
|
||||
## Build artifacts
|
||||
Remove-Quiet -Recurse -Force "public\.tmp"
|
||||
Remove-Quiet -Force "public\*.map"
|
||||
Remove-Quiet -Force "public\*.hot-update.*"
|
||||
## Yarn artifacts
|
||||
Remove-Quiet -Recurse -Force ".yarn\cache"
|
||||
Remove-Quiet -Recurse -Force ".yarn\unplugged"
|
||||
Remove-Quiet -Recurse -Force ".yarn\webpack"
|
||||
Remove-Quiet -Force ".yarn\build-state.yml"
|
||||
Remove-Quiet -Force ".yarn\install-state.gz"
|
||||
Remove-Quiet -Force ".yarn\install-target"
|
||||
Remove-Quiet -Force ".pnp.*"
|
||||
## NPM artifacts
|
||||
Get-ChildItem -Path "." -Include "node_modules" -Recurse -File:$false | Remove-Item -Recurse -Force
|
||||
Remove-Quiet -Force "package-lock.json"
|
||||
}
|
||||
|
||||
|
||||
## Main
|
||||
## --------------------------------------------------------
|
||||
|
||||
if ($Args.Length -gt 0) {
|
||||
if ($Args[0] -eq "--clean") {
|
||||
task-clean
|
||||
exit 0
|
||||
}
|
||||
|
||||
if ($Args[0] -eq "--dev") {
|
||||
$Rest = $Args | Select-Object -Skip 1
|
||||
task-install
|
||||
task-dev-server @Rest
|
||||
exit 0
|
||||
}
|
||||
|
||||
if ($Args[0] -eq "--lint") {
|
||||
$Rest = $Args | Select-Object -Skip 1
|
||||
task-install
|
||||
task-lint @Rest
|
||||
exit 0
|
||||
}
|
||||
|
||||
if ($Args[0] -eq "--lint-harder") {
|
||||
$Rest = $Args | Select-Object -Skip 1
|
||||
task-install
|
||||
task-lint -c ".eslintrc-harder.yml" @Rest
|
||||
exit 0
|
||||
}
|
||||
|
||||
if ($Args[0] -eq "--fix") {
|
||||
$Rest = $Args | Select-Object -Skip 1
|
||||
task-install
|
||||
task-lint --fix @Rest
|
||||
exit 0
|
||||
}
|
||||
|
||||
if ($Args[0] -eq "--test") {
|
||||
$Rest = $Args | Select-Object -Skip 1
|
||||
task-install
|
||||
task-test @Rest
|
||||
exit 0
|
||||
}
|
||||
|
||||
if ($Args[0] -eq "--pretty") {
|
||||
$Rest = $Args | Select-Object -Skip 1
|
||||
task-install
|
||||
task-prettify
|
||||
task-prettier
|
||||
task-lint
|
||||
task-webpack --mode=production
|
||||
exit 0
|
||||
}
|
||||
|
||||
## Analyze the bundle
|
||||
if ($Args[0] -eq "--analyze") {
|
||||
task-install
|
||||
task-webpack --mode=production --analyze
|
||||
exit 0
|
||||
}
|
||||
|
||||
if ($Args[0] -eq "--bench") {
|
||||
$Rest = $Args | Select-Object -Skip 1
|
||||
task-install
|
||||
task-bench --wait-on-error
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
|
||||
## Make a production webpack build
|
||||
if ($Args.Length -eq 0) {
|
||||
task-install
|
||||
task-prettier
|
||||
task-lint
|
||||
task-webpack --mode=production
|
||||
exit 0
|
||||
}
|
||||
|
||||
## Run webpack with custom flags
|
||||
task-install
|
||||
task-webpack @Args
|
||||
Vendored
+23
-25
@@ -1,52 +1,50 @@
|
||||
@font-face {
|
||||
font-family: 'tgfont';
|
||||
src: url('./tgfont.woff2?958b912b123580c55529f68c4e2261bd') format('woff2'),
|
||||
url('./tgfont.eot?958b912b123580c55529f68c4e2261bd#iefix')
|
||||
format('embedded-opentype');
|
||||
font-family: "tgfont";
|
||||
src: url("./tgfont.woff2?958b912b123580c55529f68c4e2261bd") format("woff2"),
|
||||
url("./tgfont.eot?958b912b123580c55529f68c4e2261bd#iefix") format("embedded-opentype");
|
||||
}
|
||||
|
||||
i[class^='tg-']:before,
|
||||
i[class*=' tg-']:before {
|
||||
font-family: tgfont !important;
|
||||
font-style: normal;
|
||||
font-weight: normal !important;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
i[class^="tg-"]:before, i[class*=" tg-"]:before {
|
||||
font-family: tgfont !important;
|
||||
font-style: normal;
|
||||
font-weight: normal !important;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.tg-air-tank-slash:before {
|
||||
content: '\f101';
|
||||
content: "\f101";
|
||||
}
|
||||
.tg-air-tank:before {
|
||||
content: '\f102';
|
||||
content: "\f102";
|
||||
}
|
||||
.tg-bad-touch:before {
|
||||
content: '\f103';
|
||||
content: "\f103";
|
||||
}
|
||||
.tg-image-minus:before {
|
||||
content: '\f104';
|
||||
content: "\f104";
|
||||
}
|
||||
.tg-image-plus:before {
|
||||
content: '\f105';
|
||||
content: "\f105";
|
||||
}
|
||||
.tg-nanotrasen-logo:before {
|
||||
content: '\f106';
|
||||
content: "\f106";
|
||||
}
|
||||
.tg-non-binary:before {
|
||||
content: '\f107';
|
||||
content: "\f107";
|
||||
}
|
||||
.tg-prosthetic-leg:before {
|
||||
content: '\f108';
|
||||
content: "\f108";
|
||||
}
|
||||
.tg-sound-minus:before {
|
||||
content: '\f109';
|
||||
content: "\f109";
|
||||
}
|
||||
.tg-sound-plus:before {
|
||||
content: '\f10a';
|
||||
content: "\f10a";
|
||||
}
|
||||
.tg-syndicate-logo:before {
|
||||
content: '\f10b';
|
||||
content: "\f10b";
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "tgfont",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"build": "node mkdist.cjs && fantasticon --config config.cjs"
|
||||
"tgfont:build": "node mkdist.cjs && fantasticon --config config.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"fantasticon": "^1.2.3"
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
@font-face {
|
||||
font-family: "tgfont";
|
||||
src: url("./tgfont.woff2?958b912b123580c55529f68c4e2261bd") format("woff2"),
|
||||
url("./tgfont.eot?958b912b123580c55529f68c4e2261bd#iefix") format("embedded-opentype");
|
||||
}
|
||||
|
||||
i[class^="tg-"]:before, i[class*=" tg-"]:before {
|
||||
font-family: tgfont !important;
|
||||
font-style: normal;
|
||||
font-weight: normal !important;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.tg-air-tank-slash:before {
|
||||
content: "\f101";
|
||||
}
|
||||
.tg-air-tank:before {
|
||||
content: "\f102";
|
||||
}
|
||||
.tg-bad-touch:before {
|
||||
content: "\f103";
|
||||
}
|
||||
.tg-image-minus:before {
|
||||
content: "\f104";
|
||||
}
|
||||
.tg-image-plus:before {
|
||||
content: "\f105";
|
||||
}
|
||||
.tg-nanotrasen-logo:before {
|
||||
content: "\f106";
|
||||
}
|
||||
.tg-non-binary:before {
|
||||
content: "\f107";
|
||||
}
|
||||
.tg-prosthetic-leg:before {
|
||||
content: "\f108";
|
||||
}
|
||||
.tg-sound-minus:before {
|
||||
content: "\f109";
|
||||
}
|
||||
.tg-sound-plus:before {
|
||||
content: "\f10a";
|
||||
}
|
||||
.tg-syndicate-logo:before {
|
||||
content: "\f10b";
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -26,10 +26,10 @@ const createStats = (verbose) => ({
|
||||
|
||||
// prettier-ignore
|
||||
module.exports = (env = {}, argv) => {
|
||||
const mode = argv.mode === 'production' ? 'production' : 'development';
|
||||
const mode = argv.mode || 'production';
|
||||
const bench = env.TGUI_BENCH;
|
||||
const config = {
|
||||
mode,
|
||||
mode: mode === 'production' ? 'production' : 'development',
|
||||
context: path.resolve(__dirname),
|
||||
target: ['web', 'es3', 'browserslist:ie 8'],
|
||||
entry: {
|
||||
@@ -108,7 +108,7 @@ module.exports = (env = {}, argv) => {
|
||||
stats: createStats(true),
|
||||
plugins: [
|
||||
new webpack.EnvironmentPlugin({
|
||||
NODE_ENV: env.NODE_ENV || argv.mode || 'development',
|
||||
NODE_ENV: env.NODE_ENV || mode,
|
||||
WEBPACK_HMR_ENABLED: env.WEBPACK_HMR_ENABLED || argv.hot || false,
|
||||
DEV_SERVER_IP: env.DEV_SERVER_IP || null,
|
||||
}),
|
||||
@@ -129,7 +129,7 @@ module.exports = (env = {}, argv) => {
|
||||
}
|
||||
|
||||
// Production build specific options
|
||||
if (argv.mode === 'production') {
|
||||
if (mode === 'production') {
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
config.optimization.minimizer = [
|
||||
new TerserPlugin({
|
||||
@@ -146,7 +146,7 @@ module.exports = (env = {}, argv) => {
|
||||
}
|
||||
|
||||
// Development build specific options
|
||||
if (argv.mode !== 'production') {
|
||||
if (mode !== 'production') {
|
||||
config.devtool = 'cheap-module-source-map';
|
||||
}
|
||||
|
||||
|
||||
Regular → Executable
Regular → Executable
@@ -0,0 +1,10 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
cd "$(dirname "$0")"
|
||||
exec ../bootstrap/node build.js "$@"
|
||||
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
"%~dp0\..\bootstrap\node.bat" --experimental-modules "%~dp0\build.js" %*
|
||||
@@ -0,0 +1,325 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Build script for CHOMPStation codebase.
|
||||
*
|
||||
* This script uses Juke Build, read the docs here:
|
||||
* https://github.com/stylemistake/juke-build
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import { get } from 'http';
|
||||
import { env } from 'process';
|
||||
import Juke from './juke/index.js';
|
||||
import { DreamDaemon, DreamMaker, NamedVersionFile } from './lib/byond.js';
|
||||
import { yarn } from './lib/yarn.js';
|
||||
|
||||
Juke.chdir('../..', import.meta.url);
|
||||
Juke.setup({ file: import.meta.url }).then((code) => {
|
||||
// We're using the currently available quirk in Juke Build, which
|
||||
// prevents it from exiting on Windows, to wait on errors.
|
||||
if (code !== 0 && process.argv.includes('--wait-on-error')) {
|
||||
Juke.logger.error('Please inspect the error and close the window.');
|
||||
return;
|
||||
}
|
||||
process.exit(code);
|
||||
});
|
||||
|
||||
const DME_NAME = 'vorestation';
|
||||
|
||||
export const DefineParameter = new Juke.Parameter({
|
||||
type: 'string[]',
|
||||
alias: 'D',
|
||||
});
|
||||
|
||||
export const PortParameter = new Juke.Parameter({
|
||||
type: 'string',
|
||||
alias: 'p',
|
||||
});
|
||||
|
||||
export const DmVersionParameter = new Juke.Parameter({
|
||||
type: 'string',
|
||||
})
|
||||
|
||||
export const CiParameter = new Juke.Parameter({ type: 'boolean' });
|
||||
|
||||
export const WarningParameter = new Juke.Parameter({
|
||||
type: 'string[]',
|
||||
alias: 'W',
|
||||
});
|
||||
|
||||
export const NoWarningParameter = new Juke.Parameter({
|
||||
type: 'string[]',
|
||||
alias: 'NW',
|
||||
});
|
||||
|
||||
export const DmMapsIncludeTarget = new Juke.Target({
|
||||
executes: async () => {
|
||||
const folders = [
|
||||
...Juke.glob('_maps/map_files/**/modular_pieces/*.dmm'),
|
||||
...Juke.glob('_maps/RandomRuins/**/*.dmm'),
|
||||
...Juke.glob('_maps/RandomZLevels/**/*.dmm'),
|
||||
...Juke.glob('_maps/shuttles/**/*.dmm'),
|
||||
...Juke.glob('_maps/templates/**/*.dmm'),
|
||||
];
|
||||
const content = folders
|
||||
.map((file) => file.replace('_maps/', ''))
|
||||
.map((file) => `#include "${file}"`)
|
||||
.join('\n') + '\n';
|
||||
fs.writeFileSync('_maps/templates.dm', content);
|
||||
},
|
||||
});
|
||||
|
||||
export const DmTarget = new Juke.Target({
|
||||
parameters: [DefineParameter, DmVersionParameter, WarningParameter, NoWarningParameter],
|
||||
dependsOn: ({ get }) => [
|
||||
get(DefineParameter).includes('ALL_MAPS') && DmMapsIncludeTarget,
|
||||
],
|
||||
inputs: [
|
||||
'_maps/map_files/generic/**',
|
||||
'code/**',
|
||||
'html/**',
|
||||
'icons/**',
|
||||
'interface/**',
|
||||
`${DME_NAME}.dme`,
|
||||
NamedVersionFile,
|
||||
],
|
||||
outputs: ({ get }) => {
|
||||
if (get(DmVersionParameter)) {
|
||||
return []; // Always rebuild when dm version is provided
|
||||
}
|
||||
return [
|
||||
`${DME_NAME}.dmb`,
|
||||
`${DME_NAME}.rsc`,
|
||||
]
|
||||
},
|
||||
executes: async ({ get }) => {
|
||||
await DreamMaker(`${DME_NAME}.dme`, {
|
||||
defines: ['CBT', ...get(DefineParameter)],
|
||||
warningsAsErrors: get(WarningParameter).includes('error'),
|
||||
ignoreWarningCodes: get(NoWarningParameter),
|
||||
namedDmVersion: get(DmVersionParameter),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const DmTestTarget = new Juke.Target({
|
||||
parameters: [DefineParameter, DmVersionParameter, WarningParameter, NoWarningParameter],
|
||||
dependsOn: ({ get }) => [
|
||||
get(DefineParameter).includes('ALL_MAPS') && DmMapsIncludeTarget,
|
||||
],
|
||||
executes: async ({ get }) => {
|
||||
fs.copyFileSync(`${DME_NAME}.dme`, `${DME_NAME}.test.dme`);
|
||||
await DreamMaker(`${DME_NAME}.test.dme`, {
|
||||
defines: ['CBT', 'CIBUILDING', ...get(DefineParameter)],
|
||||
warningsAsErrors: get(WarningParameter).includes('error'),
|
||||
ignoreWarningCodes: get(NoWarningParameter),
|
||||
namedDmVersion: get(DmVersionParameter),
|
||||
});
|
||||
Juke.rm('data/logs/ci', { recursive: true });
|
||||
const options = {
|
||||
dmbFile : `${DME_NAME}.test.dmb`,
|
||||
namedDmVersion: get(DmVersionParameter),
|
||||
}
|
||||
await DreamDaemon(
|
||||
options,
|
||||
'-close', '-trusted', '-verbose', '-invisible',
|
||||
'-params', 'log-directory=ci'
|
||||
);
|
||||
Juke.rm('*.test.*');
|
||||
try {
|
||||
const cleanRun = fs.readFileSync('data/logs/ci/clean_run.lk', 'utf-8');
|
||||
console.log(cleanRun);
|
||||
}
|
||||
catch (err) {
|
||||
Juke.logger.error('Test run was not clean, exiting');
|
||||
throw new Juke.ExitCode(1);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const YarnTarget = new Juke.Target({
|
||||
parameters: [CiParameter],
|
||||
inputs: [
|
||||
'tgui/.yarn/+(cache|releases|plugins|sdks)/**/*',
|
||||
'tgui/**/package.json',
|
||||
'tgui/yarn.lock',
|
||||
],
|
||||
outputs: [
|
||||
'tgui/.yarn/install-target',
|
||||
],
|
||||
executes: ({ get }) => yarn('install', get(CiParameter) && '--immutable'),
|
||||
});
|
||||
|
||||
export const TgFontTarget = new Juke.Target({
|
||||
dependsOn: [YarnTarget],
|
||||
inputs: [
|
||||
'tgui/.yarn/install-target',
|
||||
'tgui/packages/tgfont/**/*.+(js|cjs|svg)',
|
||||
'tgui/packages/tgfont/package.json',
|
||||
],
|
||||
outputs: [
|
||||
'tgui/packages/tgfont/dist/tgfont.css',
|
||||
'tgui/packages/tgfont/dist/tgfont.eot',
|
||||
'tgui/packages/tgfont/dist/tgfont.woff2',
|
||||
],
|
||||
executes: async () => {
|
||||
await yarn('tgfont:build');
|
||||
fs.copyFileSync('tgui/packages/tgfont/dist/tgfont.css', 'tgui/packages/tgfont/static/tgfont.css');
|
||||
fs.copyFileSync('tgui/packages/tgfont/dist/tgfont.eot', 'tgui/packages/tgfont/static/tgfont.eot');
|
||||
fs.copyFileSync('tgui/packages/tgfont/dist/tgfont.woff2', 'tgui/packages/tgfont/static/tgfont.woff2');
|
||||
}
|
||||
});
|
||||
|
||||
export const TguiTarget = new Juke.Target({
|
||||
dependsOn: [YarnTarget],
|
||||
inputs: [
|
||||
'tgui/.yarn/install-target',
|
||||
'tgui/webpack.config.js',
|
||||
'tgui/**/package.json',
|
||||
'tgui/packages/**/*.+(js|cjs|ts|tsx|scss)',
|
||||
],
|
||||
outputs: [
|
||||
'tgui/public/tgui.bundle.css',
|
||||
'tgui/public/tgui.bundle.js',
|
||||
//'tgui/public/tgui-panel.bundle.css',
|
||||
//'tgui/public/tgui-panel.bundle.js',
|
||||
//'tgui/public/tgui-say.bundle.css',
|
||||
//'tgui/public/tgui-say.bundle.js',
|
||||
],
|
||||
executes: () => yarn('tgui:build'),
|
||||
});
|
||||
|
||||
export const TguiEslintTarget = new Juke.Target({
|
||||
parameters: [CiParameter],
|
||||
dependsOn: [YarnTarget],
|
||||
executes: ({ get }) => yarn('tgui:lint', !get(CiParameter) && '--fix'),
|
||||
});
|
||||
|
||||
export const TguiPrettierTarget = new Juke.Target({
|
||||
dependsOn: [YarnTarget],
|
||||
executes: () => yarn('tgui:prettier'),
|
||||
});
|
||||
|
||||
export const TguiSonarTarget = new Juke.Target({
|
||||
dependsOn: [YarnTarget],
|
||||
executes: () => yarn('tgui:sonar'),
|
||||
});
|
||||
|
||||
export const TguiTscTarget = new Juke.Target({
|
||||
dependsOn: [YarnTarget],
|
||||
executes: () => yarn('tgui:tsc'),
|
||||
});
|
||||
|
||||
export const TguiTestTarget = new Juke.Target({
|
||||
parameters: [CiParameter],
|
||||
dependsOn: [YarnTarget],
|
||||
executes: ({ get }) => yarn(`tgui:test-${get(CiParameter) ? 'ci' : 'simple'}`),
|
||||
});
|
||||
|
||||
export const TguiLintTarget = new Juke.Target({
|
||||
dependsOn: [YarnTarget, TguiPrettierTarget, TguiEslintTarget, TguiTscTarget],
|
||||
});
|
||||
|
||||
export const TguiDevTarget = new Juke.Target({
|
||||
dependsOn: [YarnTarget],
|
||||
executes: ({ args }) => yarn('tgui:dev', ...args),
|
||||
});
|
||||
|
||||
export const TguiAnalyzeTarget = new Juke.Target({
|
||||
dependsOn: [YarnTarget],
|
||||
executes: () => yarn('tgui:analyze'),
|
||||
});
|
||||
|
||||
export const TguiBenchTarget = new Juke.Target({
|
||||
dependsOn: [YarnTarget],
|
||||
executes: () => yarn('tgui:bench'),
|
||||
});
|
||||
|
||||
export const TestTarget = new Juke.Target({
|
||||
dependsOn: [DmTestTarget, TguiTestTarget],
|
||||
});
|
||||
|
||||
export const LintTarget = new Juke.Target({
|
||||
dependsOn: [TguiLintTarget],
|
||||
});
|
||||
|
||||
export const BuildTarget = new Juke.Target({
|
||||
dependsOn: [TguiTarget, DmTarget],
|
||||
});
|
||||
|
||||
export const ServerTarget = new Juke.Target({
|
||||
parameters: [DmVersionParameter, PortParameter],
|
||||
dependsOn: [BuildTarget],
|
||||
executes: async ({ get }) => {
|
||||
const port = get(PortParameter) || '1337';
|
||||
const options = {
|
||||
dmbFile: `${DME_NAME}.dmb`,
|
||||
namedDmVersion: get(DmVersionParameter),
|
||||
}
|
||||
await DreamDaemon(options, port, '-trusted -invisible');
|
||||
},
|
||||
});
|
||||
|
||||
export const AllTarget = new Juke.Target({
|
||||
dependsOn: [TestTarget, LintTarget, BuildTarget],
|
||||
});
|
||||
|
||||
export const TguiCleanTarget = new Juke.Target({
|
||||
executes: async () => {
|
||||
Juke.rm('tgui/public/.tmp', { recursive: true });
|
||||
Juke.rm('tgui/public/*.map');
|
||||
Juke.rm('tgui/public/*.{chunk,bundle,hot-update}.*');
|
||||
Juke.rm('tgui/packages/tgfont/dist', { recursive: true });
|
||||
Juke.rm('tgui/.yarn/{cache,unplugged,webpack}', { recursive: true });
|
||||
Juke.rm('tgui/.yarn/build-state.yml');
|
||||
Juke.rm('tgui/.yarn/install-state.gz');
|
||||
Juke.rm('tgui/.yarn/install-target');
|
||||
Juke.rm('tgui/.pnp.*');
|
||||
},
|
||||
});
|
||||
|
||||
export const CleanTarget = new Juke.Target({
|
||||
dependsOn: [TguiCleanTarget],
|
||||
executes: async () => {
|
||||
Juke.rm('*.{dmb,rsc}');
|
||||
Juke.rm('*.mdme*');
|
||||
Juke.rm('*.m.*');
|
||||
Juke.rm('_maps/templates.dm');
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Removes more junk at the expense of much slower initial builds.
|
||||
*/
|
||||
export const CleanAllTarget = new Juke.Target({
|
||||
dependsOn: [CleanTarget],
|
||||
executes: async () => {
|
||||
Juke.logger.info('Cleaning up data/logs');
|
||||
Juke.rm('data/logs', { recursive: true });
|
||||
Juke.logger.info('Cleaning up global yarn cache');
|
||||
await yarn('cache', 'clean', '--all');
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Prepends the defines to the .dme.
|
||||
* Does not clean them up, as this is intended for TGS which
|
||||
* clones new copies anyway.
|
||||
*/
|
||||
const prependDefines = (...defines) => {
|
||||
const dmeContents = fs.readFileSync(`${DME_NAME}.dme`);
|
||||
const textToWrite = defines.map(define => `#define ${define}\n`);
|
||||
fs.writeFileSync(`${DME_NAME}.dme`, `${textToWrite}\n${dmeContents}`);
|
||||
};
|
||||
|
||||
export const TgsTarget = new Juke.Target({
|
||||
dependsOn: [TguiTarget],
|
||||
executes: async () => {
|
||||
Juke.logger.info('Prepending TGS define');
|
||||
prependDefines('TGS');
|
||||
},
|
||||
});
|
||||
|
||||
const TGS_MODE = process.env.CBT_BUILD_MODE === 'TGS';
|
||||
|
||||
export default TGS_MODE ? TgsTarget : BuildTarget;
|
||||
Vendored
+248
@@ -0,0 +1,248 @@
|
||||
// Generated by dts-bundle-generator v5.9.0
|
||||
|
||||
/// <reference types="node" />
|
||||
|
||||
import _chalk from 'chalk';
|
||||
import { SpawnOptionsWithoutStdio } from 'child_process';
|
||||
import EventEmitter from 'events';
|
||||
|
||||
/**
|
||||
* Change the current working directory of the Node.js process.
|
||||
*
|
||||
* Second argument is a file (or directory), relative to which chdir will be
|
||||
* performed. This is usually `import.meta.url`.
|
||||
*/
|
||||
export declare const chdir: (directory: string, relativeTo?: string | undefined) => void;
|
||||
export declare const logger: {
|
||||
log: (...args: unknown[]) => void;
|
||||
error: (...args: unknown[]) => void;
|
||||
action: (...args: unknown[]) => void;
|
||||
warn: (...args: unknown[]) => void;
|
||||
info: (...args: unknown[]) => void;
|
||||
debug: (...args: unknown[]) => void;
|
||||
};
|
||||
export declare type ParameterType = (string | string[] | number | number[] | boolean | boolean[]);
|
||||
export declare type StringType = ("string" | "string[]" | "number" | "number[]" | "boolean" | "boolean[]");
|
||||
export declare type TypeByString<T extends StringType> = (T extends "string" ? string : T extends "string[]" ? string[] : T extends "number" ? number : T extends "number[]" ? number[] : T extends "boolean" ? boolean : T extends "boolean[]" ? boolean[] : never);
|
||||
export declare type ParameterConfig<T extends StringType> = {
|
||||
/**
|
||||
* Parameter name, as it would be used in CLI.
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Parameter type, one of:
|
||||
* - `string`
|
||||
* - `string[]`
|
||||
* - `number`
|
||||
* - `number[]`
|
||||
* - `boolean`
|
||||
* - `boolean[]`
|
||||
*/
|
||||
type: T;
|
||||
/**
|
||||
* Short flag for use in CLI, can only be a single character.
|
||||
*/
|
||||
alias?: string;
|
||||
};
|
||||
export interface Parameter<T extends ParameterType = ParameterType> {
|
||||
type: StringType;
|
||||
name?: string;
|
||||
alias?: string;
|
||||
__internalType?: T;
|
||||
isString(): this is Parameter<string | string[]>;
|
||||
isNumber(): this is Parameter<number | number[]>;
|
||||
isBoolean(): this is Parameter<boolean | boolean[]>;
|
||||
isArray(): this is Parameter<string[] | number[] | boolean[]>;
|
||||
toKebabCase(): string | undefined;
|
||||
toConstCase(): string | undefined;
|
||||
toCamelCase(): string | undefined;
|
||||
}
|
||||
export declare type ParameterCtor = {
|
||||
new <T extends StringType>(config: ParameterConfig<T>): Parameter<TypeByString<T>>;
|
||||
};
|
||||
export declare const Parameter: ParameterCtor;
|
||||
export declare type ParameterCreator = <T extends StringType>(config: ParameterConfig<T>) => Parameter<TypeByString<T>>;
|
||||
export declare const createParameter: ParameterCreator;
|
||||
export declare type ExecutionContext = {
|
||||
/** Get parameter value. */
|
||||
get: <T extends ParameterType>(parameter: Parameter<T>) => (T extends Array<unknown> ? T : T | null);
|
||||
args: string[];
|
||||
};
|
||||
export declare type BooleanLike = boolean | null | undefined;
|
||||
export declare type WithExecutionContext<R> = (context: ExecutionContext) => R | Promise<R>;
|
||||
export declare type WithOptionalExecutionContext<R> = R | WithExecutionContext<R>;
|
||||
export declare type DependsOn = WithOptionalExecutionContext<(Target | BooleanLike)[]>;
|
||||
export declare type ExecutesFn = WithExecutionContext<unknown>;
|
||||
export declare type OnlyWhenFn = WithExecutionContext<BooleanLike>;
|
||||
export declare type FileIo = WithOptionalExecutionContext<(string | BooleanLike)[]>;
|
||||
export declare type TargetConfig = {
|
||||
/**
|
||||
* Target name. This parameter is required.
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Dependencies for this target. They will be ran before executing this
|
||||
* target, and may run in parallel.
|
||||
*/
|
||||
dependsOn?: DependsOn;
|
||||
/**
|
||||
* Function that is delegated to the execution engine for building this
|
||||
* target. It is normally an async function, which accepts a single
|
||||
* argument - execution context (contains `get` for interacting with
|
||||
* parameters).
|
||||
*
|
||||
* @example
|
||||
* executes: async ({ get }) => {
|
||||
* console.log(get(Parameter));
|
||||
* },
|
||||
*/
|
||||
executes?: ExecutesFn;
|
||||
/**
|
||||
* Files that are consumed by this target.
|
||||
*/
|
||||
inputs?: FileIo;
|
||||
/**
|
||||
* Files that are produced by this target. Additionally, they are also
|
||||
* touched every time target finishes executing in order to stop
|
||||
* this target from re-running.
|
||||
*/
|
||||
outputs?: FileIo;
|
||||
/**
|
||||
* Parameters that are local to this task. Can be retrieved via `get`
|
||||
* in the executor function.
|
||||
*/
|
||||
parameters?: Parameter[];
|
||||
/**
|
||||
* Target will run only when this function returns true. It accepts a
|
||||
* single argument - execution context.
|
||||
*/
|
||||
onlyWhen?: OnlyWhenFn;
|
||||
};
|
||||
export declare class Target {
|
||||
name?: string;
|
||||
dependsOn: DependsOn;
|
||||
executes?: ExecutesFn;
|
||||
inputs: FileIo;
|
||||
outputs: FileIo;
|
||||
parameters: Parameter[];
|
||||
onlyWhen?: OnlyWhenFn;
|
||||
constructor(target: TargetConfig);
|
||||
}
|
||||
export declare type TargetCreator = (target: TargetConfig) => Target;
|
||||
export declare const createTarget: TargetCreator;
|
||||
export declare type RunnerConfig = {
|
||||
targets?: Target[];
|
||||
default?: Target;
|
||||
parameters?: Parameter[];
|
||||
singleTarget?: boolean;
|
||||
};
|
||||
export declare const runner: {
|
||||
config: RunnerConfig;
|
||||
targets: Target[];
|
||||
parameters: Parameter[];
|
||||
workers: Worker[];
|
||||
configure(config: RunnerConfig): void;
|
||||
start(): Promise<number>;
|
||||
};
|
||||
declare class Worker {
|
||||
readonly target: Target;
|
||||
readonly context: ExecutionContext;
|
||||
readonly dependsOn: Target[];
|
||||
dependencies: Set<Target>;
|
||||
generator?: AsyncGenerator;
|
||||
emitter: EventEmitter;
|
||||
hasFailed: boolean;
|
||||
constructor(target: Target, context: ExecutionContext, dependsOn: Target[]);
|
||||
resolveDependency(target: Target): void;
|
||||
rejectDependency(target: Target): void;
|
||||
start(): void;
|
||||
onFinish(fn: () => void): void;
|
||||
onFail(fn: () => void): void;
|
||||
private debugLog;
|
||||
private process;
|
||||
}
|
||||
export declare class ExitCode extends Error {
|
||||
code: number | null;
|
||||
signal: string | null;
|
||||
constructor(code: number | null, signal?: string | null);
|
||||
}
|
||||
export declare type ExecOptions = SpawnOptionsWithoutStdio & {
|
||||
/**
|
||||
* If `true`, this exec call will not pipe its output to stdio.
|
||||
* @default false
|
||||
*/
|
||||
silent?: boolean;
|
||||
/**
|
||||
* Throw an exception on non-zero exit code.
|
||||
* @default true
|
||||
*/
|
||||
throw?: boolean;
|
||||
};
|
||||
export declare type ExecReturn = {
|
||||
/** Exit code of the program. */
|
||||
code: number | null;
|
||||
/** Signal received by the program which caused it to exit. */
|
||||
signal: NodeJS.Signals | null;
|
||||
/** Output collected from `stdout` */
|
||||
stdout: string;
|
||||
/** Output collected from `stderr` */
|
||||
stderr: string;
|
||||
/** A combined output collected from `stdout` and `stderr`. */
|
||||
combined: string;
|
||||
};
|
||||
export declare const exec: (executable: string, args?: string[], options?: ExecOptions) => Promise<ExecReturn>;
|
||||
/**
|
||||
* Unix style pathname pattern expansion.
|
||||
*
|
||||
* Perform a search matching a specified pattern according to the rules of
|
||||
* the `glob` npm package. Path can be either absolute or relative, and can
|
||||
* contain shell-style wildcards. Broken symlinks are included in the results
|
||||
* (as in the shell). Whether or not the results are sorted depends on the
|
||||
* file system.
|
||||
*
|
||||
* @returns A possibly empty list of file paths.
|
||||
*/
|
||||
export declare const glob: (globPath: string) => string[];
|
||||
export declare type RmOptions = {
|
||||
/**
|
||||
* If true, perform a recursive directory removal.
|
||||
*/
|
||||
recursive?: boolean;
|
||||
/**
|
||||
* If true, exceptions will be ignored if file or directory does not exist.
|
||||
*/
|
||||
force?: boolean;
|
||||
};
|
||||
/**
|
||||
* Removes files and directories (synchronously). Supports globs.
|
||||
*/
|
||||
export declare const rm: (path: string, options?: RmOptions) => void;
|
||||
export declare const chalk: _chalk.Chalk & _chalk.ChalkFunction & {
|
||||
supportsColor: false | _chalk.ColorSupport;
|
||||
Level: _chalk.Level;
|
||||
Color: ("black" | "red" | "green" | "yellow" | "blue" | "magenta" | "cyan" | "white" | "gray" | "grey" | "blackBright" | "redBright" | "greenBright" | "yellowBright" | "blueBright" | "magentaBright" | "cyanBright" | "whiteBright") | ("bgBlack" | "bgRed" | "bgGreen" | "bgYellow" | "bgBlue" | "bgMagenta" | "bgCyan" | "bgWhite" | "bgGray" | "bgGrey" | "bgBlackBright" | "bgRedBright" | "bgGreenBright" | "bgYellowBright" | "bgBlueBright" | "bgMagentaBright" | "bgCyanBright" | "bgWhiteBright");
|
||||
ForegroundColor: "black" | "red" | "green" | "yellow" | "blue" | "magenta" | "cyan" | "white" | "gray" | "grey" | "blackBright" | "redBright" | "greenBright" | "yellowBright" | "blueBright" | "magentaBright" | "cyanBright" | "whiteBright";
|
||||
BackgroundColor: "bgBlack" | "bgRed" | "bgGreen" | "bgYellow" | "bgBlue" | "bgMagenta" | "bgCyan" | "bgWhite" | "bgGray" | "bgGrey" | "bgBlackBright" | "bgRedBright" | "bgGreenBright" | "bgYellowBright" | "bgBlueBright" | "bgMagentaBright" | "bgCyanBright" | "bgWhiteBright";
|
||||
Modifiers: "bold" | "reset" | "dim" | "italic" | "underline" | "inverse" | "hidden" | "strikethrough" | "visible";
|
||||
stderr: _chalk.Chalk & {
|
||||
supportsColor: false | _chalk.ColorSupport;
|
||||
};
|
||||
};
|
||||
export declare type SetupConfig = {
|
||||
file: string;
|
||||
/**
|
||||
* If true, CLI will only accept a single target to run and will receive all
|
||||
* passed arguments as is (not only flags).
|
||||
*/
|
||||
singleTarget?: boolean;
|
||||
};
|
||||
/**
|
||||
* Configures Juke Build and starts executing targets.
|
||||
*
|
||||
* @param config Juke Build configuration.
|
||||
* @returns Exit code of the whole runner process.
|
||||
*/
|
||||
export declare const setup: (config: SetupConfig) => Promise<number>;
|
||||
export declare const sleep: (time: number) => Promise<unknown>;
|
||||
|
||||
export {};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"private": true,
|
||||
"type": "commonjs"
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import Juke from '../juke/index.js';
|
||||
import { regQuery } from './winreg.js';
|
||||
|
||||
/**
|
||||
* Cached path to DM compiler
|
||||
*/
|
||||
let dmPath;
|
||||
|
||||
const getDmPath = async (namedVersion) => {
|
||||
// Use specific named version
|
||||
if(namedVersion) {
|
||||
return getNamedByondVersionPath(namedVersion);
|
||||
}
|
||||
if (dmPath) {
|
||||
return dmPath;
|
||||
}
|
||||
dmPath = await (async () => {
|
||||
// Search in array of paths
|
||||
const paths = [
|
||||
...((process.env.DM_EXE && process.env.DM_EXE.split(',')) || []),
|
||||
...getDefaultNamedByondVersionPath(),
|
||||
'C:\\Program Files\\BYOND\\bin\\dm.exe',
|
||||
'C:\\Program Files (x86)\\BYOND\\bin\\dm.exe',
|
||||
['reg', 'HKLM\\Software\\Dantom\\BYOND', 'installpath'],
|
||||
['reg', 'HKLM\\SOFTWARE\\WOW6432Node\\Dantom\\BYOND', 'installpath'],
|
||||
];
|
||||
const isFile = path => {
|
||||
try {
|
||||
return fs.statSync(path).isFile();
|
||||
}
|
||||
catch (err) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
for (let path of paths) {
|
||||
// Resolve a registry key
|
||||
if (Array.isArray(path)) {
|
||||
const [type, ...args] = path;
|
||||
path = await regQuery(...args);
|
||||
}
|
||||
if (!path) {
|
||||
continue;
|
||||
}
|
||||
// Check if path exists
|
||||
if (isFile(path)) {
|
||||
return path;
|
||||
}
|
||||
if (isFile(path + '/dm.exe')) {
|
||||
return path + '/dm.exe';
|
||||
}
|
||||
if (isFile(path + '/bin/dm.exe')) {
|
||||
return path + '/bin/dm.exe';
|
||||
}
|
||||
}
|
||||
// Default paths
|
||||
return (
|
||||
process.platform === 'win32' && 'dm.exe'
|
||||
|| 'DreamMaker'
|
||||
);
|
||||
})();
|
||||
return dmPath;
|
||||
};
|
||||
|
||||
|
||||
|
||||
const getNamedByondVersionPath = (namedVersion) =>{
|
||||
const all_entries = getAllNamedDmVersions(true)
|
||||
const map_entry = all_entries.find(x => x.name === namedVersion);
|
||||
if(map_entry === undefined){
|
||||
Juke.logger.error(`No named byond version with name "${namedVersion}" found.`);
|
||||
throw new Juke.ExitCode(1);
|
||||
}
|
||||
return map_entry.path;
|
||||
}
|
||||
|
||||
const getDefaultNamedByondVersionPath = () =>{
|
||||
const all_entries = getAllNamedDmVersions(false)
|
||||
const map_entry = all_entries.find(x => x.default == true);
|
||||
if(map_entry === undefined)
|
||||
return []
|
||||
return [map_entry.path];
|
||||
}
|
||||
|
||||
|
||||
/** @type {[{ name, path, default }]} */
|
||||
let namedDmVersionList;
|
||||
export const NamedVersionFile = "tools/build/dm_versions.json"
|
||||
|
||||
const getAllNamedDmVersions = (throw_on_fail) => {
|
||||
if(!namedDmVersionList){
|
||||
if(!fs.existsSync(NamedVersionFile)){
|
||||
if(throw_on_fail){
|
||||
Juke.logger.error(`No byond version map file found.`);
|
||||
throw new Juke.ExitCode(1);
|
||||
}
|
||||
namedDmVersionList = []
|
||||
return namedDmVersionList;
|
||||
}
|
||||
try{
|
||||
namedDmVersionList = JSON.parse(fs.readFileSync(NamedVersionFile));
|
||||
}
|
||||
catch(err){
|
||||
if(throw_on_fail){
|
||||
Juke.logger.error(`Failed to parse byond version map file. ${err}`);
|
||||
throw new Juke.ExitCode(1);
|
||||
}
|
||||
namedDmVersionList = []
|
||||
return namedDmVersionList;
|
||||
}
|
||||
}
|
||||
return namedDmVersionList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dmeFile
|
||||
* @param {{
|
||||
* defines?: string[];
|
||||
* warningsAsErrors?: boolean;
|
||||
* namedDmVersion?: string;
|
||||
* }} options
|
||||
*/
|
||||
export const DreamMaker = async (dmeFile, options = {}) => {
|
||||
if(options.namedDmVersion !== null){
|
||||
Juke.logger.info('Using named byond version:', options.namedDmVersion);
|
||||
}
|
||||
const dmPath = await getDmPath(options.namedDmVersion);
|
||||
// Get project basename
|
||||
const dmeBaseName = dmeFile.replace(/\.dme$/, '');
|
||||
// Make sure output files are writable
|
||||
const testOutputFile = (name) => {
|
||||
try {
|
||||
fs.closeSync(fs.openSync(name, 'r+'));
|
||||
}
|
||||
catch (err) {
|
||||
if (err && err.code === 'ENOENT') {
|
||||
return;
|
||||
}
|
||||
if (err && err.code === 'EBUSY') {
|
||||
Juke.logger.error(`File '${name}' is locked by the DreamDaemon process.`);
|
||||
Juke.logger.error(`Stop the currently running server and try again.`);
|
||||
throw new Juke.ExitCode(1);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
testOutputFile(`${dmeBaseName}.dmb`);
|
||||
testOutputFile(`${dmeBaseName}.rsc`);
|
||||
const runWithWarningChecks = async (dmeFile, args) => {
|
||||
const execReturn = await Juke.exec(dmeFile, args);
|
||||
const ignoredWarningCodes = options.ignoreWarningCodes ?? [];
|
||||
const reg = ignoredWarningCodes.length > 0 ? new RegExp(`\d+:warning: (?!(${ignoredWarningCodes.join('|')}))`) : /\d+:warning: /;
|
||||
if (options.warningsAsErrors && execReturn.combined.match(reg)) {
|
||||
Juke.logger.error(`Compile warnings treated as errors`);
|
||||
throw new Juke.ExitCode(2);
|
||||
}
|
||||
return execReturn;
|
||||
}
|
||||
// Compile
|
||||
const { defines } = options;
|
||||
if (defines && defines.length > 0) {
|
||||
Juke.logger.info('Using defines:', defines.join(', '));
|
||||
try {
|
||||
const injectedContent = defines
|
||||
.map(x => `#define ${x}\n`)
|
||||
.join('');
|
||||
fs.writeFileSync(`${dmeBaseName}.m.dme`, injectedContent);
|
||||
const dmeContent = fs.readFileSync(`${dmeBaseName}.dme`);
|
||||
fs.appendFileSync(`${dmeBaseName}.m.dme`, dmeContent);
|
||||
await runWithWarningChecks(dmPath, [`${dmeBaseName}.m.dme`]);
|
||||
fs.writeFileSync(`${dmeBaseName}.dmb`, fs.readFileSync(`${dmeBaseName}.m.dmb`));
|
||||
fs.writeFileSync(`${dmeBaseName}.rsc`, fs.readFileSync(`${dmeBaseName}.m.rsc`));
|
||||
}
|
||||
finally {
|
||||
Juke.rm(`${dmeBaseName}.m.*`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
await runWithWarningChecks(dmPath, [dmeFile]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
* dmbFile: string;
|
||||
* namedDmVersion?: string;
|
||||
* }} options
|
||||
*/
|
||||
export const DreamDaemon = async (options, ...args) => {
|
||||
const dmPath = await getDmPath(options.namedDmVersion);
|
||||
const baseDir = path.dirname(dmPath);
|
||||
const ddExeName = process.platform === 'win32' ? 'dreamdaemon.exe' : 'DreamDaemon';
|
||||
const ddExePath = baseDir === '.' ? ddExeName : path.join(baseDir, ddExeName);
|
||||
return Juke.exec(ddExePath, [options.dmbFile, ...args]);
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Tools for dealing with Windows Registry bullshit.
|
||||
*
|
||||
* Adapted from `tgui/packages/tgui-dev-server/winreg.js`.
|
||||
*
|
||||
* @file
|
||||
* @copyright 2021 Aleksej Komarov
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
|
||||
export const regQuery = async (path, key) => {
|
||||
if (process.platform !== 'win32') {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
const command = `reg query "${path}" /v ${key}`;
|
||||
const { stdout } = await promisify(exec)(command);
|
||||
const keyPattern = ` ${key} `;
|
||||
const indexOfKey = stdout.indexOf(keyPattern);
|
||||
if (indexOfKey === -1) {
|
||||
return null;
|
||||
}
|
||||
const indexOfEol = stdout.indexOf('\r\n', indexOfKey);
|
||||
if (indexOfEol === -1) {
|
||||
return null;
|
||||
}
|
||||
const indexOfValue = stdout.indexOf(
|
||||
' ',
|
||||
indexOfKey + keyPattern.length);
|
||||
if (indexOfValue === -1) {
|
||||
return null;
|
||||
}
|
||||
const value = stdout.substring(indexOfValue + 4, indexOfEol);
|
||||
return value;
|
||||
}
|
||||
catch (err) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
import Juke from '../juke/index.js';
|
||||
|
||||
let yarnPath;
|
||||
|
||||
export const yarn = (...args) => {
|
||||
if (!yarnPath) {
|
||||
yarnPath = Juke.glob('./tgui/.yarn/releases/*.cjs')[0]
|
||||
.replace('/tgui/', '/');
|
||||
}
|
||||
return Juke.exec('node', [
|
||||
yarnPath,
|
||||
...args.filter((arg) => typeof arg === 'string'),
|
||||
], {
|
||||
cwd: './tgui',
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"private": true,
|
||||
"type": "module"
|
||||
}
|
||||
Reference in New Issue
Block a user