Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# MoonBit build artifacts
_build/
target/
.mooncakes/
.repos/
dist/
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ developer must perform them.
aligned with the actual examples.
- `proton/prebuilt/<platform>/`: shipped Proton-only native artifacts. Do not
put CEF runtime files here.
- `lib/`, `build/`, `_build/`, `target/`, `native/build*`, `native/dist/`:
generated or vendored artifacts.
- `lib/`, `build/`, `_build/`, `native/build*`, `native/dist/`: generated or
vendored artifacts. Packaged application artifacts are written to `dist/`.
- `.proton/`: generated project runtime cache created by `proton_cli cef setup`.

## Build And Test
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ default targets and output directory:
"role": "Editor"
}
],
"output": "target/proton-dist"
"output": "dist"
}
}
```
Expand All @@ -439,7 +439,7 @@ proton_cli package --release

The package command performs a debug build by default. Pass `--release` to use
MoonBit's release build mode, or `--no-build` to reuse an existing build from
the selected mode. Package output is written to `target/proton-dist` by default.
the selected mode. Package output is written to `dist` by default.
Icons, resources, output targets, signing, notarization, custom URL schemes, and
macOS document types are configured through `proton.project.json` and package command
options.
Expand Down
54 changes: 20 additions & 34 deletions cli/build_cmd/build_wbtest.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ async fn[T] expect_build_config_error(

///|
fn ensure_build_test_dir(path : String) -> Unit {
@mbfs.create_dir("target") catch {
_ => ()
}
@mbfs.create_dir(path) catch {
_ => ()
}
Expand Down Expand Up @@ -101,9 +98,9 @@ test "parse build args package and config" {
///|
test "parse build args accepts an isolated Moon target directory" {
let raw = parse_build_args([
"--package", "app", "--moon-target-dir", "target/build-app",
"--package", "app", "--moon-target-dir", "custom-build",
])
@debug.assert_eq(raw.moon_target_dir, Some("target/build-app"))
@debug.assert_eq(raw.moon_target_dir, Some("custom-build"))
}

///|
Expand Down Expand Up @@ -146,19 +143,18 @@ test "moon build args prepend an isolated target directory" {
moon_build_args_with_target_dir(
"app",
["--diagnostic-limit", "80"],
Some("target/build-app"),
Some("custom-build"),
),
[
"--target-dir", "target/build-app", "build", "app", "--diagnostic-limit", "80",
"--target-dir", "custom-build", "build", "app", "--diagnostic-limit", "80",
"--target", "native",
],
)
}

///|
async test "frontend path validation reports missing directory" {
let root = "target/proton-build-cwd"
ensure_build_test_dir(root)
let root = @async_fs.tmpdir(prefix="proton-build-cwd-")
let error = try
resolve_frontend_path(root, Some("missing"), "npm run build")
catch {
Expand All @@ -172,8 +168,7 @@ async test "frontend path validation reports missing directory" {

///|
async test "backend path supports nested directories with spaces" {
let root = "target/proton build backend"
ensure_build_test_dir(root)
let root = @async_fs.tmpdir(prefix="proton-build-backend-")
ensure_build_test_dir(@fsutil.path_join(root, "nested"))
ensure_build_test_dir(@fsutil.path_join(root, "nested/backend app"))
let path = resolve_backend_path(root, Some("nested/backend app"))
Expand All @@ -182,8 +177,7 @@ async test "backend path supports nested directories with spaces" {

///|
async test "build config discovery prefers package-local proton.project.json" {
let root = "target/proton-build-package-config"
ensure_build_test_dir(root)
let root = @async_fs.tmpdir(prefix="proton-build-config-")
ensure_build_test_dir(@fsutil.path_join(root, "desktop"))
let package_config = @fsutil.path_join(
@fsutil.path_join(root, "desktop"),
Expand All @@ -201,9 +195,8 @@ async test "build config discovery prefers package-local proton.project.json" {
///|
async test "resolve path accepts Windows backslash relative input" {
if @path.sep == '\\' {
let dir = "target/proton-build-path"
ensure_build_test_dir(dir)
let resolved = @fsutil.resolve_path(".", "target\\proton-build-path")
let dir = @async_fs.tmpdir(prefix="proton-build-path-")
let resolved = @fsutil.resolve_path(".", dir.replace_all(old="/", new="\\"))
assert_true(resolved.contains(":/") || resolved.contains(":\\"))
assert_true(@fsutil.path_exists(resolved))
let absolute = resolved.replace_all(old="/", new="\\")
Expand All @@ -213,8 +206,7 @@ async test "resolve path accepts Windows backslash relative input" {

///|
async test "project config validation rejects unknown top-level fields" {
let dir = "target/proton-build-config"
ensure_build_test_dir(dir)
let dir = @async_fs.tmpdir(prefix="proton-build-config-")
let path = @fsutil.path_join(dir, "unknown.proton.project.json")
write_build_test_file(path, build_config_with("legacy_runtime", true))
let error = expect_build_config_error(() => read_project_config(path))
Expand All @@ -231,8 +223,7 @@ async test "project config validation rejects unknown top-level fields" {

///|
async test "project config validation requires window" {
let dir = "target/proton-build-config"
ensure_build_test_dir(dir)
let dir = @async_fs.tmpdir(prefix="proton-build-config-")
let path = @fsutil.path_join(dir, "missing-window.proton.project.json")
write_build_test_file(
path,
Expand All @@ -259,8 +250,7 @@ async test "project config validation requires window" {

///|
async test "project config validation rejects unsupported size_hint" {
let dir = "target/proton-build-config"
ensure_build_test_dir(dir)
let dir = @async_fs.tmpdir(prefix="proton-build-config-")
let path = @fsutil.path_join(dir, "bad-size-hint.proton.project.json")
write_build_test_file(
path,
Expand Down Expand Up @@ -294,18 +284,18 @@ async test "project config validation rejects unsupported size_hint" {

///|
async test "project config parsing keeps active bundle metadata out of build validation" {
let dir = "target/proton-build-config"
ensure_build_test_dir(dir)
let dir = @async_fs.tmpdir(prefix="proton-build-config-")
let path = @fsutil.path_join(dir, "active-bundle.proton.project.json")
write_build_test_file(path, build_config_with("bundle", { "active": true }))
ignore(read_project_config(path))
}

///|
async test "production entry validation requires file-backed entry" {
let dir = @async_fs.tmpdir(prefix="proton-build-entry-")
let error = try
validate_production_entry_file(
@proton_config.ProjectEntry::Asset("target/proton-build-missing.html"),
@proton_config.ProjectEntry::Asset(@fsutil.path_join(dir, "missing.html")),
)
catch {
BuildPathError::Missing(..) as error => error.message()
Expand All @@ -314,8 +304,6 @@ async test "production entry validation requires file-backed entry" {
_ => fail("expected build error")
}
assert_true(error.contains("production entry does not exist"))
let dir = "target/proton-build-entry"
ensure_build_test_dir(dir)
let file = @fsutil.path_join(dir, "index.html")
@mbfs.write_string_to_file(file, "<!doctype html>", encoding="utf8") catch {
err => abort(@debug.render(Repr(err)))
Expand All @@ -325,8 +313,7 @@ async test "production entry validation requires file-backed entry" {

///|
async test "release validation checks secondary window entry files" {
let dir = "target/proton-build-secondary-entry"
ensure_build_test_dir(dir)
let dir = @async_fs.tmpdir(prefix="proton-build-secondary-")
let main = @fsutil.path_join(dir, "main.html")
let missing = @fsutil.path_join(dir, "secondary/missing.html")
write_build_test_file(main, "<!doctype html>")
Expand Down Expand Up @@ -354,7 +341,7 @@ async test "release validation checks secondary window entry files" {
test "frontend release rejects url production entry" {
let frontend = Some(
@proton_config.ProjectFrontendConfig::new(
dist=Some("target/proton-build-entry"),
dist=Some("fixtures/frontend-dist"),
),
)
let error = expect_build_error_message(() => {
Expand All @@ -374,7 +361,7 @@ test "frontend release config preflight rejects url entry" {
backend: None,
frontend: Some(
@proton_config.ProjectFrontendConfig::new(
dist=Some("target/proton-build-entry"),
dist=Some("fixtures/frontend-dist"),
),
),
}
Expand All @@ -387,7 +374,7 @@ test "frontend release requires dist" {
let config = BuildProjectConfig::{
base_dir: ".",
entries: [
@proton_config.ProjectEntry::Asset("target/proton-build-entry/index.html"),
@proton_config.ProjectEntry::Asset("fixtures/frontend-dist/index.html"),
],
backend: None,
frontend: Some(
Expand All @@ -402,8 +389,7 @@ test "frontend release requires dist" {

///|
async test "production entry validation rejects directories" {
let dir = "target/proton-build-entry-dir"
ensure_build_test_dir(dir)
let dir = @async_fs.tmpdir(prefix="proton-build-entry-dir-")
let error = try
validate_production_entry_file(@proton_config.ProjectEntry::Asset(dir))
catch {
Expand Down
11 changes: 5 additions & 6 deletions cli/cef/cef_platform_wbtest.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ test "runtime manifests separate portable and active metadata" {

///|
test "CEF cache paths are absolute and scoped by platform and archive" {
let project_root = @fsutil.resolve_path(".", "target/proton-cache-project")
let project_root = @fsutil.resolve_path(".", "fixtures/proton-cache-project")
let home = @fsutil.resolve_path(project_root, "../proton-cache-home")
let cache_root = resolve_global_cef_cache_root(
project_root~,
Expand All @@ -97,7 +97,7 @@ test "CEF cache paths are absolute and scoped by platform and archive" {

///|
test "relative CEF cache overrides resolve from the project root" {
let project_root = @fsutil.resolve_path(".", "target/proton-cache-project")
let project_root = @fsutil.resolve_path(".", "fixtures/proton-cache-project")
let actual = resolve_global_cef_cache_root(
project_root~,
configured_root=Some("../shared-cef"),
Expand All @@ -116,10 +116,9 @@ test "relative CEF cache overrides resolve from the project root" {

///|
async test "runtime metadata does not persist the active CEF cache path" {
let root = @fsutil.resolve_path(".", "target/proton-runtime-manifest")
let root = @async_fs.tmpdir(prefix="proton-runtime-manifest-")
let proton_dir = @fsutil.path_join(root, ".proton")
let runtime_dir = @fsutil.path_join(proton_dir, "runtime")
remove_tree(root)
ensure_dir(runtime_dir)
let cef_root = @fsutil.resolve_path(
root, "../shared-cef/darwin-arm64/cef-test",
Expand Down Expand Up @@ -306,8 +305,8 @@ test "generated runtime directories must stay under the project root" {

///|
test "CEF installation never removes a project boundary or filesystem root" {
let root = @fsutil.resolve_path(".", "target/proton-cef-project")
let cache = @fsutil.resolve_path(".", "target/proton-cef-cache/runtime")
let root = @fsutil.resolve_path(".", "fixtures/proton-cef-project")
let cache = @fsutil.resolve_path(".", "fixtures/proton-cef-cache/runtime")
assert_safe_install_dir(cache, root)
let parent = @fsutil.path_parent(root)
let mut filesystem_root = root
Expand Down
38 changes: 14 additions & 24 deletions cli/dev/dev_wbtest.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ fn parse_dev_args(args : Array[String]) -> RawDevOptions raise {

///|
fn ensure_dev_test_dir(path : String) -> Unit {
@mbfs.create_dir("target") catch {
_ => ()
}
@mbfs.create_dir(path) catch {
_ => ()
}
Expand Down Expand Up @@ -79,15 +76,14 @@ test "parse dev args package and frontend overrides" {
///|
test "parse dev args accepts an isolated Moon target directory" {
let raw = parse_dev_args([
"--package", "desktop", "--moon-target-dir", "target/dev-app",
"--package", "desktop", "--moon-target-dir", "custom-dev-build",
])
@debug.assert_eq(raw.moon_target_dir, Some("target/dev-app"))
@debug.assert_eq(raw.moon_target_dir, Some("custom-dev-build"))
}

///|
async test "read dev project config extracts module paths" {
let dir = "target/proton-dev-config"
ensure_dev_test_dir(dir)
let dir = @async_fs.tmpdir(prefix="proton-dev-config-")
let path = @fsutil.path_join(dir, "proton.project.json")
@mbfs.write_string_to_file(
path,
Expand Down Expand Up @@ -129,8 +125,7 @@ async test "read dev project config extracts module paths" {

///|
async test "read dev frontend config validates full project config" {
let dir = "target/proton-dev-config"
ensure_dev_test_dir(dir)
let dir = @async_fs.tmpdir(prefix="proton-dev-config-")
let path = @fsutil.path_join(dir, "bad-size-hint.proton.project.json")
@mbfs.write_string_to_file(
path,
Expand Down Expand Up @@ -171,8 +166,7 @@ async test "read dev frontend config validates full project config" {

///|
async test "frontend path is validated only when frontend starts" {
let root = "target/proton-dev-cwd"
ensure_dev_test_dir(root)
let root = @async_fs.tmpdir(prefix="proton-dev-cwd-")
ensure_dev_test_dir(@fsutil.path_join(root, "frontend"))
let resolved = resolve_frontend_path(
root,
Expand Down Expand Up @@ -206,8 +200,7 @@ async test "frontend path is validated only when frontend starts" {

///|
async test "dev config discovery prefers package-local proton.project.json" {
let root = "target/proton-dev-package-config"
ensure_dev_test_dir(root)
let root = @async_fs.tmpdir(prefix="proton-dev-config-")
ensure_dev_test_dir(@fsutil.path_join(root, "desktop"))
let package_config = @fsutil.path_join(
@fsutil.path_join(root, "desktop"),
Expand All @@ -226,9 +219,8 @@ async test "dev config discovery prefers package-local proton.project.json" {

///|
async test "backend path supports nested directories with spaces" {
let root = "target/proton dev backend"
let root = @async_fs.tmpdir(prefix="proton-dev-backend-")
let backend = @fsutil.path_join(root, "modules/backend app")
ensure_dev_test_dir(root)
ensure_dev_test_dir(@fsutil.path_join(root, "modules"))
ensure_dev_test_dir(backend)
let resolved = resolve_backend_path(root, Some("modules/backend app"))
Expand All @@ -237,7 +229,7 @@ async test "backend path supports nested directories with spaces" {

///|
async test "dev runtime layout validates helper" {
let root = "target/proton-dev-runtime-layout"
let root = @async_fs.tmpdir(prefix="proton-dev-runtime-")
let runtime = create_fake_dev_runtime(root)
let loaded = dev_runtime_from_root(
@fsutil.resolve_path(".", runtime),
Expand Down Expand Up @@ -277,7 +269,7 @@ async test "dev runtime layout validates helper" {

///|
async test "dev process preloads an indirect Linux CEF runtime" {
let root = "target/proton-dev-runtime-preload"
let root = @async_fs.tmpdir(prefix="proton-dev-preload-")
let runtime_path = create_fake_dev_runtime(root)
let runtime = dev_runtime_from_root(
@fsutil.resolve_path(".", runtime_path),
Expand Down Expand Up @@ -377,7 +369,7 @@ test "dev app spawn env replaces inherited Windows variable spellings" {

///|
async test "read dev runtime honors PROTON_NATIVE_DIST override" {
let root = "target/proton-dev-runtime-env"
let root = @async_fs.tmpdir(prefix="proton-dev-runtime-env-")
let runtime = create_fake_dev_runtime(root)
let previous = @env.get_env_var("PROTON_NATIVE_DIST")
defer (match previous {
Expand All @@ -396,7 +388,7 @@ async test "read dev runtime honors PROTON_NATIVE_DIST override" {
@fsutil.path_join(loaded.bin_dir, helper_executable_name()),
),
)
let bad_root = "target/proton-dev-runtime-bad-env"
let bad_root = @fsutil.path_join(root, "bad")
ensure_dev_test_dir(bad_root)
@env.set_env_var("PROTON_NATIVE_DIST", "missing-runtime")
try ensure_dev_runtime(@fsutil.resolve_path(".", bad_root), true) catch {
Expand All @@ -413,9 +405,8 @@ async test "read dev runtime honors PROTON_NATIVE_DIST override" {
///|
async test "resolve path accepts Windows backslash relative input" {
if @path.sep == '\\' {
let dir = "target/proton-dev-path"
ensure_dev_test_dir(dir)
let resolved = @fsutil.resolve_path(".", "target\\proton-dev-path")
let dir = @async_fs.tmpdir(prefix="proton-dev-path-")
let resolved = @fsutil.resolve_path(".", dir.replace_all(old="/", new="\\"))
assert_true(resolved.contains(":/") || resolved.contains(":\\"))
assert_true(@fsutil.path_exists(resolved))
let absolute = resolved.replace_all(old="/", new="\\")
Expand Down Expand Up @@ -510,8 +501,7 @@ async test "ready path validates curl probe availability" {
///|
#cfg(not(platform="windows"))
async test "frontend cancellation terminates child processes" {
let dir = "target/proton-dev-cancel-tree"
ensure_dev_test_dir(dir)
let dir = @async_fs.tmpdir(prefix="proton-dev-cancel-")
let pid_path = @fsutil.path_join(dir, "child.pid")
@mbfs.remove_file(pid_path) catch {
_ => ()
Expand Down
Loading
Loading