diff --git a/src/conventional.rs b/src/conventional.rs index 8f6075ef..3fa0fd26 100644 --- a/src/conventional.rs +++ b/src/conventional.rs @@ -1,3 +1,6 @@ +//! # Conventional +//! +//! This module is responsible for generating changelog output for a package based on conventional commits. #![allow(clippy::all)] use git_cliff_core::{ changelog::Changelog, @@ -267,8 +270,8 @@ pub fn get_conventional_for_package( None => get_project_root_path(None).unwrap(), }; - if no_fetch_all.is_none() { - git_fetch_all(Some(current_working_dir.to_string()), None).expect("Fetch all"); + if no_fetch_all.is_some() { + git_fetch_all(Some(current_working_dir.to_string()), no_fetch_all).expect("Fetch all"); } let tag_info = get_last_known_publish_tag_info_for_package( @@ -356,3 +359,137 @@ pub fn get_conventional_for_package( conventional_package } + +#[cfg(test)] +mod tests { + use super::*; + + use crate::manager::PackageManager; + use crate::packages::get_packages; + use crate::paths::get_project_root_path; + use crate::utils::create_test_monorepo; + use std::fs::remove_dir_all; + use std::fs::File; + use std::io::Write; + use std::process::Command; + use std::process::Stdio; + + fn create_package_change(monorepo_dir: &PathBuf) -> Result<(), Box> { + let js_path = monorepo_dir.join("packages/package-b/index.js"); + + let branch = Command::new("git") + .current_dir(&monorepo_dir) + .arg("checkout") + .arg("-b") + .arg("feat/message") + .stdout(Stdio::piped()) + .spawn() + .expect("Git branch problem"); + + branch.wait_with_output()?; + + let mut js_file = File::create(&js_path)?; + js_file + .write_all(r#"export const message = "hello";"#.as_bytes()) + .unwrap(); + + let add = Command::new("git") + .current_dir(&monorepo_dir) + .arg("add") + .arg(".") + .stdout(Stdio::piped()) + .spawn() + .expect("Git add problem"); + + add.wait_with_output()?; + + let commit = Command::new("git") + .current_dir(&monorepo_dir) + .arg("commit") + .arg("-m") + .arg("feat: message to the world") + .stdout(Stdio::piped()) + .spawn() + .expect("Git commit problem"); + + commit.wait_with_output()?; + + let main = Command::new("git") + .current_dir(&monorepo_dir) + .arg("checkout") + .arg("main") + .stdout(Stdio::piped()) + .spawn() + .expect("Git checkout problem"); + + main.wait_with_output()?; + + let merge = Command::new("git") + .current_dir(&monorepo_dir) + .arg("merge") + .arg("feat/message") + .stdout(Stdio::piped()) + .spawn() + .expect("Git merge problem"); + + merge.wait_with_output()?; + + let tag_b = Command::new("git") + .current_dir(&monorepo_dir) + .arg("tag") + .arg("-a") + .arg("@scope/package-b@1.1.0") + .arg("-m") + .arg("chore: release package-b@1.1.0") + .stdout(Stdio::piped()) + .spawn() + .expect("Git tag problem"); + + tag_b.wait_with_output()?; + + Ok(()) + } + + #[test] + fn test_get_conventional_for_package() -> Result<(), Box> { + 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 packages = get_packages(Some(root.to_string())); + let package = packages.first(); + + let conventional = + get_conventional_for_package(package.unwrap(), None, Some(root.to_string()), &None); + + assert_eq!(conventional.package_info, package.unwrap().to_owned()); + remove_dir_all(&monorepo_dir)?; + Ok(()) + } + + #[test] + fn test_get_conventional_for_package_with_changes() -> Result<(), Box> { + let ref monorepo_dir = create_test_monorepo(&PackageManager::Npm)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); + + create_package_change(monorepo_dir)?; + + let ref root = project_root.unwrap().to_string(); + + let packages = get_packages(Some(root.to_string())); + let package = packages.first(); + + let conventional = + get_conventional_for_package(package.unwrap(), None, Some(root.to_string()), &None); + + assert_eq!( + conventional + .changelog_output + .contains("Message to the world"), + true + ); + remove_dir_all(&monorepo_dir)?; + Ok(()) + } +} diff --git a/src/git.rs b/src/git.rs index b0abe1f9..8fa5e1dc 100644 --- a/src/git.rs +++ b/src/git.rs @@ -167,6 +167,7 @@ pub fn git_previous_sha(cwd: Option) -> String { let output = command.execute_output().unwrap(); let hash = String::from_utf8(output.stdout).unwrap(); + strip_trailing_newline(&hash) } @@ -703,79 +704,126 @@ pub fn get_last_known_publish_tag_info_for_all_packages( .collect::>>() } -/* #[cfg(test)] mod tests { use super::*; + use crate::{ + manager::PackageManager, paths::get_project_root_path, utils::create_test_monorepo, + }; + use std::fs::{remove_dir_all, File}; #[test] - fn test_git_fetch_all() { - let result = git_fetch_all(None, None); - assert_eq!(result.unwrap(), true); + fn test_git_fetch_all() -> Result<(), std::io::Error> { + let ref monorepo_dir = create_test_monorepo(&PackageManager::Npm)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); + + let result = git_fetch_all(project_root, None)?; + assert_eq!(result, false); + remove_dir_all(&monorepo_dir)?; + Ok(()) } #[test] - fn test_get_diverged_commit() { - let result = get_diverged_commit(String::from("0.9.0"), None); - dbg!(&result); + fn test_get_diverged_commit() -> Result<(), std::io::Error> { + let ref monorepo_dir = create_test_monorepo(&PackageManager::Npm)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); + + let result = get_diverged_commit(String::from("@scope/package-a@1.0.0"), project_root); + assert!(result.is_some()); + remove_dir_all(&monorepo_dir)?; + Ok(()) } #[test] - fn test_git_current_sha() { - let result = git_current_sha(None); + fn test_git_current_sha() -> Result<(), std::io::Error> { + let ref monorepo_dir = create_test_monorepo(&PackageManager::Npm)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); + + let result = git_current_sha(project_root); assert_eq!(result.is_empty(), false); + remove_dir_all(&monorepo_dir)?; + Ok(()) } #[test] - fn test_git_previous_sha() { - let result = git_previous_sha(None); - dbg!(&result); - assert_eq!(result.is_empty(), false); + fn test_git_previous_sha() -> Result<(), std::io::Error> { + let ref monorepo_dir = create_test_monorepo(&PackageManager::Npm)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); + + let result = git_previous_sha(project_root); + assert_eq!(result.is_empty(), true); + remove_dir_all(&monorepo_dir)?; + Ok(()) } #[test] - fn test_git_workdir_unclean() { - let result = git_workdir_unclean(None); - assert_eq!(result, result); + fn test_git_workdir_unclean() -> Result<(), std::io::Error> { + let ref monorepo_dir = create_test_monorepo(&PackageManager::Npm)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); + let js_path = monorepo_dir.join("packages/package-a/index.js"); + + let mut js_file = File::create(&js_path)?; + js_file.write_all(r#"export const message = "hello";"#.as_bytes())?; + + let result = git_workdir_unclean(project_root); + assert_eq!(result, true); + remove_dir_all(&monorepo_dir)?; + Ok(()) } #[test] - fn test_git_branch_from_commit() { - let commit = git_current_sha(None); - let result = git_branch_from_commit(commit, None); + fn test_git_branch_from_commit() -> Result<(), std::io::Error> { + let ref monorepo_dir = create_test_monorepo(&PackageManager::Npm)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); + + let commit = git_current_sha(Some(project_root.as_ref().unwrap().to_string())); + let result = git_branch_from_commit(commit, project_root); assert_eq!(result.is_some(), true); + remove_dir_all(&monorepo_dir)?; + Ok(()) } #[test] - fn test_get_commits_since() { + fn test_get_commits_since() -> Result<(), std::io::Error> { + let ref monorepo_dir = create_test_monorepo(&PackageManager::Npm)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); + let result = get_commits_since( - None, + project_root, Some(String::from("main")), Some(String::from("packages/package-a")), ); let count = result.len(); - assert_eq!(count, count); - } - #[test] - fn test_get_local_tags() { - let result = get_remote_or_local_tags(None, Some(true)); - let count = result.len(); - assert_eq!(count, count); + assert_eq!(count, 0); + remove_dir_all(&monorepo_dir)?; + Ok(()) } #[test] - fn test_get_remote_tags() { - let result = get_remote_or_local_tags(None, Some(false)); + fn test_get_local_tags() -> Result<(), std::io::Error> { + let ref monorepo_dir = create_test_monorepo(&PackageManager::Npm)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); + + let result = get_remote_or_local_tags(project_root, Some(true)); let count = result.len(); - assert_eq!(count, count); + + assert_eq!(count, 2); + remove_dir_all(&monorepo_dir)?; + Ok(()) } #[test] - fn test_git_all_files_changed_since_sha() { - let result = git_all_files_changed_since_sha(String::from("main"), None); + fn test_git_all_files_changed_since_sha() -> Result<(), std::io::Error> { + let ref monorepo_dir = create_test_monorepo(&PackageManager::Npm)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); + + let result = git_all_files_changed_since_sha(String::from("main"), project_root); let count = result.len(); - assert_eq!(count, count); + + assert_eq!(count, 0); + remove_dir_all(&monorepo_dir)?; + Ok(()) } -}*/ +} diff --git a/src/manager.rs b/src/manager.rs index b77aedfb..85e5f8df 100644 --- a/src/manager.rs +++ b/src/manager.rs @@ -63,85 +63,61 @@ pub fn detect_package_manager(path: &Path) -> Option { None } -/* #[cfg(test)] mod tests { use super::*; - use core::time; - use std::{fs::{remove_file, File}, thread}; - - fn create_package_manager_file(path: &Path) -> Result { - let file = File::create(path)?; - thread::sleep(time::Duration::from_secs(1)); - Ok(file) - } - - fn delete_package_manager_file(path: &Path) -> Result<(), std::io::Error> { - remove_file(path)?; - thread::sleep(time::Duration::from_secs(1)); - Ok(()) - } + use crate::{paths::get_project_root_path, utils::create_test_monorepo}; + use std::{fs::remove_dir_all, path::PathBuf}; #[test] fn package_manager_for_npm_lock() -> Result<(), std::io::Error> { - let path = std::env::current_dir().expect("Current user home directory"); - let npm_lock = path.join("package-lock.json"); + let ref monorepo_dir = create_test_monorepo(&PackageManager::Npm)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); - create_package_manager_file(&npm_lock)?; - - let package_manager = detect_package_manager(&path); + let package_manager = + detect_package_manager(&PathBuf::from(project_root.unwrap()).as_path()); assert_eq!(package_manager, Some(PackageManager::Npm)); - - delete_package_manager_file(&npm_lock)?; + remove_dir_all(&monorepo_dir)?; Ok(()) } #[test] fn package_manager_for_yarn_lock() -> Result<(), std::io::Error> { - let path = std::env::current_dir().expect("Current user home directory"); - let yarn_lock = path.join("yarn.lock"); - - create_package_manager_file(&yarn_lock)?; + let ref monorepo_dir = create_test_monorepo(&PackageManager::Yarn)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); - let package_manager = detect_package_manager(&path); + let package_manager = + detect_package_manager(&PathBuf::from(project_root.unwrap()).as_path()); assert_eq!(package_manager, Some(PackageManager::Yarn)); - - delete_package_manager_file(&yarn_lock)?; + remove_dir_all(&monorepo_dir)?; Ok(()) } #[test] fn package_manager_for_pnpm_lock() -> Result<(), std::io::Error> { - let path = std::env::current_dir().expect("Current user home directory"); - let pnpm_lock = path.join("pnpm-lock.yaml"); - - create_package_manager_file(&pnpm_lock)?; + let ref monorepo_dir = create_test_monorepo(&PackageManager::Pnpm)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); - let package_manager = detect_package_manager(&path); + let package_manager = + detect_package_manager(&PathBuf::from(project_root.unwrap()).as_path()); assert_eq!(package_manager, Some(PackageManager::Pnpm)); - - delete_package_manager_file(&pnpm_lock)?; + remove_dir_all(&monorepo_dir)?; Ok(()) } #[test] fn package_manager_for_bun_lock() -> Result<(), std::io::Error> { - let path = std::env::current_dir().expect("Current user home directory"); - let bun_lock = path.join("bun.lockb"); + let ref monorepo_dir = create_test_monorepo(&PackageManager::Bun)?; + let project_root = get_project_root_path(Some(monorepo_dir.to_path_buf())); - dbg!(&bun_lock); - dbg!(&path); - - create_package_manager_file(&bun_lock)?; - - let package_manager = detect_package_manager(&path); + let package_manager = + detect_package_manager(&PathBuf::from(project_root.unwrap()).as_path()); assert_eq!(package_manager, Some(PackageManager::Bun)); - - delete_package_manager_file(&bun_lock)?; + remove_dir_all(&monorepo_dir)?; Ok(()) } @@ -161,4 +137,4 @@ mod tests { assert_eq!(package_manager.unwrap().to_string(), String::from("")); } -}*/ +} diff --git a/src/packages.rs b/src/packages.rs index fbb69c20..7fd7ce76 100644 --- a/src/packages.rs +++ b/src/packages.rs @@ -378,7 +378,7 @@ pub fn get_changed_packages(sha: Option, cwd: Option) -> Vec Result<(), Box> { let js_path = monorepo_dir.join("packages/package-a/index.js"); @@ -500,8 +501,12 @@ mod tests { create_package_change(monorepo_dir)?; let packages = get_changed_packages(Some("main".to_string()), project_root); + let package = packages.first(); + + let changed_files = package.unwrap().get_changed_files(); assert_eq!(packages.len(), 1); + assert_eq!(changed_files.len(), 1); remove_dir_all(&monorepo_dir)?; Ok(()) } diff --git a/src/utils.rs b/src/utils.rs index 8c2067f9..9ff1719d 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -161,7 +161,7 @@ pub(crate) fn create_test_monorepo( )?; } PackageManager::Bun => { - let bun_lock = monorepo_temp_dir.join("bun.lock"); + let bun_lock = monorepo_temp_dir.join("bun.lockb"); File::create(&bun_lock)?; } PackageManager::Npm => {