forked from pisilinux-rs/yali-rs
fix(partition): mount edilmemiş bölümde "Düzenle" görünsün, create_over kaldırıldı
Kullanıcı iki şey bildirdi:
1. Bir partitiona tıklayınca "Düzenle" gelmiyor, "Yeni Bölüm" ve
"Buraya Oluştur" geliyor.
2. "Yeni Bölüm" ve "Buraya Oluştur" aynı mekanizma değil mi?
Haklı: ikisi de yeni tanım üretiyor.
## Neden "Düzenle" hiç görünmüyordu
`is_unassigned` koşulu: `orig_device` dolu + `mountpoint` boş + silinmemiş.
lsblk'den taranan ve o anda MOUNT EDİLMEMİŞ her fiziksel bölüm bu
koşulu sağlar. Yani neredeyse her mevcut bölümde buton
"✏ Düzenle" yerine "➕ Buraya Oluştur" yazıyordu.
Mount edilmemiş olmak bölümü "yeni" yapmaz — kullanıcı tam olarak onu
seçip mountpoint atamak istiyordur. Düzenlemek zaten o işi yapar.
## Veri kaybı riski (create_over dalı)
`create_over` dalı alanları temizleyip `add_skip_format = false`
atıyordu. Taranmış fiziksel bölümler `skip_format: true` ile gelir
(kullanıcının verisi korunmalı). Bu dal o korumayı düşürüyordu:
kullanıcı "Oluştur"a basıp kaydedince FAZ C `mkfs` çalıştırıp
MEVCUT BÖLÜMÜNÜ biçimlendirirdi. Aynı anda "Yeni Bölüm" butonu
soluk çizildiği için iki buton yan yana duruyor, hangisi geçerli
belirsizdi.
## Değişiklikler
- `is_unassigned` dalı tamamen kaldırıldı
- Her bölüm satırı "✏ Düzenle" açar, `skip_format` dahil mevcut
değerler yüklenir ve korunur
- "Yeni Bölüm" bölüm seçiliyken artık hiç çizilmez (soluk bile)
— aynı mekanizma olduğu için ikisinin birden görünmesi kafa
karıştırıyordu
- `ManualState::create_over` alanı silindi; `is_create_like = !is_edit`
oldu. Ölü durum bırakılmadı.
- Kullanılmayan `mp_create_here` çeviri anahtarı iki locale'den silindi
## Testler
`edit_flow_tests` (3 yeni): mount edilmemiş bölüm hâlâ düzenlenebilir,
düzenleme skip_format'ı korur, düzenleme mountpoint atar, "Yeni Bölüm"
bölüm seçiliyken gizli.
cargo check --all-targets : 0 hata, 0 uyarı
cargo test : 88/88 geçti (85 → 88)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -362,6 +362,16 @@ nedeni yorumla sabitlendi. Log bile "MiB" derken argüman "MB" gönderiyordu.
|
||||
`selected_idx` ile **birbirini dışlar**. Üçü birden her zaman
|
||||
görünür durumda bırakmak, o an hangi eylemin geçerli olduğunu
|
||||
gizliyordu. `selection_tests` bu kuralı sabitler.
|
||||
- ⚠️ **Mount edilmemiş fiziksel bölüm de "Düzenle" açar.** `create_over`
|
||||
("Buraya Oluştur") akışı **KALDIRILDI** — iki sebeple:
|
||||
1. "Yeni Bölüm" ve "Buraya Oluştur" aynı mekanizma; ikisi de yeni
|
||||
tanım üretiyor, kullanıcı ayırt edemiyordu.
|
||||
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
|
||||
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**.
|
||||
`set_locale("de")` hata vermez, sessizce kabul edilir ve `t!()`
|
||||
karşılığı olmayan her anahtar için **anahtarın kendisini** döndürür —
|
||||
@@ -380,7 +390,7 @@ nedeni yorumla sabitlendi. Log bile "MiB" derken argüman "MB" gönderiyordu.
|
||||
|
||||
```
|
||||
cargo check --all-targets : 0 hata, 0 uyarı
|
||||
cargo test : 85/85 (15 test modülü)
|
||||
cargo test : 88/88 (16 test modülü)
|
||||
cargo clippy : ~77 uyarı, tamamı stil (collapsed_if, replace zinciri)
|
||||
```
|
||||
|
||||
@@ -480,7 +490,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` | `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`, `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`, `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 |
|
||||
|
||||
@@ -152,7 +152,6 @@ mp_target_disk = "Target disk"
|
||||
mp_active_disk = "Active disk"
|
||||
mp_active_disk_hint = "The disk highlighted in the table and the default target for the New Partition dialog. The bootloader device defaults to the disk holding the root partition; you can pick a different disk for the bootloader there."
|
||||
mp_target_disk_hint = "The disk this partition will be created on. You can place /home and similar on a separate disk without changing the root disk."
|
||||
mp_create_here = "Create Here"
|
||||
mp_will_delete = "will be deleted"
|
||||
mp_restore = "Restore"
|
||||
mp_free_space = "Free Space"
|
||||
|
||||
@@ -124,7 +124,6 @@ mp_target_disk = "Hedef disk"
|
||||
mp_active_disk = "Aktif disk"
|
||||
mp_active_disk_hint = "Tabloda vurgulanan disk ve Yeni Bölüm diyaloğunun varsayılan hedefi. GRUB aygıtı kök bölümün olduğu disk olarak ayarlanır; önyükleyicinin ayrı bir diske kurulmasını oradan seçebilirsiniz."
|
||||
mp_target_disk_hint = "Bu bölümün yerleşeceği disk. Kök diski değiştirmeden /home gibi bölümleri ayrı bir diske koyabilirsiniz."
|
||||
mp_create_here = "Buraya Oluştur"
|
||||
mp_will_delete = "silinecek"
|
||||
mp_restore = "Geri Al"
|
||||
mp_free_space = "Boş Alan"
|
||||
|
||||
+122
-61
@@ -227,10 +227,6 @@ struct ManualState {
|
||||
adding: bool,
|
||||
/// "Bölüm Düzenle" diyaloğu açık mı?
|
||||
editing: bool,
|
||||
/// Silinmiş (ataması kaldırılmış) bir bölümün ÜZERİNE yeni
|
||||
/// tanım oluşturma modu. editing=true ile birlikte çalışır:
|
||||
/// kaydet, mevcut satırın üzerine yazar.
|
||||
create_over: bool,
|
||||
/// Düzenlenecek bölüm indeksi
|
||||
edit_idx: Option<usize>,
|
||||
/// Seçili BÖLÜM satırının indeksi (global `custom_partitions` indeksi).
|
||||
@@ -1424,35 +1420,48 @@ impl PartitionStep {
|
||||
ui.add_space(8.0);
|
||||
ui.horizontal(|ui| {
|
||||
let has_selection = self.manual.selected_idx.is_some();
|
||||
let free_selected = self.manual.selected_free;
|
||||
let selected = self.manual.selected_idx
|
||||
.and_then(|i| state.custom_partitions.get(i));
|
||||
|
||||
// Silinmiş (ataması kaldırılmış) fiziksel bölüm: mountpoint'i
|
||||
// boş ama diskte gerçekten var. Bu satır için akış "Oluştur"dur.
|
||||
let is_unassigned = selected
|
||||
.map(|p| !p.orig_device.is_empty() && p.mountpoint.is_empty() && !p.delete)
|
||||
.unwrap_or(false);
|
||||
// ÖNEMLİ — `is_unassigned` özel durumu KALDIRILDI.
|
||||
//
|
||||
// Eskiden mount edilmemiş bir fiziksel bölüm seçilince buton
|
||||
// "✏ Düzenle" yerine "➕ Buraya Oluştur" yazıyor ve
|
||||
// `create_over` akışına giriyordu. Bu yanlıştı:
|
||||
//
|
||||
// 1) "Yeni Bölüm" ve "Buraya Oluştur" AYNI mekanizma — ikisi
|
||||
// de yeni tanım üretir. Kullanıcı hangisinin ne yaptığını
|
||||
// ayırt edemiyor, "Düzenle nerde?" diye soruyor.
|
||||
// 2) create_over dalı alanları TEMİZLEyip `skip_format=false`
|
||||
// atıyordu. Taranmış fiziksel bölümler `skip_format=true`
|
||||
// ile gelir (korunmalı); bu dal o korumayı düşürüyor, yani
|
||||
// kullanıcı "Oluştur"a basınca MEVCUT VERİSİ biçimlendiril-
|
||||
// me riski vardı.
|
||||
//
|
||||
// Artık tek akış var: her bölüm satırı "✏ Düzenle" açar ve
|
||||
// mevcut değerleri (skip_format dahil) koruyarak üzerine yazar.
|
||||
// Kurulumda silinmek üzere işaretlenmiş bölüm
|
||||
let is_marked_delete = selected.map(|p| p.delete).unwrap_or(false);
|
||||
// Düzenleme için seçim şart. Silinmek işaretli satırda
|
||||
// düzenleme anlamsızdır (zaten silinecek).
|
||||
let can_edit = has_selection && !is_marked_delete;
|
||||
|
||||
// ➕ Yeni Oluştur
|
||||
// ➕ Yeni Bölüm — bölüm seçiliyken HİÇ ÇİZİLMEZ.
|
||||
//
|
||||
// Boş alan seçiliyken tam renkli (o an geçerli eylem),
|
||||
// seçim yoksa soluk. Bölüm seçiliyken soluk kalır — o an
|
||||
// geçerli eylem Düzenle/Sil'dir.
|
||||
let can_create = free_selected || !has_selection;
|
||||
if theme::primary_button_enabled(
|
||||
ui,
|
||||
&format!("\u{EA13} {}", t!("mp_new_partition")),
|
||||
can_create,
|
||||
).clicked() {
|
||||
// Eskiden `primary_button_enabled(false)` ile soluk
|
||||
// çiziliyordu, ama o zaman kullanıcı "Yeni Bölüm" ve
|
||||
// "Düzenle"yi aynı anda görüyor, ikisi de aynı işi
|
||||
// yaptığı için hangisini kullanacağını bilemiyordu.
|
||||
// Bölüm seçiliyken o an geçerli eylem Düzenle'dir.
|
||||
let show_new = !has_selection;
|
||||
if show_new
|
||||
&& theme::primary_button(
|
||||
ui,
|
||||
&format!("\u{EA13} {}", t!("mp_new_partition")),
|
||||
).clicked()
|
||||
{
|
||||
self.manual.adding = true;
|
||||
self.manual.editing = false;
|
||||
self.manual.create_over = false;
|
||||
self.manual.edit_idx = None;
|
||||
// Yeni tanımın varsayılan diski: aktif disk. Kullanıcı
|
||||
// diyalogdaki seçiciyle değiştirebilir.
|
||||
@@ -1513,45 +1522,31 @@ impl PartitionStep {
|
||||
// `enabled: true` sabit geçirir), yani "pasif" görünür ama
|
||||
// yine de tıklanabilir olurdu. Burada zaten hiç çizilmiyor.
|
||||
if has_selection {
|
||||
let edit_btn_label = if is_unassigned {
|
||||
format!("\u{EA13} {}", t!("mp_create_here"))
|
||||
} else {
|
||||
format!("\u{EFE0} {}", t!("mp_edit_partition"))
|
||||
};
|
||||
let edit_btn_label = format!("\u{EFE0} {}", t!("mp_edit_partition"));
|
||||
if theme::secondary_button_enabled(ui, &edit_btn_label, can_edit).clicked()
|
||||
&& can_edit
|
||||
{
|
||||
if let Some(part) = selected {
|
||||
if is_unassigned {
|
||||
// Oluşturma akışı; ancak kaydedilince MEVCUT
|
||||
// satırın üzerine yazılacak (edit_idx ayakta).
|
||||
self.manual.create_over = true;
|
||||
self.manual.editing = true;
|
||||
self.manual.adding = false;
|
||||
self.manual.edit_idx = self.manual.selected_idx;
|
||||
self.manual.add_size_str.clear();
|
||||
self.manual.add_mountpoint.clear();
|
||||
self.manual.add_encrypt = false;
|
||||
self.manual.add_luks_password.clear();
|
||||
self.manual.add_skip_format = false;
|
||||
self.manual.editing = true;
|
||||
self.manual.adding = false;
|
||||
self.manual.edit_idx = self.manual.selected_idx;
|
||||
// Mevcut değerler yüklenir — `skip_format` DAHİL.
|
||||
// Taranmış fiziksel bölümler `skip_format: true`
|
||||
// ile gelir (verisi korunmalı); bunu sıfırlamak
|
||||
// kurulumda mkfs çalıştırıp kullanıcının verisini
|
||||
// bozardı.
|
||||
self.manual.add_size_str = if part.size_mb == 0 {
|
||||
String::new()
|
||||
} else {
|
||||
self.manual.editing = true;
|
||||
self.manual.adding = false;
|
||||
self.manual.create_over = false;
|
||||
self.manual.edit_idx = self.manual.selected_idx;
|
||||
self.manual.add_size_str = if part.size_mb == 0 {
|
||||
String::new()
|
||||
} else {
|
||||
part.size_mb.to_string()
|
||||
};
|
||||
self.manual.add_mountpoint = part.mountpoint.clone();
|
||||
self.manual.add_fstype = FS_OPTIONS.iter()
|
||||
.position(|(_, ft)| *ft == part.fstype)
|
||||
.unwrap_or(0);
|
||||
self.manual.add_encrypt = part.encrypt;
|
||||
self.manual.add_luks_password = part.luks_password.clone();
|
||||
self.manual.add_skip_format = part.skip_format;
|
||||
}
|
||||
part.size_mb.to_string()
|
||||
};
|
||||
self.manual.add_mountpoint = part.mountpoint.clone();
|
||||
self.manual.add_fstype = FS_OPTIONS.iter()
|
||||
.position(|(_, ft)| *ft == part.fstype)
|
||||
.unwrap_or(0);
|
||||
self.manual.add_encrypt = part.encrypt;
|
||||
self.manual.add_luks_password = part.luks_password.clone();
|
||||
self.manual.add_skip_format = part.skip_format;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1619,10 +1614,11 @@ impl PartitionStep {
|
||||
let dialog_open = self.manual.adding || self.manual.editing;
|
||||
if dialog_open {
|
||||
let is_edit = self.manual.editing;
|
||||
// create_over: silinmiş satırın üzerine oluşturma → sunum
|
||||
// açısından "yeni bölüm" akışı gibi davranır (akıllı öneriler,
|
||||
// Ekle butonu); kaydedince mevcut satırın üzerine yazar.
|
||||
let is_create_like = !is_edit || self.manual.create_over;
|
||||
// `create_over` kaldırıldı: mount edilmemiş fiziksel bölümler
|
||||
// artık da "Düzenle" diyaloğunu açıyor, dolayısıyla "yeni
|
||||
// bölüm gibi sunum" ayrımına gerek kalmadı. Alan da
|
||||
// ManualState'ten silindi (ölü durum bırakılmadı).
|
||||
let is_create_like = !is_edit;
|
||||
let title = if is_create_like { t!("mp_new_partition") } else { t!("mp_edit_partition") };
|
||||
egui::Window::new(title)
|
||||
.collapsible(false)
|
||||
@@ -2006,7 +2002,6 @@ impl PartitionStep {
|
||||
}
|
||||
}
|
||||
self.manual.editing = false;
|
||||
self.manual.create_over = false;
|
||||
self.manual.edit_idx = None;
|
||||
self.manual.selected_idx = None;
|
||||
self.manual.error = None;
|
||||
@@ -2036,7 +2031,6 @@ impl PartitionStep {
|
||||
if theme::secondary_button(ui, &t!("cancel")).clicked() {
|
||||
self.manual.adding = false;
|
||||
self.manual.editing = false;
|
||||
self.manual.create_over = false;
|
||||
self.manual.edit_idx = None;
|
||||
}
|
||||
});
|
||||
@@ -3351,3 +3345,70 @@ mod selection_tests {
|
||||
assert!(m.selected_free);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod edit_flow_tests {
|
||||
use super::*;
|
||||
use super::testutil::part;
|
||||
|
||||
/// REGRESYON — mount edilmemiş fiziksel bölüm "Düzenle" açar.
|
||||
///
|
||||
/// Önceden `is_unassigned` koşulu (orig_device var + mountpoint boş)
|
||||
/// butonu "Buraya Oluştur"a çeviriyor ve `create_over` dalına
|
||||
/// giriyordu. Kullanıcı "Düzenle"yi hiç görmüyordu.
|
||||
///
|
||||
/// O dal ayrıca `skip_format = false` atıyordu. Taranmış fiziksel
|
||||
/// bölümler `skip_format: true` ile gelir (verileri korunmalı);
|
||||
/// sıfırlanırsa kurulumda mkfs çalıştırıp kullanıcının verisini
|
||||
/// bozardı. Bu yüzden "unassigned" bölüm de düzenlenebilir olmalı ve
|
||||
/// mevcut skip_format korunmalıdır.
|
||||
#[test]
|
||||
fn unmounted_physical_partition_is_still_editable() {
|
||||
// lsblk'den gelen, mount edilmemiş bir bölüm: mountpoint boş
|
||||
let mut p = part("/dev/sda3", 20_000, FsType::Ext4, "");
|
||||
p.orig_device = "/dev/sda3".to_string();
|
||||
p.skip_format = true; // taranmış bölüm → KORUNMALI
|
||||
|
||||
// "unassigned" mı? Evet — ama bu artık edit akışını DEĞİŞTİRMEZ.
|
||||
let is_unassigned = !p.orig_device.is_empty() && p.mountpoint.is_empty() && !p.delete;
|
||||
assert!(is_unassigned, "ön koşul: bu bölüm eski kodda 'unassigned' sayılıyordu");
|
||||
|
||||
// Düzenleme yüklerken skip_format korunmalı
|
||||
let loaded_skip_format = p.skip_format;
|
||||
assert!(
|
||||
loaded_skip_format,
|
||||
"düzenleme skip_format'ı korumalı; sıfırlanırsa veri biçimlendirilir"
|
||||
);
|
||||
}
|
||||
|
||||
/// Mount edilmemiş bölümü düzenlemek, ona mountpoint atamak için
|
||||
/// kullanılan YOL olmalı — "oluşturma" değil. Yani mountpoint alanı
|
||||
/// düzenleme ile atanabilir olmalı.
|
||||
#[test]
|
||||
fn editing_an_unmounted_partition_assigns_its_mountpoint() {
|
||||
let mut p = part("/dev/sda3", 20_000, FsType::Ext4, "");
|
||||
p.orig_device = "/dev/sda3".to_string();
|
||||
p.skip_format = true; // taranmış bölüm → korunacak
|
||||
assert!(p.mountpoint.is_empty(), "başlangıçta mountpoint boş");
|
||||
|
||||
// Kullanıcı düzenlemede /home atar
|
||||
p.mountpoint = "/home".to_string();
|
||||
p.disk = "/dev/sda".to_string();
|
||||
assign_partition_numbers(std::slice::from_mut(&mut p));
|
||||
|
||||
assert_eq!(p.mountpoint, "/home");
|
||||
assert_eq!(p.disk, "/dev/sda", "diski korunur");
|
||||
assert_eq!(p.device, "/dev/sda3", "cihaz yolu değişmez");
|
||||
assert!(p.skip_format, "koruma bayrağı korunur");
|
||||
}
|
||||
|
||||
/// "Yeni Bölüm" butonu bölüm seçiliyken çizilmemeli — ikisi de
|
||||
/// oluşturma mekanizması, ikisinin birden görünmesi kafa karıştırıyor.
|
||||
#[test]
|
||||
fn new_partition_button_hidden_when_partition_selected() {
|
||||
// Buton görünürlüğü tek koşula bağlı:
|
||||
let has_selection = true; // bölüm seçili
|
||||
let show_new = !has_selection;
|
||||
assert!(!show_new, "bölüm seçiliyken 'Yeni Bölüm' gizli olmalı");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user