24 poin oleh xguru 2020-12-28 | 3 komentar | Bagikan ke WhatsApp

Panduan open-source yang mengikuti prinsip Unix tradisional sambil diperbarui secara modern

  • Filosofi desain CLI

→ manusia sebagai prioritas

→ komponen sederhana yang bekerja bersama

→ menjaga konsistensi antarprogram

→ berbicara seperlunya (output tidak terlalu sedikit dan tidak terlalu banyak)

→ mudah ditemukan (help yang komprehensif, contoh, saran perintah berikutnya yang bisa dijalankan, saran tindakan saat terjadi error)

→ seperti percakapan biasa

→ tangguh

→ berempati kepada pengguna

→ kekacauan: jika harus melanggar aturan, jelaskan niat dan tujuannya dengan jelas

  • Panduan CLI

→ Dasar

✓ gunakan library parsing command line: Go(Cobra,cli), Node(oclif), Python (Click,Typer), Ruby(TTY)

✓ kembalikan kode 0 saat sukses, dan kode selain 0 saat error

✓ output ke stdout

✓ log, error, dan pesan lainnya ke stderr

→ Bantuan

✓ jika dijalankan tanpa menentukan opsi, tampilkan bantuan (-h, --help)

✓ secara default tampilkan bantuan yang ringkas

· apa yang dilakukan program ini

· satu atau dua contoh pemanggilan

· penjelasan flag (jika tidak banyak)

· `--help` untuk penjelasan tambahan

✓ saat opsi -h, --help diberikan, tampilkan bantuan lengkap

✓ sediakan jalur untuk menerima feedback/isu

✓ dalam bantuan, sertakan tautan ke dokumentasi versi web

✓ jelaskan dengan contoh

✓ jika contohnya banyak, letakkan di tempat lain (cheat sheet atau halaman web)

✓ jangan terlalu memikirkan halaman man (jarang dipakai, dan juga tidak berjalan di Windows)

✓ jika bantuan panjang, pipe ke pager

✓ tampilkan flag dan perintah yang paling sering dipakai di awal bantuan

✓ gunakan formatting dalam bantuan (tebal)

✓ jika pengguna melakukan sesuatu yang salah dan Anda bisa menebaknya, berikan saran

✓ jika perintah Anda mengharapkan menerima sesuatu lewat pipe, tetapi stdin adalah terminal interaktif, tampilkan bantuan lalu segera keluar

→ Output

✓ output human-readable (dapat dibaca manusia) adalah yang paling penting

✓ jika tidak menimbulkan masalah kegunaan, sediakan output machine-readable

✓ jika human-readable membuat machine-readable tidak mungkin, sediakan opsi --plain agar bisa dipakai bersama grep / awk dan sebagainya

✓ jika menerima input --json, keluarkan dalam format JSON

✓ saat sukses sebaiknya tidak ada output, tetapi jika harus ada, buatlah ringkas. Dukung opsi -q untuk meniadakan output yang tidak perlu

✓ jika mengubah status, beri tahu pengguna (lihat output git push)

✓ buat status sistem saat ini mudah dilihat

✓ sarankan perintah yang bisa dijalankan pengguna. (seperti git status yang menampilkan git add / restore)

✓ tindakan yang melampaui bagian internal program harus eksplisit. Misalnya membaca atau menulis file yang tidak diminta pengguna (cache), atau terhubung ke server jarak jauh (mengunduh file)

✓ gunakan ASCII art untuk meningkatkan kepadatan informasi

✓ gunakan warna dengan tujuan. Jangan berlebihan

✓ matikan warna jika bukan terminal, atau jika diminta pengguna

✓ jika stdout bukan terminal interaktif, jangan tampilkan animasi

✓ gunakan simbol/emoji hanya saat memperjelas sesuatu

✓ secara default, jangan tampilkan informasi yang hanya bisa dipahami pembuatnya

✓ jangan gunakan stderr seperti file log (setidaknya jangan jadikan default. Tampilkan level log seperti ERR, WARN hanya dalam mode verbose)

✓ jika mengeluarkan banyak teks, gunakan alat paging seperti less

→ Error

