Menulis Aturan di Windows

Laporkan masalah Lihat sumber Per Malam · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Halaman ini berfokus pada penulisan aturan yang kompatibel dengan Windows, masalah umum menulis aturan portabel, dan beberapa solusi.

Jalur

Permasalahan:

  • Batas panjang: panjang jalur maksimum adalah 259 karakter.

    Meskipun Windows juga mendukung jalur yang lebih panjang (hingga 32.767 karakter), banyak program dibangun dengan batas bawah.

    Perhatikan hal ini tentang program yang Anda jalankan dalam tindakannya.

  • Direktori kerja: juga dibatasi hingga 259 karakter.

    Proses tidak boleh cd ke dalam direktori yang berisi lebih dari 259 karakter.

  • Kepekaan huruf besar/kecil: Jalur Windows tidak peka huruf besar/kecil, sedangkan jalur Unix peka huruf besar/kecil.

    Perhatikan hal ini saat membuat command line untuk tindakan.

  • Pemisah jalur: adalah garis miring terbalik (\`), not forward slash (/`).

    Bazel menyimpan jalur bergaya Unix dengan pemisah /. Meskipun beberapa program Windows mendukung Jalur gaya Unix, yang lainnya tidak. Beberapa perintah bawaan di {i>cmd.exe<i} mendukungnya, beberapa tidak.

    Sebaiknya selalu gunakan \` separators on Windows: replace/with` saat Anda membuat perintah variabel lingkungan dan garis untuk tindakan.

  • Jalur absolut: jangan diawali dengan garis miring (/).

    Jalur absolut di Windows dimulai dengan huruf drive, seperti C:\foo\bar.txt. Tidak ada satu pun {i>root<i} sistem file.

    Perhatikan hal ini jika aturan Anda memeriksa apakah suatu jalur bersifat absolut. Jalur absolut harus dihindari karena mereka sering tidak portabel.

