aboutsummaryrefslogtreecommitdiff
path: root/development/tools/cargo-workspace2/src/models/cargo.rs
diff options
context:
space:
mode:
Diffstat (limited to 'development/tools/cargo-workspace2/src/models/cargo.rs')
-rw-r--r--development/tools/cargo-workspace2/src/models/cargo.rs132
1 files changed, 132 insertions, 0 deletions
diff --git a/development/tools/cargo-workspace2/src/models/cargo.rs b/development/tools/cargo-workspace2/src/models/cargo.rs
new file mode 100644
index 000000000000..b020e82e418d
--- /dev/null
+++ b/development/tools/cargo-workspace2/src/models/cargo.rs
@@ -0,0 +1,132 @@
+use crate::cargo::{self, Dependency, Result};
+use std::{fmt, path::PathBuf};
+use toml_edit::{value, Document, Item, Value};
+
+/// Initial representation of a crate, before being parsed
+#[derive(Clone)]
+pub struct CargoCrate {
+ pub doc: Document,
+ pub path: PathBuf,
+ pub dependencies: Vec<Dependency>,
+}
+
+impl fmt::Debug for CargoCrate {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", self.path.as_path().display())
+ }
+}
+
+impl CargoCrate {
+ /// Get the crate name from the inner document
+ pub fn name(&self) -> String {
+ match &self.doc["package"]["name"] {
+ Item::Value(Value::String(ref name)) => {
+ name.to_string().replace("\"", "").as_str().trim().into()
+ }
+ _ => panic!(format!("Invalid Cargo.toml: {:?}", self.path)),
+ }
+ }
+
+ /// Get the current version
+ pub fn version(&self) -> String {
+ match &self.doc["package"]["version"] {
+ Item::Value(Value::String(ref name)) => {
+ name.to_string().replace("\"", "").as_str().trim().into()
+ }
+ _ => panic!(format!("Invalid Cargo.toml: {:?}", self.path)),
+ }
+ }
+
+ /// Find a cargo dependency by name
+ pub fn dep_by_name(&self, name: &String) -> &Dependency {
+ self.dependencies
+ .iter()
+ .find(|c| &c.name == name)
+ .as_ref()
+ .unwrap()
+ }
+
+ pub fn change_dep(&mut self, dep: &String, ver: &String) {
+ let dep = self
+ .dep_by_name(dep)
+ .alias()
+ .unwrap_or(dep.to_string())
+ .clone();
+ cargo::update_dependency(&mut self.doc, &dep, ver);
+ }
+
+ pub fn all_deps_mut(&mut self) -> Vec<&mut Dependency> {
+ self.dependencies.iter_mut().collect()
+ }
+
+ /// Check if this crate depends on a specific version of another
+ pub fn has_version(&self, name: &String) -> bool {
+ self.dep_by_name(name).has_version()
+ }
+
+ /// Check if this crate depends on a specific path of another
+ pub fn has_path(&self, name: &String) -> bool {
+ self.dep_by_name(name).has_version()
+ }
+
+ /// Set a new version for this crate
+ pub fn set_version(&mut self, version: String) {
+ self.doc["package"]["version"] = value(version);
+ }
+
+ /// Sync any changes made to the document to disk
+ pub fn sync(&mut self) {
+ cargo::sync(&mut self.doc, self.path.join("Cargo.toml")).unwrap();
+ }
+}
+
+/// Initial representation of the workspate, before getting parsed
+pub struct CargoWorkspace {
+ pub root: PathBuf,
+ pub crates: Vec<CargoCrate>,
+}
+
+impl CargoWorkspace {
+ /// Open a workspace and parse dependency graph
+ ///
+ /// Point this to the root of the workspace, do the root
+ /// `Cargo.toml` file.
+ pub fn open(p: impl Into<PathBuf>) -> Result<Self> {
+ let path = p.into();
+
+ let root_cfg = cargo::parse_root_toml(path.join("Cargo.toml"))?;
+ let members = cargo::get_members(&root_cfg)?;
+
+ let m_cfg: Vec<_> = members
+ .into_iter()
+ .filter_map(
+ |name| match cargo::parse_toml(path.join(&name).join("Cargo.toml")) {
+ Ok(doc) => Some((
+ PathBuf::new().join(name),
+ cargo::parse_dependencies(&doc),
+ doc,
+ )),
+ Err(e) => {
+ eprintln!(
+ "Error occured while parsing member `{}`/`Cargo.toml`: {:?}",
+ name, e
+ );
+ None
+ }
+ },
+ )
+ .collect();
+
+ Ok(Self {
+ root: path,
+ crates: m_cfg
+ .into_iter()
+ .map(|(path, dependencies, doc)| CargoCrate {
+ path,
+ dependencies,
+ doc,
+ })
+ .collect(),
+ })
+ }
+}