✓ tangkap error dan tulis ulang pesannya untuk manusia

✓ signal-to-noise ratio penting. Jika error yang sama muncul berulang kali, kelompokkan dan tampilkan bersama header penjelasan

✓ pertimbangkan bagian mana yang pertama kali dilihat pengguna

✓ jika terjadi error yang tidak terduga/tidak bisa dijelaskan, berikan informasi debug/trace dan jelaskan cara mengirim bug ini ke pengembang

✓ buat pelaporan bug bisa dilakukan tanpa usaha tambahan. (misalnya membuat URL yang sudah memuat semua informasi, sehingga cukup dibuka di browser untuk menyelesaikan pelaporan)

→ Argument & Flags : argumen dan flag

✓ argumen: parameter posisi. Urutan penting. cp bar foo dan cp foo bar berbeda

✓ flag: parameter bernama. Satu huruf seperti -r atau beberapa huruf seperti --recursive. Urutan umumnya tidak penting.

    bisa juga memuat nilai pengguna. `--file foo.txt` atau `--file=foo.txt`

✓ utamakan flag daripada argumen. Memang perlu lebih banyak mengetik, tetapi lebih jelas. Jika argumen terlalu banyak, akan sulit memperluas fitur di kemudian hari

✓ miliki versi pendek dan versi panjang untuk flag. Jika memakai versi panjang dalam skrip, tidak perlu penjelasan tambahan

✓ gunakan flag satu huruf hanya untuk flag yang sering dipakai

✓ untuk operasi sederhana, boleh juga menerima beberapa argumen

✓ jika memerlukan dua atau lebih argumen yang berbeda, mungkin ada sesuatu yang keliru

✓ gunakan nama flag yang standar (jika sudah ada)

-a --all , -d --debug , -f --force , -h --help , -o --output , -p --port , -q --quiet , -u --user

✓ jadikan default sesuai yang cocok bagi sebagian besar pengguna

✓ jika pengguna memberikan argumen/flag yang memerlukan input tetapi tidak ada nilai yang diterima, mintalah input kepada pengguna

✓ selalu sediakan cara untuk memberikan nilai lewat argumen/flag, dan jangan memaksa input interaktif (prompt)

✓ selalu minta konfirmasi sebelum melakukan sesuatu yang berbahaya

✓ jika input atau output adalah file, dukung - untuk menerima dari stdin atau menulis ke stdout

$ curl https://example.com/something.tar.gz | tar xvf -

✓ jika flag bisa menerima nilai tambahan, izinkan kata khusus seperti none. ssh -F none

✓ jika memungkinkan, buat argumen, flag, dan subcommand tidak bergantung pada urutan

✓ nilai argumen yang sensitif (seperti kata sandi) sebaiknya bisa dimasukkan lewat file

→ Interaktivitas

✓ gunakan prompt atau fitur interaktif hanya saat stdin adalah terminal interaktif

✓ jika --no-input diberikan, jangan gunakan prompt atau fitur interaktif apa pun

✓ saat menerima input kata sandi, jangan tampilkan nilai yang diketik pengguna

✓ buat pengguna bisa keluar dengan mudah (jangan seperti vim). Pastikan Ctrl-C berfungsi. Jika karena alasan seperti menjalankan ssh, tmux, atau program lain Ctrl-C tidak memungkinkan, tampilkan dengan jelas bahwa tersedia escape sequence yang diawali ~ seperti pada SSH

→ Subcommands

✓ alat yang kompleks dapat menyediakan subcommand untuk mengurangi kompleksitas.

✓ selain itu, jika ada beberapa alat yang sangat terkait, semuanya bisa digabung dalam satu perintah agar lebih nyaman digunakan

✓ konsisten antar-subcommand. Flag yang sama harus bermakna sama, dan format outputnya serupa

✓ gunakan penamaan yang konsisten di antara subcommand bertingkat

✓ jangan buat perintah dengan nama yang membingungkan atau mirip. Seperti update dan upgrade

→ Robustness

✓ validasi semua input pengguna. Periksa sedini mungkin, dan tampilkan error yang mudah dipahami

