chore(build): preparing for CI
This commit is contained in:
@@ -37,3 +37,10 @@ predicates = "3.1.3"
|
|||||||
|
|
||||||
[lints.rust]
|
[lints.rust]
|
||||||
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin_include)'] }
|
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin_include)'] }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = "z"
|
||||||
|
lto = true
|
||||||
|
codegen-units = 1
|
||||||
|
panic = "abort"
|
||||||
|
strip = true
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
pkgs,
|
||||||
rustPlatform,
|
rustPlatform,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
@@ -8,8 +9,17 @@
|
|||||||
rustBuild = rustPlatform.buildRustPackage {
|
rustBuild = rustPlatform.buildRustPackage {
|
||||||
pname = name;
|
pname = name;
|
||||||
inherit version;
|
inherit version;
|
||||||
src = ../.;
|
src = pkgs.lib.cleanSource ../.;
|
||||||
cargoLock.lockFile = ../Cargo.lock;
|
cargoLock.lockFile = ../Cargo.lock;
|
||||||
|
buildInputs = [ pkgs.upx ];
|
||||||
|
useNextest = true;
|
||||||
|
meta = {
|
||||||
|
description = "Conventional commits for Jujutsu";
|
||||||
|
homepage = "https://labs.phundrak.com/phundrak/jj-cz";
|
||||||
|
};
|
||||||
|
postBuild = ''
|
||||||
|
${pkgs.upx}/bin/upx target/*/release/${name}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
default = rustBuild;
|
default = rustBuild;
|
||||||
|
|||||||
@@ -19,26 +19,10 @@ inputs.devenv.lib.mkShell {
|
|||||||
})
|
})
|
||||||
bacon
|
bacon
|
||||||
cargo-deny
|
cargo-deny
|
||||||
|
cargo-nextest
|
||||||
cargo-tarpaulin
|
cargo-tarpaulin
|
||||||
just
|
just
|
||||||
];
|
];
|
||||||
|
|
||||||
# processes.run.exec = "cargo watch -x run";
|
|
||||||
|
|
||||||
# enterShell = ''
|
|
||||||
# echo ""
|
|
||||||
# echo "Rust development environment loaded!"
|
|
||||||
# echo "Rust version: $(rustc --version)"
|
|
||||||
# echo "Cargo version: $(cargo --version)"
|
|
||||||
# echo ""
|
|
||||||
# echo "Available tools:"
|
|
||||||
# echo " - rust-analyzer (LSP)"
|
|
||||||
# echo " - clippy (linter)"
|
|
||||||
# echo " - rustfmt (formatter)"
|
|
||||||
# echo " - bacon (continuous testing/linting)"
|
|
||||||
# echo " - cargo-deny (dependency checker)"
|
|
||||||
# echo " - cargo-tarpaulin (code coverage)"
|
|
||||||
# '';
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,44 +127,51 @@ impl JjExecutor for JjLib {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
/// Initialize a jj repository in the given directory using `jj git init`
|
/// Initialize a jj repository in the given directory using jj-lib directly
|
||||||
fn init_jj_repo(dir: &Path) -> std::io::Result<()> {
|
async fn init_jj_repo(dir: &Path) -> Result<(), String> {
|
||||||
let output = Command::new("jj")
|
let settings = JjLib::load_settings().map_err(|e| e.to_string())?;
|
||||||
.args(["git", "init"])
|
Workspace::init_internal_git(&settings, dir)
|
||||||
.current_dir(dir)
|
.await
|
||||||
.output()?;
|
.map(|_| ())
|
||||||
|
.map_err(|e| format!("Failed to init jj repo: {e}"))
|
||||||
if !output.status.success() {
|
|
||||||
return Err(std::io::Error::other(format!(
|
|
||||||
"jj git init failed: {}",
|
|
||||||
String::from_utf8_lossy(&output.stderr)
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current commit description from a jj repository
|
/// Get the current commit description from a jj repository using jj-lib
|
||||||
fn get_commit_description(dir: &Path) -> std::io::Result<String> {
|
async fn get_commit_description(dir: &Path) -> Result<String, String> {
|
||||||
let output = Command::new("jj")
|
let settings = JjLib::load_settings().map_err(|e| e.to_string())?;
|
||||||
.args(["log", "-r", "@", "--no-graph", "-T", "description"])
|
let store_factories = StoreFactories::default();
|
||||||
.current_dir(dir)
|
let wc_factories = default_working_copy_factories();
|
||||||
.output()?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
let workspace = Workspace::load(&settings, dir, &store_factories, &wc_factories)
|
||||||
return Err(std::io::Error::other(format!(
|
.map_err(|e| format!("Failed to load workspace: {e}"))?;
|
||||||
"jj log failed: {}",
|
|
||||||
String::from_utf8_lossy(&output.stderr)
|
let repo = workspace
|
||||||
)));
|
.repo_loader()
|
||||||
}
|
.load_at_head()
|
||||||
Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
|
.await
|
||||||
|
.map_err(|e| format!("Failed to load repo: {e}"))?;
|
||||||
|
|
||||||
|
let wc_commit_id = repo
|
||||||
|
.view()
|
||||||
|
.get_wc_commit_id(WorkspaceName::DEFAULT)
|
||||||
|
.ok_or_else(|| "No working copy commit found".to_string())?
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
let wc_commit = repo
|
||||||
|
.store()
|
||||||
|
.get_commit(&wc_commit_id)
|
||||||
|
.map_err(|e| format!("Failed to get commit: {e}"))?;
|
||||||
|
|
||||||
|
Ok(wc_commit.description().trim_end().to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn is_repository_returns_true_inside_jj_repo() {
|
async fn is_repository_returns_true_inside_jj_repo() {
|
||||||
let temp_dir = assert_fs::TempDir::new().unwrap();
|
let temp_dir = assert_fs::TempDir::new().unwrap();
|
||||||
init_jj_repo(temp_dir.path()).expect("Failed to init jj repo");
|
init_jj_repo(temp_dir.path())
|
||||||
|
.await
|
||||||
|
.expect("Failed to init jj repo");
|
||||||
|
|
||||||
let executor = JjLib::with_working_dir(temp_dir.path());
|
let executor = JjLib::with_working_dir(temp_dir.path());
|
||||||
let result = executor.is_repository().await;
|
let result = executor.is_repository().await;
|
||||||
@@ -187,7 +194,9 @@ mod tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn describe_updates_commit_description() {
|
async fn describe_updates_commit_description() {
|
||||||
let temp_dir = assert_fs::TempDir::new().unwrap();
|
let temp_dir = assert_fs::TempDir::new().unwrap();
|
||||||
init_jj_repo(temp_dir.path()).expect("Failed to init jj repo");
|
init_jj_repo(temp_dir.path())
|
||||||
|
.await
|
||||||
|
.expect("Failed to init jj repo");
|
||||||
|
|
||||||
let test_message = "test: initial commit";
|
let test_message = "test: initial commit";
|
||||||
let executor = JjLib::with_working_dir(temp_dir.path());
|
let executor = JjLib::with_working_dir(temp_dir.path());
|
||||||
@@ -195,14 +204,18 @@ mod tests {
|
|||||||
let result = executor.describe(test_message).await;
|
let result = executor.describe(test_message).await;
|
||||||
assert!(result.is_ok(), "describe failed: {result:?}");
|
assert!(result.is_ok(), "describe failed: {result:?}");
|
||||||
|
|
||||||
let actual = get_commit_description(temp_dir.path()).expect("Failed to get description");
|
let actual = get_commit_description(temp_dir.path())
|
||||||
|
.await
|
||||||
|
.expect("Failed to get description");
|
||||||
assert_eq!(actual, test_message);
|
assert_eq!(actual, test_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn describe_handles_special_characters() {
|
async fn describe_handles_special_characters() {
|
||||||
let temp_dir = assert_fs::TempDir::new().unwrap();
|
let temp_dir = assert_fs::TempDir::new().unwrap();
|
||||||
init_jj_repo(temp_dir.path()).expect("Failed to init jj repo");
|
init_jj_repo(temp_dir.path())
|
||||||
|
.await
|
||||||
|
.expect("Failed to init jj repo");
|
||||||
|
|
||||||
let test_message = "feat: add feature with special chars !@#$%^&*()";
|
let test_message = "feat: add feature with special chars !@#$%^&*()";
|
||||||
let executor = JjLib::with_working_dir(temp_dir.path());
|
let executor = JjLib::with_working_dir(temp_dir.path());
|
||||||
@@ -210,14 +223,18 @@ mod tests {
|
|||||||
let result = executor.describe(test_message).await;
|
let result = executor.describe(test_message).await;
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
|
|
||||||
let actual = get_commit_description(temp_dir.path()).expect("Failed to get description");
|
let actual = get_commit_description(temp_dir.path())
|
||||||
|
.await
|
||||||
|
.expect("Failed to get description");
|
||||||
assert_eq!(actual, test_message);
|
assert_eq!(actual, test_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn describe_handles_unicode() {
|
async fn describe_handles_unicode() {
|
||||||
let temp_dir = assert_fs::TempDir::new().unwrap();
|
let temp_dir = assert_fs::TempDir::new().unwrap();
|
||||||
init_jj_repo(temp_dir.path()).expect("Failed to init jj repo");
|
init_jj_repo(temp_dir.path())
|
||||||
|
.await
|
||||||
|
.expect("Failed to init jj repo");
|
||||||
|
|
||||||
let test_message = "docs: add unicode support 🎉 🚀";
|
let test_message = "docs: add unicode support 🎉 🚀";
|
||||||
let executor = JjLib::with_working_dir(temp_dir.path());
|
let executor = JjLib::with_working_dir(temp_dir.path());
|
||||||
@@ -225,14 +242,18 @@ mod tests {
|
|||||||
let result = executor.describe(test_message).await;
|
let result = executor.describe(test_message).await;
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
|
|
||||||
let actual = get_commit_description(temp_dir.path()).expect("Failed to get description");
|
let actual = get_commit_description(temp_dir.path())
|
||||||
|
.await
|
||||||
|
.expect("Failed to get description");
|
||||||
assert_eq!(actual, test_message);
|
assert_eq!(actual, test_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn describe_handles_multiline_message() {
|
async fn describe_handles_multiline_message() {
|
||||||
let temp_dir = assert_fs::TempDir::new().unwrap();
|
let temp_dir = assert_fs::TempDir::new().unwrap();
|
||||||
init_jj_repo(temp_dir.path()).expect("Failed to init jj repo");
|
init_jj_repo(temp_dir.path())
|
||||||
|
.await
|
||||||
|
.expect("Failed to init jj repo");
|
||||||
|
|
||||||
let test_message = "feat: add feature\n\nThis is a multiline\ndescription";
|
let test_message = "feat: add feature\n\nThis is a multiline\ndescription";
|
||||||
let executor = JjLib::with_working_dir(temp_dir.path());
|
let executor = JjLib::with_working_dir(temp_dir.path());
|
||||||
@@ -240,7 +261,9 @@ mod tests {
|
|||||||
let result = executor.describe(test_message).await;
|
let result = executor.describe(test_message).await;
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
|
|
||||||
let actual = get_commit_description(temp_dir.path()).expect("Failed to get description");
|
let actual = get_commit_description(temp_dir.path())
|
||||||
|
.await
|
||||||
|
.expect("Failed to get description");
|
||||||
assert_eq!(actual, test_message);
|
assert_eq!(actual, test_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +281,9 @@ mod tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn describe_can_be_called_multiple_times() {
|
async fn describe_can_be_called_multiple_times() {
|
||||||
let temp_dir = assert_fs::TempDir::new().unwrap();
|
let temp_dir = assert_fs::TempDir::new().unwrap();
|
||||||
init_jj_repo(temp_dir.path()).expect("Failed to init jj repo");
|
init_jj_repo(temp_dir.path())
|
||||||
|
.await
|
||||||
|
.expect("Failed to init jj repo");
|
||||||
|
|
||||||
let executor = JjLib::with_working_dir(temp_dir.path());
|
let executor = JjLib::with_working_dir(temp_dir.path());
|
||||||
|
|
||||||
@@ -266,16 +291,18 @@ mod tests {
|
|||||||
.describe("feat: first commit")
|
.describe("feat: first commit")
|
||||||
.await
|
.await
|
||||||
.expect("First describe failed");
|
.expect("First describe failed");
|
||||||
let desc1 =
|
let desc1 = get_commit_description(temp_dir.path())
|
||||||
get_commit_description(temp_dir.path()).expect("Failed to get first description");
|
.await
|
||||||
|
.expect("Failed to get first description");
|
||||||
assert_eq!(desc1, "feat: first commit");
|
assert_eq!(desc1, "feat: first commit");
|
||||||
|
|
||||||
executor
|
executor
|
||||||
.describe("feat: updated commit")
|
.describe("feat: updated commit")
|
||||||
.await
|
.await
|
||||||
.expect("Second describe failed");
|
.expect("Second describe failed");
|
||||||
let desc2 =
|
let desc2 = get_commit_description(temp_dir.path())
|
||||||
get_commit_description(temp_dir.path()).expect("Failed to get second description");
|
.await
|
||||||
|
.expect("Failed to get second description");
|
||||||
assert_eq!(desc2, "feat: updated commit");
|
assert_eq!(desc2, "feat: updated commit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,4 @@ pub use crate::{
|
|||||||
///
|
///
|
||||||
/// Enable with `--features test-utils` (e.g. `cargo test --features test-utils`).
|
/// Enable with `--features test-utils` (e.g. `cargo test --features test-utils`).
|
||||||
#[cfg(feature = "test-utils")]
|
#[cfg(feature = "test-utils")]
|
||||||
pub use crate::{
|
pub use crate::{jj::mock::MockJjExecutor, prompts::mock::MockPrompts};
|
||||||
jj::mock::MockJjExecutor,
|
|
||||||
prompts::mock::MockPrompts,
|
|
||||||
};
|
|
||||||
|
|||||||
Reference in New Issue
Block a user