Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bermain dengan Karat: Membina rm yang Lebih Selamat dan Bergembira Sepanjang Perjalanan

Bermain dengan Karat: Membina rm yang Lebih Selamat dan Bergembira Sepanjang Perjalanan

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-10-21 06:07:02335semak imbas

Playing with Rust: Building a Safer rm and Having Fun Along the Way

Selamat datang ke siri YOLO saya, di mana saya akan mempamerkan alatan dan projek mudah yang telah saya bina—kadangkala untuk berseronok, kadangkala untuk menyelesaikan masalah tertentu, dan pada masa lain hanya kerana rasa ingin tahu. Matlamat di sini bukan hanya untuk membentangkan alat; Saya juga akan menyelami sesuatu yang menarik berkaitan dengan proses itu, sama ada cerapan teknikal atau pengajaran yang dipelajari semasa membuat eksperimen kecil ini.

Memperkenalkan rrm: Alat Baris Perintah Tiada Siapa Diminta

Tiada sesiapa yang memintanya, dan tiada siapa yang menginginkannya—tetapi inilah ia. Temui rrm, alat yang menyelesaikan masalah hanya saya yang ada (tetapi hei, ini mungkin isu Lapisan 8—atau, lebih berkemungkinan, isu kemahiran!).

rrm menambah lapisan keselamatan pada pengalaman baris arahan anda dengan mengalihkan fail ke tong sampah dan bukannya memadamkannya secara kekal. Dengan tempoh tangguh yang boleh disesuaikan, anda berpeluang untuk menyedari, "Op, saya sebenarnya memerlukannya!" sebelum terlambat.

Apatah lagi, rrm tidak bergantung pada fail konfigurasi luaran atau sistem penjejakan untuk mengurus fail yang dipadamkan. Sebaliknya, ia memanfaatkan atribut lanjutan sistem fail anda untuk menyimpan metadata penting—seperti laluan fail asal dan masa pemadaman—terus dalam item yang dibuang.

Anda mungkin tertanya-tanya, "Mengapa saya membina alat ini sedangkan terdapat alat yang serupa, mungkin lebih baik di luar sana?" Nah, jawapannya mudah:

  • Saya mahu bermain dengan Rust. Membina alatan kecil dan bertujuan ialah cara yang bagus untuk meneroka bahasa dan mengasah kemahiran.
  • seperti membangunkan alatan CLI saya sendiri sebagai cara untuk mencipta rangka kerja mental. Ini membantu saya secara konsisten mendekati cara saya menstruktur utiliti baris arahan untuk teknologi tertentu. Dengan membina alatan ini, saya memperhalusi pemahaman saya tentang kebergantungan yang hendak digunakan, cara mengatur kod dan cara menyesuaikan setiap alat kepada ekosistem bahasa. Ini adalah cara membina buku permainan mental untuk mencipta alatan CLI yang sesuai dengan keperluan saya.
  • Kerana YOLO. Saya gemar membuat alatan mudah atau bukti konsep mengenai masalah yang ingin saya selesaikan atau perkara yang saya ingin tahu. Kadangkala, ini mengenai percubaan demi pembelajaran.

Nota menyeronokkan: Semasa bekerja dengan std::Path, saya menemui contoh dalam pustaka standard Rust yang menggunakan folder bernama laputa

. Saya tahu ia merujuk kepada Castle in the Sky, tetapi bagi penutur bahasa Sepanyol, ia juga merupakan perkataan kutukan, yang menjadikannya sebagai detik lucu bagi saya!<script> // Detect dark theme var iframe = document.getElementById('tweet-1844834987184410735-190'); if (document.body.className.includes('dark-theme')) { iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1844834987184410735&theme=dark" } </script>

Atribut Lanjutan: Menyimpan Metadata Tanpa Menukar Fail

Apabila saya mula membina rrm, saya memerlukan cara untuk menjejaki laluan asal fail yang dipadamkan dan masa ia harus dialih keluar secara kekal. Saya tidak mahu menggunakan fail JSON atau melaksanakan format penamaan pelik yang menyertakan maklumat ini—terutamanya jika saya mahu menyimpan lebih banyak data kemudian. Pangkalan data terasa seperti berlebihan untuk tugasan sekecil itu.

Ketika itulah saya menemui atribut lanjutan.

Apakah Atribut Lanjutan?

Sekarang, saya tidak tahu tentang anda, tetapi saya tidak menyedari terdapat mekanisme terbina dalam yang membolehkan anda menambah metadata tersuai pada fail, yang disokong oleh kebanyakan sistem fail Linux dan sistem seperti Unix seperti macOS . Ciri ini dipanggil Atribut Fail Lanjutan. Sistem yang berbeza mempunyai hadnya sendiri—seperti jumlah data yang boleh ditambah atau ruang nama tertentu yang digunakan—tetapi sistem tersebut mempunyai membolehkan anda menyimpan metadata yang ditentukan pengguna.

