Skip to content

Commit

Permalink
chore: merge pull request #20 from websublime/feature/docs-and-change…
Browse files Browse the repository at this point in the history
…-file-exist

feat: change file exist check
  • Loading branch information
miguelramos authored Jul 22, 2024
2 parents 301bdb6 + 4ee4151 commit 248eaf3
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "workspace-node-tools"
version = "1.0.8"
version = "1.0.9"
edition = "2021"
description = "Node workspace version tools"
repository = "https://github.com/websublime/workspace-node-tools"
Expand Down
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,28 @@
[![Docs.rs](https://docs.rs/workspace-node-tools/badge.svg)](https://docs.rs/workspace-node-tools)
[![CI](https://github.com/websublime/workspace-node-tools/workflows/CI/badge.svg)](https://github.com/websublime/workspace-node-tools/actions)

## About

This is a tool to help manage packages in a monorepo style. It can give info about packages existence, package manager defined (node), git helpers to check which package as changes, manage those changes thur a file (.changes.json), give output of conventional commit and changelog generation.

## Installation

`cargo install workspace-node-tools`

### Cargo

* Install the rust toolchain in order to have cargo installed by following
- Install the rust toolchain in order to have cargo installed by following
[this](https://www.rust-lang.org/tools/install) guide.
* run `cargo install workspace-node-tools`
- run `cargo install workspace-node-tools`

## License

Licensed under either of

* Apache License, Version 2.0
([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license
([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0
([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license
([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.

Expand All @@ -35,4 +39,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md).

## Info

Template from [here](https://rust-github.github.io/)
Template from [here](https://rust-github.github.io/)
9 changes: 9 additions & 0 deletions src/bumps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub enum Bump {

#[cfg(not(feature = "napi"))]
#[derive(Debug, Clone, Deserialize, Serialize, Copy, PartialEq)]
/// Enum representing the type of bump to be performed.
pub enum Bump {
Major,
Minor,
Expand All @@ -50,6 +51,7 @@ pub struct BumpOptions {

#[cfg(not(feature = "napi"))]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
/// Struct representing the options for the bump operation.
pub struct BumpOptions {
pub packages: Vec<String>,
pub release_as: Bump,
Expand All @@ -60,6 +62,7 @@ pub struct BumpOptions {

#[cfg(not(feature = "napi"))]
#[derive(Debug, Clone, Deserialize, Serialize)]
/// Struct representing the bump package.
pub struct BumpPackage {
pub from: String,
pub to: String,
Expand All @@ -78,6 +81,7 @@ pub struct BumpPackage {
}

impl Bump {
/// Bumps the version of the package to major.
fn bump_major(version: String) -> SemVersion {
let mut sem_version = SemVersion::parse(&version).unwrap();
sem_version.major += 1;
Expand All @@ -88,6 +92,7 @@ impl Bump {
sem_version
}

/// Bumps the version of the package to minor.
fn bump_minor(version: String) -> SemVersion {
let mut sem_version = SemVersion::parse(&version).unwrap();
sem_version.minor += 1;
Expand All @@ -97,6 +102,7 @@ impl Bump {
sem_version
}

/// Bumps the version of the package to patch.
fn bump_patch(version: String) -> SemVersion {
let mut sem_version = SemVersion::parse(&version).unwrap();
sem_version.patch += 1;
Expand All @@ -105,6 +111,7 @@ impl Bump {
sem_version
}

/// Bumps the version of the package to snapshot appending the sha to the version.
fn bump_snapshot(version: String) -> SemVersion {
let sha = git_current_sha(None);
let alpha = format!("alpha.{}", sha);
Expand All @@ -116,6 +123,7 @@ impl Bump {
}
}

/// Bumps the version of dev-dependencies and dependencies.
pub fn sync_bumps(bump_package: &BumpPackage, cwd: Option<String>) -> Vec<String> {
get_packages(cwd)
.iter()
Expand All @@ -139,6 +147,7 @@ pub fn sync_bumps(bump_package: &BumpPackage, cwd: Option<String>) -> Vec<String
.collect::<Vec<String>>()
}

/// Get bumps version of the package.
pub fn get_bumps(options: BumpOptions) -> Vec<BumpPackage> {
let ref root = match options.cwd {
Some(ref dir) => get_project_root_path(Some(PathBuf::from(dir))).unwrap(),
Expand Down
43 changes: 43 additions & 0 deletions src/changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//! The changes are stored in a `.changes.json` file in the root of the project.
//!
//! # Example
//! ```json
//! {
//! "message": "chore(release): release new version",
//! "changes": {
Expand All @@ -16,6 +17,7 @@
//! }],
//! }
//!}
//!```
use serde::{Deserialize, Serialize};
use std::io::BufWriter;
use std::{
Expand All @@ -30,10 +32,12 @@ use crate::bumps::Bump;
use super::git::git_current_branch;
use super::paths::get_project_root_path;

/// Dynamic data structure to store changes
type ChangesData = BTreeMap<String, Vec<Change>>;

#[cfg(not(feature = "napi"))]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
/// Options to initialize the changes file
pub struct ChangesOptions {
pub message: Option<String>,
}
Expand All @@ -47,6 +51,7 @@ pub struct ChangesOptions {

#[cfg(not(feature = "napi"))]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
/// Data structure to store changes file
pub struct ChangesFileData {
pub message: Option<String>,
pub changes: ChangesData,
Expand All @@ -62,6 +67,7 @@ pub struct ChangesFileData {

#[cfg(not(feature = "napi"))]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
/// Data structure to store changes
pub struct Changes {
pub changes: ChangesData,
}
Expand All @@ -75,6 +81,7 @@ pub struct Changes {

#[cfg(not(feature = "napi"))]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
/// Data structure to store a change
pub struct Change {
pub package: String,
pub release_as: Bump,
Expand All @@ -90,6 +97,8 @@ pub struct Change {
pub deploy: Vec<String>,
}

/// Initialize the changes file. If the file does not exist, it will create it with the default message.
/// If the file exists, it will return the content of the file.
pub fn init_changes(
cwd: Option<String>,
change_options: &Option<ChangesOptions>,
Expand Down Expand Up @@ -131,6 +140,7 @@ pub fn init_changes(
}
}

/// Add a change to the changes file in the root of the project.
pub fn add_change(change: &Change, cwd: Option<String>) -> bool {
let ref root = match cwd {
Some(ref dir) => get_project_root_path(Some(PathBuf::from(dir))).unwrap(),
Expand Down Expand Up @@ -182,6 +192,7 @@ pub fn add_change(change: &Change, cwd: Option<String>) -> bool {
false
}

/// Remove a change from the changes file in the root of the project.
pub fn remove_change(branch_name: String, cwd: Option<String>) -> bool {
let ref root = match cwd {
Some(ref dir) => get_project_root_path(Some(PathBuf::from(dir))).unwrap(),
Expand Down Expand Up @@ -212,6 +223,7 @@ pub fn remove_change(branch_name: String, cwd: Option<String>) -> bool {
false
}

/// Get all changes from the changes file in the root of the project.
pub fn get_changes(cwd: Option<String>) -> Changes {
let ref root = match cwd {
Some(ref dir) => get_project_root_path(Some(PathBuf::from(dir))).unwrap(),
Expand All @@ -237,6 +249,7 @@ pub fn get_changes(cwd: Option<String>) -> Changes {
}
}

/// Get all changes for a specific branch from the changes file in the root of the project.
pub fn get_change(branch: String, cwd: Option<String>) -> Vec<Change> {
let ref root = match cwd {
Some(ref dir) => get_project_root_path(Some(PathBuf::from(dir))).unwrap(),
Expand All @@ -262,6 +275,7 @@ pub fn get_change(branch: String, cwd: Option<String>) -> Vec<Change> {
vec![]
}

/// Check if a change exists in the changes file in the root of the project.
pub fn change_exist(branch: String, cwd: Option<String>) -> bool {
let ref root = match cwd {
Some(ref dir) => get_project_root_path(Some(PathBuf::from(dir))).unwrap(),
Expand All @@ -283,6 +297,19 @@ pub fn change_exist(branch: String, cwd: Option<String>) -> bool {
false
}

/// Check if a changes file exists in the root of the project.
pub fn changes_file_exist(cwd: Option<String>) -> bool {
let ref root = match cwd {
Some(ref dir) => get_project_root_path(Some(PathBuf::from(dir))).unwrap(),
None => get_project_root_path(None).unwrap(),
};

let root_path = Path::new(root);
let ref changes_path = root_path.join(String::from(".changes.json"));

changes_path.exists()
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -436,4 +463,20 @@ mod tests {
remove_dir_all(&monorepo_dir)?;
Ok(())
}

#[test]
fn test_changes_file_exist() -> Result<(), Box<dyn std::error::Error>> {
let ref monorepo_dir = create_test_monorepo(&PackageManager::Npm)?;
let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf()));

let ref root = project_root.unwrap().to_string();

let ref changes_path = monorepo_dir.join(String::from(".changes.json"));
let result = changes_file_exist(Some(root.to_string()));

assert_eq!(result, false);
assert_eq!(changes_path.is_file(), false);
remove_dir_all(&monorepo_dir)?;
Ok(())
}
}
54 changes: 49 additions & 5 deletions src/conventional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use git_cliff_core::{
use regex::Regex;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use std::fs::read_to_string;
use std::path::PathBuf;

use super::git::{
Expand All @@ -34,6 +35,7 @@ pub struct ConventionalPackage {

#[cfg(not(feature = "napi"))]
#[derive(Debug, Clone, Deserialize, Serialize)]
/// A struct that represents a conventional package
pub struct ConventionalPackage {
pub package_info: PackageInfo,
pub conventional_config: Value,
Expand All @@ -51,11 +53,13 @@ pub struct ConventionalPackageOptions {

#[cfg(not(feature = "napi"))]
#[derive(Debug, Clone)]
/// A struct that represents options for a conventional package
pub struct ConventionalPackageOptions {
pub version: Option<String>,
pub title: Option<String>,
}

/// Process commits for groupint type, extracting data
fn process_commits<'a>(commits: &Vec<Commit>, config: &GitConfig) -> Vec<GitCommit<'a>> {
commits
.iter()
Expand All @@ -78,6 +82,7 @@ fn process_commits<'a>(commits: &Vec<Commit>, config: &GitConfig) -> Vec<GitComm
.collect::<Vec<GitCommit>>()
}

/// Defines the config for conventional, template usage for changelog
fn define_config(
owner: String,
repo: String,
Expand Down Expand Up @@ -239,6 +244,7 @@ fn define_config(
cliff_config
}

/// Generate changelog output
fn generate_changelog(
commits: &Vec<GitCommit>,
config: &Config,
Expand All @@ -258,6 +264,30 @@ fn generate_changelog(
String::from_utf8(changelog_output).unwrap_or_default()
}

/// Prepend changelog output
fn prepend_generate_changelog(
commits: &Vec<GitCommit>,
config: &Config,
changelog_content: &String,
version: Option<String>,
) -> String {
let releases = Release {
version,
commits: commits.to_vec().to_owned(),
..Release::default()
};

let changelog = Changelog::new(vec![releases], config);
let mut changelog_output = Vec::new();

changelog
.unwrap()
.prepend(changelog_content.to_string(), &mut changelog_output)
.unwrap();

String::from_utf8(changelog_output).unwrap_or_default()
}

/// Give info about commits in a package, generate changelog output
pub fn get_conventional_for_package(
package_info: &PackageInfo,
Expand All @@ -270,6 +300,9 @@ pub fn get_conventional_for_package(
None => get_project_root_path(None).unwrap(),
};

let changelog_dir =
PathBuf::from(package_info.package_path.to_string()).join(String::from("CHANGELOG.md"));

if no_fetch_all.is_some() {
git_fetch_all(Some(current_working_dir.to_string()), no_fetch_all).expect("Fetch all");
}
Expand Down Expand Up @@ -344,11 +377,22 @@ pub fn get_conventional_for_package(

let conventional_commits = process_commits(&commits_since, &conventional_config.git);

let changelog = generate_changelog(
&conventional_commits,
&conventional_config,
conventional_default_options.version,
);
let changelog = match changelog_dir.exists() {
true => {
let changelog_content = read_to_string(&changelog_dir).unwrap();
prepend_generate_changelog(
&conventional_commits,
&conventional_config,
&changelog_content,
conventional_default_options.version,
)
}
false => generate_changelog(
&conventional_commits,
&conventional_config,
conventional_default_options.version,
),
};

let changelog_output = &changelog.to_string();
conventional_package.changelog_output = changelog_output.to_string();
Expand Down
Loading

0 comments on commit 248eaf3

Please sign in to comment.