From 3783b6ace86957c95e5137c7645af319dd2462e9 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 28 Mar 2021 17:13:27 +0300 Subject: feat: set version in Cargo.toml for Rust projects --- src/bin/bumper.rs | 5 ++++ src/bin/toml.rs | 20 ++++++++++++++ src/errors.rs | 26 ++++++++++++++++++ src/lib.rs | 2 ++ src/project.rs | 26 ++++++++++++++++++ src/rust.rs | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 159 insertions(+) create mode 100644 src/bin/toml.rs create mode 100644 src/project.rs create mode 100644 src/rust.rs (limited to 'src') diff --git a/src/bin/bumper.rs b/src/bin/bumper.rs index 1a2e567..564b589 100644 --- a/src/bin/bumper.rs +++ b/src/bin/bumper.rs @@ -1,5 +1,6 @@ use bumper::errors::BumperError; use bumper::git; +use bumper::project::ProjectKind; use log::{error, info}; use std::process::exit; use structopt::StructOpt; @@ -15,6 +16,10 @@ fn bumper() -> Result<(), BumperError> { pretty_env_logger::init_custom_env("BUMPER_LOG"); info!("Bumper starts"); let opt = Opt::from_args(); + + let mut project = ProjectKind::detect(".")?; + project.set_version(&opt.version)?; + git::tag(&opt.version)?; info!("Bumper ends OK"); Ok(()) diff --git a/src/bin/toml.rs b/src/bin/toml.rs new file mode 100644 index 0000000..f796057 --- /dev/null +++ b/src/bin/toml.rs @@ -0,0 +1,20 @@ +use cargo_edit::Manifest; +use toml_edit::{Item, Value}; + +fn main() { + let mut m = Manifest::open(&None).unwrap(); + let package = m + .get_table(&[String::from("package")]) + .unwrap() + .as_table_mut() + .unwrap(); + // println!("package: {:?}", package); + + let version = package.entry("version"); + *version = Item::Value(Value::from("1.2")); + println!("version: {:?}", version); + + let mut f = Manifest::find_file(&None).unwrap(); + println!("file: {:?}", f); + m.write_to_file(&mut f).unwrap(); +} diff --git a/src/errors.rs b/src/errors.rs index 607eecb..282b5c5 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,5 +1,31 @@ +use std::path::PathBuf; + #[derive(Debug, thiserror::Error)] pub enum BumperError { + #[error("Can't figure out what kind of project: {0}")] + UnknownProjectKind(PathBuf), + + #[error("Couldn't read file {0}: {1}")] + Read(PathBuf, #[source] std::io::Error), + + #[error("Couldn't write file {0}: {1}")] + Write(PathBuf, #[source] std::io::Error), + + #[error("Couldn't find Cargo.toml in {0}: {1}")] + CargoTomlNotFound(PathBuf, #[source] cargo_edit::Error), + + #[error("Couldn't parse Cargo.toml from {0}: {1}")] + FromToml(PathBuf, #[source] cargo_edit::Error), + + #[error("Couldn't create Cargo.toml manifest to {0}: {1}")] + WriteToml(PathBuf, #[source] cargo_edit::Error), + + #[error("Cargo.toml doesn't have a 'package' table")] + NoPackage(#[source] cargo_edit::Error), + + #[error("'project' in Cargo.toml is not a table")] + ProjectNotTable, + #[error("Failed to run git: {0}")] GitInvoke(#[source] std::io::Error), diff --git a/src/lib.rs b/src/lib.rs index 7d4548a..06071a6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,4 @@ pub mod errors; pub mod git; +pub mod project; +pub mod rust; diff --git a/src/project.rs b/src/project.rs new file mode 100644 index 0000000..7471c66 --- /dev/null +++ b/src/project.rs @@ -0,0 +1,26 @@ +use crate::errors::BumperError; +use crate::rust::Rust; +use std::path::Path; + +pub enum ProjectKind { + Rust(Rust), +} + +impl ProjectKind { + pub fn detect>(dirname: P) -> Result { + let dirname = dirname.as_ref(); + + if let Ok(p) = Rust::new(dirname) { + return Ok(Self::Rust(p)); + } + + Err(BumperError::UnknownProjectKind(dirname.to_path_buf())) + } + + pub fn set_version(&mut self, version: &str) -> Result<(), BumperError> { + match self { + Self::Rust(ref mut rust) => rust.set_version(version)?, + } + Ok(()) + } +} diff --git a/src/rust.rs b/src/rust.rs new file mode 100644 index 0000000..192c387 --- /dev/null +++ b/src/rust.rs @@ -0,0 +1,80 @@ +use crate::errors::BumperError; +use cargo_edit::Manifest; +use log::{debug, info}; +use std::path::{Path, PathBuf}; +use toml_edit::{Item, Value}; + +pub struct Rust { + dirname: PathBuf, + cargo_toml: CargoToml, +} + +impl Rust { + pub fn new(dirname: &Path) -> Result { + let cargo_toml = dirname.join("Cargo.toml"); + if cargo_toml.exists() { + return Ok(Self { + dirname: dirname.to_path_buf(), + cargo_toml: CargoToml::parse(&cargo_toml)?, + }); + } + Err(BumperError::UnknownProjectKind(dirname.to_path_buf())) + } + + pub fn set_version(&mut self, version: &str) -> Result<(), BumperError> { + debug!("parsing Cargo.toml from {}", self.dirname.display()); + // debug!("Cargo.toml:\n{:#?}", self.cargo_toml); + self.cargo_toml.set_version(version)?; + self.cargo_toml.write()?; + + info!( + "Rust project {}, in {}, version set to {}", + self.dirname.display(), + "xxx", + version + ); + Ok(()) + } +} + +#[derive(Debug)] +struct CargoToml { + dirname: PathBuf, + manifest: Manifest, +} + +impl CargoToml { + fn parse(dirname: &Path) -> Result { + let manifest = Manifest::open(&Some(dirname.to_path_buf())) + .map_err(|err| BumperError::FromToml(dirname.to_path_buf(), err))?; + Ok(Self { + dirname: dirname.to_path_buf(), + manifest, + }) + } + + fn write(&self) -> Result<(), BumperError> { + debug!("saving Cargo.toml to {}", self.dirname.display()); + let mut file = Manifest::find_file(&Some(self.dirname.to_path_buf())) + .map_err(|err| BumperError::CargoTomlNotFound(self.dirname.to_path_buf(), err))?; + self.manifest + .write_to_file(&mut file) + .map_err(|err| BumperError::WriteToml(self.dirname.to_path_buf(), err))?; + Ok(()) + } + + fn set_version(&mut self, version: &str) -> Result<(), BumperError> { + let package = self + .manifest + .get_table(&["package".to_string()]) + .map_err(BumperError::NoPackage)?; + if let Some(package) = package.as_table_mut() { + debug!("setting Cargo.toml set version to {} in memory", version); + let v = package.entry("version"); + *v = Item::Value(Value::from(version)); + } else { + return Err(BumperError::ProjectNotTable); + } + Ok(()) + } +} -- cgit v1.2.1