updated README and a bunch of other stuff
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
cargo-features = ["profile-rustflags"]
|
||||
|
||||
[package]
|
||||
name = "mize-part-dev"
|
||||
name = "mize-part-mize-dev"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
|
||||
@@ -91,7 +91,13 @@ fn generate_part_struct(out: &mut String, meta: &PartMetadata) {
|
||||
let _ = writeln!(out);
|
||||
|
||||
// part methods (skip ones that belong to include_native)
|
||||
for m in meta.methods.iter().chain(meta.effects.iter()).chain(meta.threads.iter()) {
|
||||
for m in meta
|
||||
.methods
|
||||
.iter()
|
||||
.chain(meta.effects.iter())
|
||||
.chain(meta.applies.iter())
|
||||
.chain(meta.threads.iter())
|
||||
{
|
||||
if native_fns.contains(&m.name) {
|
||||
continue;
|
||||
}
|
||||
@@ -466,7 +472,12 @@ pub fn extract_mize_dependency(cargo_toml: &str) -> Result<String, String> {
|
||||
///
|
||||
/// `mize_dep` is the full assignment line copied from the part Cargo.toml,
|
||||
/// e.g. `mize = { workspace = true }` or `mize = { path = "../../core" }`.
|
||||
pub fn generate_cargo_toml(package_name: &str, mize_dep: &str) -> String {
|
||||
pub fn generate_cargo_toml(package_name: &str, mize_dep: &str, spacetime_sdk: bool) -> String {
|
||||
let spacetime_dep = if spacetime_sdk {
|
||||
"spacetimedb-sdk = \"2.6.0\"\n"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
format!(
|
||||
r#"[package]
|
||||
name = "{package_name}"
|
||||
@@ -479,9 +490,10 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
{mize_dep}
|
||||
"#,
|
||||
{spacetime_dep}"#,
|
||||
package_name = package_name,
|
||||
lib_name = package_name.replace('-', "_"),
|
||||
mize_dep = mize_dep.trim(),
|
||||
spacetime_dep = spacetime_dep,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
use std::fs::{create_dir_all, write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use mize::prelude::*;
|
||||
use cmd_lib::run_cmd as sh;
|
||||
use mize::tracing::info;
|
||||
use mize::tracing::debug;
|
||||
use mize::platform::os::{
|
||||
cargo_package_version, get_part_hash, part_dist_artifact_name, parts_dist_cd,
|
||||
};
|
||||
|
||||
// a static version of what would be generated.
|
||||
// as we need mize.dev to generate anything.
|
||||
@@ -10,8 +14,6 @@ mod generated;
|
||||
mod codegen;
|
||||
use generated::*;
|
||||
|
||||
// spacetime gen command: sh!(RUST_LOG=error RUST_BACKTRACE=0 spacetime generate --build-options="--lint-dir=" -p $SRC/mize/marts/spacetime -o $SRC/mize/marts/generated/src/spacetime --lang rust)?;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
extern "C" fn part_dev() -> MizeResult<()> {
|
||||
let cli = generated::CliPart::get("cli")?;
|
||||
@@ -26,20 +28,245 @@ extern "C" fn part_dev() -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct PartToPublish {
|
||||
/// Runtime part id (e.g. `dev`, `auth.client`, `mize`)
|
||||
id: String,
|
||||
/// Directory containing Cargo.toml (None for the special `mize` core part)
|
||||
dir: Option<PathBuf>,
|
||||
version: String,
|
||||
}
|
||||
|
||||
fn dylib_ext(target: &str) -> &'static str {
|
||||
if target.contains("windows") {
|
||||
"dll"
|
||||
} else if target.contains("apple") || target.contains("darwin") {
|
||||
"dylib"
|
||||
} else {
|
||||
"so"
|
||||
}
|
||||
}
|
||||
|
||||
fn part_lib_filename(part_id: &str, target: &str) -> String {
|
||||
let sym = part_id.replace('.', "_");
|
||||
let ext = dylib_ext(target);
|
||||
if target.contains("windows") {
|
||||
format!("mize_part_{sym}.{ext}")
|
||||
} else {
|
||||
format!("libmize_part_{sym}.{ext}")
|
||||
}
|
||||
}
|
||||
|
||||
fn mize_lib_filename(target: &str) -> String {
|
||||
let ext = dylib_ext(target);
|
||||
if target.contains("windows") {
|
||||
format!("mize.{ext}")
|
||||
} else {
|
||||
format!("libmize.{ext}")
|
||||
}
|
||||
}
|
||||
|
||||
fn mize_bin_filename(target: &str) -> String {
|
||||
if target.contains("windows") {
|
||||
"mize.exe".to_owned()
|
||||
} else {
|
||||
"mize".to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
fn release_dir(mize_src: &str, target: &str) -> PathBuf {
|
||||
PathBuf::from(mize_src)
|
||||
.join("target")
|
||||
.join(target)
|
||||
.join("release")
|
||||
}
|
||||
|
||||
fn resolve_part_id(dir: &Path) -> MizeResult<String> {
|
||||
let part_file = dir.join("part");
|
||||
if part_file.exists() {
|
||||
let toml = std::fs::read_to_string(&part_file)
|
||||
.map_err(|e| mize_err!("could not read {}: {e}", part_file.display()))?;
|
||||
let data = ItemData::from_toml(&toml)?;
|
||||
if let Ok(id) = data.get_path("id").and_then(|v| v.value_string()) {
|
||||
if !id.is_empty() {
|
||||
return Ok(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let cargo_path = dir.join("Cargo.toml");
|
||||
let cargo = std::fs::read_to_string(&cargo_path)
|
||||
.map_err(|e| mize_err!("could not read {}: {e}", cargo_path.display()))?;
|
||||
let data = ItemData::from_toml(&cargo)?;
|
||||
if let Ok(lib_name) = data.get_path("lib.name").and_then(|v| v.value_string()) {
|
||||
if let Some(rest) = lib_name.strip_prefix("mize_part_") {
|
||||
return Ok(rest.replace('_', "."));
|
||||
}
|
||||
}
|
||||
dir.file_name()
|
||||
.and_then(|s| s.to_str())
|
||||
.map(|s| s.to_owned())
|
||||
.ok_or_else(|| mize_err!("could not resolve part id for {}", dir.display()))
|
||||
}
|
||||
|
||||
fn collect_parts_to_publish(mize: &mut Mize, mize_src: &str) -> MizeResult<Vec<PartToPublish>> {
|
||||
let mut out = Vec::new();
|
||||
|
||||
// Special core part "mize"
|
||||
let mize_version = cargo_package_version(&format!("{mize_src}/core/Cargo.toml"))?;
|
||||
out.push(PartToPublish {
|
||||
id: "mize".to_owned(),
|
||||
dir: None,
|
||||
version: mize_version.clone(),
|
||||
});
|
||||
|
||||
let workspaces = match mize.get_config("parts.workspaces") {
|
||||
Ok(data) => data,
|
||||
Err(_) => {
|
||||
info!("parts.workspaces not set; only publishing special part 'mize'");
|
||||
return Ok(out);
|
||||
}
|
||||
};
|
||||
let arr = workspaces
|
||||
.cbor()
|
||||
.as_array()
|
||||
.ok_or_else(|| mize_err!("parts.workspaces must be an array of directory paths"))?;
|
||||
|
||||
for src in arr {
|
||||
let dir_str = src
|
||||
.as_text()
|
||||
.ok_or_else(|| mize_err!("parts.workspaces entries must be strings"))?;
|
||||
let dir = PathBuf::from(dir_str);
|
||||
if !dir.is_dir() {
|
||||
info!("parts.workspaces entry is not a directory, skipping: {dir_str}");
|
||||
continue;
|
||||
}
|
||||
let entries = std::fs::read_dir(&dir)
|
||||
.map_err(|e| mize_err!("could not read parts.workspaces dir {dir_str}: {e}"))?;
|
||||
for entry in entries {
|
||||
let entry = entry.map_err(|e| mize_err!("read_dir error in {dir_str}: {e}"))?;
|
||||
let path = entry.path();
|
||||
if !path.is_dir() {
|
||||
continue;
|
||||
}
|
||||
let cargo = path.join("Cargo.toml");
|
||||
if !cargo.exists() {
|
||||
debug!("skipping {} (no Cargo.toml)", path.display());
|
||||
continue;
|
||||
}
|
||||
let id = resolve_part_id(&path)?;
|
||||
let version = cargo_package_version(cargo.to_str().unwrap())?;
|
||||
out.push(PartToPublish {
|
||||
id,
|
||||
dir: Some(path),
|
||||
version,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn pack_and_upload_part(
|
||||
mize: &mut Mize,
|
||||
mize_src: &str,
|
||||
target: &str,
|
||||
part: &PartToPublish,
|
||||
mize_version: &str,
|
||||
) -> MizeResult<()> {
|
||||
let rel = release_dir(mize_src, target);
|
||||
let tmp = std::env::var("TMP").unwrap_or_else(|_| "/tmp".to_owned());
|
||||
let staging = PathBuf::from(&tmp).join(format!("mize-dist-{}-{}", part.id, target));
|
||||
if staging.exists() {
|
||||
std::fs::remove_dir_all(&staging)
|
||||
.map_err(|e| mize_err!("could not clear staging {}: {e}", staging.display()))?;
|
||||
}
|
||||
let lib_dir = staging.join("lib");
|
||||
create_dir_all(&lib_dir)
|
||||
.map_err(|e| mize_err!("could not create {}: {e}", lib_dir.display()))?;
|
||||
|
||||
if part.id == "mize" {
|
||||
let lib_name = mize_lib_filename(target);
|
||||
let bin_name = mize_bin_filename(target);
|
||||
let lib_src = rel.join(&lib_name);
|
||||
let bin_src = rel.join(&bin_name);
|
||||
if !lib_src.exists() {
|
||||
return Err(mize_err!("missing built artifact {}", lib_src.display()));
|
||||
}
|
||||
if !bin_src.exists() {
|
||||
return Err(mize_err!("missing built artifact {}", bin_src.display()));
|
||||
}
|
||||
std::fs::copy(&lib_src, lib_dir.join(&lib_name))
|
||||
.map_err(|e| mize_err!("copy {}: {e}", lib_src.display()))?;
|
||||
let bin_dir = staging.join("bin");
|
||||
create_dir_all(&bin_dir)?;
|
||||
std::fs::copy(&bin_src, bin_dir.join(&bin_name))
|
||||
.map_err(|e| mize_err!("copy {}: {e}", bin_src.display()))?;
|
||||
} else {
|
||||
let lib_name = part_lib_filename(&part.id, target);
|
||||
let lib_src = rel.join(&lib_name);
|
||||
if !lib_src.exists() {
|
||||
info!(
|
||||
"skipping part '{}': missing {} (not built for this target?)",
|
||||
part.id,
|
||||
lib_src.display()
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
// Archive always uses the fetch_part layout: lib/libmize_part_<sym>.so
|
||||
// For non-linux targets keep the native filename inside lib/.
|
||||
let dest_name = if dylib_ext(target) == "so" {
|
||||
format!("libmize_part_{}.so", part.id.replace('.', "_"))
|
||||
} else {
|
||||
lib_name.clone()
|
||||
};
|
||||
std::fs::copy(&lib_src, lib_dir.join(&dest_name))
|
||||
.map_err(|e| mize_err!("copy {}: {e}", lib_src.display()))?;
|
||||
}
|
||||
|
||||
let mut hash_opts = ItemData::new();
|
||||
hash_opts.set_path("system", target)?;
|
||||
hash_opts.set_path("mize_version", mize_version)?;
|
||||
let (hash, selector) = get_part_hash(mize, &part.id, hash_opts)?;
|
||||
debug!("part {} selector: {}", part.id, selector);
|
||||
|
||||
let cd = parts_dist_cd(mize);
|
||||
let artifact = part_dist_artifact_name(&hash, &part.id, &part.version, cd);
|
||||
let archive_path = PathBuf::from(&tmp).join(&artifact);
|
||||
|
||||
let staging_str = staging.to_string_lossy().to_string();
|
||||
let archive_str = archive_path.to_string_lossy().to_string();
|
||||
sh!(tar -C $staging_str -czf $archive_str .)?;
|
||||
|
||||
info!("uploading {artifact} -> ocib:host/mize-dist/");
|
||||
sh!(rsync -av $archive_str ocib:host/mize-dist/)?;
|
||||
|
||||
let _ = std::fs::remove_dir_all(&staging);
|
||||
let _ = std::fs::remove_file(&archive_path);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn publish_mize(_ : ArgMatches) -> MizeResult<()> {
|
||||
let mut mize = get_global_mize()?;
|
||||
let mize_src = mize.get_config("mize.src")?.value_string()?;
|
||||
let cargo_dir = std::env::home_dir().unwrap().join(".cargo");
|
||||
let mize_version = cargo_package_version(&format!("{mize_src}/core/Cargo.toml"))?;
|
||||
let parts = collect_parts_to_publish(&mut mize, &mize_src)?;
|
||||
info!(
|
||||
"publishing {} part(s) (mize_version={mize_version}, cd={})",
|
||||
parts.len(),
|
||||
parts_dist_cd(&mut mize)
|
||||
);
|
||||
|
||||
let targets = vec![
|
||||
"x86_64-pc-windows-gnu",
|
||||
"aarch64-pc-windows-gnullvm",
|
||||
|
||||
"x86_64-unknown-linux-gnu",
|
||||
"aarch64-unknown-linux-gnu",
|
||||
"armv7-unknown-linux-gnueabihf",
|
||||
"arm-unknown-linux-gnueabi",
|
||||
|
||||
"x86_64-pc-windows-gnu",
|
||||
"aarch64-pc-windows-gnullvm",
|
||||
|
||||
"aarch64-apple-darwin",
|
||||
"x86_64-apple-darwin",
|
||||
];
|
||||
@@ -50,7 +277,7 @@ pub fn publish_mize(_ : ArgMatches) -> MizeResult<()> {
|
||||
"x86_64-apple-darwin" => "darwin",
|
||||
_ => "base",
|
||||
};
|
||||
let tmp = std::env::var("TMP").unwrap();
|
||||
let tmp = std::env::var("TMP").unwrap_or_else(|_| "/tmp".to_owned());
|
||||
let mut build_config = ItemData::new();
|
||||
build_config.set_path("namespace", "mize.buildtime.ns")?;
|
||||
std::fs::create_dir_all(&tmp)?;
|
||||
@@ -58,10 +285,19 @@ pub fn publish_mize(_ : ArgMatches) -> MizeResult<()> {
|
||||
std::fs::write(format!("{tmp}/mize-part-dev-build-config.toml"), build_config.to_json()?)?;
|
||||
sh!(docker build -t mize-build-$docker_image $mize_src/parts/mize.dev/docker/$docker_image)?;
|
||||
sh!(echo running in container: docker run -it --rm -v "$tmp/mize-part-dev-build-config.toml:/build-config.toml" -e MIZE_BUILD_CONFIG=/build-config.toml -v $cargo_dir/registry:/usr/local/cargo/registry -v $cargo_dir/git:/usr/local/cargo/git -v $mize_src:/src -v $mize_src/target:/src/target mize-build-$docker_image cargo build --target $target_name --release --workspace)?;
|
||||
let res = sh!(docker run -it --rm -v "$tmp/mize-part-dev-build-config.toml:/build-config.toml" -e MIZE_BUILD_CONFIG=/build-config.toml -v $cargo_dir/registry:/usr/local/cargo/registry -v $cargo_dir/git:/usr/local/cargo/git -v $mize_src:/src -v $mize_src/target:/src/target mize-build-$docker_image cargo build --target $target_name --release);
|
||||
let res = sh!(docker run -it --rm -v "$tmp/mize-part-dev-build-config.toml:/build-config.toml" -e MIZE_BUILD_CONFIG=/build-config.toml -v $cargo_dir/registry:/usr/local/cargo/registry -v $cargo_dir/git:/usr/local/cargo/git -v $mize_src:/src -v $mize_src/target:/src/target mize-build-$docker_image cargo build --target $target_name --release --workspace);
|
||||
if res.is_err() {
|
||||
info!("build for {target_name} failed...");
|
||||
break;
|
||||
}
|
||||
|
||||
for part in &parts {
|
||||
if let Err(e) = pack_and_upload_part(&mut mize, &mize_src, target_name, part, &mize_version) {
|
||||
info!("pack/upload for part '{}' target '{target_name}' failed", part.id);
|
||||
e.log();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
@@ -106,12 +342,16 @@ pub fn gen_bindings(_ : ArgMatches) -> MizeResult<()> {
|
||||
gen_parts.push(s.to_owned());
|
||||
}
|
||||
debug!("parts to generate bindings for: {:?}", gen_parts);
|
||||
let gen_spacetime = gen_parts.iter().any(|p| p == "spacetime");
|
||||
let spacetime_module_dir = cwd.join("spacetime");
|
||||
let gen_spacetime_sdk = gen_spacetime && spacetime_module_dir.is_dir();
|
||||
|
||||
// 3. enable generate mode and clear any old metadata
|
||||
mize.set_generate_mode(true)?;
|
||||
mize.clear_metadata()?;
|
||||
|
||||
// 4. load each part — in generate mode their part_smth funcs only record metadata
|
||||
// (`"spacetime"` still produces normal SpacetimePart bindings; SDK client codegen is extra)
|
||||
for p in &gen_parts {
|
||||
info!("loading part in generate mode: {p}");
|
||||
mize.load_part(p)?;
|
||||
@@ -136,11 +376,36 @@ pub fn gen_bindings(_ : ArgMatches) -> MizeResult<()> {
|
||||
let mize_dep = codegen::extract_mize_dependency(&part_cargo)
|
||||
.map_err(|e| mize_err!("{e}"))?;
|
||||
debug!("using mize dependency from part Cargo.toml: {mize_dep}");
|
||||
let cargo_toml = codegen::generate_cargo_toml(&package_name, &mize_dep);
|
||||
let cargo_toml = codegen::generate_cargo_toml(&package_name, &mize_dep, gen_spacetime_sdk);
|
||||
write(gen_dir.join("Cargo.toml"), cargo_toml)
|
||||
.map_err(|e| mize_err!("could not write generated/Cargo.toml: {e}"))?;
|
||||
|
||||
let lib_rs = codegen::generate_lib_rs(&all_metadata);
|
||||
let mut lib_rs = codegen::generate_lib_rs(&all_metadata);
|
||||
|
||||
// 8. if gen includes "spacetime" and {cwd}/spacetime exists, emit SpacetimeDB rust client bindings
|
||||
if gen_spacetime_sdk {
|
||||
let module_path = spacetime_module_dir.to_string_lossy().to_string();
|
||||
let spacetime_out = src_dir.join("spacetime");
|
||||
create_dir_all(&spacetime_out)
|
||||
.map_err(|e| mize_err!("could not create {}: {e}", spacetime_out.display()))?;
|
||||
|
||||
info!(
|
||||
"running spacetime generate -p {} -o {}",
|
||||
module_path,
|
||||
spacetime_out.display()
|
||||
);
|
||||
let spacetime_out_str = spacetime_out.to_string_lossy().to_string();
|
||||
sh!(
|
||||
RUST_LOG=error RUST_BACKTRACE=0 spacetime generate
|
||||
--build-options="--lint-dir="
|
||||
-p $module_path
|
||||
-o $spacetime_out_str
|
||||
--lang rust
|
||||
)?;
|
||||
|
||||
lib_rs.push_str("\npub mod spacetime;\npub use spacetime::*;\n");
|
||||
}
|
||||
|
||||
write(src_dir.join("lib.rs"), lib_rs)
|
||||
.map_err(|e| mize_err!("could not write generated/src/lib.rs: {e}"))?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user