style: 格式化代码并优化导入顺序
This commit is contained in:
@@ -95,9 +95,7 @@ impl ChangelogGenerator {
|
||||
ChangelogFormat::GitHubReleases => {
|
||||
self.generate_github_releases(version, date, commits)
|
||||
}
|
||||
ChangelogFormat::Custom => {
|
||||
self.generate_custom(version, date, commits)
|
||||
}
|
||||
ChangelogFormat::Custom => self.generate_custom(version, date, commits),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,13 +108,13 @@ impl ChangelogGenerator {
|
||||
commits: &[CommitInfo],
|
||||
) -> Result<()> {
|
||||
let entry = self.generate(version, date, commits)?;
|
||||
|
||||
|
||||
let existing = if changelog_path.exists() {
|
||||
fs::read_to_string(changelog_path)?
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
|
||||
let new_content = if existing.is_empty() {
|
||||
format!("{}{}", CHANGELOG_HEADER, entry)
|
||||
} else if existing.starts_with(CHANGELOG_HEADER) {
|
||||
@@ -124,7 +122,7 @@ impl ChangelogGenerator {
|
||||
} else if existing.starts_with("# Changelog") {
|
||||
let lines: Vec<&str> = existing.lines().collect();
|
||||
let mut header_end = 0;
|
||||
|
||||
|
||||
for (i, line) in lines.iter().enumerate() {
|
||||
if i == 0 && line.starts_with('#') {
|
||||
header_end = i + 1;
|
||||
@@ -134,18 +132,18 @@ impl ChangelogGenerator {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let header = lines[..header_end].join("\n");
|
||||
let rest = lines[header_end..].join("\n");
|
||||
|
||||
|
||||
format!("{}\n{}\n{}", header, entry, rest)
|
||||
} else {
|
||||
format!("{}{}", CHANGELOG_HEADER, entry)
|
||||
};
|
||||
|
||||
|
||||
fs::write(changelog_path, new_content)
|
||||
.with_context(|| format!("Failed to write changelog: {:?}", changelog_path))?;
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -157,10 +155,10 @@ impl ChangelogGenerator {
|
||||
) -> Result<String> {
|
||||
let date_str = date.format("%Y-%m-%d").to_string();
|
||||
let mut output = format!("## [{}] - {}\n\n", version, date_str);
|
||||
|
||||
|
||||
if self.group_by_type {
|
||||
let _grouped = self.group_commits(commits);
|
||||
|
||||
|
||||
// Standard categories
|
||||
let categories = vec![
|
||||
("Added", vec!["feat"]),
|
||||
@@ -170,7 +168,7 @@ impl ChangelogGenerator {
|
||||
("Fixed", vec!["fix"]),
|
||||
("Security", vec!["security"]),
|
||||
];
|
||||
|
||||
|
||||
for (title, types) in &categories {
|
||||
let items: Vec<&CommitInfo> = commits
|
||||
.iter()
|
||||
@@ -182,7 +180,7 @@ impl ChangelogGenerator {
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
if !items.is_empty() {
|
||||
output.push_str(&format!("### {}\n\n", title));
|
||||
for commit in items {
|
||||
@@ -192,13 +190,13 @@ impl ChangelogGenerator {
|
||||
output.push('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Other changes
|
||||
let categorized: Vec<String> = categories
|
||||
.iter()
|
||||
.flat_map(|(_, types)| types.iter().map(|s| s.to_string()))
|
||||
.collect();
|
||||
|
||||
|
||||
let other: Vec<&CommitInfo> = commits
|
||||
.iter()
|
||||
.filter(|c| {
|
||||
@@ -209,7 +207,7 @@ impl ChangelogGenerator {
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
if !other.is_empty() {
|
||||
output.push_str("### Other\n\n");
|
||||
for commit in other {
|
||||
@@ -224,7 +222,7 @@ impl ChangelogGenerator {
|
||||
output.push('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
@@ -235,19 +233,19 @@ impl ChangelogGenerator {
|
||||
commits: &[CommitInfo],
|
||||
) -> Result<String> {
|
||||
let mut output = "## What's Changed\n\n".to_string();
|
||||
|
||||
|
||||
// Group by type
|
||||
let mut features = vec![];
|
||||
let mut fixes = vec![];
|
||||
let mut docs = vec![];
|
||||
let mut other = vec![];
|
||||
let mut breaking = vec![];
|
||||
|
||||
|
||||
for commit in commits {
|
||||
if commit.message.contains("BREAKING CHANGE") {
|
||||
breaking.push(commit);
|
||||
}
|
||||
|
||||
|
||||
if let Some(ref t) = commit.commit_type() {
|
||||
match t.as_str() {
|
||||
"feat" => features.push(commit),
|
||||
@@ -259,7 +257,7 @@ impl ChangelogGenerator {
|
||||
other.push(commit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if !breaking.is_empty() {
|
||||
output.push_str("### ⚠ Breaking Changes\n\n");
|
||||
for commit in breaking {
|
||||
@@ -267,7 +265,7 @@ impl ChangelogGenerator {
|
||||
}
|
||||
output.push('\n');
|
||||
}
|
||||
|
||||
|
||||
if !features.is_empty() {
|
||||
output.push_str("### 🚀 Features\n\n");
|
||||
for commit in features {
|
||||
@@ -275,7 +273,7 @@ impl ChangelogGenerator {
|
||||
}
|
||||
output.push('\n');
|
||||
}
|
||||
|
||||
|
||||
if !fixes.is_empty() {
|
||||
output.push_str("### 🐛 Bug Fixes\n\n");
|
||||
for commit in fixes {
|
||||
@@ -283,7 +281,7 @@ impl ChangelogGenerator {
|
||||
}
|
||||
output.push('\n');
|
||||
}
|
||||
|
||||
|
||||
if !docs.is_empty() {
|
||||
output.push_str("### 📚 Documentation\n\n");
|
||||
for commit in docs {
|
||||
@@ -291,14 +289,14 @@ impl ChangelogGenerator {
|
||||
}
|
||||
output.push('\n');
|
||||
}
|
||||
|
||||
|
||||
if !other.is_empty() {
|
||||
output.push_str("### Other Changes\n\n");
|
||||
for commit in other {
|
||||
output.push_str(&self.format_commit_github(commit));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
@@ -312,7 +310,7 @@ impl ChangelogGenerator {
|
||||
if !self.custom_categories.is_empty() {
|
||||
let date_str = date.format("%Y-%m-%d").to_string();
|
||||
let mut output = format!("## [{}] - {}\n\n", version, date_str);
|
||||
|
||||
|
||||
for category in &self.custom_categories {
|
||||
let items: Vec<&CommitInfo> = commits
|
||||
.iter()
|
||||
@@ -324,7 +322,7 @@ impl ChangelogGenerator {
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
if !items.is_empty() {
|
||||
output.push_str(&format!("### {}\n\n", category.title));
|
||||
for commit in items {
|
||||
@@ -334,7 +332,7 @@ impl ChangelogGenerator {
|
||||
output.push('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ok(output)
|
||||
} else {
|
||||
// Fall back to keep-a-changelog
|
||||
@@ -344,30 +342,35 @@ impl ChangelogGenerator {
|
||||
|
||||
fn format_commit(&self, commit: &CommitInfo) -> String {
|
||||
let mut line = format!("- {}", commit.subject());
|
||||
|
||||
|
||||
if self.include_hashes {
|
||||
line.push_str(&format!(" ({})", &commit.short_id));
|
||||
}
|
||||
|
||||
|
||||
if self.include_authors {
|
||||
line.push_str(&format!(" - @{}", commit.author));
|
||||
}
|
||||
|
||||
|
||||
line
|
||||
}
|
||||
|
||||
fn format_commit_github(&self, commit: &CommitInfo) -> String {
|
||||
format!("- {} by @{} in {}\n", commit.subject(), commit.author, &commit.short_id)
|
||||
format!(
|
||||
"- {} by @{} in {}\n",
|
||||
commit.subject(),
|
||||
commit.author,
|
||||
&commit.short_id
|
||||
)
|
||||
}
|
||||
|
||||
fn group_commits<'a>(&self, commits: &'a [CommitInfo]) -> HashMap<String, Vec<&'a CommitInfo>> {
|
||||
let mut groups: HashMap<String, Vec<&'a CommitInfo>> = HashMap::new();
|
||||
|
||||
|
||||
for commit in commits {
|
||||
let commit_type = commit.commit_type().unwrap_or_else(|| "other".to_string());
|
||||
groups.entry(commit_type).or_default().push(commit);
|
||||
}
|
||||
|
||||
|
||||
groups
|
||||
}
|
||||
}
|
||||
@@ -380,8 +383,7 @@ impl Default for ChangelogGenerator {
|
||||
|
||||
/// Read existing changelog
|
||||
pub fn read_changelog(path: &Path) -> Result<String> {
|
||||
fs::read_to_string(path)
|
||||
.with_context(|| format!("Failed to read changelog: {:?}", path))
|
||||
fs::read_to_string(path).with_context(|| format!("Failed to read changelog: {:?}", path))
|
||||
}
|
||||
|
||||
/// Initialize new changelog file
|
||||
@@ -389,10 +391,10 @@ pub fn init_changelog(path: &Path) -> Result<()> {
|
||||
if path.exists() {
|
||||
anyhow::bail!("Changelog already exists at {:?}", path);
|
||||
}
|
||||
|
||||
|
||||
fs::write(path, CHANGELOG_HEADER)
|
||||
.with_context(|| format!("Failed to create changelog: {:?}", path))?;
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -403,7 +405,7 @@ pub fn generate_from_history(
|
||||
to_ref: Option<&str>,
|
||||
) -> Result<Vec<CommitInfo>> {
|
||||
let to_ref = to_ref.unwrap_or("HEAD");
|
||||
|
||||
|
||||
if let Some(from) = from_tag {
|
||||
repo.get_commits_between(from, to_ref)
|
||||
} else {
|
||||
@@ -413,11 +415,7 @@ pub fn generate_from_history(
|
||||
}
|
||||
|
||||
/// Update version links in changelog
|
||||
pub fn update_version_links(
|
||||
changelog: &str,
|
||||
version: &str,
|
||||
compare_url: &str,
|
||||
) -> String {
|
||||
pub fn update_version_links(changelog: &str, version: &str, compare_url: &str) -> String {
|
||||
// Add version link at the end of changelog
|
||||
format!("{}\n[{}]: {}\n", changelog, version, compare_url)
|
||||
}
|
||||
@@ -425,27 +423,29 @@ pub fn update_version_links(
|
||||
/// Parse changelog to extract versions
|
||||
pub fn parse_versions(changelog: &str) -> Vec<(String, String)> {
|
||||
let mut versions = vec![];
|
||||
|
||||
|
||||
for line in changelog.lines() {
|
||||
if line.starts_with("## [")
|
||||
&& let Some(start) = line.find('[')
|
||||
&& let Some(end) = line.find(']') {
|
||||
let version = &line[start + 1..end];
|
||||
if version != "Unreleased"
|
||||
&& let Some(date_start) = line.find(" - ") {
|
||||
let date = &line[date_start + 3..].trim();
|
||||
versions.push((version.to_string(), date.to_string()));
|
||||
}
|
||||
}
|
||||
&& let Some(end) = line.find(']')
|
||||
{
|
||||
let version = &line[start + 1..end];
|
||||
if version != "Unreleased"
|
||||
&& let Some(date_start) = line.find(" - ")
|
||||
{
|
||||
let date = &line[date_start + 3..].trim();
|
||||
versions.push((version.to_string(), date.to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
versions
|
||||
}
|
||||
|
||||
/// Get unreleased changes
|
||||
pub fn get_unreleased_changes(repo: &GitRepo) -> Result<Vec<CommitInfo>> {
|
||||
let tags = repo.get_tags()?;
|
||||
|
||||
|
||||
if let Some(latest_tag) = tags.first() {
|
||||
repo.get_commits_between(&latest_tag.name, "HEAD")
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user