add testing
Some checks failed
Build / build-windows (push) Successful in 34s
Build / build-linux (push) Failing after 38s
Build / package-dist (push) Has been skipped

This commit is contained in:
2025-02-17 21:10:16 -06:00
parent 75c7e304de
commit 1ae73aed06
12 changed files with 115 additions and 340 deletions

View File

@@ -9,7 +9,6 @@ RUN echo "https://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositor
# Update indexes and install packages
RUN apk update && \
apk add --no-cache \
# Basic dev tools
build-base \
binutils \
mold \
@@ -19,21 +18,13 @@ RUN apk update && \
git \
pkgconf \
ccache \
# Node.js + npm
nodejs \
npm \
# Misc
zip \
# Audio/Video dev libs
alsa-lib-dev \
pulseaudio-dev \
libudev-zero-dev \
# Wayland dev libs
wayland-dev \
wayland-protocols \
mesa-dev \
# Finally, the new SDL3 dev package on Alpine edge
sdl3
# (Optional) If you want a default working directory:
WORKDIR /workspace

View File

@@ -1,31 +1,32 @@
# Dockerfile.linux
FROM ubuntu:24.04
FROM ubuntu:plucky
RUN apt-get update && \
apt-get install -y --no-install-recommends \
libasound2-dev \
libpulse-dev \
libudev-dev \
libwayland-dev \
wayland-protocols \
libxkbcommon-dev \
libx11-dev \
libxext-dev \
libxrandr-dev \
libxcursor-dev \
libxi-dev \
libxinerama-dev \
libxss-dev \
libegl1-mesa-dev \
libgl1-mesa-dev \
cmake \
ninja-build \
git \
build-essential \
binutils \
mold \
meson \
pkg-config \
npm nodejs zip \
ccache && \
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 python3-pip \
libasound2-dev \
libpulse-dev \
libudev-dev \
libwayland-dev \
wayland-protocols \
libxkbcommon-dev \
libx11-dev \
libxext-dev \
libxrandr-dev \
libxcursor-dev \
libxi-dev \
libxinerama-dev \
libxss-dev \
libegl1-mesa-dev \
libgl1-mesa-dev \
cmake \
ninja-build \
git \
build-essential \
binutils \
mold \
pkg-config \
meson \
ccache \
mingw-w64 \
wine \
npm nodejs zip && \
rm -rf /var/lib/apt/lists/*

View File

@@ -1,5 +1,4 @@
# Dockerfile.windows-cross
FROM ubuntu:24.04
FROM ubuntu:plucky
RUN apt-get update && \
apt-get install -y --no-install-recommends \
@@ -10,8 +9,7 @@ RUN apt-get update && \
build-essential \
binutils \
pkg-config \
meson \
zip \
npm nodejs \
ccache && \
ccache \
npm nodejs && \
rm -rf /var/lib/apt/lists/*

View File

@@ -11,7 +11,6 @@ jobs:
build-linux:
runs-on: ubuntu-latest
container:
# Pull and run inside your prebuilt Docker image for Linux
image: gitea.pockle.world/john/prosperon/linux:latest
steps:
@@ -48,14 +47,27 @@ jobs:
- name: Build Prosperon (Linux)
run: |
export PKG_CONFIG_PATH="${PWD}/sdl3-build/installed_sdl3/lib/pkgconfig:$PKG_CONFIG_PATH"
meson setup build_dbg -Dbuildtype=debugoptimized
meson compile -C build_dbg
meson setup build -Dbuildtype=release -Db_lto=true -Db_ndebug=true
meson compile -C build
- name: Test Prosperon (Linux)
env:
TRACY_NO_INVARIANT_CHECK: 1
run: |
meson test --print-errorlogs -C build
- name: Upload Test Log (Linux)
if: ${{ always() }}
uses: actions/upload-artifact@v3
with:
name: testlog-linux
path: build/meson-logs/testlog.txt
- name: Create artifact folder (Linux)
if: ${{ github.event_name == 'release' && github.event.action == 'published' }}
run: |
mkdir _pack
cp build_dbg/prosperon _pack/
# Adjust wildcard if there's a versioned libSDL3. e.g. libSDL3-0.600.0.so
cp build/prosperon _pack/
cp sdl3-build/installed_sdl3/lib/libSDL3.so _pack/
- name: Upload Artifact (Linux)
@@ -68,8 +80,7 @@ jobs:
build-windows:
runs-on: ubuntu-latest
container:
# Pull and run inside your prebuilt Docker image for Windows cross-compilation
image: gitea.pockle.world/john/prosperon/mingw:latest
image: gitea.pockle.world/john/prosperon/linux:latest
steps:
- name: Check Out Code
@@ -112,13 +123,13 @@ jobs:
- name: Build Prosperon (Windows cross)
run: |
meson setup -Dbuildtype=debugoptimized --cross-file mingw32.cross build_win
meson compile -C build_win
meson setup build -Dbuildtype=release -Db_lto=true -Db_ndebug=true --cross-file mingw32.cross
meson compile -C build
- name: Create package folder
run: |
mkdir _pack
cp build_win/prosperon.exe _pack/
cp build/prosperon.exe _pack/
cp sdl3-build-win/installed_sdl3_win/bin/SDL3.dll _pack/
- name: Upload Artifact (Windows cross)

View File

@@ -151,9 +151,7 @@ core = custom_target('core.zip',
'cd ' + meson.project_source_root() +
' && echo "Rebuilding core.zip" && rm -f ' + meson.current_build_dir() + '/core.zip && ' +
'zip -r ' + meson.current_build_dir() + '/core.zip scripts fonts icons shaders'
],
build_always_stale: true,
build_by_default: true
]
)
prosperon_raw = executable('prosperon_raw', sources,
@@ -175,16 +173,36 @@ prosperon = custom_target('prosperon',
input: [prosperon_raw, core],
command: [
'sh', '-c',
'cat "$1" "$2" > "$3"',
'cat "$1" "$2" > "$3" && chmod +x "$3" >/dev/null 2>&1',
'concat',
'@INPUT0@',
'@INPUT1@',
'@OUTPUT@'
],
build_always: true,
build_by_default: true
build_always: true
)
prosperon_dep = declare_dependency(
link_with:prosperon
)
copy_tests = custom_target(
'copy_tests',
output: 'tests',
command: [
'cp', '-rf',
join_paths(meson.source_root(), 'tests'),
meson.build_root()
],
build_always: true
)
tests = [
'spawn_actor',
'empty'
]
foreach file : tests
test(file, prosperon, args:['tests/' + file + '.js'], depends:copy_tests)
endforeach

View File

@@ -14,4 +14,4 @@ cpu = 'x86_64'
endian = 'little'
[properties]
needs_exe_wrapper = false
needs_exe_wrapper = true

View File

@@ -1156,7 +1156,7 @@ var os = use_embed('os')
var js = use_embed('js')
prosperon.on('SIGINT', function() {
os.exit()
os.exit(1)
})
prosperon.on('SIGABRT', function() {
@@ -1218,7 +1218,6 @@ var script_fn = function script_fn(path) {
var file = resources.find_script(path)
if (!file) {
// attempt to bare load
parsed.module_ret = bare_load(path)
if (!parsed.module_ret) throw new Error(`Module ${path} could not be created`)
return parsed
@@ -1237,8 +1236,6 @@ var script_fn = function script_fn(path) {
if (parsed.module_ret === undefined || parsed.module_ret === null)
throw new Error(`Module ${module_name} must return a value`)
parsed.module_fn = module_fn
// console.log(`api for ${path}`)
// print_api(parsed.module_ret)
}
if (parsed.program) {
@@ -1265,6 +1262,7 @@ function console_rec(category, priority, line, file, msg) {
return `${file}:${line}: [${category} ${priority}]: ${msg}\n`
}
io.mkdir('.prosperon')
var logfile = io.open('.prosperon/log.txt')
function pprint(msg, lvl = 0) {

View File

@@ -1,6 +1,6 @@
var io = use('io')
var util = use('util')
var loop = use('loop')
var dumpfolder = ".prosperon";
@@ -24,51 +24,6 @@ Cmdline.register_order = function (order, fn, doc, usage = "") {
fn.usage = `${order} ${usage}`;
};
Cmdline.register_order(
"edit",
function () {
if (!io.exists(projectfile)) {
console.print("No game to edit. Try making one with 'prosperon init'.");
return;
}
},
"Edit the project in this folder. Give it the name of an UR to edit that specific object.",
"?UR?",
);
Cmdline.register_order(
"init",
function () {
if (io.exists(projectfile)) {
console.print("Already a game here.");
return;
}
io.mkdir(dumpfolder);
var project = {};
project.version = prosperon.version;
project.revision = prosperon.revision;
io.slurpwrite(projectfile, json.encode(project));
},
"Turn the directory into a Prosperon game.",
);
Cmdline.register_order(
"debug",
function () {
Cmdline.orders.play([]);
},
"Play the game with debugging enabled.",
);
Cmdline.register_order(
"web",
function () {
Cmdline.orders.play([]);
},
"Play the game in a web browser.",
);
Cmdline.register_order(
"makedoc",
function() {
@@ -115,12 +70,9 @@ for (var m of globals) {
"Make documentation."
})
Cmdline.register_order(
"play",
function (argv) {
var app
if (io.exists("main.js"))
app = actor.spawn("main.js", {}, function(underling, msg) {
function spawn_root(script)
{
return actor.spawn(script, {}, function(underling, msg) {
if (msg.message !== "created") return;
Object.defineProperty(underling, 'then', {
configurable:false,
@@ -130,72 +82,26 @@ Cmdline.register_order(
}
});
})
}
Cmdline.register_order(
"play",
function (argv) {
var app
if (io.exists("main.js"))
app = spawn_root("main.js")
else
app = actor.spawn("nogame.js");
app = spawn_root("nogame.js")
// rm actor so it can't be tampered
globalThis.actor = undefined
var ren = use('render')
var loop = use('loop')
while(1) loop.step();
},
"Play the game present in this folder.",
);
Cmdline.register_order(
"pack",
function (str) {
var packname;
if (str.length === 0) packname = "game.zip";
else if (str.length > 1) {
console.warn("Give me a single filename for the pack.");
return;
} else packname = str[0];
console.print(`Packing into ${packname}`);
io.pack_start(packname);
files = allfiles.filter(f => !f.startsWith(".git"));
files = files.filter(f => !f.startsWith(".nova"));
files = files.filter(f => !f.includes(".DS_Store"));
files = files.filter(f => !f.startsWith(".gitignore"));
console.print(files);
for (var f of files) io.pack_add(f);
io.pack_end();
},
"Pack the game into the given name.",
"NAME",
);
Cmdline.register_order(
"cdb",
function (argv) {
var cdb = "game.zip";
if (!io.exists(cdb)) {
console.print(`No 'game.zip' present.`);
return;
}
if (argv.length === 0) {
console.print(`cdb name: ${cdb}`);
}
},
"CDB commands.",
);
Cmdline.register_order(
"qoa",
function (argv) {
var sounds = Resources.sounds.filter(x => x !== "qoa");
for (var file of argv) {
if (!sounds.includes(file.ext())) continue;
console.print(`converting ${file}`);
io.save_qoa(file);
}
},
"Convert file(s) to qoa.",
);
Cmdline.register_order(
"about",
function (argv) {
@@ -213,92 +119,6 @@ Cmdline.register_order(
"Get information about this game.",
);
Cmdline.register_order(
"ur",
function (argv) {
// game.loadurs();
for (var i of ur._list.sort()) console.print(i);
},
"Get information about the ur types in your game.",
);
Cmdline.register_order(
"env",
function (argv) {
if (argv.length > 2) return;
var gg = json.decode(io.slurp(projectfile));
if (argv.length === 0) {
console.print(json.encode(gg, null, 1));
return;
}
if (argv.length === 1) {
var v = gg[argv[0]];
if (!v) {
console.print(`Value ${argv[0]} not found.`);
return;
}
console.print(`${argv[0]}:${v}`);
} else {
gg[argv[0]] = argv[1];
console.print(`Set ${argv[0]}:${v}`);
console.print(json.encode(gg, null, 1));
io.slurpwrite(projectfile, json.encode(gg));
}
},
"Get or set game variables.",
);
Cmdline.register_order(
"unpack",
function () {
console.print("Unpacking not implemented.");
},
"Unpack this binary's contents into this folder for editing.",
);
Cmdline.register_order(
"build",
function () {
console.print("Building not implemented.");
},
"Build static assets for this project.",
);
Cmdline.register_order(
"nota",
function (argv) {
for (var file of argv) {
if (!io.exists(file)) {
console.print(`File ${file} does not exist.`);
continue;
}
var obj = json.decode(io.slurp(file));
var nn = nota.encode(obj);
io.slurpwrite(file.strip_ext() + ".nota", nn);
}
},
"Create a nota file from a json.",
);
Cmdline.register_order(
"json",
function (argv) {
for (var file of argv) {
if (!io.exists(file)) {
console.print(`File ${file} does not exist.`);
continue;
}
console.print(file.ext());
var obj = nota.decode(io.slurp(file));
var nn = json.encode(obj);
io.slurpwrite(file.strip_ext() + ".json", nn);
}
},
"Create a JSON from a nota.",
);
Cmdline.register_order(
"api",
function (obj) {
@@ -330,8 +150,12 @@ Cmdline.register_order(
console.print("Need something to run.");
return;
}
console.print(eval(script));
try {
spawn_root(script)
} catch(e) {
console.error(e);
os.exit(1);
}
},
"Run a given script. SCRIPT can be the script itself, or a file containing the script",
"SCRIPT",
@@ -384,80 +208,12 @@ function cmd_args(cmds) {
cmds.shift()
if (cmds.length === 0) cmds[0] = "play";
else if (!Cmdline.orders[cmds[0]]) {
console.warn(`Command ${cmds[0]} not found. Playing instead.`);
cmds[0] = "play";
// assume it's a script
cmds[1] = cmds[0]
cmds[0] = "run"
}
Cmdline.orders[cmds[0]](cmds.slice(1));
}
Cmdline.register_order(
"clean",
function (argv) {
console.print("Cleaning not implemented.");
},
"Clean up a given object file.",
"JSON ...",
);
Cmdline.register_order(
"test",
function (argv) {
use("test.js");
},
"Run tests.",
);
Cmdline.register_cmd(
"l",
function (n) {
console.level = n;
},
"Set log level.",
);
function convertYAMLtoJSON(yamlString) {
const lines = yamlString.split("\n");
const jsonObj = {};
let currentKey = "";
let currentValue = "";
let currentDepth = 0;
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (!line || line.startsWith("#")) {
continue;
}
const depth = (line.match(/^\s+/g) || [""])[0].length;
const keyValue = line.split(":");
const key = keyValue[0].trim();
const value = keyValue[1].trim();
if (depth > currentDepth) {
jsonObj[currentKey] = convertYAMLtoJSON(currentValue);
currentKey = key;
currentValue = value;
} else if (depth === currentDepth) {
jsonObj[currentKey] = convertYAMLtoJSON(currentValue);
currentKey = key;
currentValue = value;
} else {
jsonObj[currentKey] = convertYAMLtoJSON(currentValue);
currentKey = "";
currentValue = "";
i--; // To reprocess the current line with updated values
}
currentDepth = depth;
}
if (currentKey) {
jsonObj[currentKey] = convertYAMLtoJSON(currentValue);
}
return jsonObj;
}
return cmd_args;

View File

@@ -93,15 +93,18 @@ if (!ret) {
int main(int argc, char **argv) {
prosperon = argv[0];
PHYSFS_init(argv[0]);
char *base = PHYSFS_getBaseDir();
PHYSFS_setWriteDir(base);
PHYSFS_mount(base, "/", 0);
prosperon_mount_core();
/* int mounted = PHYSFS_mount("core.zip", NULL, 0);
if (!mounted) {
printf("Could not mount core. Reason: %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
return 1;
}
*/
script_startup(argc, argv); // runs engine.js
return 0;
}

View File

@@ -31,16 +31,11 @@ JSValue on_exception = JS_UNDEFINED;
#define ENGINE "scripts/core/engine.js"
#ifndef NDEBUG
#define JS_EVAL_FLAGS JS_EVAL_FLAG_STRICT
#else
#define JS_EVAL_FLAGS JS_EVAL_FLAG_STRICT | JS_EVAL_FLAG_STRIP
#endif
#ifdef TRACY_ENABLE
#include <tracy/TracyC.h>
#if defined(__APPLE__)
#define MALLOC_OVERHEAD 0
#else
@@ -183,6 +178,7 @@ void script_startup(int argc, char **argv) {
void script_stop()
{
return;
JS_FreeContext(js);
JS_FreeRuntime(rt);
JS_FreeValue(js,on_exception);

1
tests/empty.js Normal file
View File

@@ -0,0 +1 @@
os.exit(1)

2
tests/spawn_actor.js Normal file
View File

@@ -0,0 +1,2 @@
this.spawn()
console.log("SPAWNED")