Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,29 @@ jobs:

- name: Clippy
working-directory: src-tauri
run: cargo clippy -- -D warnings
run: cargo clippy --all-targets --all-features -- -D warnings

- name: Install cargo-tarpaulin
run: cargo install cargo-tarpaulin
- name: Run tests
working-directory: src-tauri
run: cargo test --verbose

- name: Run tests with coverage
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov

- name: Generate coverage
working-directory: src-tauri
run: cargo tarpaulin --out Xml --fail-under 80 --verbose
run: cargo llvm-cov --all-features --lcov --output-path ../coverage-rust.lcov

- name: Upload coverage
uses: codecov/codecov-action@v4
with:
files: ./coverage-rust.lcov
flags: backend
fail_ci_if_error: false

- name: Build check
working-directory: src-tauri
run: cargo build
run: cargo build --release

# Build verification (ensures app can be built)
build-check:
Expand Down
35 changes: 35 additions & 0 deletions src-tauri/Cargo.lock

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

2 changes: 2 additions & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ env_logger = "0.11"
# Error handling
thiserror = "2"
anyhow = "1"
sysinfo = "0.36.1"
open = "5.3.3"

[dev-dependencies]
tempfile = "3"
Expand Down
1 change: 1 addition & 0 deletions src-tauri/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod system;
107 changes: 107 additions & 0 deletions src-tauri/src/commands/system.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use crate::utils::permissions;
use serde::Serialize;
#[cfg(not(target_os = "macos"))]
use std::path::PathBuf;
use sysinfo::Disks;
use tauri::command;

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DiskInfo {
pub total_space: u64,
pub available_space: u64,
pub used_space: u64,
pub mount_point: String,
pub name: String,
}

#[command]
pub fn get_disk_info() -> Result<DiskInfo, String> {
let disks = Disks::new_with_refreshed_list();

// On macOS, the system disk is usually mounted at "/"
// We'll find the disk mounted at "/" or take the first one
let disk = disks
.list()
.iter()
.find(|d| d.mount_point().to_string_lossy() == "/")
.or_else(|| disks.list().first())
.ok_or("No disks found")?;

let total_space = disk.total_space();
let available_space = disk.available_space();
let used_space = total_space.saturating_sub(available_space);

Ok(DiskInfo {
total_space,
available_space,
used_space,
mount_point: disk.mount_point().to_string_lossy().to_string(),
name: disk.name().to_string_lossy().to_string(),
})
}

#[command]
pub fn check_full_disk_access() -> bool {
permissions::check_full_disk_access()
}

#[command]
pub fn open_full_disk_access_settings() -> Result<(), String> {
#[cfg(target_os = "macos")]
{
// Deep link to Full Disk Access settings
// macOS 13+ (Ventura) uses a different URL scheme than older versions, but this usually redirects correctly
// x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles
open::that("x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles")
.map_err(|e| e.to_string())
}
#[cfg(not(target_os = "macos"))]
{
Ok(())
}
}

#[command]
pub fn reveal_in_finder(path: String) -> Result<(), String> {
#[cfg(target_os = "macos")]
{
// Use "open -R <path>" to reveal in Finder
std::process::Command::new("open")
.arg("-R")
.arg(path)
.spawn()
.map_err(|e| e.to_string())?;
Ok(())
}
#[cfg(not(target_os = "macos"))]
{
// Fallback for other OS (open parent dir)
let p = PathBuf::from(path);
if let Some(parent) = p.parent() {
open::that(parent).map_err(|e| e.to_string())
} else {
Ok(())
}
}
}

#[command]
pub fn open_file(path: String) -> Result<(), String> {
open::that(path).map_err(|e| e.to_string())
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_get_disk_info() {
// This test mostly checks that the function doesn't panic
// It might return Err if no disk is found (e.g. in some containers), which is handled
let result = get_disk_info();
println!("Disk info result: {:?}", result);
// We don't assert ok/err because it depends on the environment,
// but we ensure the code path is executable.
}
}
8 changes: 7 additions & 1 deletion src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// CleanMac - macOS disk cleanup and optimization utility

pub mod commands;
pub mod models;
pub mod utils;

Expand Down Expand Up @@ -30,7 +31,12 @@ pub fn run() {
.invoke_handler(tauri::generate_handler![
greet,
format_size,
get_relative_time
get_relative_time,
commands::system::get_disk_info,
commands::system::check_full_disk_access,
commands::system::open_full_disk_access_settings,
commands::system::reveal_in_finder,
commands::system::open_file
])
.run(tauri::generate_context!())
.expect("error while running CleanMac application");
Expand Down
Loading