mod cargo_script;
mod cargo_toml;
mod package_json;
mod tauri_conf_json;
use super::Package;
use crate::agent::Agent;
use crate::dependency::{self, Target};
use anyhow::{Result, bail};
use cargo_script::CargoScript;
use cargo_toml::CargoToml;
use dependency::DependencyTree;
use globset::Glob;
use package_json::PackageJson;
use semver::Version;
use std::path::Path;
use strum::{EnumIter, IntoEnumIterator};
use tauri_conf_json::TauriConfJson;
pub(super) type ManifestBox = Box<dyn Handler + Send + Sync>;
pub const DEFAULT_VERSION: Version = Version::new(0, 0, 0);
trait Manifest {
type Value;
fn read(path: impl AsRef<Path>) -> Result<ManifestBox>;
fn read_as_value(path: impl AsRef<Path>) -> Result<Self::Value>;
}
pub trait Handler {
fn agent(&self) -> Agent;
fn bump(&self, package: &Package, new_version: Version) -> Result<()>;
fn name(&self) -> &str;
fn update(&self, package: &Package, targets: &[Target]) -> Result<()>;
fn version(&self) -> Result<Version>;
fn dependency_tree(&self) -> DependencyTree {
DependencyTree::new(self.agent())
}
}
#[derive(Debug, EnumIter)]
pub enum ManifestKind {
CargoScript,
CargoToml,
PackageJson,
TauriConfJson,
}
impl ManifestKind {
pub(crate) fn read<P>(&self, path: P) -> Result<ManifestBox>
where
P: AsRef<Path>,
{
match self {
ManifestKind::CargoScript => CargoScript::read(path),
ManifestKind::CargoToml => CargoToml::read(path),
ManifestKind::PackageJson => PackageJson::read(path),
ManifestKind::TauriConfJson => TauriConfJson::read(path),
}
}
pub(crate) fn glob(&self) -> &str {
match self {
ManifestKind::CargoScript => "**/scripts/**/*.rs",
ManifestKind::CargoToml => "**/Cargo.toml",
ManifestKind::PackageJson => "**/package.json",
ManifestKind::TauriConfJson => "**/tauri.conf.json",
}
}
}
impl TryFrom<&Path> for ManifestKind {
type Error = anyhow::Error;
fn try_from(path: &Path) -> Result<Self> {
for kind in ManifestKind::iter() {
let glob = Glob::new(kind.glob())?.compile_matcher();
if glob.is_match(path) {
return Ok(kind);
}
}
let path = path.to_string_lossy();
bail!("invalid manifest:\n{path}");
}
}
fn default_version() -> String {
DEFAULT_VERSION.to_string()
}