#[cfg(windows)]
use crate::WINDOWS_DIRS;
#[cfg(unix)]
use crate::XDG_DIRS;
use crate::terminal::{print_separator, prompt_yesno};
use color_eyre::eyre::{Context, Result};
use etcetera::base_strategy::BaseStrategy;
use rust_i18n::t;
use semver::Version;
use std::path::PathBuf;
use std::process::exit;
use std::{env, fs};
static VERSION_STR: &str = env!("CARGO_PKG_VERSION");
static BREAKINGCHANGES: &str = include_str!(concat!(env!("OUT_DIR"), "/breaking_changes.txt"));
pub(crate) fn run() -> Result<()> {
let version = VERSION_STR.parse::<Version>().expect("should be a valid version");
let keep_file = keep_file_path();
if !keep_file.exists() {
write_keep_file()?;
return Ok(());
}
if version.major
> fs::read_to_string(&keep_file)?
.parse::<Version>()
.wrap_err_with(|| format!("Invalid version in Topgrade keep file at {}", keep_file.display()))?
.major
{
print_separator(t!(
"Topgrade {version_str} Breaking Changes",
version_str = format!("v{}", version.major)
));
let contents = if BREAKINGCHANGES.is_empty() {
t!("No breaking changes").to_string()
} else {
BREAKINGCHANGES.to_string()
};
println!(
"{contents}\nSee the full release notes at {}\n",
release_notes_link(VERSION_STR)
);
if prompt_yesno(&t!("Continue?"))? {
write_keep_file()?;
} else {
exit(1);
}
}
Ok(())
}
fn release_notes_link(version: &str) -> String {
format!("https://github.com/topgrade-rs/topgrade/releases/tag/v{version}")
}
fn write_keep_file() -> Result<()> {
fs::create_dir_all(data_dir())?;
fs::write(keep_file_path(), VERSION_STR)?;
Ok(())
}
fn data_dir() -> PathBuf {
#[cfg(unix)]
return XDG_DIRS.data_dir();
#[cfg(windows)]
return WINDOWS_DIRS.data_dir();
}
fn keep_file_path() -> PathBuf {
data_dir().join("topgrade_keep")
}
pub(crate) fn should_skip() -> bool {
env::var("TOPGRADE_SKIP_BRKC_NOTIFY").is_ok_and(|var| var.as_str() == "true")
}