diff --git a/AGENTS.md b/AGENTS.md index b82c42b..e78eb6f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -323,6 +323,30 @@ kalanın tamamını alır, ikincisine hiç yer kalmaz. `orig_device` dolu (taranmış) 0 boyutlu bölüm sembolik **DEĞİLDİR**: sıfır boyut "kalanın tamamı" anlamına gelmez. +### ⭐ Bağlanmayan dosya sistemleri — mountpoint isteğe bağlı + +`mountpoint_required(editing, fstype)` üç dosya sisteminde `false` +döndürür: + +| FsType | Neden | +|---|---| +| `Lvm` | PV'nin kendisi bağlanmaz, üzerinde LV'ler yaşar | +| **`Ntfs`** | **Linux'ta bağlanması GEREKEN bir dosya sistemi değil** | +| düzenlenen fiziksel bölüm | "yalnızca GRUB için" işaretlemesi | + +NTFS'te zorunluluk kullanıcıya anlamsız geliyordu: *"format için ntfs +seçtiğim halde bağlama noktası seçmemi bekliyor bu mantıksız değil +mi"*. Tipik kullanım Windows ile veri alışverişi — bölüm biçimlendirilir +ama sisteme bağlanmaz, kullanıcı elle bağlar veya dosyayı doğrudan açar. + +Boş bırakıldığında kurulumda ne olduğu **mevcut ve doğru**: mount +atlanır (`jobs/partition.rs:1111`), fstab'a girmez (`:1171`), ama +`mkfs.ntfs -f` **çalışır** (FAZ C, `FsType::Ntfs`). + +Diyalogda NTFS seçilince: +1. geçersiz öneri kalıntısı (`/`, `/boot/efi`, `swap`…) **temizlenir** +2. `mp_mountpoint_optional` ipucu gösterilir + ### `selected_disk` hâlâ 3 yerde kullanılıyor 1. Tablo hangi diski gösteriyor + `manual_dual_bars` 2. Diyaloğun varsayılan hedefi @@ -482,11 +506,11 @@ nedeni yorumla sabitlendi. Log bile "MiB" derken argüman "MB" gönderiyordu. ``` cargo check --all-targets : 0 hata, 0 uyarı -cargo test : 122/122 (test modülü sayısı arttıkça güncel tut) +cargo test : 124/124 (test modülü sayısı arttıkça güncel tut) cargo clippy : ~77 uyarı, tamamı stil (collapsed_if, replace zinciri) ``` -Bu oturumda 1 → 122 test. Test modülü olmayan dosyalar (`users.rs`, +Bu oturumda 1 → 124 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()`). diff --git a/locales/en.toml b/locales/en.toml index e13c286..b170b3a 100644 --- a/locales/en.toml +++ b/locales/en.toml @@ -296,6 +296,7 @@ job_mount_custom = "Mounting manual partitions" # ── Extra Localization / i18n ───────────────────────────── mp_delete_confirm_title = "Delete Partition" mp_error_empty_mountpoint = "Mount point cannot be empty." +mp_mountpoint_optional = "Mount point is optional. Leave it empty to format the partition without mounting it at boot — useful for exchanging data with Windows." mp_error_empty_mountpoint_named = "Mount point cannot be empty: {device}. Pick a mount point from the list, or mark the partition for deletion and continue." mp_plan_valid = "✓ Partition plan is valid. You can proceed." mp_select_disk_first = "← Select a disk first." diff --git a/locales/tr.toml b/locales/tr.toml index 8031959..2e5d01c 100644 --- a/locales/tr.toml +++ b/locales/tr.toml @@ -260,6 +260,7 @@ job_mount_custom = "Manuel bölümler bağlanıyor" # ── Ek Yerelleştirme / i18n ────────────────────────────────── mp_delete_confirm_title = "Bölümü Sil" mp_error_empty_mountpoint = "Bağlama noktası boş olamaz." +mp_mountpoint_optional = "Bağlama noktası isteğe bağlı. Boş bırakırsanız bölüm biçimlendirilir ama sistem başlangıcında bağlanmaz; Windows'tan erişmek için kullanılır." mp_error_empty_mountpoint_named = "Bağlama noktası boş olamaz: {device}. Listeden bir bağlama noktası seçin ya da bölümü \"Sil\" işaretleyip geçin." mp_plan_valid = "Bölüm planı geçerli. İleri tuşuna basabilirsiniz." mp_select_disk_first = "← Önce bir disk seçin." diff --git a/src/steps/partition.rs b/src/steps/partition.rs index 23f7640..8892bb0 100644 --- a/src/steps/partition.rs +++ b/src/steps/partition.rs @@ -474,7 +474,7 @@ fn validate_manual_on( /// Bir tanımın bağlama noktası BOŞ olmak zorunda mı? /// -/// Boş bırakmak "bu bölüm kuruluma ait değil" demektir. İki durumda +/// Boş bırakmak "bu bölüm kuruluma ait değil" demektir. Üç durumda /// serbesttir: /// /// 1. **LVM PV** — üzerinde mantıksal hacimler yaşar, kendisi @@ -482,16 +482,26 @@ fn validate_manual_on( /// 2. **Düzenlenen FİZİKSEL bölüm** (`orig_device` dolu) — kullanıcı /// çift önyüklemeli kurulumda Windows'un boot bölümünü "yalnızca /// GRUB için, mount edilmeyecek" diye işaretlemek isteyebilir. +/// 3. **NTFS** — Linux tarafında bağlanması GEREKEN bir dosya sistemi +/// değildir. Kullanıcı çoğunlukla Windows ile veri alışverişi +/// için biçimlendirir ve sisteme bağlamaz; elle bağlar veya +/// dosyayı doğrudan açar. Zorunlu olması anlamsızdı ve +/// kullanıcıyı "/data" gibi uydurma bir noktaya zorluyordu +/// (rapor: "ntfs seçtiğim halde bağlama noktası seçmemi bekliyor +/// bu mantıksız değil mi"). /// -/// Yeni bir tanımda (`None` ya da `orig_device` boş) ZORUNLUDUR: kullanıcı -/// "ne işe yarayacak" diye sormadan kaydedemez. +/// Yeni bir tanımda (`None` ya da `orig_device` boş) ZORUNLUDUR: +/// kullanıcı "ne işe yarayacak" diye sormadan kaydedemez. /// /// ⚠️ Bu kural hem `validate_manual_on`'da hem de kaydetme diyaloğunda /// aynen uygulanmalı — birinde serbest olan diğerinde reddediliyorsa /// kullanıcı "İleri"ye geçemez. fn mountpoint_required(editing: Option<&CustomPartition>, fstype: &FsType) -> bool { - if *fstype == FsType::Lvm { - return false; + // Kendisi bağlanmayan / bağlanması gerekmeyen dosya sistemleri + match fstype { + FsType::Lvm => return false, + FsType::Ntfs => return false, + _ => {} } match editing { None => true, @@ -1966,6 +1976,46 @@ impl PartitionStep { self.manual.add_fstype = idx(FsType::Fat32); } + // NTFS seçildiğinde mountpoint'i TEMİZLE ve ne + // olacağını söyle. + // + // Kullanıcı isteği: "format için ntfs seçtiğim halde + // bağlama noktası seçmemi bekliyor bu mantıksız + // değil mi". + // + // NTFS Linux'ta bağlanması gereken bir dosya sistemi + // DEĞİLDİR; çoğunlukla Windows ile veri alışverişi + // için biçimlendirilir. Önceden öneri ("/boot/efi", + // "/" gibi) geçerli bir noktaya çevriliyor ve + // kullanıcı anlamsız bir seçim yapmak zorunda + // kalıyordu — ya da "boş olamaz" hatası alıyordu. + let fstype_now = FS_OPTIONS + .get(self.manual.add_fstype) + .map(|x| x.1.clone()) + .unwrap_or(FsType::Ext4); + let mp_optional = !mountpoint_required( + if self.manual.editing { + self.manual.edit_idx + .and_then(|i| state.custom_partitions.get(i)) + } else { + None + }, + &fstype_now, + ); + if mp_optional { + // Önceki öneri ("/boot/efi", "/", "swap"…) geçersiz + // bir kalıntı olurdu; temizleniyor. + if matches!(self.manual.add_mountpoint.as_str(), + "/" | "/boot" | "/boot/efi" | "/home" | "/var" | "/tmp" | "swap") { + self.manual.add_mountpoint.clear(); + } + ui.label( + egui::RichText::new(t!("mp_mountpoint_optional")) + .size(11.0) + .color(crate::ui::theme::c_text_dim()), + ); + } + ui.add_space(6.0); ui.separator(); @@ -3373,6 +3423,54 @@ mod multidisk_tests { ); } + /// NTFS'in mountpoint'i isteğe bağlıdır — bağlanması gereken bir + /// dosya sistemi değildir. + /// + /// Kullanıcı isteği: "format için ntfs seçtiğim halde bağlama noktası + /// seçmemi bekliyor bu mantıksız değil mi." + #[test] + fn ntfs_does_not_require_a_mountpoint() { + let mut new_def = p("/dev/sda", "/dev/sda2", 19_000, FsType::Ntfs, ""); + new_def.orig_device = String::new(); + assert!( + !mountpoint_required(None, &FsType::Ntfs), + "yeni NTFS tanımı mountpointsiz kaydedilebilmeli" + ); + assert!( + !mountpoint_required(Some(&new_def), &FsType::Ntfs), + "yeni NTFS tanımı mountpointsiz kaydedilebilmeli" + ); + } + + /// Mountpointsiz NTFS düzeni doğrulamadan geçmeli. + /// + /// Windows ile veri alışverişi için biçimlendirilen bölüm sisteme + /// bağlanmaz; yine de kurulum geçerli sayılmalı. + #[test] + fn mountless_ntfs_layout_passes_validation() { + let disks = vec![disk("/dev/sda", 250), disk("/dev/sdb", 500)]; + let parts = vec![ + // GRUB için ayrılmış, bağlanmayacak + p("/dev/sda", "/dev/sda1", 512, FsType::Fat32, ""), + p("/dev/sdb", "/dev/sdb1", 1_024, FsType::Fat32, "/boot/efi"), + p("/dev/sdb", "/dev/sdb2", 8_192, FsType::Swap, "swap"), + p("/dev/sdb", "/dev/sdb3", 400_000, FsType::Ext4, "/"), + ]; + // NTFS tanımı mountpointsiz + let mut ntfs = p("/dev/sda", "/dev/sda2", 0, FsType::Ntfs, ""); + ntfs.orig_device = String::new(); + ntfs.mountpoint = String::new(); + let mut all = parts; + all.push(ntfs); + + assert_eq!( + validate_manual_on(&all, &[], true, &disks), + None, + "mountpointsiz NTFS düzeni geçerli olmalı: {:?}", + validate_manual_on(&all, &[], true, &disks) + ); + } + /// Kullanıcının tam senaryosu: sda'da Windows (sda1 yalnızca GRUB /// için, mount edilmeyecek), sdb'de Linux, sdc boş. Düzen GEÇERLİ /// olmalı — GRUB için ayrılmış bölüm yüzünden reddedilmemeli.