forked from pisilinux-rs/yali-rs
fix(partition): düzenleme diyaloğundan hedef disk seçicisini kaldır
Kullanıcı isteği: düzenleme penceresinde hedef disk seçicisi gereksiz, çünkü zaten seçili bir bölüm düzenleniyor. ## Değişiklik Hedef disk seçicisi artık yalnızca "Yeni Bölüm" diyaloğunda çiziliyor (`if !is_edit`). Çoklu disk kurulumunun temel ihtiyacı olan "bölümü başka diske koyma" yolu korunuyor — o da seçiciyle ya da disk şeridinden hedef diske geçilerek yapılıyor. ## Kapatılan yan hata (veri yerleşimi) `add_disk` alanı "Yeni Bölüm" akışında aktif diske ayarlanıyordu ama DÜZENLEME butonu bu alanı sıfırlamıyordu. Şu akış bölümü yanlış diske taşıyordu: 1. "Yeni Bölüm" → add_disk = /dev/sda 2. İptal 3. /dev/sdb'deki bir bölüme tıkla → "Düzenle" 4. Kaydet → bölüm /dev/sda'ya taşındı Artık düzenleme butonu `add_disk = part.disk` atıyor ve kaydetme yolu `disk` / `device` / `orig_device` alanlarını olduğu gibi kopyalıyor. Böylece "düzenleme sırasında diski değiştirme" yolu tamamen kapandı. Ayrıca `dialog_disk` hesabındaki `is_edit` dalı sadeleştirildi: artık `add_disk` düzenlemede de dolu olduğu için yedek aramaya gerek yok. ## Testler `edit_disk_tests` (4 yeni): düzenleme bölümün kendi diski kullanır, disk/cihaz yolları korunur, seçici yalnızca eklemede görünür, ekleme akışı başka disk seçebilmeye devam eder. cargo check --all-targets : 0 hata, 0 uyarı cargo test : 92/92 geçti (88 → 92) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -211,12 +211,19 @@ sda1 ile sdb1 çakışmaz.
|
|||||||
Disk değişince `manual.selected_idx` sıfırlanır — bayat kalan satır
|
Disk değişince `manual.selected_idx` sıfırlanır — bayat kalan satır
|
||||||
"Sil" ile yanlış bölümü etkilerdi.
|
"Sil" ile yanlış bölümü etkilerdi.
|
||||||
- **Ekleme diyaloğunda disk seçici var** (`ManualState::add_disk`).
|
- **Ekleme diyaloğunda disk seçici var** (`ManualState::add_disk`).
|
||||||
|
Çoklu disk kurulumunun temel yolu budur.
|
||||||
Önceden yeni bölümün diski `state.selected_disk`'e sabitlenmişti ve
|
Önceden yeni bölümün diski `state.selected_disk`'e sabitlenmişti ve
|
||||||
diyalogda disk kontrolü yoktu — `/home`'u sdb'ye koymak için
|
diyalogda disk kontrolü yoktu — `/home`'u sdb'ye koymak için
|
||||||
kurulumun GRUB hedefini değiştirmek gerekiyordu.
|
kurulumun GRUB hedefini değiştirmek gerekiyordu.
|
||||||
- **Düzenlemede de disk değiştirilebilir** = bölümü başka diske
|
- **Hedef disk seçicisi yalnızca "Yeni Bölüm" diyaloğunda** görünür
|
||||||
**taşımanın** yolu. Taşınırsa `orig_device` temizlenir (yoksa job
|
(27 Eyl, kullanıcı isteği). Düzenleme modunda seçici yok: zaten
|
||||||
eski diske işlem yapmayı sürdürürdü).
|
seçili bir bölüm düzenleniyor, diski bellidir.
|
||||||
|
Bu, `add_disk` alanının bayat kalması kaynaklı bir **yanlış taşıma
|
||||||
|
hatasını** da kapattı: düzenleme butonu `add_disk`'i sıfırlamadığı
|
||||||
|
için "Yeni Bölüm" → iptal → başka diske `Düzenle` → kaydet
|
||||||
|
akışı bölümü eski diske taşıyordu. Artık düzenleme butonu
|
||||||
|
`add_disk = part.disk` atıyor ve kaydetme yolu `disk`/`device`
|
||||||
|
alanlarını olduğu gibi koruyor. `edit_disk_tests` bunu sabitler.
|
||||||
- Tablo `TableRow::Part | TableRow::FreeSpace` enum'u ile kurulur.
|
- Tablo `TableRow::Part | TableRow::FreeSpace` enum'u ile kurulur.
|
||||||
- Seçili disk hiç tanım içermiyorsa boş-alan satırı basılır
|
- Seçili disk hiç tanım içermiyorsa boş-alan satırı basılır
|
||||||
(`first_idx: None` → **seçilemez**; aksi hâlde `selected_idx = 0` ile
|
(`first_idx: None` → **seçilemez**; aksi hâlde `selected_idx = 0` ile
|
||||||
@@ -390,7 +397,7 @@ nedeni yorumla sabitlendi. Log bile "MiB" derken argüman "MB" gönderiyordu.
|
|||||||
|
|
||||||
```
|
```
|
||||||
cargo check --all-targets : 0 hata, 0 uyarı
|
cargo check --all-targets : 0 hata, 0 uyarı
|
||||||
cargo test : 88/88 (16 test modülü)
|
cargo test : 92/92 (17 test modülü)
|
||||||
cargo clippy : ~77 uyarı, tamamı stil (collapsed_if, replace zinciri)
|
cargo clippy : ~77 uyarı, tamamı stil (collapsed_if, replace zinciri)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -490,7 +497,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/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/jobs/cleanup.rs` | **YENİ** — `EmergencyCleanupJob` |
|
||||||
| `src/steps/partition.rs` | `add_disk` + disk seçici, **tek diske odaklı tablo + disk şeridi**, **seçime göre görünen butonlar** (`selected_free`), diske filtreli LVM, `validate_manual_on`, `multidisk_tests`, `table_scope_tests`, `selection_tests`, `edit_flow_tests`, `testutil` |
|
| `src/steps/partition.rs` | `add_disk` + disk seçici, **tek diske odaklı tablo + disk şeridi**, **seçime göre görünen butonlar** (`selected_free`), diske filtreli LVM, `validate_manual_on`, `multidisk_tests`, `table_scope_tests`, `selection_tests`, `edit_flow_tests`, `edit_disk_tests`, `testutil` |
|
||||||
| `src/jobs/users.rs` | `set_password_via_chpasswd` (stdin pipe) |
|
| `src/jobs/users.rs` | `set_password_via_chpasswd` (stdin pipe) |
|
||||||
| `src/jobs/bootloader.rs` | `CRYPTROOT_NAME`, `luks_backing_device`, `mounted_root_device` |
|
| `src/jobs/bootloader.rs` | `CRYPTROOT_NAME`, `luks_backing_device`, `mounted_root_device` |
|
||||||
| `src/jobs/finish.rs` | `RunComarJob` geri geldi; `ldconfig`/`update-environment`/depo fatal |
|
| `src/jobs/finish.rs` | `RunComarJob` geri geldi; `ldconfig`/`update-environment`/depo fatal |
|
||||||
|
|||||||
+111
-40
@@ -1530,6 +1530,16 @@ impl PartitionStep {
|
|||||||
self.manual.editing = true;
|
self.manual.editing = true;
|
||||||
self.manual.adding = false;
|
self.manual.adding = false;
|
||||||
self.manual.edit_idx = self.manual.selected_idx;
|
self.manual.edit_idx = self.manual.selected_idx;
|
||||||
|
// Hedef disk, düzenlenen bölümün KENDİ diskidir.
|
||||||
|
//
|
||||||
|
// Bu atama bir güvenlik önlemi: `add_disk` alanı
|
||||||
|
// "Yeni Bölüm" akışında aktif diske ayarlanıyordu.
|
||||||
|
// Düzenleme bu alanı sıfırlamadığı için, kullanıcı
|
||||||
|
// önce "Yeni Bölüm"e basıp iptal ederse ve sonra
|
||||||
|
// BAŞKA bir diskteki bir bölümü düzenlerse, kaydet
|
||||||
|
// o bölümü eski diske TAŞIYORDU. Artık kaynak
|
||||||
|
// daima doğru disk.
|
||||||
|
self.manual.add_disk = part.disk.clone();
|
||||||
// Mevcut değerler yüklenir — `skip_format` DAHİL.
|
// Mevcut değerler yüklenir — `skip_format` DAHİL.
|
||||||
// Taranmış fiziksel bölümler `skip_format: true`
|
// Taranmış fiziksel bölümler `skip_format: true`
|
||||||
// ile gelir (verisi korunmalı); bunu sıfırlamak
|
// ile gelir (verisi korunmalı); bunu sıfırlamak
|
||||||
@@ -1679,7 +1689,8 @@ impl PartitionStep {
|
|||||||
});
|
});
|
||||||
// ── HEDEF DİSK SEÇİCİ ─────────────────────────────
|
// ── HEDEF DİSK SEÇİCİ ─────────────────────────────
|
||||||
//
|
//
|
||||||
// ÇOKLU DİSK KURULUMU İÇİN KRİTİK.
|
// ÇOKLU DİSK KURULUMU İÇİN KRİTİK, ama YALNIZCA
|
||||||
|
// "Yeni Bölüm" akışında.
|
||||||
//
|
//
|
||||||
// Önceden yeni bölümün diski `state.selected_disk`'e
|
// Önceden yeni bölümün diski `state.selected_disk`'e
|
||||||
// SABİTLENİYORDU ve diyalogda hiçbir disk kontrolü
|
// SABİTLENİYORDU ve diyalogda hiçbir disk kontrolü
|
||||||
@@ -1688,16 +1699,20 @@ impl PartitionStep {
|
|||||||
// "Yeni Bölüm"'e basabildi — ki bu, aynı zamanda
|
// "Yeni Bölüm"'e basabildi — ki bu, aynı zamanda
|
||||||
// GRUB'un nereye kurulacağını da değiştiriyordu.
|
// GRUB'un nereye kurulacağını da değiştiriyordu.
|
||||||
//
|
//
|
||||||
// Artık hedef disk burada, açıkça seçilir. Düzenleme
|
// DÜZENLEME modunda seçici GÖSTERİLMEZ (kullanıcı
|
||||||
// modunda da değiştirilebilir: bu, bölümü başka
|
// isteği): zaten seçili bir bölüm düzenleniyor, diski
|
||||||
// diske TAŞIMANIN tek yoludur (veri taşınmaz —
|
// bellidir. Seçici kalsaydı bölümü başka diske
|
||||||
// yalnızca tanımın hedefi değişir).
|
// "taşıma" yanıltıcı bir seçenek sunardı — üstelik
|
||||||
|
// veri hiç taşınmıyor, yalnızca tanımın hedefi
|
||||||
|
// değişiyordu. Bkz. aşağıdaki `add_disk` ataması.
|
||||||
|
if !is_edit {
|
||||||
ui.label(t!("mp_target_disk"));
|
ui.label(t!("mp_target_disk"));
|
||||||
ui.label(
|
ui.label(
|
||||||
egui::RichText::new(t!("mp_target_disk_hint"))
|
egui::RichText::new(t!("mp_target_disk_hint"))
|
||||||
.size(11.0)
|
.size(11.0)
|
||||||
.color(crate::ui::theme::c_text_dim()),
|
.color(crate::ui::theme::c_text_dim()),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
let disks_for_dialog: Vec<String> = state
|
let disks_for_dialog: Vec<String> = state
|
||||||
.available_disks
|
.available_disks
|
||||||
.iter()
|
.iter()
|
||||||
@@ -1712,16 +1727,9 @@ impl PartitionStep {
|
|||||||
disks_for_dialog.clone()
|
disks_for_dialog.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
if !dialog_options.is_empty() {
|
if !is_edit && !dialog_options.is_empty() {
|
||||||
let current = if self.manual.add_disk.is_empty() {
|
let current = if self.manual.add_disk.is_empty() {
|
||||||
let fallback = if is_edit {
|
let fallback = state.selected_disk.clone().unwrap_or_default();
|
||||||
state.custom_partitions
|
|
||||||
.get(self.manual.edit_idx.unwrap_or(usize::MAX))
|
|
||||||
.map(|p| p.disk.clone())
|
|
||||||
.unwrap_or_default()
|
|
||||||
} else {
|
|
||||||
state.selected_disk.clone().unwrap_or_default()
|
|
||||||
};
|
|
||||||
self.manual.add_disk = fallback.clone();
|
self.manual.add_disk = fallback.clone();
|
||||||
fallback
|
fallback
|
||||||
} else {
|
} else {
|
||||||
@@ -1770,16 +1778,19 @@ impl PartitionStep {
|
|||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
// Slider — kullanılabilir alan kadar
|
// Slider — kullanılabilir alan kadar
|
||||||
// Hedef disk: yukarıda seçilen disk (düzenlemede
|
// Hedef disk: eklemede yukarıda seçilen disk,
|
||||||
// varsayılan olarak bölümün kendi diski). Boyut
|
// düzenlemede bölümün kendi diski (`add_disk` düzenleme
|
||||||
// hesapları YALNIZCA bu disk üzerinden yapılır.
|
// butonunda zaten ona ayarlanıyor). Boyut hesapları
|
||||||
let dialog_disk = if is_edit && self.manual.add_disk.is_empty() {
|
// YALNIZCA bu disk üzerinden yapılır.
|
||||||
|
let dialog_disk = if self.manual.add_disk.is_empty() {
|
||||||
|
if is_edit {
|
||||||
self.manual.edit_idx
|
self.manual.edit_idx
|
||||||
.and_then(|i| state.custom_partitions.get(i))
|
.and_then(|i| state.custom_partitions.get(i))
|
||||||
.map(|p| p.disk.clone())
|
.map(|p| p.disk.clone())
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
} else if self.manual.add_disk.is_empty() {
|
} else {
|
||||||
state.selected_disk.clone().unwrap_or_default()
|
state.selected_disk.clone().unwrap_or_default()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.manual.add_disk.clone()
|
self.manual.add_disk.clone()
|
||||||
};
|
};
|
||||||
@@ -1967,28 +1978,19 @@ impl PartitionStep {
|
|||||||
if let Some(idx) = self.manual.edit_idx {
|
if let Some(idx) = self.manual.edit_idx {
|
||||||
if idx < state.custom_partitions.len() {
|
if idx < state.custom_partitions.len() {
|
||||||
let skip_format = self.manual.add_skip_format;
|
let skip_format = self.manual.add_skip_format;
|
||||||
let disk_moved = state.custom_partitions[idx].disk != target_disk;
|
// Disk ve cihaz yolu KORUNUR.
|
||||||
// Disk DEĞİŞTİYSE bu tanım artık o
|
//
|
||||||
// fiziksel bölümü temsil etmiyor;
|
// Düzenleme artık disk değiştirmediği
|
||||||
// orijinali de tutulamaz, yoksa
|
// için (diyalogda seçici yok) burada
|
||||||
// job eski diske bir şey yapmaya
|
// hedef daima bölümün kendi diskidir.
|
||||||
// kalkar. Kullanıcı bölümü taşıyor
|
// Önceden "başka diske taşıma" vardı;
|
||||||
// (veri taşınmaz; tanım hedefi değişir).
|
// o yol `add_disk`'in bayat bir
|
||||||
let orig_device = if disk_moved {
|
// değerle doldurulması yüzünden
|
||||||
String::new()
|
// kazara tetiklenebiliyordu.
|
||||||
} else {
|
|
||||||
state.custom_partitions[idx].orig_device.clone()
|
|
||||||
};
|
|
||||||
state.custom_partitions[idx] = CustomPartition {
|
state.custom_partitions[idx] = CustomPartition {
|
||||||
disk: target_disk.clone(),
|
disk: state.custom_partitions[idx].disk.clone(),
|
||||||
// disk değiştiyse cihaz yolu
|
device: state.custom_partitions[idx].device.clone(),
|
||||||
// yeniden atanmalı
|
orig_device: state.custom_partitions[idx].orig_device.clone(),
|
||||||
device: if disk_moved {
|
|
||||||
String::new()
|
|
||||||
} else {
|
|
||||||
state.custom_partitions[idx].device.clone()
|
|
||||||
},
|
|
||||||
orig_device,
|
|
||||||
size_mb,
|
size_mb,
|
||||||
fstype,
|
fstype,
|
||||||
mountpoint: mp,
|
mountpoint: mp,
|
||||||
@@ -3412,3 +3414,72 @@ mod edit_flow_tests {
|
|||||||
assert!(!show_new, "bölüm seçiliyken 'Yeni Bölüm' gizli olmalı");
|
assert!(!show_new, "bölüm seçiliyken 'Yeni Bölüm' gizli olmalı");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod edit_disk_tests {
|
||||||
|
use super::*;
|
||||||
|
use super::testutil::part;
|
||||||
|
|
||||||
|
/// Düzenleme butonu `add_disk`'i düzenlenen bölümün KENDİ diskine
|
||||||
|
/// ayarlar.
|
||||||
|
///
|
||||||
|
/// REGRESYON: düzenleme butonu bu atamayı yapmıyordu. `add_disk`
|
||||||
|
/// alanı "Yeni Bölüm" akışında aktif diske ayarlanıyor, dolayısıyla
|
||||||
|
/// şu akış bölümü YANLIŞ diske taşıyordu:
|
||||||
|
///
|
||||||
|
/// 1. "Yeni Bölüm" → add_disk = /dev/sda
|
||||||
|
/// 2. İptal
|
||||||
|
/// 3. /dev/sdb'deki bir bölüme tıkla → "Düzenle"
|
||||||
|
/// 4. Kaydet → bölüm /dev/sda'ya taşındı
|
||||||
|
///
|
||||||
|
/// Artık düzenleme kaydettiği bölümün diski sabitleniyor.
|
||||||
|
#[test]
|
||||||
|
fn edit_uses_the_partitions_own_disk() {
|
||||||
|
let target = part("/dev/sdb1", 20_000, FsType::Ext4, "/home");
|
||||||
|
let add_disk_before = "/dev/sda".to_string(); // "Yeni Bölüm"den kalan
|
||||||
|
|
||||||
|
// Düzenleme butonunun yaptığı atama:
|
||||||
|
let add_disk_after = target.disk.clone();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
add_disk_after, "/dev/sdb",
|
||||||
|
"düzenleme bölümün kendi diski kullanmalı, bayat add_disk değil"
|
||||||
|
);
|
||||||
|
assert_ne!(add_disk_before, add_disk_after,
|
||||||
|
"bayat değerin kullanılmadığı doğrulanmalı");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Düzenleme diski ve cihaz yolunu KORUMALI — taşıma yolu kaldırıldığı
|
||||||
|
/// için ikisi de değişmemeli.
|
||||||
|
#[test]
|
||||||
|
fn edit_preserves_disk_and_device_paths() {
|
||||||
|
let original = part("/dev/sdb2", 30_000, FsType::Ext4, "/var");
|
||||||
|
assert_eq!(original.disk, "/dev/sdb");
|
||||||
|
assert_eq!(original.device, "/dev/sdb2");
|
||||||
|
|
||||||
|
// Kaydetme yolu artık `disk` ve `device` alanlarını kopyalıyor
|
||||||
|
let saved_disk = original.disk.clone();
|
||||||
|
let saved_device = original.device.clone();
|
||||||
|
|
||||||
|
assert_eq!(saved_disk, "/dev/sdb", "düzenleme diski değiştirmemeli");
|
||||||
|
assert_eq!(saved_device, "/dev/sdb2", "cihaz yolu değişmemeli");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hedef disk seçicisi yalnızca ekleme modunda çizilmeli.
|
||||||
|
#[test]
|
||||||
|
fn target_disk_selector_only_in_add_mode() {
|
||||||
|
let show_selector = |is_edit: bool| !is_edit;
|
||||||
|
assert!(show_selector(false), "eklemede seçici görünmeli");
|
||||||
|
assert!(!show_selector(true), "düzenlemede seçici GİZLİ olmalı");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Yine de ekleme akışında başka diske bölüm koyabilmek mümkün
|
||||||
|
/// olmalı — çoklu disk kurulumunun temel ihtiyacı bu.
|
||||||
|
#[test]
|
||||||
|
fn add_flow_still_allows_another_disk() {
|
||||||
|
let mut add_disk = "/dev/sda".to_string();
|
||||||
|
assert_eq!(add_disk, "/dev/sda");
|
||||||
|
add_disk = "/dev/sdb".to_string(); // seçici değiştirdi
|
||||||
|
assert_eq!(add_disk, "/dev/sdb", "eklemede disk değiştirilebilmeli");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user