Compare commits

..

No commits in common. '340b520e588434c645063b40794bc16962606fbf' and 'df234e24074745a7ca420f4b3f8c082623fa9c94' have entirely different histories.

  1. 3
      changelog/entries/Add "cl status".md
  2. 106
      src/action_pack.rs
  3. 14
      src/action_status.rs
  4. 26
      src/main.rs
  5. 28
      src/store.rs

@ -1,3 +0,0 @@
# New features
- Add command line option `cl status` (#SW-4716)
- Change `cl pack` to show a preview of the rendered changelog before asking for version.

@ -1,56 +1,21 @@
use crate::AppContext;
use crate::config::ChannelName;
use crate::git::{BranchName, get_branch_name};
use crate::git::get_branch_name;
use crate::store::{Release, Store};
use anyhow::bail;
use colored::Colorize;
pub fn pack_resolve_and_show_preview(
ctx: &AppContext,
user_chosen_channel: Option<ChannelName>,
branch: Option<&BranchName>,
) -> anyhow::Result<Option<(Release, ChannelName)>> {
let channel = resolve_channel(&ctx, user_chosen_channel, branch)?;
let store = Store::new(&ctx, false)?;
let unreleased = store.find_unreleased_changes(&channel)?;
if unreleased.is_empty() {
eprintln!("No unreleased changes.");
return Ok(None);
}
println!();
println!("Changes waiting for release:");
for entry in &unreleased {
println!("+ {}", entry.cyan());
}
println!();
let release = Release {
version: "Unreleased".to_string(),
entries: unreleased,
};
let rendered = store.render_release(&release)?;
println!("\nPreview:\n\n{}", rendered);
Ok(Some((release, channel)))
}
/// Perform the action of packing changelog entries for a release
pub(crate) fn cl_pack(ctx: AppContext, channel: Option<ChannelName>) -> anyhow::Result<()> {
let mut store = Store::new(&ctx, false)?;
let branch = get_branch_name(&ctx);
/// Resolve channel from current branch or other context info, ask if needed
fn resolve_channel(
ctx: &AppContext,
user_chosen_channel: Option<ChannelName>,
branch: Option<&BranchName>,
) -> anyhow::Result<ChannelName> {
let (channel_detected, channel_explicit) = match user_chosen_channel {
let (channel_detected, channel_explicit) = match channel {
Some(ch) => (Some(ch), true), // passed via flag already
None => (
branch
.as_ref()
.map(|b| b.parse_channel(ctx))
.map(|b| b.parse_channel(&ctx))
.transpose()?
.flatten(),
false,
@ -63,6 +28,22 @@ fn resolve_channel(
bail!("No such channel: {ch}");
}
// If the branch is named rel/3.40, this can extract 3.40.
// TODO try to get something better from git!
let version_base = branch
.as_ref()
.map(|b| b.parse_version(&ctx))
.transpose()?
.flatten();
// TODO detect version from git query?
// TODO remove this
eprintln!(
"Branch name: {:?}, channel: {:?}, version: {:?}",
branch, channel_detected, version_base
);
// Ask for the channel
let channel = if ctx.config.channels.len() > 1 {
if channel_explicit {
@ -85,31 +66,19 @@ fn resolve_channel(
};
println!("Channel: {}", channel.green().bold());
Ok(channel)
}
let unreleased = store.find_unreleased_changes(&channel)?;
/// Perform the action of packing changelog entries for a release
pub(crate) fn cl_pack(
ctx: AppContext,
user_chosen_channel: Option<ChannelName>,
) -> anyhow::Result<()> {
let branch = get_branch_name(&ctx);
let Some((mut release, channel)) =
pack_resolve_and_show_preview(&ctx, user_chosen_channel, branch.as_ref())?
else {
// No changes
if unreleased.is_empty() {
eprintln!("No unreleased changes.");
return Ok(());
};
let mut store = Store::new(&ctx, false)?;
}
// If the branch is named rel/3.40, this can extract 3.40.
// TODO try to get something better from git!
let version_base = branch
.as_ref()
.map(|b| b.parse_version(&ctx))
.transpose()?
.flatten();
println!();
println!("Changes waiting for release:");
for entry in &unreleased {
println!("+ {}", entry.cyan());
}
println!();
// Ask for the version
let mut version = version_base.unwrap_or_default();
@ -130,7 +99,14 @@ pub(crate) fn cl_pack(
}
}
release.version = version;
let release = Release {
version,
entries: unreleased,
};
let rendered = store.render_release(&release)?;
println!("\n\nPreview:\n\n{}\n", rendered);
if !inquire::Confirm::new("Continue - write to changelog file?")
.with_default(true)

@ -1,14 +0,0 @@
use crate::AppContext;
use crate::action_pack::pack_resolve_and_show_preview;
use crate::config::ChannelName;
use crate::git::{get_branch_name};
/// Perform the action of packing changelog entries for a release
pub(crate) fn cl_status(
ctx: AppContext,
user_chosen_channel: Option<ChannelName>,
) -> anyhow::Result<()> {
let branch = get_branch_name(&ctx);
pack_resolve_and_show_preview(&ctx, user_chosen_channel, branch.as_ref())?;
Ok(())
}

@ -1,7 +1,6 @@
use crate::action_init::{ClInit, cl_init};
use crate::action_init::{cl_init, ClInit};
use crate::action_log::cl_log;
use crate::action_pack::cl_pack;
use crate::action_status::cl_status;
use crate::config::{ChannelName, Config};
use anyhow::bail;
use clap::builder::NonEmptyStringValueParser;
@ -18,8 +17,6 @@ mod action_pack;
mod action_init;
mod action_status;
mod store;
mod utils;
@ -50,12 +47,6 @@ fn main_try() -> anyhow::Result<()> {
.flatten()
.unwrap_or_else(|| "cl".to_string());
let optional_channel_arg = clap::Arg::new("CHANNEL")
.short('x')
.long("channel")
.value_parser(NonEmptyStringValueParser::new())
.required(false);
let args = clap::Command::new(&binary_name)
.version(env!("CARGO_PKG_VERSION"))
.author(env!("CARGO_PKG_AUTHORS"))
@ -66,12 +57,11 @@ fn main_try() -> anyhow::Result<()> {
clap::Command::new("pack")
.visible_alias("release")
.about("Pack changelog entries to a changelog section")
.arg(optional_channel_arg.clone()),
)
.subcommand(
clap::Command::new("status")
.about("Show outstanding change entries on the current channel (or specified channel)")
.arg(optional_channel_arg),
.arg(clap::Arg::new("CHANNEL")
.short('x')
.long("channel")
.value_parser(NonEmptyStringValueParser::new())
.required(false)),
)
.subcommand(clap::Command::new("add")
.visible_alias("log")
@ -143,10 +133,6 @@ fn main_try() -> anyhow::Result<()> {
let channel: Option<ChannelName> = subargs.get_one("CHANNEL").cloned();
cl_pack(ctx, channel)?;
}
Some(("status", subargs)) => {
let channel: Option<ChannelName> = subargs.get_one("CHANNEL").cloned();
cl_status(ctx, channel)?;
}
None | Some(("add", _)) => cl_log(ctx)?,
// TODO: status, flush
Some((other, _)) => {

@ -382,32 +382,22 @@ struct ChannelReleaseStore {
impl ChannelReleaseStore {
/// Load from a versions file
fn load(releases_file: PathBuf, channel_name: ChannelName) -> anyhow::Result<Self> {
println!(
"Loading versions for channel {} from: {}",
channel_name,
releases_file.display()
);
let releases = if !releases_file.exists() {
// File did not exist yet, create it - this catches error with write access early
let mut f = OpenOptions::new()
.write(true)
.create(true)
.open(&releases_file)
.with_context(|| {
format!("Failed to open channel file: {}", releases_file.display())
})?;
f.write_all("[]".as_bytes()).with_context(|| {
format!(
"Failed to write into channel file: {}",
releases_file.display()
)
})?;
.open(&releases_file)?;
f.write_all("[]".as_bytes())?;
Default::default()
} else {
let channel_json = read_to_string(&releases_file).with_context(|| {
format!("Failed to read channel file: {}", releases_file.display())
})?;
serde_json::from_str::<ReleaseList>(&channel_json).with_context(|| {
format!(
"Failed to parse content of channel file: {}",
releases_file.display()
)
})?
let channel_json = read_to_string(&releases_file)?;
serde_json::from_str::<ReleaseList>(&channel_json)?
};
Ok(Self {

Loading…
Cancel
Save