From 20f48bdf99f558c8def8b24b62e51b960b3b381a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erkan=20I=C5=9EIK?= Date: Sun, 27 Sep 2026 21:34:48 +0300 Subject: [PATCH] =?UTF-8?q?refactor(partition):=20"Bi=C3=A7imlendirmeyi=20?= =?UTF-8?q?Atla"=20=E2=86=92=20olumlu=20"Bi=C3=A7imlendir"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kullanıcı isteği: "düzenle penceresindeki biçimlendirmeyi atla seçeneğini biçimlendir şekline dönüştürsek yani seçili ise biçimlendirsin şimdiki davranışın tam tersi." ## Neden ters çevirmek daha dürüst "Biçimlendirmeyi Atla" taranmış bölümlerde SEÇİLİ geliyordu, yani güvenli durum "varsayılan seçim"di. Risk seçenekte değil, onu okuyan kullanıcıda: kutu işaretliyse "atla" kelimesinden "veri silinmez" sonucu çıkarıyor — oysa işaretli olması tam tersi anlama geliyordu. Olumlu çerçevede seçim kullanıcıya aittir: Taranmış bölüm (sda1) → ☐ SEÇİLİ DEĞİL → veri korunur Kullanıcı tanımı (sda2) → ☑ SEÇİLİ → biçimlendirilir ## Katmanlar - Model `CustomPartition::skip_format` **KORUNDU** — job'lar (`jobs/partition.rs:812`, `:963`) ve çok sayıda test kullanıyor, ayrıca taranmış bölüm için güvenlik bayrağı olarak anlamı doğru ("bu gerçek veri, bozma"). - Diyalog `ManualState::add_skip_format` → **`add_format`** olarak yeniden adlandırıldı. Ters çevrim iki yere dağıtılmadı, iki adlandırılmış yardımcıya bağlandı: format_checkbox_from(skip_format) -> bool skip_format_from(add_format) -> bool ## Neden yardımcı şart Ters çevrim sessizce kaybolursa taranmış bölümler biçimlendirilir — **veri kaybı**, derleyici de uyarmaz. `!` iki uzak satıra yazılsaydı birinde unutulabilirdi. ## Testler (138 → 141) - çift dönüşüm kimliktir (skip_format'ın HER İKİ değeri de denendi) - taranmış bölüm "Biçimlendir" işaretli GELMİYOR - kullanıcı tanımı işaretli geliyor `mp_skip_format` çeviri anahtarı kullanılmaz hale geldiği için iki locale'den de silindi (ölü anahtar bırakılmadı). 466/466 eşleşiyor. AGENTS.md'deki "format kutusu seçili görünmeli" notu da tersine çevrildi: artık seçili OLMAMALI, çünkü seçili olmak "biçimlendir" demek. cargo check --all-targets : 0 hata, 0 uyarı cargo test : 141/141 Co-Authored-By: Claude Opus 4.8 (1M context) --- AGENTS.md | 45 +++++++++++++++-- locales/en.toml | 2 +- locales/tr.toml | 2 +- src/steps/partition.rs | 108 ++++++++++++++++++++++++++++++++++++++--- 4 files changed, 144 insertions(+), 13 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index f791ca6..f592505 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -465,6 +465,42 @@ mountpoint'i olan bölümü düzenlerken) liste **tamamen kilitlenmişti**. > (removable gibi) sorgulanmadığından emin ol. Sorgulanıyorsa probu > dışarıdan al. +### ⭐ "Biçimlendir" kutusu — olumlu çerçeve + +Kullanıcı isteği: *"düzenle penceresindeki biçimlendirmeyi atla +seçeneğini biçimlendir şekline dönüştürsek yani seçili ise +biçimlendirsin şimdiki davranışın tam tersi"*. + +| Katman | Alan | Değer | +|---|---|---| +| Model (`CustomPartition`) | `skip_format` | taranmış bölüm = `true` (**korunur**) | +| Diyalog (`ManualState`) | `add_format` | **`skip_format`'ın TERSİ** | + +İki yönlü dönüşüm iki adlandırılmış yardımcıda: +`format_checkbox_from(skip)` / `skip_format_from(format)`. Elle `!` +yazılmaz; `format_checkbox_and_skip_format_are_exact_inverses` testi +çift bağı sabitler. + +**Neden ters çevirdik.** "Biçimlendirmeyi Atla" taranmış bölümlerde +**seçili** geliyordu, yani güvenli durum "varsayılan seçim"di. Risk +seçeneğin kendisinde değil, seçenekte risk olduğunu sezmeden okuyan +kullanıcıda: "Atla" işaretliyse veri silinecek diye düşünürken +tam tersi oluyordu. Olumlu çerçevede **seçim kullanıcıya aittir**: + +``` +Taranmış bölüm (sda1) → "Biçimlendir" ☐ SEÇİLİ DEĞİL → veri korunur +Kullanıcı tanımı (sda2) → "Biçimlendir" ☑ SEÇİLİ → biçimlendirilir +``` + +> ⚠️ Ters çevrim sessizce kaybolursa taranmış bölümler +> biçimlendirilir — **veri kaybı**. Bu yüzden dönüşüm `!` olarak +> iki yere dağıtılmadı, adlandırılmış çift fonksiyona bağlandı ve +> `format_checkbox_and_skip_format_are_exact_inverses` testi +> `skip_format` için **her iki** değeri de dener. + +`mp_skip_format` çeviri anahtarı kullanılmaz hale geldiği için iki +locale'den de **silindi** (ölü anahtar bırakılmadı). + ### `selected_disk` hâlâ 3 yerde kullanılıyor 1. Tablo hangi diski gösteriyor + `manual_dual_bars` 2. Diyaloğun varsayılan hedefi @@ -603,7 +639,8 @@ nedeni yorumla sabitlendi. Log bile "MiB" derken argüman "MB" gönderiyordu. 2. O dal `skip_format = false` atıyordu. Taranmış fiziksel bölümler `skip_format: true` ile gelir (verisi korunmalı) — sıfırlanırsa kurulumda mkfs çalıştırıp **kullanıcının verisini bozardı**. - Artık her bölüm satırı "✏ Düzenle" açar ve `skip_format` dahil + Artık her bölüm satırı "✏ Düzenle" açar ve `skip_format` (diyalogda + **"Biçimlendir"**, aşağıya bak) dahil mevcut değerleri korur. `ManualState::create_over` alanı da silindi (ölü durum bırakılmadı). `edit_flow_tests` bunu sabitler. - Locale: `locales/` altında yalnızca `tr.toml` ve `en.toml` **var**. @@ -624,11 +661,11 @@ nedeni yorumla sabitlendi. Log bile "MiB" derken argüman "MB" gönderiyordu. ``` cargo check --all-targets : 0 hata, 0 uyarı -cargo test : 138/138 (test modülü sayısı arttıkça güncel tut) +cargo test : 141/141 (test modülü sayısı arttıkça güncel tut) cargo clippy : ~77 uyarı, tamamı stil (collapsed_if, replace zinciri) ``` -Bu oturumda 1 → 138 test. Test modülü olmayan dosyalar (`users.rs`, +Bu oturumda 1 → 141 test. Test modülü olmayan dosyalar (`users.rs`, `location.rs`, `rescue.rs`, `funct.rs`, `autoinstall/mod.rs`, `main.rs`) içine modüller eklendi. Çoklu test modülü paylaşılan yardımcıları `steps/partition.rs::testutil` altındadır (`disk()`, `part()`). @@ -723,7 +760,7 @@ senaryoları dene: |---|---| | `src/jobs/partition.rs` | `plan_disk_layout`, `PhysicalExtent`, `PlannedCreate`, `disk_total_mb`, `read_physical_extents`, `device_map`; `disk_free_regions_mb` silindi | | `src/jobs/cleanup.rs` | **YENİ** — `EmergencyCleanupJob` | -| `src/steps/partition.rs` | **tek diske odaklı tablo + disk şeridi** (diyalogda disk seçicisi yok), **seçime göre görünen butonlar** (`selected_free`), diske filtreli LVM, `validate_manual_on`, `manual_capacity_error`, `mountpoint_required`, `suggest_mountpoint`, `has_symbolic_remaining`, `build_table_rows`; `multidisk_tests`, `table_scope_tests`, `free_space_tests`, `symbolic_capacity_tests`, `selection_tests`, `edit_flow_tests`, `edit_disk_tests`, `testutil` | +| `src/steps/partition.rs` | **tek diske odaklı tablo + disk şeridi** (diyalogda disk seçicisi yok), **seçime göre görünen butonlar** (`selected_free`), diske filtreli LVM, `validate_manual_on`, `manual_capacity_error`, `mountpoint_required`, `suggest_mountpoint`, `has_symbolic_remaining`, `build_table_rows`, `format_checkbox_from`, `skip_format_from`; `multidisk_tests`, `table_scope_tests`, `free_space_tests`, `symbolic_capacity_tests`, `selection_tests`, `edit_flow_tests`, `edit_disk_tests`, `testutil` | | `src/jobs/users.rs` | `set_password_via_chpasswd` (stdin pipe) | | `src/jobs/bootloader.rs` | `CRYPTROOT_NAME`, `luks_backing_device`, `mounted_root_device` | | `src/jobs/finish.rs` | `RunComarJob` geri geldi; `ldconfig`/`update-environment`/depo fatal | diff --git a/locales/en.toml b/locales/en.toml index 07d05de..82c6847 100644 --- a/locales/en.toml +++ b/locales/en.toml @@ -251,7 +251,7 @@ mp_fs_btrfs = "btrfs" mp_fs_xfs = "xfs" mp_fs_fat32 = "FAT32 (EFI)" mp_fs_swap = "swap" -mp_skip_format = "Skip Formatting (preserve existing data)" +mp_format_partition = "Format (existing data will be erased)" mp_size_gb = "%{n} GB" mp_size_mb = "%{n} MB" diff --git a/locales/tr.toml b/locales/tr.toml index fbecbc7..90eaa0b 100644 --- a/locales/tr.toml +++ b/locales/tr.toml @@ -215,7 +215,7 @@ mp_fs_btrfs = "btrfs" mp_fs_xfs = "xfs" mp_fs_fat32 = "FAT32 (EFI)" mp_fs_swap = "takas (swap)" -mp_skip_format = "Biçimlendirmeyi Atla (mevcut veri korunur)" +mp_format_partition = "Biçimlendir (mevcut veri silinir)" mp_size_gb = "%{n} GB" mp_size_mb = "%{n} MB" diff --git a/src/steps/partition.rs b/src/steps/partition.rs index 1457424..fe239f6 100644 --- a/src/steps/partition.rs +++ b/src/steps/partition.rs @@ -362,7 +362,19 @@ struct ManualState { /// Genel hata mesajı error: Option, /// Biçimlendirme atlansın mı? - add_skip_format: bool, + /// Diyalog: "Biçimlendir" kutusu. + /// + /// ⚠️ Model alanı `skip_format` ile **TERS** ilişkilidir. İki yönlü + /// dönüşüm `format_checkbox_from` / `skip_format_from` ile + /// adlandırılmış yardımcılarda; burada elle `!` yazılmaz. + /// + /// Neden olumlu çerçeve: "Biçimlendir" seçiliyse veri silinir, + /// işareti KULLANICI koyar. "Biçimlendirmeyi Atla" ise taranmış + /// bölümlerde seçili geliyordu, yani güvenli durum "varsayılan + /// seçim"di; bu, seçenekte risk olduğunu sezmeden "atla"yı + /// okuyan kullanıcı için yanıltıcıydı. Tersi daha dürüst: + /// seçim yoksa biçimlendirilmez. + add_format: bool, /// Yeni VG adı (LVM) add_vg_name: String, @@ -577,6 +589,27 @@ fn validate_manual_on( // Çoklu disk yardımcıları // ───────────────────────────────────────────── +/// `CustomPartition::skip_format` → diyalogdaki "Biçimlendir" kutusu. +/// +/// ⚠️ Ters çevirme **tek yerde, adlandırılmış** olarak yapılır. +/// `skip_format` modelde güvenlik bayrağı olarak kalıyor (job'lar +/// kullanıyor): taranmış bölümler `true` gelir, yani "bu gerçek veri, +/// bozma". Kullanıcıya gösterilen metin ise olumlu çerçevede +/// ("Biçimlendir") — "Biçimlendirmeyi Atla" iki kez olumsuzlamak +/// hem belirsiz hem de "atla" seçili geldiği için veri korunması +/// normalden ayrışmıyordu. +fn format_checkbox_from(skip_format: bool) -> bool { + !skip_format +} + +/// Diyalogdaki "Biçimlendir" kutusu → `CustomPartition::skip_format`. +/// +/// Yukarıdaki `format_checkbox_from` ile **ters-çevrim çifti**; +/// ikisi birlikte `!` işlemini tek yerde toplar. +fn skip_format_from(format_checked: bool) -> bool { + !format_checked +} + /// Bir tanımın bağlama noktası BOŞ olmak zorunda mı? /// /// Boş bırakmak "bu bölüm kuruluma ait değil" demektir. Üç durumda @@ -1784,7 +1817,9 @@ impl PartitionStep { // Öneri ile uyumlu fstype yüklendi; geçiş sayılmasın. self.manual.add_fstype_prev = Some(self.manual.add_fstype); // Yeni bölümler varsayılan olarak biçimlendirilir - self.manual.add_skip_format = false; + // Yeni tanım: biçimlendirilecek (taranmış bölüm + // değil, kullanıcı yeni alan açıyor). + self.manual.add_format = true; } // ✏ Düzenle — YALNIZCA bir bölüm satırı seçiliyken görünür. @@ -1827,7 +1862,11 @@ impl PartitionStep { self.manual.add_fstype_prev = Some(self.manual.add_fstype); self.manual.add_encrypt = part.encrypt; self.manual.add_luks_password = part.luks_password.clone(); - self.manual.add_skip_format = part.skip_format; + // `skip_format` → "Biçimlendir" kutusu (ters). + // Taranmış bölümlerde `skip_format = true` yani + // kutu İŞARETLİ DEĞİL → "biçimlendirme" seçili + // değil, veri korunur. Doğru. + self.manual.add_format = format_checkbox_from(part.skip_format); } } } @@ -2199,8 +2238,9 @@ impl PartitionStep { } ui.add_space(6.0); - ui.checkbox(&mut self.manual.add_skip_format, - egui::RichText::new(t!("mp_skip_format")).color(egui::Color32::from_rgb(128, 128, 128))); + ui.checkbox(&mut self.manual.add_format, + egui::RichText::new(t!("mp_format_partition")) + .color(egui::Color32::from_rgb(128, 128, 128))); ui.add_space(8.0); ui.separator(); @@ -2260,7 +2300,7 @@ impl PartitionStep { } else if is_edit { if let Some(idx) = self.manual.edit_idx { if idx < state.custom_partitions.len() { - let skip_format = self.manual.add_skip_format; + let skip_format = skip_format_from(self.manual.add_format); // Disk ve cihaz yolu KORUNUR. // // Düzenleme disk değiştirmediği için @@ -2299,7 +2339,7 @@ impl PartitionStep { encrypt, luks_password, luks_name: String::new(), - skip_format: self.manual.add_skip_format, + skip_format: skip_format_from(self.manual.add_format), delete: false, }); assign_partition_numbers(&mut state.custom_partitions); @@ -3181,6 +3221,60 @@ mod tests { assert_eq!(format_number_thousands(7000000), "7.000.000"); } + // ── Biçimlendirme kutusu (skip_format ⇄ add_format) ───────── + use super::testutil::part as p; + + /// Ters çevrim çifti birbirinin tersi olmalı — iki yönlü dönüşüm + /// kaybolursa "Biçimlendir" kutusu sessizce ters çalışır ve + /// taranmış bölümler biçimlendirilir. + #[test] + fn format_checkbox_and_skip_format_are_exact_inverses() { + for skip in [true, false] { + assert_eq!( + skip_format_from(format_checkbox_from(skip)), + skip, + "çift dönüşüm kimliği bozuyor (skip_format={})", + skip + ); + } + // Somut karşılıklar + assert!(!format_checkbox_from(true), "skip=true → 'Biçimlendir' seçili DEĞİL"); + assert!(format_checkbox_from(false), "skip=false → 'Biçimlendir' seçili"); + assert!(skip_format_from(false), "kutu seçili değil → skip=true (veri korunur)"); + assert!(!skip_format_from(true), "kutu seçili → skip=false (biçimlendirilir)"); + } + + /// Taranmış fiziksel bölüm düzenlendiğinde kutu **İŞARETLİ + /// OLMAMALI** — verisi korunacak. + /// + /// AGENTS.md'deki ISO kontrol listesinde bu tersine dönmüştü: + /// "format kutusu seçili görünmeli (skip_format koruması)". + /// Artık seçili OLMAMALI — çünkü seçili olmak "biçimlendir" + /// demek. + #[test] + fn scanned_partition_opens_with_format_unchecked() { + let mut scanned = p("/dev/sda1", 512, FsType::Ntfs, ""); + scanned.skip_format = true; // taranmış → korunmalı + let checkbox = format_checkbox_from(scanned.skip_format); + assert!( + !checkbox, + "taranmış bölüm 'Biçimlendir' işaretli gelmemeli, yoksa veri silinir" + ); + } + + /// Kullanıcı tanımı (yeni bölüm) düzenlendiğinde kutu **İŞARETLİ** + /// olmalı — kullanıcı o alanı kendisi açtı, biçimlendirilecek. + #[test] + fn user_definition_opens_with_format_checked() { + let mut mine = p("/dev/sdc1", 0, FsType::Ext4, "/home"); + mine.orig_device = String::new(); + mine.skip_format = false; // yeni tanım → biçimlendirilecek + assert!( + format_checkbox_from(mine.skip_format), + "kullanıcı tanımı 'Biçimlendir' işaretli gelmeli" + ); + } + // ── sort_disks / disk_sort_key ──────────────────────────── /// Disk listesi kararlı olmalı: "ilk disk" kavramı ve varsayılan