Skip to content

Commit

Permalink
[MIRROR] Adds basic support for multiple byond versions to build scri…
Browse files Browse the repository at this point in the history
…pts. [MDB IGNORE] (#17528)

* Adds basic support for multiple byond versions to build scripts. (#71283)

You can now specify few named versions in `tools/build/dm_versions.json`
file and either set them as default (overriding anything but env vars)
or just use them with new --dm-version parameter.

Makes juggling versions bit easier during testing. I'll look into adding
support in sdmm so debugging is in line later.

Co-authored-by: Aleksej Komarov <stylemistake@ gmail.com>

* Adds basic support for multiple byond versions to build scripts.

Co-authored-by: AnturK <[email protected]>
Co-authored-by: Aleksej Komarov <stylemistake@ gmail.com>
  • Loading branch information
3 people authored Nov 17, 2022
1 parent fe05ec3 commit d08d158
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 17 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,6 @@ libprof.so

# Screenshot tests
/artifacts

# named byond versions config
/tools/build/dm_versions.json
20 changes: 20 additions & 0 deletions tools/build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,23 @@ tools/build/build --help
We used to include compiled versions of the tgui JavaScript code in the Git repository so that the project could be compiled using BYOND only. These pre-compiled files tended to have merge conflicts for no good reason. Using a build script lets us avoid this problem, while keeping builds convenient for people who are not modifying tgui.

This build script is based on [Juke Build](https://github.com/stylemistake/juke-build) - follow the link to read the documentation for the project and understand how it works and how to contribute.

## Named byond versions

If you have byond installations in non-standard locations or want to use few versions at once for testing you can fill in `dm_versions.json` file in this directory.
Entries with "default" set to true will be used BEFORE byond installations in standard locations. Otherwise you need to pass `--dm-version={name}` to the build script to choose version you want to use.
Example dm_versions.json file:
```
[
{
"name": "515.1594",
"path": "C:\\Repo\\ByondVersions\\515.1594_byond\\byond\\bin\\dm.exe",
"default": false
},
{
"name": "funny_version",
"path": "D:\\Repo\\ByondVersions\\514.1589_byond\\byond\\bin\\dm.exe",
"default": true
}
]
```
52 changes: 40 additions & 12 deletions tools/build/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
*/

import fs from 'fs';
import { get } from 'http';
import { env } from 'process';
import Juke from './juke/index.js';
import { DreamDaemon, DreamMaker } from './lib/byond.js';
import { DreamDaemon, DreamMaker, NamedVersionFile } from './lib/byond.js';
import { yarn } from './lib/yarn.js';

Juke.chdir('../..', import.meta.url);
Expand All @@ -34,6 +36,10 @@ export const PortParameter = new Juke.Parameter({
alias: 'p',
});

export const DmVersionParameter = new Juke.Parameter({
type: 'string',
})

export const CiParameter = new Juke.Parameter({ type: 'boolean' });

export const WarningParameter = new Juke.Parameter({
Expand All @@ -59,7 +65,7 @@ export const DmMapsIncludeTarget = new Juke.Target({
});

export const DmTarget = new Juke.Target({
parameters: [DefineParameter],
parameters: [DefineParameter, DmVersionParameter],
dependsOn: ({ get }) => [
get(DefineParameter).includes('ALL_MAPS') && DmMapsIncludeTarget,
],
Expand All @@ -71,21 +77,28 @@ export const DmTarget = new Juke.Target({
'interface/**',
'modular_skyrat/**', ///SKYRAT EDIT ADDITION - Making the CBT work
`${DME_NAME}.dme`,
NamedVersionFile,
],
outputs: [
`${DME_NAME}.dmb`,
`${DME_NAME}.rsc`,
],
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'),
namedDmVersion: get(DmVersionParameter),
});
},
});

export const DmTestTarget = new Juke.Target({
parameters: [DefineParameter],
parameters: [DefineParameter, DmVersionParameter],
dependsOn: ({ get }) => [
get(DefineParameter).includes('ALL_MAPS') && DmMapsIncludeTarget,
],
Expand All @@ -94,10 +107,15 @@ export const DmTestTarget = new Juke.Target({
await DreamMaker(`${DME_NAME}.test.dme`, {
defines: ['CBT', 'CIBUILDING', ...get(DefineParameter)],
warningsAsErrors: get(WarningParameter).includes('error'),
namedDmVersion: get(DmVersionParameter),
});
Juke.rm('data/logs/ci', { recursive: true });
const options = {
dmbFile : `${DME_NAME}.test.dmb`,
namedDmVersion: get(DmVersionParameter),
}
await DreamDaemon(
`${DME_NAME}.test.dmb`,
options,
'-close', '-trusted', '-verbose',
'-params', 'log-directory=ci'
);
Expand All @@ -114,7 +132,7 @@ export const DmTestTarget = new Juke.Target({
});

export const AutowikiTarget = new Juke.Target({
parameters: [DefineParameter],
parameters: [DefineParameter, DmVersionParameter],
dependsOn: ({ get }) => [
get(DefineParameter).includes('ALL_MAPS') && DmMapsIncludeTarget,
],
Expand All @@ -126,12 +144,18 @@ export const AutowikiTarget = new Juke.Target({
await DreamMaker(`${DME_NAME}.test.dme`, {
defines: ['CBT', 'AUTOWIKI', ...get(DefineParameter)],
warningsAsErrors: get(WarningParameter).includes('error'),
namedDmVersion: get(DmVersionParameter),
});
Juke.rm('data/autowiki_edits.txt');
Juke.rm('data/autowiki_files', { recursive: true });
Juke.rm('data/logs/ci', { recursive: true });

const options = {
dmbFile: `${DME_NAME}.test.dmb`,
namedDmVersion: get(DmVersionParameter),
}
await DreamDaemon(
`${DME_NAME}.test.dmb`,
options,
'-close', '-trusted', '-verbose',
'-params', 'log-directory=ci',
);
Expand Down Expand Up @@ -254,10 +278,14 @@ export const BuildTarget = new Juke.Target({
});

export const ServerTarget = new Juke.Target({
dependsOn: [BuildTarget],
dependsOn: [BuildTarget, DmVersionParameter],
executes: async ({ get }) => {
const port = get(PortParameter) || '1337';
await DreamDaemon(`${DME_NAME}.dmb`, port, '-trusted');
const options = {
dmbFile: `${DME_NAME}.dmb`,
namedDmVersion: get(DmVersionParameter),
}
await DreamDaemon(options, port, '-trusted');
},
});

Expand Down
76 changes: 71 additions & 5 deletions tools/build/lib/byond.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ import { regQuery } from './winreg.js';
*/
let dmPath;

const getDmPath = async () => {
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'],
Expand Down Expand Up @@ -58,15 +63,69 @@ const getDmPath = async () => {
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 = {}) => {
const dmPath = await getDmPath();
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
Expand Down Expand Up @@ -120,10 +179,17 @@ export const DreamMaker = async (dmeFile, options = {}) => {
}
};

export const DreamDaemon = async (dmbFile, ...args) => {
const dmPath = await getDmPath();

/**
* @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, [dmbFile, ...args]);
return Juke.exec(ddExePath, [options.dmbFile, ...args]);
};

0 comments on commit d08d158

Please sign in to comment.