Something went wrong. Try again.
A native desktop app that quietly cleans copied text and links using rules you control
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186#![cfg(unix)]
use std::io::Write;use std::path::Path;use std::path::PathBuf;use std::process::{Command, Stdio};
fn transform(config: &str, input: &str) -> std::process::Output { let root = tempfile::tempdir().unwrap(); let mut child = Command::new(env!("CARGO_BIN_EXE_clipboard-transformer")) .args(["transform", "-", "--config", config]) .env("XDG_CONFIG_HOME", root.path().join("config")) .env("XDG_STATE_HOME", root.path().join("state")) .env("XDG_CACHE_HOME", root.path().join("cache")) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .unwrap(); child .stdin .take() .unwrap() .write_all(input.as_bytes()) .unwrap(); child.wait_with_output().unwrap()}
fn transform_file(config: &Path, input: &str) -> std::process::Output { let root = tempfile::tempdir().unwrap(); let mut child = Command::new(env!("CARGO_BIN_EXE_clipboard-transformer")) .args(["transform", "-", "--config-file"]) .arg(config) .env("XDG_CONFIG_HOME", root.path().join("config")) .env("XDG_STATE_HOME", root.path().join("state")) .env("XDG_CACHE_HOME", root.path().join("cache")) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .unwrap(); child .stdin .take() .unwrap() .write_all(input.as_bytes()) .unwrap(); child.wait_with_output().unwrap()}
fn example_plugin_module() -> Option<PathBuf> { let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) .join("../../plugins/gitlab-link/target/wasm32-wasip1/release/gitlab_link.wasm"); path.is_file().then_some(path)}
#[test]fn shell_rule_transforms_stdin_with_the_system_shell_contract() { let output = transform( r#"config: shell: enabled: truerules: - id: uppercase type: shell shell: /bin/sh run: tr '[:lower:]' '[:upper:]'"#, "Hello shell", );
assert!(output.status.success(), "{output:?}"); assert_eq!(String::from_utf8(output.stdout).unwrap(), "HELLO SHELL");}
#[test]fn item_shell_rule_can_atomically_replace_text() { let output = transform( r#"config: shell: enabled: truerules: - id: item-output type: item-shell shell: /bin/sh run: | printf '%s' '{"action":"replace-text","text":"item result"}' > "$CT_OUTPUT_ITEM""#, "original", );
assert!(output.status.success(), "{output:?}"); assert_eq!(String::from_utf8(output.stdout).unwrap(), "item result");}
#[test]fn script_path_is_relative_to_the_declaring_import() { let root = tempfile::tempdir().unwrap(); let rules_dir = root.path().join("rules"); std::fs::create_dir_all(&rules_dir).unwrap(); std::fs::write( root.path().join("config.yaml"), r#"config: shell: enabled: truerules: - import: rules/shell.yaml"#, ) .unwrap(); std::fs::write( rules_dir.join("shell.yaml"), r#"rules: - id: uppercase-file type: shell shell: /bin/sh script_path: uppercase.sh"#, ) .unwrap(); std::fs::write(rules_dir.join("uppercase.sh"), "tr '[:lower:]' '[:upper:]'").unwrap();
let output = transform_file(&root.path().join("config.yaml"), "Imported script"); assert!(output.status.success(), "{output:?}"); assert_eq!( String::from_utf8(output.stdout.clone()).unwrap(), "IMPORTED SCRIPT", "{output:?}" );}
#[test]fn plugin_transform_keeps_runtime_trace_out_of_stderr() { let Some(module) = example_plugin_module() else { eprintln!( "skipping plugin CLI test: run `just build-example-plugin` to build the guest module" ); return; }; let root = tempfile::tempdir().unwrap(); std::fs::copy(module, root.path().join("gitlab-link.wasm")).unwrap(); let config = r#"rules: - id: gitlab-project type: dev.jag-k.gitlab/project hosts: [gitlab.example.com] online: false"#; let mut child = Command::new(env!("CARGO_BIN_EXE_clipboard-transformer")) .args([ "transform", "-", "--config", config, "--plugin-dir", root.path().to_str().unwrap(), ]) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .unwrap(); child .stdin .take() .unwrap() .write_all(b"https://gitlab.example.com/acme/widget") .unwrap(); let output = child.wait_with_output().unwrap();
assert!(output.status.success(), "{output:?}"); assert_eq!( String::from_utf8(output.stdout).unwrap(), "[acme/widget](https://gitlab.example.com/acme/widget)" ); assert!( output.stderr.is_empty(), "unexpected stderr: {}", String::from_utf8_lossy(&output.stderr) );}