Atribut lanjutan pada asasnya ialah pasangan nama:nilai yang dikaitkan secara kekal dengan fail dan direktori. Seperti yang saya nyatakan sebelum ini, sistem berbeza dalam cara mereka mengendalikan ini. Contohnya, dalam Linux, nama bermula dengan pengecam ruang nama. Terdapat empat ruang nama sedemikian: keselamatan, sistem, dipercayai dan pengguna. Di Linux, nama bermula dengan salah satu daripada ini, diikuti dengan titik (".") dan kemudian rentetan yang ditamatkan nol. Pada macOS, keadaan agak berbeza. macOS tidak memerlukan ruang nama sama sekali, terima kasih kepada Pendekatan Metadata Bersatunya, yang menganggap atribut lanjutan sebagai metadata tambahan yang terikat secara langsung dengan fail tanpa perlu dikategorikan.

Dalam CLI kecil ini, saya menggunakan peti xattr, yang menyokong kedua-dua Linux dan macOS. Mengenai ruang nama yang saya nyatakan sebelum ini untuk Linux, kami akan menumpukan pada ruang nama pengguna kerana atribut ini dimaksudkan untuk digunakan oleh pengguna. Jadi, dalam kod, anda akan melihat sesuatu seperti ini:

/// Namespace for extended attributes (xattrs) on macOS and other operating systems.
/// On macOS, this is an empty string, while on other operating systems, it is "user.".
#[cfg(target_os = "macos")]
const XATTR_NAMESPACE: &str = "";
#[cfg(not(target_os = "macos"))]
const XATTR_NAMESPACE: &str = "user.";

...

    fn set_attr(&self, path: &Path, attr: &str, value: &str) -> Result<()> {
        let attr_name = format!("{}{}", XATTR_NAMESPACE, attr);
        ...
    }

Atribut #[cfg(target_os = "macos")] dalam Rust digunakan untuk menyusun kod secara bersyarat berdasarkan sistem pengendalian sasaran. Dalam kes ini, ia memastikan bahawa blok kod hanya disertakan semasa menyusun untuk macOS. Ini berkaitan kerana, seperti yang dinyatakan sebelum ini, macOS tidak memerlukan ruang nama untuk atribut lanjutan, jadi XATTR_NAMESPACE ditetapkan kepada rentetan kosong. Untuk sistem pengendalian lain, ruang nama ditetapkan kepada "pengguna.". Penyusunan bersyarat ini membolehkan kod menyesuaikan dengan lancar merentas platform yang berbeza, menjadikan CLI serasi silang dengan kedua-dua Linux dan macOS.

Satu perkara yang saya dapati cukup menarik tentang atribut lanjutan ialah mereka tidak mengubah suai fail itu sendiri. Metadata tinggal dalam ruang cakera yang berasingan, dirujuk oleh inod. Ini bermakna kandungan sebenar fail kekal tidak berubah. Contohnya, jika kita mencipta fail mudah dan menggunakan shasum untuk mendapatkan checksumnya:

Inode (nod indeks) ialah struktur data dalam sistem fail gaya Unix yang menerangkan objek sistem fail seperti fail atau direktori. Pautan

/// Namespace for extended attributes (xattrs) on macOS and other operating systems.
/// On macOS, this is an empty string, while on other operating systems, it is "user.".
#[cfg(target_os = "macos")]
const XATTR_NAMESPACE: &str = "";
#[cfg(not(target_os = "macos"))]
const XATTR_NAMESPACE: &str = "user.";

...

    fn set_attr(&self, path: &Path, attr: &str, value: &str) -> Result<()> {
        let attr_name = format!("{}{}", XATTR_NAMESPACE, attr);
        ...
    }

Selepas menggunakan rrm untuk memadam fail, kami boleh menyenaraikan fail yang dipadam dan melihat bahawa fail telah dialihkan ke tong sampah dengan metadatanya utuh:

$ cat a.txt
https://www.kungfudev.com/

$ shasum a.txt
e4c51607d5e7494143ffa5a20b73aedd4bc5ceb5  a.txt

Seperti yang anda lihat, nama fail ditukar kepada UUID. Ini dilakukan untuk mengelakkan perlanggaran nama semasa memadam fail dengan nama yang sama. Dengan memberikan pengecam unik pada setiap fail, rrm memastikan setiap fail yang dipadamkan, walaupun mempunyai nama yang sama, boleh dijejaki dan dipulihkan tanpa sebarang isu.

Kami boleh menavigasi ke folder sampah dan memeriksa fail untuk mengesahkan bahawa kandungannya kekal tidak berubah:

$ rrm rm a.txt

