use anyhow::*;
use crate::cargo::Cargo;
use crate::manifest::Manifest;
use crate::repository::Repository;
#[derive(Debug)]
enum BumpLevel {
Patch,
Minor,
Major
}
#[derive(Debug)]
pub struct Release {
bump_level: BumpLevel,
pre_release_suffix: String,
allow_dirty: bool,
skip_git: bool,
skip_push: bool,
skip_tag: bool,
}
impl Release {
pub fn new() -> Self {
Self {
bump_level: BumpLevel::Patch,
pre_release_suffix: "alpha".to_string(),
allow_dirty: false,
skip_git: false,
skip_push: false,
skip_tag: false,
}
}
pub fn set_pre_release_suffix( &mut self, pre_release_suffix: &str ) {
self.pre_release_suffix = pre_release_suffix.to_string();
}
pub fn set_bump_level(&mut self, bump_level: &str ) -> anyhow::Result<()> {
self.bump_level = match bump_level {
"patch" => BumpLevel::Patch,
"minor" => BumpLevel::Minor,
"major" => BumpLevel::Major,
o => bail!( "Invalid bump level: {}", &o ),
};
Ok(())
}
pub fn set_allow_dirty( &mut self, allow_dirty: bool ) {
self.allow_dirty = allow_dirty;
}
pub fn set_skip_git( &mut self, skip_git: bool ) {
self.skip_git = skip_git;
}
pub fn set_skip_push( &mut self, skip_push: bool ) {
self.skip_push = skip_push;
}
pub fn set_skip_tag( &mut self, skip_tag: bool ) {
self.skip_tag = skip_tag;
}
pub fn run( &self ) -> anyhow::Result<()> {
if false { let root = std::path::Path::new(&std::env::current_dir()?).join("./automatic-octo-guacamole/");
std::env::set_current_dir(&root)?;
} else {
}
println!("Working in {:?}", std::env::current_dir()?);
let mut repo = Repository::new( "." );
if !self.skip_git {
repo.open()?;
if !self.allow_dirty { println!("Checking if repository is clean...");
let dirty = repo.get_dirty();
if dirty.len() > 0 {
println!("Dirty files:");
for d in dirty.iter() {
println!("{}", d);
}
bail!("Repository is dirty");
}
println!("Repositiory is clean (enough)");
} else {
println!("Skipping check if repository is clean!");
}
}
let mut manifest = Manifest::new( "Cargo.toml" );
manifest.load()?;
let old_version = manifest.get_pretty_version()?;
println!("Current version: {}", &old_version);
manifest.set_version_suffix( &self.pre_release_suffix )?;
manifest.save()?;
let mut cargo = Cargo::new( "." );
cargo.open()?;
cargo.update_workspace()?;
let release_version = manifest.get_pretty_version()?;
println!("Release version: {}", &release_version);
if !self.skip_git {
let dirty = repo.get_dirty();
if dirty.len() > 0 {
println!("Dirty files:");
for d in dirty.iter() {
println!("{}", d);
}
}
let mut files = Vec::new();
files.push( "Cargo.toml".to_owned() );
files.push( "Cargo.lock".to_owned() );
let msg = format!( ": Bump version for {} release - {}", &self.pre_release_suffix ,&release_version );
println!("Commit");
repo.commit( &files, &msg )?;
println!("Fetch");
if repo.fetch()? > 0 {
bail!("Fetch was not empty. Please resolve manually!")
};
println!("Rebase");
repo.rebase()?;
if !self.skip_push {
println!("Push");
repo.push()?;
} else {
println!("Skipping push to origin as requested.");
}
if !self.skip_tag {
let tag_msg = format!( ". Tag {}", &release_version );
println!("Tag");
repo.tag( &release_version, &tag_msg )?;
if !self.skip_push {
println!("Push Tag");
repo.push_tag( &release_version )?;
} else {
println!("Skipping push (of tag) to origin as requested.");
}
} else {
println!("Skipping tagging as requested.");
}
}
let mut repo = Repository::new( "." );
if !self.skip_git {
repo.open()?;
}
println!("---- Post Release ----");
match self.bump_level {
BumpLevel::Patch => manifest.bump_patch_version()?,
BumpLevel::Minor => manifest.bump_minor_version()?,
BumpLevel::Major => manifest.bump_major_version()?,
};
manifest.set_version_suffix("dev")?;
manifest.save()?;
cargo.update_workspace()?;
let new_version = manifest.get_pretty_version()?;
println!("New development version: {}", &new_version);
if !self.skip_git {
let mut files = Vec::new();
files.push( "Cargo.toml".to_owned() );
files.push( "Cargo.lock".to_owned() );
let msg = format!( ": Bump version back to dev release, and bump patch level - {}", &new_version );
repo.commit( &files, &msg )?;
let dirty = repo.get_dirty();
if dirty.len() > 0 {
println!("Dirty files before fetch:");
for d in dirty.iter() {
println!("{}", d);
}
}
println!("Fetch");
if repo.fetch()? > 0 {
bail!("Fetch was not empty. Please resolve manually!")
};
println!("Rebase");
repo.rebase()?;
if !self.skip_push {
println!("Push");
repo.push()?;
} else {
println!("Skipping push to origin as requested.");
}
let dirty = repo.get_dirty();
if dirty.len() > 0 {
println!("Dirty files:");
for d in dirty.iter() {
println!("{}", d);
}
}
}
Ok(())
}
}