#![forbid(missing_docs)]
use holochain_types::prelude::{AppManifest, DnaManifest, ValidatedDnaManifest};
use holochain_types::web_app::WebAppManifest;
use holochain_util::ffs;
use mr_bundle::Manifest;
use std::path::Path;
use std::path::PathBuf;
use structopt::StructOpt;
use crate::error::HcBundleResult;
pub const DNA_BUNDLE_EXT: &str = "dna";
pub const APP_BUNDLE_EXT: &str = "happ";
pub const WEB_APP_BUNDLE_EXT: &str = "webhapp";
#[derive(Debug, StructOpt)]
pub enum HcDnaBundle {
Init {
path: PathBuf,
},
Pack {
path: std::path::PathBuf,
#[structopt(short = "o", long)]
output: Option<PathBuf>,
},
Unpack {
path: std::path::PathBuf,
#[structopt(short = "o", long)]
output: Option<PathBuf>,
#[structopt(short = "f", long)]
force: bool,
},
}
#[derive(Debug, StructOpt)]
pub enum HcAppBundle {
Init {
path: PathBuf,
},
Pack {
path: std::path::PathBuf,
#[structopt(short = "o", long)]
output: Option<PathBuf>,
},
Unpack {
path: std::path::PathBuf,
#[structopt(short = "o", long)]
output: Option<PathBuf>,
#[structopt(short = "f", long)]
force: bool,
},
}
#[derive(Debug, StructOpt)]
pub enum HcWebAppBundle {
Init {
path: PathBuf,
},
Pack {
path: std::path::PathBuf,
#[structopt(short = "o", long)]
output: Option<PathBuf>,
},
Unpack {
path: std::path::PathBuf,
#[structopt(short = "o", long)]
output: Option<PathBuf>,
#[structopt(short = "f", long)]
force: bool,
},
}
impl HcDnaBundle {
pub async fn run(self) -> anyhow::Result<()> {
match self {
Self::Init { path } => {
crate::init::init_dna(path).await?;
}
Self::Pack { path, output } => {
let name = get_dna_name(&path).await?;
let (bundle_path, _) =
crate::packing::pack::<ValidatedDnaManifest>(&path, output, name).await?;
println!("Wrote bundle {}", bundle_path.to_string_lossy());
}
Self::Unpack {
path,
output,
force,
} => {
let dir_path = crate::packing::unpack::<ValidatedDnaManifest>(
DNA_BUNDLE_EXT,
&path,
output,
force,
)
.await?;
println!("Unpacked to directory {}", dir_path.to_string_lossy());
}
}
Ok(())
}
}
impl HcAppBundle {
pub async fn run(self) -> anyhow::Result<()> {
match self {
Self::Init { path } => {
crate::init::init_app(path).await?;
}
Self::Pack { path, output } => {
let name = get_app_name(&path).await?;
let (bundle_path, _) =
crate::packing::pack::<AppManifest>(&path, output, name).await?;
println!("Wrote bundle {}", bundle_path.to_string_lossy());
}
Self::Unpack {
path,
output,
force,
} => {
let dir_path =
crate::packing::unpack::<AppManifest>(APP_BUNDLE_EXT, &path, output, force)
.await?;
println!("Unpacked to directory {}", dir_path.to_string_lossy());
}
}
Ok(())
}
}
impl HcWebAppBundle {
pub async fn run(self) -> anyhow::Result<()> {
match self {
Self::Init { path } => {
crate::init::init_web_app(path).await?;
}
Self::Pack { path, output } => {
let name = get_web_app_name(&path).await?;
let (bundle_path, _) =
crate::packing::pack::<WebAppManifest>(&path, output, name).await?;
println!("Wrote bundle {}", bundle_path.to_string_lossy());
}
Self::Unpack {
path,
output,
force,
} => {
let dir_path = crate::packing::unpack::<WebAppManifest>(
WEB_APP_BUNDLE_EXT,
&path,
output,
force,
)
.await?;
println!("Unpacked to directory {}", dir_path.to_string_lossy());
}
}
Ok(())
}
}
async fn get_dna_name(manifest_path: &Path) -> HcBundleResult<String> {
let manifest_path = manifest_path.to_path_buf();
let manifest_path = manifest_path.join(&ValidatedDnaManifest::path());
let manifest_yaml = ffs::read_to_string(&manifest_path).await?;
let manifest: DnaManifest = serde_yaml::from_str(&manifest_yaml)?;
Ok(manifest.name())
}
async fn get_app_name(manifest_path: &Path) -> HcBundleResult<String> {
let manifest_path = manifest_path.to_path_buf();
let manifest_path = manifest_path.join(&AppManifest::path());
let manifest_yaml = ffs::read_to_string(&manifest_path).await?;
let manifest: AppManifest = serde_yaml::from_str(&manifest_yaml)?;
Ok(manifest.app_name().to_string())
}
async fn get_web_app_name(manifest_path: &Path) -> HcBundleResult<String> {
let manifest_path = manifest_path.to_path_buf();
let manifest_path = manifest_path.join(&WebAppManifest::path());
let manifest_yaml = ffs::read_to_string(&manifest_path).await?;
let manifest: WebAppManifest = serde_yaml::from_str(&manifest_yaml)?;
Ok(manifest.app_name().to_string())
}