$ rrm list
╭──────────────────────────────────────────────────────┬──────────────────────────────────────┬──────┬─────────────────────╮
│ Original Path                                        ┆ ID                                   ┆ Kind ┆ Deletion Date       │
╞══════════════════════════════════════════════════════╪══════════════════════════════════════╪══════╪═════════════════════╡
│ /Users/douglasmakey/workdir/personal/kungfudev/a.txt ┆ 3f566788-75dc-4674-b069-0faeaa86aa55 ┆ File ┆ 2024-10-27 04:10:19 │
╰──────────────────────────────────────────────────────┴──────────────────────────────────────┴──────┴─────────────────────╯

Selain itu, dengan menggunakan xattr pada macOS, kami boleh mengesahkan bahawa fail tersebut mempunyai metadatanya, seperti tarikh pemadaman dan laluan asal:

$ shasum 3f566788-75dc-4674-b069-0faeaa86aa55
e4c51607d5e7494143ffa5a20b73aedd4bc5ceb5  3f566788-75dc-4674-b069-0faeaa86aa55

Anda boleh bayangkan julat kes penggunaan yang berpotensi untuk pengesahan atau tindakan mudah menggunakan metadata ini. Memandangkan atribut lanjutan berfungsi tanpa mengubah suai fail itu sendiri, ia membenarkan anda menyemak integriti fail atau melakukan operasi lain tanpa menjejaskan kandungan asal.

Ini hanyalah pengenalan kecil kepada atribut lanjutan dan cara ia digunakan dalam projek ini. Ia tidak bermaksud untuk menjadi penjelasan yang mendalam, tetapi jika anda berminat untuk mengetahui lebih lanjut, terdapat banyak sumber terperinci di luar sana. Berikut ialah beberapa pautan ke sumber yang paling berguna dan diterangkan dengan baik mengenai topik:

  • https://wiki.archlinux.org/title/Extended_attributes
  • https://man7.org/linux/man-pages/man7/xattr.7.html
  • https://ms.wikipedia.org/wiki/Extended_file_attributes

Mengejek dalam Karat: Meneroka mockall untuk Ujian

Saya telah menghabiskan beberapa tahun bekerja dengan Go, dan saya menjadi gemar corak tertentu—mengejek menjadi salah satu daripadanya. Dalam Go, saya biasanya melaksanakan perkara sendiri jika ia mengelakkan import yang tidak perlu atau memberi saya lebih fleksibiliti. Saya sangat terbiasa dengan pendekatan ini sehingga apabila saya mula menulis ujian dalam Rust, saya mendapati diri saya lebih suka mengejek perkara tertentu secara manual, seperti mencipta pelaksanaan olok-olok ciri.

Sebagai contoh, dalam CLI kecil ini, saya mencipta sifat untuk memisahkan pengurus sampah daripada cara ia berinteraksi dengan atribut lanjutan. Sifat itu, bernama ExtendedAttributes, pada mulanya bertujuan untuk tujuan ujian, tetapi juga kerana saya tidak pasti sama ada saya akan menggunakan xattr atau pelaksanaan lain. Jadi, saya mentakrifkan sifat berikut:

$ xattr -l 3f566788-75dc-4674-b069-0faeaa86aa55
deletion_date: 2024-10-27T04:10:19.875614+00:00
original_path: /Users/douglasmakey/workdir/personal/kungfudev/a.txt

Dalam Go, saya akan mencipta sesuatu seperti berikut, yang menyediakan pelaksanaan mudah antara muka yang dinyatakan sebelum ini. Kod di bawah adalah mudah dan dijana tanpa banyak pertimbangan, hanya untuk contoh:

/// Namespace for extended attributes (xattrs) on macOS and other operating systems.
/// On macOS, this is an empty string, while on other operating systems, it is "user.".
#[cfg(target_os = "macos")]
const XATTR_NAMESPACE: &str = "";
#[cfg(not(target_os = "macos"))]
const XATTR_NAMESPACE: &str = "user.";

...

    fn set_attr(&self, path: &Path, attr: &str, value: &str) -> Result<()> {
        let attr_name = format!("{}{}", XATTR_NAMESPACE, attr);
        ...
    }

Kemudian, saya akan menggunakan olok-olok saya dan menyuntik tingkah laku khusus yang diperlukan untuk setiap ujian. Sekali lagi, ini adalah kod mudah hanya untuk contoh:

$ cat a.txt
https://www.kungfudev.com/

$ shasum a.txt
e4c51607d5e7494143ffa5a20b73aedd4bc5ceb5  a.txt

Saya sudah terbiasa dengan corak ini dalam Go, dan saya bercadang untuk terus menggunakannya. Tetapi saya juga telah melakukan sesuatu yang serupa dalam Rust. Untuk projek ini, saya memutuskan untuk mencuba peti mockall, dan saya mendapati ia sangat berguna.

