pub mod build_script;
pub mod build_script_cas;
pub mod build_script_directives;
pub mod build_script_env;
pub mod build_script_keys;
pub mod build_script_purity;
pub mod builder;
pub mod cargo_config;
pub mod compiler;
pub mod compiler_args;
mod compiler_remap;
pub mod compiler_resolve;
pub mod dag;
pub mod dag_cache;
pub mod dag_runner;
pub mod dag_scheduler;
pub mod dag_unit;
pub mod dag_unit_build_script;
pub mod dag_unit_externs;
pub mod dag_unit_publish;
pub mod dag_worker;
pub mod dep_info;
pub mod dependency_check;
pub mod doctest;
pub mod env_macro;
pub mod env_macro_cache;
pub mod env_macro_scope;
pub mod features;
pub mod features_helpers;
pub mod credential_provider;
pub mod fetcher;
pub mod git_resolve;
pub mod patch_resolve;
pub mod git_source;
pub mod registry_config;
pub mod resolve_graph;
pub mod vendor_source;
pub mod inputs;
pub mod key;
pub mod key_flags;
pub mod lockfile;
pub mod manifest;
pub mod manifest_digest;
pub mod manifest_inherit;
pub mod manifest_models;
pub mod manifest_snapshot;
pub mod manifest_tests;
pub mod manifest_workspace;
pub mod package_selection;
pub mod pipelining;
pub mod planner;
pub mod planner_deps;
pub mod planner_units;
pub mod profile;
pub mod project_config;
pub mod resolver;
pub mod single_flight;
pub mod source_lookup;
pub mod sparse_index;
pub mod target_filter;
pub mod toolchain_probes;
pub mod target_incompatible;
pub mod test_selection;
pub mod types;
pub mod unescape;
pub mod unit_env;
pub mod unit_inputs;
pub use build_script::execute_build_script;
pub use build_script_directives::BuildScriptDirectives;
pub use compiler::{RustcInvocation, RustcOutput};
pub use dag::CompilationDag;
pub use dag_runner::run_native_dag_build;
pub use dag_scheduler::{LockMode, UnitExecutionStatus, WaveWorkQueue};
pub use env_macro::scan_env_macros;
pub use fetcher::{CrateFetcher, FetchOptions, FetchResult};
pub use key::{derive_unit_action_key_context, derive_unit_action_keys, UnitKeyDeriver};
pub use lockfile::{CargoLock, CargoLockPackage};
pub use resolver::NativeResolver;
pub use sparse_index::SparseIndexClient;
pub use types::{
BuildMode, BuildProgressCallback, BuildProgressEvent, EffectivePlanExplanation,
EnvMacroDiscovery, PlannedCompilationUnit, RustAdapterError, RustBuildOptions,
};
pub use unescape::unescape_rust_string;
use crate::core::action::{ActionResult, BuildPlan, ToolchainInfo};
use anyhow::{Context, Result};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
pub struct RustAdapter;
impl RustAdapter {
pub fn detect_toolchain() -> Result<ToolchainInfo> {
Ok(compiler_resolve::active_toolchain()?.toolchain)
}
pub fn resolve_manifest(opt: &RustBuildOptions) -> Result<PathBuf> {
if let Some(ref p) = opt.manifest_path {
let path = if p.is_absolute() {
p.clone()
} else {
std::env::current_dir()?.join(p)
};
if !path.exists() {
return Err(RustAdapterError::ManifestNotFound(path).into());
}
Ok(path)
} else {
let default_path = std::env::current_dir()?.join("Cargo.toml");
if !default_path.exists() {
return Err(RustAdapterError::ManifestNotFound(default_path).into());
}
Ok(default_path)
}
}
pub fn resolve_target_dir(manifest_path: &Path, opt: &RustBuildOptions) -> Result<PathBuf> {
let target_dir = if let Some(ref td) = opt.target_dir {
td.clone()
} else if let Ok(cargo_td) = std::env::var("CARGO_TARGET_DIR") {
PathBuf::from(cargo_td).join("mitts")
} else {
let project_dir = manifest_path
.parent()
.context("Manifest path has no parent directory")?;
project_dir.join("target").join("mitts")
};
if opt.target_dir.is_none() {
if let Some(parent) = target_dir.parent() {
let _ = Self::ensure_target_dir_tags(parent);
}
}
Ok(target_dir)
}
fn ensure_target_dir_tags(target_dir: &Path) -> std::io::Result<()> {
let tag_file = target_dir.join("CACHEDIR.TAG");
if !tag_file.exists() {
let _ = std::fs::create_dir_all(target_dir);
let content = "Signature: 8a477f597d28d172789f06886806bc55\n# This file is a cache directory tag created by Mitts.\n# For information about cache directory tags, see:\n#\thttp://www.brynosaurus.com/cachedir/\n";
let _ = std::fs::write(&tag_file, content);
}
let gitignore = target_dir.join(".gitignore");
if !gitignore.exists() {
let _ = std::fs::create_dir_all(target_dir);
let _ = std::fs::write(&gitignore, "*\n");
}
Ok(())
}
pub fn explain_plan(opt: &RustBuildOptions) -> Result<EffectivePlanExplanation> {
planner::explain_plan(opt)
}
pub fn derive_unit_action_keys(
opt: &RustBuildOptions,
explanation: &EffectivePlanExplanation,
) -> Result<HashMap<String, String>> {
key::derive_unit_action_keys(opt, explanation)
}
pub fn build(opt: &RustBuildOptions) -> Result<(BuildPlan, ActionResult)> {
builder::build(opt)
}
pub fn build_native(opt: &RustBuildOptions) -> Result<(BuildPlan, ActionResult)> {
let explanation = Self::explain_plan(opt)?;
let deriver = key::derive_unit_action_key_context(opt, &explanation)?;
dag_runner::run_native_dag_build(opt, &explanation, &deriver)
}
pub fn resolve_lockfile(
manifest_path: &Path,
offline: bool,
cache_dir: Option<&Path>,
) -> Result<lockfile::CargoLock> {
lockfile::CargoLock::resolve_or_sync(manifest_path, offline, cache_dir)
}
pub fn fetch(
manifest_path: &Path,
store: &crate::core::source_store::SourceStore,
opt: &fetcher::FetchOptions,
cache_dir: Option<&Path>,
) -> Result<fetcher::FetchResult> {
let lock = Self::resolve_lockfile(manifest_path, opt.offline, cache_dir)?;
let project_dir = manifest_path.parent().unwrap_or(Path::new("."));
let config = registry_config::RegistryConfig::load(project_dir)?;
let fetcher = fetcher::CrateFetcher::with_config(store.clone(), config);
fetcher.fetch_all(&lock, opt)
}
}