use std::path::{Path, PathBuf};
use anyhow::Result;
use colored::Colorize;
pub use zoi_cli::{cli, cmd, pkg, project};
pub use zoi_core::types::{self, Scope};
pub use zoi_core::utils;
#[derive(Debug, Clone)]
pub struct BuildOptions<'a> {
pub build_type: Option<&'a str>,
pub platforms: Vec<String>,
pub sign_key: Option<String>,
pub output_dir: Option<PathBuf>,
pub sub_packages: Option<Vec<String>>,
pub install_deps: bool,
pub test: bool,
pub method: &'a str,
pub image: Option<&'a str>,
pub version_override: Option<&'a str>,
pub fakeroot: bool
}
impl Default for BuildOptions<'_> {
fn default() -> Self {
Self {
build_type: None,
platforms: vec![
zoi_core::utils::get_platform()
.unwrap_or_else(|_| "linux-amd64".to_string()),
],
sign_key: None,
output_dir: None,
sub_packages: None,
install_deps: true,
test: false,
method: "native",
image: None,
version_override: None,
fakeroot: false
}
}
}
#[derive(Debug, Clone)]
pub struct PackageInstallOptions {
pub scope_override: Option<Scope>,
pub registry_handle: String,
pub yes: bool,
pub sub_packages: Option<Vec<String>>,
pub link_bins: bool
}
impl Default for PackageInstallOptions {
fn default() -> Self {
Self {
scope_override: Some(Scope::User),
registry_handle: "local".to_string(),
yes: true,
sub_packages: None,
link_bins: true
}
}
}
#[derive(Debug, Clone, Default)]
pub struct SourceInstallOptions {
pub repo: Option<String>,
pub force: bool,
pub all_optional: bool,
pub yes: bool,
pub scope_override: Option<Scope>,
pub save: bool,
pub build_type: Option<String>,
pub dry_run: bool,
pub build: bool,
pub frozen: bool
}
#[derive(Debug, Clone, Default)]
pub struct DependencyResolutionOptions {
pub scope_override: Option<Scope>,
pub force: bool,
pub yes: bool,
pub all_optional: bool,
pub build_type: Option<String>,
pub quiet: bool
}
#[derive(Debug, Clone)]
pub struct ResolvedPackage {
pub package: types::Package,
pub version: String,
pub sharable_manifest: Option<types::SharableInstallManifest>,
pub source_path: PathBuf,
pub registry_handle: Option<String>,
pub repo_type: Option<String>,
pub git_sha: Option<String>
}
#[derive(Debug)]
pub struct DependencyResolution {
pub graph: zoi_install::resolver::DependencyGraph,
pub non_zoi_dependencies: Vec<String>
}
fn to_install_scope(scope: Scope) -> zoi_cli::cli::InstallScope {
match scope {
Scope::User => zoi_cli::cli::InstallScope::User,
Scope::System => zoi_cli::cli::InstallScope::System,
Scope::Project => zoi_cli::cli::InstallScope::Project
}
}
pub fn build_with_options(
package_file: &Path,
options: &BuildOptions<'_>
) -> Result<()> {
if options.install_deps {
for platform in &options.platforms {
let current_platform = if platform == "current" {
zoi_core::utils::get_platform()?
} else {
platform.clone()
};
if let Some(dep_strings) =
zoi_package::build::get_build_dependencies(
package_file,
options.build_type,
¤t_platform,
options.version_override,
false
)?
&& !dep_strings.is_empty()
{
println!(
"{} Installing build dependencies...",
"::".bold().blue()
);
let processed =
std::sync::Mutex::new(std::collections::HashSet::new());
let mut installed = Vec::new();
for dep_str in dep_strings {
let dep = zoi_deps::parse_dependency_string(&dep_str)?;
zoi_install::dep_install::install_dependency(
&dep,
"build",
zoi_core::types::Scope::User,
true,
true,
&processed,
&mut installed,
None
)?;
}
}
}
}
zoi_package::build::run(
package_file,
options.build_type,
&options.platforms,
options.sign_key.clone(),
options.output_dir.as_deref(),
options.version_override,
options.sub_packages.clone(),
false,
options.method,
options.image,
options.fakeroot,
options.install_deps,
options.test
)
}
pub fn install_package_with_options(
package_file: &Path,
options: &PackageInstallOptions
) -> Result<Vec<String>> {
zoi_install::pkg_install::run(
package_file,
options.scope_override,
&options.registry_handle,
None,
options.yes,
options.sub_packages.clone(),
options.link_bins,
None
)
}
pub fn install_sources(
sources: &[String],
options: &SourceInstallOptions
) -> Result<()> {
let plugin_manager = if zoi_core::utils::is_mini_mode() {
None
} else {
let pm = zoi_plugins::PluginManager::new()?;
let _ = pm.load_all(options.yes);
Some(pm)
};
let pm_ptr = plugin_manager.as_ref();
zoi_cli::cmd::install::run(
sources,
options.repo.clone(),
options.force,
options.all_optional,
options.yes,
options.scope_override.map(to_install_scope),
false,
false,
options.save,
options.build_type.as_deref(),
options.dry_run,
pm_ptr,
options.build,
options.frozen,
false,
false,
3,
false,
false,
None
)
}
pub fn update_packages(
all: bool,
package_names: &[String],
yes: bool
) -> Result<()> {
zoi_cli::cmd::update::run(
all,
package_names,
yes,
false,
false,
false,
false
)
}
pub fn resolve_package(source: &str, yes: bool) -> Result<ResolvedPackage> {
let (
package,
version,
sharable_manifest,
source_path,
registry_handle,
repo_type,
git_sha
) = zoi_resolver::resolve::resolve_package_and_version(
source, None, true, yes
)?;
Ok(ResolvedPackage {
package,
version,
sharable_manifest,
source_path,
registry_handle,
repo_type,
git_sha
})
}
pub fn resolve_dependency_graph(
sources: &[String],
options: &DependencyResolutionOptions
) -> Result<DependencyResolution> {
let (graph, non_zoi_dependencies) =
zoi_install::resolver::resolve_dependency_graph(
sources,
options.scope_override,
options.force,
options.yes,
options.all_optional,
options.build_type.as_deref(),
options.quiet,
None
)?;
Ok(DependencyResolution {
graph,
non_zoi_dependencies
})
}
pub fn bundle_package(
package_file: &Path,
output_dir: Option<&Path>,
sign: Option<String>,
version_override: Option<&str>,
build_type: Option<&str>
) -> Result<()> {
zoi_package::bundle::run(
package_file,
output_dir,
sign,
version_override,
build_type
)
}
pub fn build(
package_file: &Path,
build_type: Option<&str>,
platforms: &[String],
sign_key: Option<String>,
install_deps: bool,
method: &str,
image: Option<&str>,
version_override: Option<&str>
) -> Result<()> {
let options = BuildOptions {
build_type,
platforms: platforms.to_vec(),
sign_key,
output_dir: None,
sub_packages: None,
install_deps,
test: false,
method,
image,
version_override,
fakeroot: false
};
build_with_options(package_file, &options)
}
pub fn install_package(
package_file: &Path,
scope_override: Option<Scope>,
registry_handle: &str,
yes: bool,
sub_packages: Option<Vec<String>>
) -> Result<Vec<String>> {
let options = PackageInstallOptions {
scope_override,
registry_handle: registry_handle.to_string(),
yes,
sub_packages,
link_bins: true
};
install_package_with_options(package_file, &options)
}
pub fn uninstall_package(
package_name: &str,
scope_override: Option<Scope>
) -> Result<()> {
zoi_uninstall::run(package_name, scope_override, false, false, false)
.map(|_| ())
}