Pertama, saya menggunakan mock! makro untuk mengejek struktur saya secara manual. Saya tahu mockall mempunyai ciri automock, tetapi saya lebih suka untuk menentukan struktur olok-olok secara langsung dalam ujian saya di mana ia akan digunakan. Beri tahu saya jika ini perkara biasa atau jika komuniti mempunyai standard yang berbeza untuk ini.

$ rrm rm a.txt

$ rrm list
╭──────────────────────────────────────────────────────┬──────────────────────────────────────┬──────┬─────────────────────╮
│ Original Path                                        ┆ ID                                   ┆ Kind ┆ Deletion Date       │
╞══════════════════════════════════════════════════════╪══════════════════════════════════════╪══════╪═════════════════════╡
│ /Users/douglasmakey/workdir/personal/kungfudev/a.txt ┆ 3f566788-75dc-4674-b069-0faeaa86aa55 ┆ File ┆ 2024-10-27 04:10:19 │
╰──────────────────────────────────────────────────────┴──────────────────────────────────────┴──────┴─────────────────────╯

Saya mendapati mockall sangat berguna, membolehkan saya menyuntik gelagat tertentu ke dalam ujian saya tanpa keterlaluan corak lama saya.

$ shasum 3f566788-75dc-4674-b069-0faeaa86aa55
e4c51607d5e7494143ffa5a20b73aedd4bc5ceb5  3f566788-75dc-4674-b069-0faeaa86aa55

Seperti yang kita lihat, mockall memberi kita keupayaan untuk menentukan tingkah laku khusus untuk ujian kami menggunakan kaedah olok-oloknya:

  • MockXattrManager::new() Ini mencipta contoh baharu objek olok-olok MockXattrManager, yang digunakan untuk mengejek tingkah laku XattrManager untuk ujian.
  • xattr_manager.expect_set_attr() Ini menetapkan jangkaan bahawa kaedah set_attr akan dipanggil semasa ujian. Anda tentukan tingkah laku yang dijangkakan bagi kaedah ini seterusnya.
  • dengan(...) Kaedah dengan menentukan hujah yang dijangkakan apabila set_attr dipanggil. Dalam kes ini, ia menjangkakan tiga argumen dan menggunakan in_iter untuk menunjukkan bahawa setiap argumen harus sepadan dengan salah satu nilai dalam vektor yang disediakan. Ini membolehkan fleksibiliti dalam ujian, kerana ia menyemak sama ada argumen adalah salah satu nilai daripada vektor yang diluluskan dan bukannya padanan tepat tunggal.
  • kali(4) Ini menyatakan bahawa kaedah set_attr dijangka akan dipanggil tepat empat kali semasa ujian.
  • kembali(|_, _, _| Ok(())) Ini memberitahu olok-olok apa yang perlu dikembalikan apabila set_attr dipanggil. Dalam kes ini, ia mengembalikan Ok(()) tanpa mengira hujah (|_, _, _| bermakna hujah diabaikan). Ini mensimulasikan kejayaan pelaksanaan set_attr.

Sesetengah daripada anda mungkin mendapati ini sangat asas atau tidak begitu menarik, tetapi seperti yang saya nyatakan, dalam siri YOLO ini, saya berkongsi perkara yang saya rasa menarik atau hanya ingin dibincangkan. Saya bukan peminat besar menggunakan perpustakaan jenis ini dalam Go, sebahagiannya disebabkan oleh kekangan Go, tetapi dalam Rust, saya mendapati mockall sangat berguna. Ia juga mengingatkan saya pada zaman dahulu saya dengan Python.

Sekali lagi, bahagian ini tidak bertujuan untuk menerangkan ejekan dalam Rust atau mockall. Saya pasti terdapat banyak sumber hebat yang merangkuminya secara terperinci. Saya cuma ingin menyebutnya secara ringkas.

Untuk membuat kesimpulan

Dalam siaran ini, saya telah berkongsi beberapa alasan di sebalik membina rrm dan alatan yang saya gunakan sepanjang perjalanan. Daripada menggunakan atribut lanjutan untuk memudahkan pengendalian metadata kepada bereksperimen dengan peti mockall untuk ujian dalam Rust, ini hanyalah perkara yang menarik minat saya.

Matlamat siri YOLO ini adalah untuk menyerlahkan keseronokan dan pembelajaran yang datang dengan membina walaupun alat mudah. Saya harap anda menemui sesuatu yang berguna di sini, dan saya berharap untuk berkongsi lebih banyak projek dan cerapan dalam siaran akan datang. Seperti biasa, maklum balas adalah dialu-alukan!

Selamat mengekod!

Atas ialah kandungan terperinci Bermain dengan Karat: Membina rm yang Lebih Selamat dan Bergembira Sepanjang Perjalanan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn