pub const CLI_COMMIT: &str = env!("WATERUI_CLI_COMMIT");
pub const WATERUI_VERSION: &str = env!("WATERUI_CLI_WATERUI_VERSION");
pub const WATERUI_CORE_VERSION: &str = env!("WATERUI_CLI_WATERUI_CORE_VERSION");
pub const WATERUI_FFI_VERSION: &str = env!("WATERUI_CLI_WATERUI_FFI_VERSION");
pub const HYDROLYSIS_VERSION: &str = env!("WATERUI_CLI_HYDROLYSIS_VERSION");
pub const HYDROLYSIS_M3_VERSION: &str = env!("WATERUI_CLI_HYDROLYSIS_M3_VERSION");
pub const DEW_VERSION: &str = env!("WATERUI_CLI_WATERUI_DEW_VERSION");
pub const GTK_BACKEND_VERSION: &str = env!("WATERUI_CLI_WATERUI_GTK_VERSION");
pub const WATERUI_BROWSER_CEF_VERSION: &str = env!("WATERUI_CLI_WATERUI_BROWSER_CEF_VERSION");
pub const PREVIEW_VERSION: &str = env!("WATERUI_CLI_WATERUI_PREVIEW_VERSION");
pub const PREVIEW_PROTOCOL_VERSION: &str = env!("WATERUI_CLI_WATERUI_PREVIEW_PROTOCOL_VERSION");
pub const ANDROID_KOTLIN_VERSION: &str = env!("WATERUI_CLI_ANDROID_KOTLIN_VERSION");
pub const APPLE_BACKEND_URL: &str = env!("WATERUI_CLI_APPLE_BACKEND_URL");
pub const APPLE_BACKEND_COMMIT: &str = env!("WATERUI_CLI_APPLE_BACKEND_COMMIT");
pub const ANDROID_BACKEND_URL: &str = env!("WATERUI_CLI_ANDROID_BACKEND_URL");
pub const ANDROID_BACKEND_COMMIT: &str = env!("WATERUI_CLI_ANDROID_BACKEND_COMMIT");
const BUILD_KIND: &str = env!("WATERUI_CLI_BUILD_KIND");
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BackendReference {
pub repository_url: &'static str,
pub commit: &'static str,
}
pub const APPLE_BACKEND: BackendReference = BackendReference {
repository_url: APPLE_BACKEND_URL,
commit: APPLE_BACKEND_COMMIT,
};
pub const ANDROID_BACKEND: BackendReference = BackendReference {
repository_url: ANDROID_BACKEND_URL,
commit: ANDROID_BACKEND_COMMIT,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BuildKind {
DevBranch,
Release,
}
#[must_use]
pub fn build_kind() -> BuildKind {
match BUILD_KIND {
"dev-branch" => BuildKind::DevBranch,
"release" => BuildKind::Release,
other => panic!("invalid WATERUI_CLI_BUILD_KIND: {other}"),
}
}
#[cfg(test)]
mod tests {
use std::{fs, path::Path, process::Command};
use toml::Value;
fn manifest_value(path: &Path) -> Value {
let contents = fs::read_to_string(path)
.unwrap_or_else(|error| panic!("failed to read {}: {error}", path.display()));
toml::from_str::<Value>(&contents)
.unwrap_or_else(|error| panic!("failed to parse {}: {error}", path.display()))
}
fn package_version(path: &Path) -> String {
manifest_value(path)["package"]["version"]
.as_str()
.unwrap_or_else(|| panic!("missing package.version in {}", path.display()))
.to_string()
}
fn git_output(repo_root: &Path, args: &[&str]) -> String {
let output = Command::new("git")
.current_dir(repo_root)
.args(args)
.output()
.unwrap_or_else(|error| panic!("failed to run git {args:?}: {error}"));
assert!(
output.status.success(),
"git {args:?} failed in {}",
repo_root.display()
);
String::from_utf8(output.stdout)
.unwrap_or_else(|error| panic!("git {args:?} returned non-utf8 output: {error}"))
.trim()
.to_string()
}
fn manifest_backend_field<'a>(cli_manifest: &'a Value, field: &str) -> &'a str {
cli_manifest["package"]["metadata"]["waterui-scaffold"][field]
.as_str()
.unwrap_or_else(|| panic!("missing package.metadata.waterui-scaffold.{field}"))
}
fn manifest_scaffold_field<'a>(cli_manifest: &'a Value, field: &str) -> &'a str {
cli_manifest["package"]["metadata"]["waterui-scaffold"][field]
.as_str()
.unwrap_or_else(|| panic!("missing package.metadata.waterui-scaffold.{field}"))
}
#[test]
fn fallback_release_versions_match_workspace_versions() {
let cli_manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let workspace_root = cli_manifest_dir
.parent()
.expect("cli crate should live under workspace root");
let cli_manifest = manifest_value(&cli_manifest_dir.join("Cargo.toml"));
let scaffold_metadata = &cli_manifest["package"]["metadata"]["waterui-scaffold"];
assert_eq!(
scaffold_metadata["waterui-version"]
.as_str()
.expect("missing package.metadata.waterui-scaffold.waterui-version"),
package_version(&workspace_root.join("Cargo.toml")),
);
assert_eq!(
scaffold_metadata["waterui-ffi-version"]
.as_str()
.expect("missing package.metadata.waterui-scaffold.waterui-ffi-version"),
package_version(&workspace_root.join("ffi/Cargo.toml")),
);
assert_eq!(
manifest_scaffold_field(&cli_manifest, "waterui-core-version"),
package_version(&workspace_root.join("core/Cargo.toml")),
);
assert_eq!(
scaffold_metadata["hydrolysis-version"]
.as_str()
.expect("missing package.metadata.waterui-scaffold.hydrolysis-version"),
package_version(&workspace_root.join("backends/hydrolysis/Cargo.toml")),
);
assert_eq!(
manifest_scaffold_field(&cli_manifest, "hydrolysis-m3-version"),
package_version(&workspace_root.join("backends/hydrolysis_m3/Cargo.toml")),
);
assert_eq!(
manifest_scaffold_field(&cli_manifest, "waterui-dew-version"),
package_version(&workspace_root.join("backends/dew/Cargo.toml")),
);
assert_eq!(
manifest_scaffold_field(&cli_manifest, "waterui-gtk-version"),
package_version(&workspace_root.join("backends/gtk/Cargo.toml")),
);
assert_eq!(
manifest_scaffold_field(&cli_manifest, "waterui-browser-cef-version"),
package_version(&workspace_root.join("components/platform/browser-cef/Cargo.toml")),
);
assert_eq!(
manifest_scaffold_field(&cli_manifest, "waterui-preview-version"),
package_version(&workspace_root.join("components/devtools/preview/runtime/Cargo.toml"))
);
assert_eq!(
manifest_scaffold_field(&cli_manifest, "waterui-preview-protocol-version"),
package_version(
&workspace_root.join("components/devtools/preview/protocol/Cargo.toml")
)
);
assert_eq!(
manifest_scaffold_field(&cli_manifest, "android-kotlin-version"),
super::ANDROID_KOTLIN_VERSION,
);
}
#[test]
fn fallback_release_backend_refs_match_workspace_backend_refs() {
let cli_manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let workspace_root = cli_manifest_dir
.parent()
.expect("cli crate should live under workspace root");
let cli_manifest = manifest_value(&cli_manifest_dir.join("Cargo.toml"));
for (backend, submodule) in [("apple", "backends/apple"), ("android", "backends/android")] {
let commit_field = format!("{backend}-backend-commit");
let pinned = manifest_backend_field(&cli_manifest, &commit_field);
let actual = git_output(&workspace_root.join(submodule), &["rev-parse", "HEAD"]);
assert_eq!(
pinned, actual,
"cli/Cargo.toml `{commit_field}` is stale. \
Set `{commit_field} = \"{actual}\"` under [package.metadata.waterui-scaffold]; \
a released CLI scaffolds against the pinned commit, not the submodule."
);
let url_field = format!("{backend}-backend-url");
assert_eq!(
manifest_backend_field(&cli_manifest, &url_field),
git_output(
workspace_root,
&[
"config",
"-f",
".gitmodules",
"--get",
&format!("submodule.{submodule}.url"),
],
),
"cli/Cargo.toml `{url_field}` disagrees with .gitmodules",
);
}
}
}