mod manifest;
mod metadata;
mod profile;
#[doc(inline)]
pub use self::{
manifest::{
Manifest,
ManifestPath,
},
profile::{
Lto,
OptLevel,
PanicStrategy,
Profile,
},
};
use anyhow::Result;
use cargo_metadata::{
Metadata as CargoMetadata,
Package,
PackageId,
};
use std::path::{
Path,
PathBuf,
};
pub struct Workspace {
workspace_root: PathBuf,
root_package: Package,
root_manifest: Manifest,
}
impl Workspace {
pub fn new(metadata: &CargoMetadata, root_package: &PackageId) -> Result<Self> {
let root_package = metadata
.packages
.iter()
.find(|p| p.id == *root_package)
.ok_or_else(|| {
anyhow::anyhow!("The root package should be a workspace member")
})?;
let manifest_path = ManifestPath::new(&root_package.manifest_path)?;
let root_manifest = Manifest::new(manifest_path)?;
Ok(Workspace {
workspace_root: metadata.workspace_root.clone().into(),
root_package: root_package.clone(),
root_manifest,
})
}
pub fn with_root_package_manifest<F>(&mut self, f: F) -> Result<&mut Self>
where
F: FnOnce(&mut Manifest) -> Result<()>,
{
f(&mut self.root_manifest)?;
Ok(self)
}
pub(super) fn with_metadata_gen_package(&mut self) -> Result<&mut Self> {
self.root_manifest.with_metadata_package()?;
Ok(self)
}
pub fn write<P: AsRef<Path>>(&mut self, target: P) -> Result<ManifestPath> {
let mut new_path: PathBuf = target.as_ref().into();
new_path.push(
self.root_package
.manifest_path
.strip_prefix(&self.workspace_root)?,
);
let new_manifest = ManifestPath::new(new_path)?;
self.root_manifest.rewrite_relative_paths()?;
self.root_manifest.write(&new_manifest)?;
Ok(new_manifest)
}
pub fn using_temp<F>(&mut self, f: F) -> Result<()>
where
F: FnOnce(&ManifestPath) -> Result<()>,
{
let tmp_dir = tempfile::Builder::new()
.prefix("cargo-contract_")
.tempdir()?;
tracing::debug!("Using temp workspace at '{}'", tmp_dir.path().display());
let tmp_root_manifest_path = self.write(&tmp_dir)?;
let src_lockfile = self.workspace_root.clone().join("Cargo.lock");
let dest_lockfile = tmp_dir.path().join("Cargo.lock");
if src_lockfile.exists() {
tracing::debug!(
"Copying '{}' to ' '{}'",
src_lockfile.display(),
dest_lockfile.display()
);
std::fs::copy(src_lockfile, dest_lockfile)?;
}
f(&tmp_root_manifest_path)
}
}