ferrum-native-ops-builder 0.8.7

Isolated source-build and packaging tools for Ferrum native operators
Documentation
use std::path::PathBuf;

use clap::{Parser, Subcommand};
use ferrum_native_ops_builder::{
    assemble_native_operator_set, lock_native_operator_source_definition,
    materialize_native_operator_package_spec, package_native_operator,
    run_native_operator_source_build, NativeOperatorPackageRequest,
    NativeOperatorPackageSpecRequest, NativeOperatorSetRequest, NativeOperatorSourceBuildRequest,
};

#[derive(Debug, Parser)]
#[command(name = "ferrum-native-ops-builder")]
#[command(about = "Build-boundary tooling for Ferrum native operator artifacts")]
struct Cli {
    #[command(subcommand)]
    command: Command,
}

#[derive(Debug, Subcommand)]
enum Command {
    LockSource {
        #[arg(long)]
        definition: PathBuf,
        #[arg(long)]
        source_root: PathBuf,
        #[arg(long)]
        out: PathBuf,
    },
    SourceBuild {
        #[arg(long)]
        plan: PathBuf,
        #[arg(long)]
        source_root: PathBuf,
        #[arg(long)]
        compute_capability: String,
        #[arg(long)]
        builder_sha: String,
        #[arg(long)]
        nvcc: PathBuf,
        #[arg(long)]
        cuda_toolkit_root: PathBuf,
        #[arg(long)]
        ccbin: PathBuf,
        #[arg(long)]
        ar: PathBuf,
        #[arg(long, default_value_t = 4)]
        nvcc_threads: u32,
        #[arg(long)]
        object_cache: PathBuf,
        #[arg(long)]
        plan_only: bool,
        #[arg(long)]
        out: PathBuf,
    },
    MaterializePackageSpec {
        #[arg(long)]
        definition: PathBuf,
        #[arg(long)]
        g03_catalog: PathBuf,
        #[arg(long)]
        out: PathBuf,
    },
    Package {
        #[arg(long)]
        spec: PathBuf,
        #[arg(long)]
        source_root: PathBuf,
        #[arg(long)]
        license_root: PathBuf,
        #[arg(long)]
        source_build_receipt: PathBuf,
        #[arg(long)]
        source_build_plan: PathBuf,
        #[arg(long)]
        g03_catalog: PathBuf,
        #[arg(long)]
        abi_contract: PathBuf,
        #[arg(long)]
        out: PathBuf,
        #[arg(long)]
        cc: PathBuf,
        #[arg(long)]
        ar: PathBuf,
    },
    AssembleSet {
        #[arg(long, required = true)]
        receipt: Vec<PathBuf>,
        #[arg(long = "receipt-sha256", required = true)]
        receipt_sha256: Vec<String>,
        #[arg(long)]
        g03_catalog_sha256: String,
        #[arg(long)]
        compute_capability: String,
        #[arg(long)]
        out: PathBuf,
    },
}

fn main() {
    if let Err(error) = run(Cli::parse()) {
        eprintln!("ferrum-native-ops-builder: {error}");
        std::process::exit(1);
    }
}

fn run(cli: Cli) -> ferrum_native_ops_builder::Result<()> {
    match cli.command {
        Command::LockSource {
            definition,
            source_root,
            out,
        } => {
            lock_native_operator_source_definition(&definition, &source_root, &out)?;
            println!("FERRUM NATIVE SOURCE LOCK READY: {}", out.display());
        }
        Command::SourceBuild {
            plan,
            source_root,
            compute_capability,
            builder_sha,
            nvcc,
            cuda_toolkit_root,
            ccbin,
            ar,
            nvcc_threads,
            object_cache,
            plan_only,
            out,
        } => {
            run_native_operator_source_build(&NativeOperatorSourceBuildRequest {
                plan_path: plan,
                source_root,
                output_dir: out.clone(),
                compute_capability,
                builder_sha,
                nvcc_path: nvcc,
                cuda_toolkit_root,
                ccbin_path: ccbin,
                ar_path: ar,
                nvcc_threads,
                object_cache_dir: object_cache,
                plan_only,
            })?;
            let kind = if plan_only { "PLAN" } else { "BUILD" };
            println!(
                "FERRUM NATIVE SOURCE {kind} READY: {}",
                out.join("source-build.receipt.json").display()
            );
        }
        Command::MaterializePackageSpec {
            definition,
            g03_catalog,
            out,
        } => {
            materialize_native_operator_package_spec(&NativeOperatorPackageSpecRequest {
                definition_path: definition,
                g03_catalog_path: g03_catalog,
                output_path: out.clone(),
            })?;
            println!("FERRUM NATIVE PACKAGE SPEC READY: {}", out.display());
        }
        Command::Package {
            spec,
            source_root,
            license_root,
            source_build_receipt,
            source_build_plan,
            g03_catalog,
            abi_contract,
            out,
            cc,
            ar,
        } => {
            package_native_operator(&NativeOperatorPackageRequest {
                spec_path: spec,
                source_root,
                license_root,
                source_build_receipt_path: source_build_receipt,
                source_build_plan_path: source_build_plan,
                g03_catalog_path: g03_catalog,
                abi_contract_path: abi_contract,
                output_dir: out.clone(),
                cc,
                ar,
            })?;
            println!(
                "FERRUM NATIVE OPERATOR PACKAGE READY: {}",
                out.join("package.receipt.json").display()
            );
        }
        Command::AssembleSet {
            receipt,
            receipt_sha256,
            g03_catalog_sha256,
            compute_capability,
            out,
        } => {
            assemble_native_operator_set(&NativeOperatorSetRequest {
                receipt_paths: receipt,
                expected_receipt_sha256: receipt_sha256,
                expected_g03_catalog_sha256: g03_catalog_sha256,
                output_lock_path: out.clone(),
                compute_capability,
            })?;
            println!("FERRUM NATIVE OPERATOR SET READY: {}", out.display());
        }
    }
    Ok(())
}