use indexmap for channel table - fix channels reordered

cl-status
Ondřej Hruška 2 days ago
parent 12933d363b
commit 0ad3cfffdf
  1. 2
      Cargo.lock
  2. 1
      Cargo.toml
  3. 6
      src/config.rs
  4. 15
      src/store.rs

2
Cargo.lock generated

@ -171,6 +171,7 @@ dependencies = [
"clap", "clap",
"colored", "colored",
"faccess", "faccess",
"indexmap",
"inquire", "inquire",
"regex", "regex",
"serde", "serde",
@ -339,6 +340,7 @@ checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown",
"serde",
] ]
[[package]] [[package]]

@ -17,6 +17,7 @@ anyhow = "1"
colored = "3" colored = "3"
faccess = "0.2" faccess = "0.2"
chrono = "0.4" chrono = "0.4"
indexmap = { version = "2.11", features = ["serde"] }
# input # input

@ -1,6 +1,6 @@
use indexmap::IndexMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use smart_default::SmartDefault; use smart_default::SmartDefault;
use std::collections::HashMap;
/// e.g. default, stable, eap /// e.g. default, stable, eap
pub type ChannelName = String; pub type ChannelName = String;
@ -75,10 +75,10 @@ pub struct Config {
/// To specify a regex, enclose it in slashes, e.g. /rel\/foo/ /// To specify a regex, enclose it in slashes, e.g. /rel\/foo/
/// ///
/// If you have a naming schema like e.g. `beta/1.0` where only the prefix stays the same, you may use e.g. `^beta/.*` /// If you have a naming schema like e.g. `beta/1.0` where only the prefix stays the same, you may use e.g. `^beta/.*`
#[default(HashMap::from([ #[default(IndexMap::from([
("default".to_string(), "/^(?:main|master)$/".to_string()) ("default".to_string(), "/^(?:main|master)$/".to_string())
]))] ]))]
pub channels: HashMap<ChannelName, String>, pub channels: IndexMap<ChannelName, String>,
/// Regex pattern to extract issue number from a branch name. /// Regex pattern to extract issue number from a branch name.
/// There should be one capture group that is the number. /// There should be one capture group that is the number.

@ -5,10 +5,10 @@ use colored::Colorize;
use faccess::PathExt; use faccess::PathExt;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::HashMap;
use std::fs::{OpenOptions, read_to_string}; use std::fs::{OpenOptions, read_to_string};
use std::io::{BufRead, BufReader, Write}; use std::io::{BufRead, BufReader, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use indexmap::IndexMap;
const DIR_ENTRIES: &str = "entries"; const DIR_ENTRIES: &str = "entries";
const DIR_CHANNELS: &str = "channels"; const DIR_CHANNELS: &str = "channels";
@ -20,7 +20,7 @@ pub struct Store<'a> {
/// Path to the changelog directory /// Path to the changelog directory
store_path: PathBuf, store_path: PathBuf,
/// Loaded version history for all channels /// Loaded version history for all channels
versions: HashMap<ChannelName, ChannelReleaseStore>, versions: IndexMap<ChannelName, ChannelReleaseStore>,
} }
impl<'a> Store<'a> { impl<'a> Store<'a> {
@ -51,7 +51,7 @@ impl<'a> Store<'a> {
let mut store = Self { let mut store = Self {
store_path, store_path,
ctx, ctx,
versions: HashMap::new(), versions: IndexMap::new(),
}; };
store.ensure_internal_subdirs_exist()?; store.ensure_internal_subdirs_exist()?;
@ -241,7 +241,7 @@ pub struct Release {
impl Release { impl Release {
/// Render the entry into a Markdown fragment, using h2 (##) as the title, h3 (###) for sections /// Render the entry into a Markdown fragment, using h2 (##) as the title, h3 (###) for sections
pub fn render(&self, entries_dir: impl AsRef<Path>, config: &Config) -> anyhow::Result<String> { pub fn render(&self, entries_dir: impl AsRef<Path>, config: &Config) -> anyhow::Result<String> {
let mut entries_per_section = HashMap::<String, String>::new(); let mut entries_per_section = IndexMap::<String, String>::new();
let entries_dir = entries_dir.as_ref(); let entries_dir = entries_dir.as_ref();
let unnamed = "".to_string(); let unnamed = "".to_string();
@ -261,6 +261,7 @@ impl Release {
let mut current_section = unnamed.clone(); let mut current_section = unnamed.clone();
for line in reader.lines() { for line in reader.lines() {
let line = line?; let line = line?;
let line = line.trim_end();
if line.trim().is_empty() { if line.trim().is_empty() {
continue; continue;
} }
@ -273,7 +274,7 @@ impl Release {
buffer.push('\n'); buffer.push('\n');
buffer.push_str(&line); buffer.push_str(&line);
} else { } else {
entries_per_section.insert(current_section.clone(), line); entries_per_section.insert(current_section.clone(), line.to_string());
} }
} }
} }
@ -282,12 +283,12 @@ impl Release {
let mut reordered_sections = Vec::<(String, String)>::new(); let mut reordered_sections = Vec::<(String, String)>::new();
// First the unlabelled section (this is probably junk, but it was entered by the user, so keep it) // First the unlabelled section (this is probably junk, but it was entered by the user, so keep it)
if let Some(unlabelled) = entries_per_section.remove("") { if let Some(unlabelled) = entries_per_section.swap_remove("") {
reordered_sections.push(("".to_string(), unlabelled)); reordered_sections.push(("".to_string(), unlabelled));
} }
for section_name in [unnamed].iter().chain(config.sections.iter()) { for section_name in [unnamed].iter().chain(config.sections.iter()) {
if let Some(content) = entries_per_section.remove(section_name) { if let Some(content) = entries_per_section.swap_remove(section_name) {
reordered_sections.push((section_name.clone(), content)); reordered_sections.push((section_name.clone(), content));
} }
} }

Loading…
Cancel
Save