Solusi:

  • Pastikan jalan tetap pendek.

    Hindari nama direktori yang panjang, struktur direktori yang sangat bertingkat, nama file yang panjang, ruang kerja yang panjang nama, nama target yang panjang.

    Semua ini dapat menjadi komponen jalur tindakan file input, dan mungkin menghabiskan panjang jalur batas tersebut.

  • Gunakan root output singkat.

    Gunakan tanda --output_user_root=<path> untuk menentukan jalur singkat untuk output Bazel. Ide bagus adalah memiliki drive (atau drive virtual) hanya untuk output Bazel (seperti file D:\`), and adding this line to your.bazelrc`:

    build --output_user_root=D:/
    

    atau

    build --output_user_root=C:/_bzl
    
  • Gunakan persimpangan.

    Persimpangan adalah [1], symlink direktori. Persimpangan mudah dibuat dan dapat menunjuk ke direktori (di komputer yang sama) dengan jalur yang panjang. Jika tindakan build membuat persimpangan yang jalurnya pendek tetapi targetnya panjang, maka alat dengan batas jalur pendek dapat mengakses file pada direktori yang disambungkan.

    Dalam file .bat atau cmd.exe, Anda dapat membuat sambungan seperti ini:

    mklink /J c:\path\to\junction c:\path\to\very\long\target\path
    

    [1]: Singkatnya Persimpangan bukan Link Simbolis, tetapi untuk demi tindakan pembangunan, Anda dapat menganggap {i>Junction <i}sebagai Direktori Symlink.

  • Ganti / dengan `` di jalur dalam actions / envvars.

    Saat Anda membuat command line atau variabel lingkungan untuk suatu tindakan, buat jalurnya Bergaya Windows. Contoh:

    def as_path(p, is_windows):
        if is_windows:
            return p.replace("/", "\\")
        else:
            return p
    

Variabel lingkungan

Permasalahan:

  • Kepekaan huruf besar/kecil: Nama variabel lingkungan Windows tidak peka huruf besar/kecil.

    Misalnya, dalam Java, System.getenv("SystemRoot") dan System.getenv("SYSTEMROOT") menghasilkan hasil yang sama. (Hal ini juga berlaku untuk bahasa lain.)

  • Hermeticity: tindakan harus menggunakan variabel lingkungan kustom sesedikit mungkin.

    Variabel lingkungan adalah bagian dari kunci cache tindakan. Jika tindakan menggunakan variabel lingkungan yang sering berubah, atau khusus bagi pengguna, sehingga membuat aturan kurang dapat di-cache.

Solusi:

  • Hanya gunakan nama variabel lingkungan dalam huruf besar.

    Cara ini berfungsi di Windows, macOS, dan Linux.

  • Minimalkan lingkungan tindakan.

    Saat menggunakan ctx.actions.run, setel lingkungan ke ctx.configuration.default_shell_env. Jika tindakan membutuhkan lebih banyak variabel lingkungan, masukkan semuanya dalam kamus, dan meneruskannya ke tindakan. Contoh:

    load("@bazel_skylib//lib:dicts.bzl", "dicts")
    
    def _make_env(ctx, output_file, is_windows):
        out_path = output_file.path
        if is_windows:
            out_path = out_path.replace("/", "\\")
        return dicts.add(ctx.configuration.default_shell_env, {"MY_OUTPUT": out_path})
    

Tindakan

Permasalahan:

  • Output yang dapat dieksekusi: Setiap file yang dapat dieksekusi harus memiliki ekstensi yang dapat dieksekusi.

    Ekstensi yang paling umum adalah .exe (file biner) dan .bat (skrip batch).

    Perlu diketahui bahwa skrip shell (.sh) TIDAK dapat dieksekusi di Windows; Anda tidak dapat menentukannya sebagai executable ctx.actions.run. Juga tidak ada izin +x yang dapat dimiliki file, sehingga Anda tidak dapat mengeksekusi file arbitrer seperti di Linux.

  • Perintah Bash: Demi portabilitas, hindari menjalankan perintah Bash langsung dalam tindakan.

    {i>Bash<i} sudah tersebar luas di sistem yang mirip Unix, tetapi sering kali tidak tersedia di Windows. Bazel sendiri adalah semakin sedikit mengandalkan Bash (MSYS2), sehingga di masa depan pengguna akan cenderung tidak memiliki MSYS2 yang diinstal bersama dengan Bazel. Untuk membuat aturan lebih mudah digunakan di Windows, hindari menjalankan perintah Bash di tindakan.

  • Akhiran baris: Windows menggunakan CRLF (\r\n), sistem seperti Unix menggunakan LF (\n).

    Perhatikan hal ini saat membandingkan file teks. Perhatikan pengaturan Git Anda, terutama baris akhir saat melakukan check out atau melakukan pembayaran. (Lihat setelan core.autocrlf Git.)

Solusi:

  • Menggunakan aturan yang dibuat tanpa tujuan Bash.

    native.genrule() adalah wrapper untuk perintah Bash, dan sering digunakan untuk menyelesaikan masalah sederhana seperti menyalin file atau menulis file teks. Anda dapat menghindari mengandalkan Bash (dan menciptakan kembali wheel): periksa apakah bazel-skylib memiliki aturan yang dibuat khusus untuk kebutuhan Anda. Tidak satu pun dari mereka bergantung pada {i>Bash<i} saat dibuat/diuji di Windows.

    Contoh aturan build:

    • copy_file() (sumber, dokumentasi): menyalin file di tempat lain, secara opsional membuatnya dapat dieksekusi

    • write_file() (sumber, dokumentasi): menulis file teks, dengan akhiran baris yang diinginkan (auto, unix, atau windows), secara opsional membuatnya dapat dieksekusi (jika itu berupa skrip)

    • run_binary() (sumber, dokumentasi): menjalankan biner (atau aturan *_binary) dengan input tertentu dan output yang diharapkan sebagai tindakan build (ini adalah wrapper aturan build untuk ctx.actions.run)

    • native_binary() (sumber, dokumentasi): menggabungkan biner native dalam aturan *_binary, yang dapat Anda bazel run atau gunakan di run_binary() atribut tool atau atribut tools native.genrule()

    Contoh aturan pengujian:

    • diff_test() (sumber, dokumentasi): pengujian yang membandingkan konten dari dua file

    • native_test() (sumber, dokumentasi): menggabungkan biner native dalam aturan *_test, yang dapat Anda bazel test

  • Di Windows, sebaiknya gunakan skrip .bat untuk hal-hal yang sederhana.

    Sebagai ganti skrip .sh, Anda dapat menyelesaikan tugas sederhana dengan skrip .bat.

    Misalnya, jika Anda memerlukan skrip yang tidak melakukan apa pun, atau mencetak pesan, atau keluar dengan skrip kode error, file .bat sederhana sudah cukup. Jika aturan Anda menampilkan DefaultInfo() penyedia layanan, kolom executable mungkin merujuk ke file .bat tersebut di Windows.

    Dan karena ekstensi file tidak berpengaruh di macOS dan Linux, Anda selalu dapat menggunakan .bat sebagai , bahkan untuk skrip shell.

    Perlu diketahui bahwa file .bat kosong tidak dapat dijalankan. Jika Anda memerlukan skrip kosong, tulis satu spasi di dalamnya.

  • Gunakan Bash dengan cara yang berprinsip.

    Dalam aturan build dan pengujian Starlark, gunakan ctx.actions.run_shell untuk menjalankan skrip Bash dan Bash perintah sebagai tindakan.

    Di makro Starlark, gabungkan skrip dan perintah Bash dalam native.sh_binary() atau native.genrule(). Bazel akan memeriksa apakah Bash tersedia dan menjalankan skrip atau perintah melalui Bash.

    Dalam aturan repositori Starlark, coba hindari Bash sama sekali. Bazel saat ini tidak menawarkan cara untuk berlari perintah Bash dengan cara berprinsip dalam aturan repositori.

Menghapus file

Permasalahan:

  • File tidak dapat dihapus saat dibuka.

    File yang terbuka tidak dapat dihapus (secara default), percobaan akan menghasilkan "Akses Ditolak" yang sama. Jika Anda tidak dapat menghapus file, mungkin proses yang sedang berjalan masih menahannya terbuka.

  • Direktori kerja dari proses yang sedang berjalan tidak dapat dihapus.

    Proses memiliki {i>handle<i} terbuka untuk direktori kerjanya, dan direktori itu tidak dapat dihapus hingga prosesnya berakhir.

Solusi:

  • Di kode Anda, cobalah menutup file dengan segera.

    Di Java, gunakan try-with-resources. Di Python, gunakan with open(...) as f:. Pada prinsipnya, cobalah menutup nama sebutan channel sesegera mungkin.