summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-03-28 17:13:27 +0300
committerLars Wirzenius <liw@liw.fi>2021-03-29 10:38:23 +0300
commit3783b6ace86957c95e5137c7645af319dd2462e9 (patch)
treef4649980e94680e9c277611e4c7b7988d0591f96 /src
parent53db547b3a4dc45aaa33b24f5b85da1e3397a38d (diff)
downloadbumper-rs-3783b6ace86957c95e5137c7645af319dd2462e9.tar.gz
feat: set version in Cargo.toml for Rust projects
Diffstat (limited to 'src')
-rw-r--r--src/bin/bumper.rs5
-rw-r--r--src/bin/toml.rs20
-rw-r--r--src/errors.rs26
-rw-r--r--src/lib.rs2
-rw-r--r--src/project.rs26
-rw-r--r--src/rust.rs80
6 files changed, 159 insertions, 0 deletions
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<P: AsRef<Path>>(dirname: P) -> Result<ProjectKind, BumperError> {
+ 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<Self, BumperError> {
+ 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<Self, BumperError> {
+ 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(())
+ }
+}