✓ responsivitas lebih penting daripada kecepatan mentah

✓ jika memakan waktu lama, tampilkan progres

✓ jika memungkinkan, proses pekerjaan secara paralel. Tetapi lakukan dengan pertimbangan matang.

✓ terapkan timeout

✓ buat idempotent. (hasilnya tidak berubah meski dijalankan lagi). Saat error terjadi, pengguna bisa menekan panah atas di shell dan melanjutkan lagi dari sebelumnya

✓ buat crash-only. Ini tahap berikutnya dari idempotence. Jika tidak perlu pembersihan setelah pekerjaan selesai, atau pembersihan bisa ditunda hingga eksekusi berikutnya, program bisa langsung berhenti saat gagal atau terputus.

✓ orang akan menyalahgunakan program Anda

→ Future-proofing

✓ sebisa mungkin lakukan perubahan secara aditif. Jangan ubah fitur lama hingga memutus kompatibilitas, tambahkan flag baru

✓ jika perubahan tidak bisa dilakukan secara aditif, berikan peringatan terlebih dahulu

✓ perubahan output untuk manusia umumnya tidak masalah

✓ meskipun ada subcommand yang paling sering dipakai orang, jangan buat catch-all subcommand yang menjalankannya tanpa disebutkan secara eksplisit

✓ jangan izinkan singkatan subcommand yang sewenang-wenang

✓ jangan buat “bom waktu” yang suatu hari akan berhenti bekerja dengan baik

→ Signals and control Characters

✓ jika pengguna menekan Ctrl-C (sinyal INT), hentikan secepat mungkin

✓ jika pengguna menekan Ctrl-C saat proses clean-up yang lama, abaikan. Tekan lagi agar bisa memaksa keluar

 ^CGracefully stopping... (press Ctrl+C again to force)

→ Configuration

✓ ikuti spesifikasi XDG(X Desktop Group)

✓ jika Anda mengubah pengaturan yang bukan milik program Anda, mintalah konfirmasi pengguna dan jelaskan dengan jelas apa yang dilakukan

✓ terapkan parameter konfigurasi menurut urutan prioritas

flag > variabel lingkungan shell > konfigurasi level proyek (.env) > konfigurasi pengguna > konfigurasi sistem

→ Environment Variables

✓ variabel lingkungan digunakan untuk perilaku yang berubah tergantung konteks eksekusi perintah

✓ untuk memaksimalkan portabilitas, variabel lingkungan sebaiknya hanya berisi huruf besar/angka/garis bawah dan tidak boleh diawali angka

✓ jika memungkinkan, gunakan nilai satu baris (single-line) untuk variabel lingkungan

✓ jangan gunakan nama yang sudah dipakai luas

✓ jika memungkinkan, periksa dan gunakan variabel lingkungan umum

NO_COLOR, DEBUG, EDITOR, HTTP_PROXY, SHELL, TERM, TERMINFO, HOME, TMPDIR, PAGER, LINES ..

✓ jika perlu, muat variabel lingkungan dari .env

✓ jangan gunakan ekstensi .env untuk file konfigurasi

→ Naming

✓ gunakan nama yang sederhana dan mudah diingat

✓ gunakan huruf kecil saja, dan pakai - (dash) hanya jika benar-benar perlu

✓ kalau bisa, buat singkat

✓ mudah diketik di keyboard

→ Distribution

✓ jika memungkinkan, distribusikan sebagai satu biner tunggal

✓ buat mudah untuk di-uninstall

→ Analytics

✓ jangan kirim data penggunaan alat dan crash kepada Anda tanpa persetujuan pengguna

3 komentar

 
jonnung 2021-01-09

Terima kasih atas kontennya yang bagus.

 
xguru 2020-12-28

Sepertinya semakin banyak alat command line yang bagus berkat Rust dan Go yang menghasilkan single binary dengan baik.

Membuatnya juga makin mudah dan makin powerful.

 
xguru 2020-12-28

Sambil menerjemahkan secara singkat, saya juga belajar banyak. Setelah selesai, saya jadi berpikir.. mungkin akan lebih baik kalau repo-nya sendiri yang diterjemahkan. ^^;;