

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Panduan pengembang plugin
<a name="sbomgen-plugin-developer-guide"></a>

 Panduan ini menjelaskan cara memperluas Amazon Inspector SBOM Generator (inspector-sbomgen) dengan plugin Lua kustom. Plugin memungkinkan Anda menambahkan dukungan untuk ekosistem paket baru tanpa memodifikasi kode sumber sbomgen atau harus mengkompilasi ulang. 

 Untuk katalog fungsi lengkap, lihat[Referensi API Plugin](sbomgen-plugin-api-reference.md). Untuk panduan tentang tes menulis, lihat[Panduan pengujian plugin](sbomgen-plugin-testing-guide.md). 

## Ikhtisar
<a name="sbomgen-plugin-developer-guide-overview"></a>

 Plugin Sbomgen ditulis dalam Lua, dan ikuti pipeline dua langkah: 
+ **Discovery** — pindai daftar file artefak dan laporkan file mana yang relevan dengan ekosistem Anda.
+ **Koleksi** — mengurai setiap file yang ditemukan dan mendorong temuan paket ke dalam SBOM.

### Model Acara Plugin
<a name="sbomgen-plugin-developer-guide-plugin-event-model"></a>

 Plugin Discovery membutuhkan cara untuk memberi tahu plugin koleksi bahwa file yang berisi metadata paket ditemukan di artefak di bawah inventaris. Untuk memfasilitasi berbagi data ini, plugin penemuan menentukan **nama acara** dan mengembalikan daftar jalur file. Plugin koleksi **berlangganan** acara itu dan menerima setiap jalur file yang cocok. Ini memisahkan deteksi file dari penguraian - Anda dapat memiliki satu plugin penemuan memberi makan beberapa kolektor (pola penggemar). Namun, setiap plugin penemuan harus memiliki nama acara yang unik, dan setiap plugin koleksi harus memiliki nama kolektor yang unik. Lihat [Aturan Tabrakan Plugin](#sbomgen-plugin-developer-guide-plugin-collision-rules) untuk detail. 

 Pengembang dapat mengenali ini sebagai pola desain **pengamat**. 

 Desain ini memungkinkan satu plugin penemuan memicu beberapa analisis independen dengan cara yang berkinerja baik. Misalnya, satu plugin penemuan dapat menemukan masing-masing `requirements.txt` dalam artefak, lalu memberi makan: 
+ **Kolektor paket** yang mem-parsing setiap baris menjadi temuan SBOM ()`name==version`.
+ **Kolektor rahasia** yang menandai baris yang berisi kunci API atau token yang secara tidak sengaja disematkan sebagai versi.
+ **Kolektor kebijakan** yang melaporkan penentu versi unpinned atau wildcard.

 Setiap kolektor berjalan secara independen terhadap daftar file yang sama tanpa berjalan kembali sistem file artefak. Ini juga memungkinkan pembuat plugin untuk menambahkan plugin koleksi baru yang berlangganan acara yang ada tanpa harus mengubah plugin penemuan yang sesuai. 

## Mulai Cepat: Membuat Plugin Baru
<a name="sbomgen-plugin-developer-guide-quick-start-creating-new-plugins"></a>

 Cara tercepat untuk membuat plugin baru adalah menggunakan perintah perancah bawaan: 

```
inspector-sbomgen plugin new
```

 Perintah meminta nama plugin dan direktori proyek. Menekan Enter menerima default yang ditunjukkan dalam tanda kurung: 

```
Plugin name (identifies the software ecosystem your plugin will inventory, e.g. debian-dpkg, rhel-rpm, python-pip, cmake) [my-custom-ecosystem]: cmake
Project directory [my-sbomgen-plugins]:
```

 Anda juga dapat meneruskan argumen secara langsung: 

```
inspector-sbomgen plugin new --name cmake --path /tmp/custom-plugins
```

### Dimulai dengan contoh kerja
<a name="sbomgen-plugin-developer-guide-starting-with-a-working-example"></a>

 Jika Anda ingin bereksperimen dengan plugin sebelum menulis logika Anda sendiri, buat plugin baru menggunakan `--with-example` bendera: 

```
inspector-sbomgen plugin new --with-example
```

 Ini menghasilkan proyek plugin yang berfungsi penuh dengan parser lockfile sampel, data uji, dan tes lulus. Plugin contoh menemukan `example.lock` file, mem-parsing `name==version` entri, dan mendorong paket ke dalam SBOM. Anda dapat segera menjalankan pengujian untuk melihat sistem plugin beraksi, lalu memodifikasi kode untuk menargetkan ekosistem Anda yang sebenarnya. 

 Untuk scaffolding lanjutan yang mencakup semua fungsi penggantian opsional (`get_scanner_name`,,, penemuan multi-peristiwa `get_event_name``get_scanner_groups`, dll.), Gunakan `--with-overrides` flag (selengkapnya tentang ini nanti): 

```
inspector-sbomgen plugin new --with-overrides
```

### Menyelesaikan Plugin Anda
<a name="sbomgen-plugin-developer-guide-completing-your-plugin"></a>

 Setelah scaffolding, file plugin yang dihasilkan berisi `TODO` penanda yang menunjukkan di mana harus menambahkan logika spesifik ekosistem Anda. Kerjakan spidol ini untuk mengubah perancah menjadi plugin yang berfungsi: 
+ Ganti semua `TODO` spidol dengan nilai aktual Anda
+ Perbarui pola file `discover()` agar sesuai dengan file target Anda
+ Terapkan logika parsing `collect()` dan panggil `sbomgen.push_package()` untuk setiap paket

### Uji Plugin Anda
<a name="sbomgen-plugin-developer-guide-test-your-plugin"></a>

 Ada dua cara untuk menguji plugin Anda: 

 **1. Built-in test harness** - Gunakan `inspector-sbomgen plugin test` untuk memvalidasi logika plugin selama pengembangan. Ini menjalankan file `init_test.lua` pengujian Anda tanpa memerlukan artefak nyata untuk memindai: 

```
inspector-sbomgen plugin test --path ./my-plugins
```

 Lihat detail tentang menulis file pengujian dan menggunakan `testing.*` API. [Panduan pengujian plugin](sbomgen-plugin-testing-guide.md) 

 **2. End-to-end**scan - Panggil plugin Anda menggunakan perintah sbomgen standar untuk memverifikasi itu bekerja terhadap artefak nyata. Untuk pendekatan ini, Anda perlu menyediakan artefak yang berisi file target plugin Anda (misalnya, direktori dengan `requirements.txt` atau setara) dan jalur ke direktori plugin Anda: 

```
inspector-sbomgen directory \
    --path /path/to/test/dir \
    --plugin-dir ./my-plugins \
    --disable-native-scanners \
    -o sbom.json
```

 `--disable-native-scanners`Bendera memastikan hanya plugin Lua Anda yang berjalan, membuatnya lebih mudah untuk menguji tanpa output dari pemindai bawaan (asli). 

## Pengaturan IDE
<a name="sbomgen-plugin-developer-guide-ide-setup"></a>

 Sbomgen menyediakan penyelesaian kode, pemeriksaan tipe, dan dokumentasi sebaris untuk seluruh `sbomgen.*` API di VS Code. 

### Kode VS dengan Server Bahasa Lua
<a name="sbomgen-plugin-developer-guide-vs-code-with-lua-language-server"></a>
+ [Instal ekstensi Lua: sumneko.lua](https://marketplace.visualstudio.com/items?itemName=sumneko.lua)
+ Buka `.lua` file apa pun di proyek plugin Anda

 Itu dia\! `plugin new`Perintah menghasilkan `.vscode/settings.json` dan `library/sbomgen.lua` yang secara otomatis terdeteksi oleh Server Bahasa Lua. Anda akan segera mendapatkan: 
+ Penyelesaian kode untuk semua `sbomgen.*` fungsi
+ Petunjuk parameter dengan tipe
+ Dokumentasi hover
+ Jenis pemeriksaan

## Struktur Direktori Plugin
<a name="sbomgen-plugin-developer-guide-plugin-directory-structure"></a>

 Plugin penemuan dan koleksi Sbomgen harus mematuhi struktur direktori berikut: 

```
{plugin-dir}/
├── discovery/
│   └── {platform}/
│       └── {category}/
│           └── {ecosystem}/
│               └── init.lua          # REQUIRED entrypoint
└── collection/
    └── {platform}/
        └── {category}/
            └── {ecosystem}/
                └── init.lua          # REQUIRED entrypoint
```

 Nama-nama direktori ini membawa arti semantik — sbomgen menggunakannya untuk mendapatkan metadata default untuk plugin Anda, termasuk nama pemindai, nama acara, grup pemindai, dan pemfilteran platform. Ini mengurangi jumlah pengembang boilerplate jika tidak harus menulis. Memilih nilai yang benar memastikan plugin Anda terintegrasi dengan benar dengan pemilihan pemindai dan model eksekusi sbomgen. 

 Bagian di bawah ini mengeksplorasi struktur direktori secara lebih rinci, memberikan panduan tentang makna dan konvensi semantik. 

### Platform
<a name="sbomgen-plugin-developer-guide-platform"></a>

 Direktori platform mengontrol sistem operasi mana yang dijalankan plugin Anda. 


| **Nilai** | **Kapan harus digunakan** | 
| --- | --- | 
| cross-platform | Plugin berfungsi pada OS apa pun (kebanyakan plugin) | 
| linux | Logika deteksi spesifik Linux | 
| windows | Logika deteksi khusus Windows | 
| macos | Logika deteksi khusus macOS | 

### Kategori
<a name="sbomgen-plugin-developer-guide-category"></a>

 Direktori kategori menentukan grup pemindai default yang ditetapkan ke plugin Anda, yang mengontrol apakah itu berjalan secara default atau memerlukan opt-in eksplisit. Lihat [Pemilihan Pemindai](#sbomgen-plugin-developer-guide-scanner-selection) bagaimana grup memengaruhi eksekusi. 


| **Nilai** | **Grup default** | **Kapan harus digunakan** | 
| --- | --- | --- | 
| proglang | programming-language-packages, pkg-scanner | Paket bahasa pemrograman (pip, npm, maven, dll.) | 
| os | os, pkg-scanner | Manajer paket OS (dpkg, rpm, apk, dll.) | 
| extra-ecosystems | extra-ecosystems, pkg-scanner | Aplikasi dan runtime (nginx, curl, wordpress, dll.) | 

 Jika Anda menggunakan nama kategori yang tidak cocok dengan salah satu di atas, nama kategori itu sendiri digunakan sebagai grup. 

### Ekosistem
<a name="sbomgen-plugin-developer-guide-ecosystem"></a>

 Nama untuk ekosistem paket tertentu (misalnya,, `python-pip``python-poetry`,`debian-dpkg`,`curl`). Nama tanda hubung adalah konvensi umum tetapi bukan persyaratan yang ketat. 

 Nama pemindai dan nama kolektor berasal langsung dari nama direktori ekosistem. 

### Pasangan nama acara
<a name="sbomgen-plugin-developer-guide-event-name-pairing"></a>

 Plugin penemuan dan koleksi di jalur direktori yang sama secara otomatis dipasangkan. Misalnya, plugin penemuan `discovery/cross-platform/proglang/python-pip/` secara otomatis berpasangan dengan`collection/cross-platform/proglang/python-pip/`. 

 Anda dapat mengganti ini dengan mendefinisikan `get_event_name()` dan `subscribe_to_event()` di plugin Anda. 

## Plugin Penemuan
<a name="sbomgen-plugin-developer-guide-discovery-plugins"></a>

 Plugin penemuan hanya membutuhkan `discover()` fungsinya. Semua fungsi lainnya bersifat opsional — default berasal dari jalur direktori. 

 Sebagian besar plugin penemuan bekerja dengan mencari file yang nama atau jalurnya mengidentifikasi ekosistem tertentu — misalnya, untuk pip `requirements.txt` Python, untuk npm, atau `package.json` untuk kargo Rust. `Cargo.lock` `sbomgen.find_files_by_*`Fungsi melakukan pencocokan ini di luar VM Lua, yang membuatnya jauh lebih cepat daripada mengulangi daftar file lengkap di Lua: 

```
-- REQUIRED: Scans the artifact and returns a table of file paths.
function discover()
    return sbomgen.find_files_by_name({"requirements.txt"})
end
```

 `discover()`harus mengembalikan tabel Lua (array) string. Jika tidak ada file yang ditemukan, kembalikan tabel kosong`{}`. 

### Pola penemuan umum
<a name="sbomgen-plugin-developer-guide-common-discovery-patterns"></a>


| **Tujuan** | **Fungsi yang direkomendasikan** | 
| --- | --- | 
| Cocokkan satu atau lebih nama file yang tepat | sbomgen.find\_files\_by\_name({names}) | 
| Cocokkan nama file kasus-tidak peka huruf besar/kecil | sbomgen.find\_files\_by\_name\_icase({names}) | 
| Cocokkan dengan sufiks jalur (mis.,/pom.properties) | sbomgen.find\_files\_by\_suffix({suffixes}) | 
| Cocokkan dengan regex jalur penuh | sbomgen.find\_files\_by\_path\_regex({patterns}) | 
| Pencocokan nama dasar gaya glob (mis.,) \*.lock | sbomgen.glob\_find\_files(pattern) | 

 Ketika logika Anda memerlukan pasca-pemfilteran — misalnya, menjaga file tetap cocok dengan sufiks tetapi tidak termasuk direktori build-output — menggabungkan panggilan dengan loop Lua: `find_files_by_*` 

```
function discover()
    local found = {}
    for _, f in ipairs(sbomgen.find_files_by_suffix({".conda-meta.json"})) do
        if not f:match("[/\\]%.cache[/\\]") then
            table.insert(found, f)
        end
    end
    return found
end
```

 Hindari `sbomgen.get_file_list()` penemuan kecuali tidak ada pencocokan lain yang cocok — itu menyalin setiap jalur ke Lua VM dan dapat memakan waktu beberapa detik pada artefak besar. Lihat [Referensi API Plugin](sbomgen-plugin-api-reference.md) untuk detailnya. 

### Penemuan multi-acara
<a name="sbomgen-plugin-developer-guide-multi-event-discovery"></a>

 Secara default, semua file yang dikembalikan oleh `discover()` dipublikasikan ke satu acara (dari`get_event_name()`). Jika pemindai Anda perlu merutekan file yang berbeda ke kolektor yang berbeda, kembalikan tabel yang dikunci sebagai gantinya: 

```
function discover()
    return {
        EventNameFoundCurl = sbomgen.find_files_by_name({"curl", "curl.exe"}),
        EventNameFoundLibcurl = sbomgen.find_files_by_name({"curlver.h"}),
    }
end
```

 Ketika `discover()` mengembalikan tabel dengan kunci string, setiap kunci diperlakukan sebagai nama acara terpisah dan nilainya (tabel jalur file) dipublikasikan ke acara itu. Plugin koleksi berlangganan acara tertentu melalui `subscribe_to_event()` seperti biasa. 

 Ini kompatibel ke belakang — mengembalikan tabel sekuensial `{"file1", "file2"}` masih berfungsi sebagai mode acara tunggal. Deteksi otomatis: tabel dengan tombol string apa pun adalah multi-acara, tabel dengan hanya kunci bilangan bulat (atau kosong) adalah peristiwa tunggal. 

 Bila menggunakan multi-event, tidak `get_event_name()` digunakan untuk penerbitan (nama acara berasal dari tombol tabel dikembalikan). Namun, itu masih dipanggil selama pemuatan plugin untuk deteksi tabrakan, jadi itu harus mengembalikan nilai unik atau dihilangkan untuk menggunakan default. 

### Fungsi penemuan opsional
<a name="sbomgen-plugin-developer-guide-optional-discovery-functions"></a>

 Semua ini memiliki default waras yang berasal dari jalur direktori. Tentukan mereka hanya jika Anda perlu mengganti: 


| **Fungsi** | **Default** | **Ganti saat...** | 
| --- | --- | --- | 
| get\_scanner\_name() | {ecosystem}(misalnya,python-pip) | Anda menginginkan nama pemindai khusus | 
| get\_scanner\_description() | "Lua discovery plugin: {ecosystem}" | Anda ingin deskripsi khusus | 
| get\_scanner\_groups() | Berasal dari direktori kategori | Anda membutuhkan grup non-standar | 
| get\_event\_name() | Berasal dari jalur direktori | Anda memerlukan perutean acara khusus | 
| get\_localhost\_scan\_paths() | Tidak ada | Plugin Anda membutuhkan jalur tertentu yang dipindai selama localhost pemindaian | 

### Jalur pemindaian localhost
<a name="sbomgen-plugin-developer-guide-localhost-scan-paths"></a>

 Ketika sbomgen menjalankan `localhost` pemindaian, ia berjalan direktori yang ditentukan pengguna ditambah jalur default yang dideklarasikan oleh pemindai. Secara default, plugin penemuan Lua tidak menyumbangkan jalur apa pun, sehingga file di luar direktori yang ditentukan pengguna tidak akan muncul dalam daftar file. 

 Tentukan `get_localhost_scan_paths()` untuk mengembalikan direktori atau jalur file yang harus disertakan oleh walker localhost: 

```
function get_localhost_scan_paths()
    return {
        "/usr/bin",
        "/usr/local/bin",
    }
end
```

 Jalur yang dikembalikan ditambahkan ke daftar pemindaian walker hanya selama `localhost` pemindaian — mereka tidak berpengaruh pada`container`,`directory`, atau pemindaian. `archive` 

### Jalur pemindaian khusus platform
<a name="sbomgen-plugin-developer-guide-platform-specific-scan-paths"></a>

 Ketika file yang Anda pedulikan tinggal di lokasi yang berbeda di Windows, macOS, dan Linux, cabang `sbomgen.get_platform()` dan kembalikan jalur yang sesuai untuk host: 

```
function get_localhost_scan_paths()
    local platform = sbomgen.get_platform()

    if platform == sbomgen.platform.WINDOWS then
        local drive = sbomgen.get_system_drive()
        return {
            drive .. "/Program Files/MyApp/myapp.exe",
            drive .. "/Program Files (x86)/MyApp/myapp.exe",
        }
    end

    if platform == sbomgen.platform.DARWIN then
        return {"/Applications/MyApp.app/Contents/MacOS/myapp"}
    end

    -- Linux
    return {
        "/usr/bin/myapp",
        "/usr/local/bin/myapp",
    }
end
```

 Pada Windows, gunakan `sbomgen.get_system_drive()` untuk menyelesaikan huruf drive sistem (misalnya,`"C:"`) daripada hard-coding itu. Untuk jalur yang berasal dari variabel lingkungan seperti `LOCALAPPDATA` or`PROGRAMFILES`, iterasi `sbomgen.get_env_vars()` dan cari nilai dengan kunci. Lihat [Referensi API Plugin](sbomgen-plugin-api-reference.md) untuk detailnya. 

## Plugin Koleksi
<a name="sbomgen-plugin-developer-guide-collection-plugins"></a>

 Plugin koleksi hanya membutuhkan `collect()` fungsinya. Semua fungsi lainnya adalah opsional. 

 `collect(file_path)`dipanggil sekali per file yang ditemukan oleh plugin penemuan berpasangan. Pola khasnya adalah: 
+ **Baca** konten file menggunakan `sbomgen.read_file()` (untuk file kecil yang dimuat ke memori) atau `sbomgen.open_file()` (untuk file besar dibaca line-by-line).
+ **Parse** konten — pencocokan string untuk manifes sederhana, `sbomgen.json_decode()` untuk JSON, untuk XHTML, atau `sbomgen.xml_decode()` `sbomgen.search_binary()` untuk binari yang dikompilasi.
+ **Publikasikan** setiap paket yang ditemukan `sbomgen.push_package()` dengan menelepon dengan metadata paket.

```
-- REQUIRED: Called once per discovered file.
-- Parse the file and call sbomgen.push_package() for each package found.
function collect(file_path)
    local content, err = sbomgen.read_file(file_path)
    if err or not content then return end

    for line in content:gmatch("[^\r\n]+") do
        local name, version = line:match("^([%w%-%_%.]+)==(.+)$")
        if name and version then
            sbomgen.push_package({
                name = name,
                version = version,
                purl_type = "pypi",
                component_type = sbomgen.component_types.LIBRARY,
            })
        end
    end
end
```

 `collect()`tidak mengembalikan nilai. Setiap `push_package()` panggilan membutuhkan`name`,`purl_type`, dan`component_type`. Lihat [Referensi API Plugin](sbomgen-plugin-api-reference.md) untuk semua bidang yang didukung. 

### Melampirkan metadata ke komponen
<a name="sbomgen-plugin-developer-guide-attaching-metadata-to-components"></a>

 **Sbomgen mendukung dua cara untuk melampirkan metadata ke komponen paket: kualifikasi **PURL** dan properti CycloneDX.** Mereka melayani tujuan yang berbeda, dan pilihan di antara mereka memiliki implikasi untuk bagaimana Amazon Inspector mengidentifikasi kerentanan dalam SBOM yang dihasilkan. 


| **Mekanisme** | **Dimana itu muncul** | **Gunakan untuk** | 
| --- | --- | --- | 
| qualifiers | Di dalam URL paket (mis.,pkg:deb/debian/curl@7.88.1?arch=amd64) | Data yang merupakan bagian dari identitas paket | 
| properties | Dalam array SBOM components[].properties | Metadata deskriptif yang tidak mengubah cara paket diidentifikasi | 

 **Rekomendasi: lebih suka properti CycloneDX (di bawah namespace Anda sendiri) untuk metadata kustom.** Properti tidak mengubah identitas komponen, sehingga tidak dapat memengaruhi identifikasi kerentanan Amazon Inspector. Cadangan kualifikasi PURL untuk kasus di mana tipe PURL ekosistem Anda memerlukannya. 

#### Kualifikasi PURL
<a name="sbomgen-plugin-developer-guide-purl-qualifiers"></a>

 Beberapa kualifikasi PURL memiliki arti semantik untuk Amazon Inspector dan memengaruhi identifikasi kerentanan. Misalnya, pada `deb` komponen Inspector menggunakan qualifier seperti `arch` dan `distro` untuk memilih feed kerentanan yang benar; pada `generic` komponen untuk binari yang dikompilasi, qualifier seperti `go_toolchain` atau mengidentifikasi toolchain yang digunakan. `rust_toolchain` Menyetel Inspector yang memenuhi syarat tidak mengenali, atau menghilangkan yang diharapkan, dapat menyebabkan kerentanan terlewatkan atau salah dikaitkan. 

 Lihat [Apa itu URL paket?](https://docs.aws.amazon.com/inspector/latest/user/sbom-generator-purl-sbom.html) dalam panduan pengguna Amazon Inspector untuk konvensi kualifikasi yang diakui Inspector per jenis PURL. 

 Tetapkan kualifikasi melalui `qualifiers` tabel di`sbomgen.push_package()`: 

```
sbomgen.push_package({
    name = "curl",
    version = "7.88.1",
    purl_type = "deb",
    namespace = "debian",
    component_type = sbomgen.component_types.LIBRARY,
    qualifiers = {
        arch = "amd64",
        distro = "debian-12",
    },
})
```

 Hanya tetapkan kualifikasi ketika mereka selaras dengan harapan Inspektur untuk tipe PURL. Jika Anda perlu merekam metadata yang bukan bagian dari identitas paket, gunakan properti CycloneDX sebagai gantinya. 

#### Properti CycloneDX
<a name="sbomgen-plugin-developer-guide-cyclonedx-properties"></a>

 Properti CycloneDX adalah anotasi nilai kunci yang muncul dalam array SBOM. `components[].properties` Mereka menggambarkan komponen tanpa mempengaruhi bagaimana itu diidentifikasi, sehingga mereka adalah pilihan yang aman untuk metadata yang ditentukan plugin. 

 **`amazon:inspector:*`Ruang nama disediakan untuk Amazon Inspector.** Secara khusus: 
+ `amazon:inspector:sbom_generator:*`— disediakan untuk sbomgen dan pemindai bawaannya.
+ `amazon:inspector:sbom_scanner:*`— disediakan untuk Amazon Inspector Scan API.

 Penulis plugin tidak boleh mengeluarkan kunci di dalam ruang nama yang dicadangkan ini. Menulis ke dalamnya dapat mengganggu perilaku Inspektur dan dapat ditimpa. Untuk daftar lengkap kunci cadangan, lihat [Menggunakan ruang nama CycloneDX dengan](https://docs.aws.amazon.com/inspector/latest/user/cyclonedx-namespace.html) Amazon Inspector. 

 Gunakan namespace Anda sendiri (biasanya pengenal organisasi atau plugin Anda) saat mendefinisikan properti: 

```
sbomgen.push_package({
    name = "requests",
    version = "2.28.1",
    purl_type = "pypi",
    component_type = sbomgen.component_types.LIBRARY,
    properties = {
        ["acme:python:manifest_path"] = file_path,
        ["acme:python:pinned"] = "true",
        ["acme:python:source"] = "requirements.txt",
    },
})
```

#### Aturan penamaan kunci
<a name="sbomgen-plugin-developer-guide-key-naming-rules"></a>

 Kunci properti diproses oleh sbomgen sebagai berikut: 
+ Kunci yang **berisi titik dua** digunakan kata demi kata di SBOM. Selalu sertakan setidaknya satu titik dua di kunci Anda sehingga Anda mengontrol namespace.
+ Kunci yang **tidak mengandung titik dua** secara otomatis diawali dengan `amazon:inspector:sbom_generator:` — menempatkannya di dalam namespace Inspector yang dicadangkan. Hindari bentuk ini untuk properti kustom.

```
properties = {
    ["acme:my_plugin:detected_via"] = "lockfile",  -- used as-is (recommended)
    detected_via                   = "lockfile",  -- becomes "amazon:inspector:sbom_generator:detected_via" (avoid)
}
```

 `sbomgen.properties.*`Konstanta ada sehingga pemindai resmi memancarkan kunci yang konsisten di dalam namespace yang dicadangkan. Mereka bukan titik ekstensi untuk plugin khusus — gunakan namespace Anda sendiri sebagai gantinya. 

#### Properti dan kualifikasi pada komponen anak
<a name="sbomgen-plugin-developer-guide-properties-and-qualifiers-on-child-components"></a>

 Bersarang `children` adalah komponen independen. Setiap anak memiliki tabelnya sendiri `properties` dan `qualifiers` tabelnya; metadata yang ditetapkan pada orang tua tidak menyebar ke anak-anak. Tetapkan nilai secara eksplisit pada setiap anak yang membutuhkannya. 

### Fungsi koleksi opsional
<a name="sbomgen-plugin-developer-guide-optional-collection-functions"></a>


| **Fungsi** | **Default** | **Ganti saat...** | 
| --- | --- | --- | 
| get\_collector\_name() | {ecosystem}(misalnya,python-pip) | Anda ingin nama kolektor khusus | 
| get\_collector\_description() | string kosong | Anda ingin deskripsi | 
| subscribe\_to\_event() | Berasal dari jalur direktori | Anda memerlukan perutean acara khusus | 

## Menjalankan Plugin Anda
<a name="sbomgen-plugin-developer-guide-running-your-plugins"></a>

 Agar plugin menghasilkan metadata paket, sbomgen harus diberi artefak untuk memindai yang berisi file target plugin Anda (misalnya, direktori dengan, `requirements.txt``package.json`, atau file manifes paket yang setara). 

### Penggunaan dasar
<a name="sbomgen-plugin-developer-guide-basic-usage"></a>

```
inspector-sbomgen <artifact type> <arguments> --plugin-dir /path/to/plugins
```

 Contoh: 

```
inspector-sbomgen directory --path /target -o /tmp/sbom.json --plugin-dir /path/to/plugins
```

### Dengan pemindai asli dinonaktifkan (mode khusus Lua)
<a name="sbomgen-plugin-developer-guide-with-native-scanners-disabled-lua-only-mode"></a>

```
inspector-sbomgen directory --path /target --plugin-dir /path/to/plugins --disable-native-scanners -o sbom.json
```

### Dengan logging verbose
<a name="sbomgen-plugin-developer-guide-with-verbose-logging"></a>

```
inspector-sbomgen directory --path /target --plugin-dir /path/to/plugins --verbose -o sbom.json
```

## Daftar Pemindai yang Tersedia
<a name="sbomgen-plugin-developer-guide-listing-available-scanners"></a>

 Gunakan `list-scanners` untuk melihat setiap pemindai yang tersedia untuk sbomgen. Ini termasuk pemindai asli bawaan, plugin Lua resmi apa pun yang dibundel dengan sbomgen, dan plugin Lua kustom apa pun yang Anda berikan melalui: `--plugin-dir` 

```
inspector-sbomgen list-scanners --plugin-dir /path/to/plugins
```

```
┌─────────────────────┬────────┬───────────────────────────────┬─────────────────────────────┐
│    SCANNER NAME     │ SOURCE │            GROUPS             │         DESCRIPTION         │
├─────────────────────┼────────┼───────────────────────────────┼─────────────────────────────┤
│ curl                │ custom │ extra-ecosystems              │ Discovers curl version      │
│                     │        │ pkg-scanner                   │ header files (curlver.h)    │
├─────────────────────┼────────┼───────────────────────────────┼─────────────────────────────┤
│ python-requirements │ custom │ pkg-scanner                   │ Discovers requirements*.txt │
│                     │        │ programming-language-packages │ files for Python pip        │
│                     │        │                               │ packages                    │
└─────────────────────┴────────┴───────────────────────────────┴─────────────────────────────┘
```

 Kolom SOURCE menunjukkan dari mana setiap pemindai berasal: 


| **Sumber** | **Arti** | 
| --- | --- | 
| native | Pemindai bawaan yang dibundel dengan sbomgen | 
| official | Plugin Lua dibundel dengan sbomgen | 
| custom | Plugin Lua yang disediakan pengguna dimuat melalui --plugin-dir | 

 Berjalan `list-scanners` tanpa `--plugin-dir` masih termasuk keduanya `native` dan `official` pemindai - itu selalu tersedia. `--plugin-dir`Bendera menambahkan `custom` pemindai Anda ke daftar. 

 Untuk mencantumkan hanya pemindai Lua tanpa pemindai asli: 

```
inspector-sbomgen list-scanners --plugin-dir /path/to/plugins --disable-native-scanners
```

## Pemilihan Pemindai
<a name="sbomgen-plugin-developer-guide-scanner-selection"></a>

 Plugin penemuan Lua berpartisipasi dalam model pemilihan pemindai yang sama dengan pemindai asli bawaan. Secara default, sbomgen menjalankan semua pemindai yang grupnya cocok dengan grup pemindai default untuk jenis artefak. Anda dapat mengganti ini dengan tiga bendera: 

### Jalankan hanya pemindai tertentu
<a name="sbomgen-plugin-developer-guide-run-only-specific-scanners"></a>

 Gunakan `--scanners` untuk menjalankan hanya pemindai bernama. Semua pemindai lainnya dikecualikan: 

```
inspector-sbomgen directory --path /target \
    --plugin-dir /path/to/plugins \
    --scanners python-requirements \
    -o sbom.json
```

 Ini hanya menjalankan `python-requirements` pemindai. Anda dapat meneruskan beberapa nama pemindai yang dipisahkan dengan koma, atau meneruskan nama grup pemindai (misalnya,`programming-language-packages`) untuk mengaktifkan setiap pemindai yang termasuk dalam grup tersebut. 

### Kecualikan pemindai tertentu
<a name="sbomgen-plugin-developer-guide-exclude-specific-scanners"></a>

 Gunakan `--skip-scanners` untuk mengecualikan pemindai bernama saat menjalankan yang lainnya: 

```
inspector-sbomgen directory --path /target \
    --plugin-dir /path/to/plugins \
    --skip-scanners python-poetry \
    -o sbom.json
```

 Ini menjalankan setiap pemindai default kecuali`python-poetry`. Seperti`--scanners`, bendera ini juga menerima nama grup, jadi passing `--skip-scanners programming-language-packages` menonaktifkan setiap pemindai di grup itu. 

**catatan**  
`--scanners`dan `--skip-scanners` saling eksklusif. Melewati keduanya menghasilkan kesalahan.

### Tambahkan pemindai dari grup non-default
<a name="sbomgen-plugin-developer-guide-add-scanners-from-non-default-groups"></a>

 Set pemindai default tergantung pada jenis artefak yang dipindai (lihat matriks di [Bagaimana kelompok mempengaruhi seleksi](#sbomgen-plugin-developer-guide-how-groups-affect-selection) bawah). Pemindai yang grupnya bukan bagian dari set default untuk tipe artefak tidak akan berjalan kecuali Anda memilihnya. Gunakan `--additional-scanners` untuk menambahkan pemindai ke set default tanpa menggantinya: 

```
inspector-sbomgen directory --path /target \
    --plugin-dir /path/to/plugins \
    --additional-scanners my-extra-scanner \
    -o sbom.json
```

 Ini menjalankan setiap pemindai default untuk jenis artefak, plus`my-extra-scanner`. Bendera menerima daftar nama pemindai atau nama grup yang dipisahkan koma, dan ditumpuk dengan set default daripada menggantinya. Gunakan `list-scanners` untuk memeriksa grup mana yang dimiliki pemindai. 

### Bagaimana kelompok mempengaruhi seleksi
<a name="sbomgen-plugin-developer-guide-how-groups-affect-selection"></a>

 `get_scanner_groups()`Fungsi dalam plugin penemuan Anda menentukan grup mana yang dimiliki pemindai. Apakah pemindai berjalan secara default tergantung pada kelompoknya dan jenis artefak yang dipindai. Matriks di bawah ini menunjukkan grup mana yang termasuk dalam set pemindai default untuk setiap jenis artefak: 


| **Kelompok** | **`directory` / `archive`** | **`container`** | **`localhost`** | **`volume`** | **`binary`** | 
| --- | --- | --- | --- | --- | --- | 
| os | — | ✓ | ✓ | ✓ | — | 
| programming-language-packages | ✓ | ✓ | ✓ | ✓ | — | 
| binary | ✓ | ✓ | — | — | ✓ | 
| extra-ecosystems | — | ✓ | ✓ | ✓ | — | 
| dockerfile | ✓ | ✓ | — | — | — | 
| custom | ✓ | ✓ | ✓ | ✓ | ✓ | 
| certificate | — | — | — | — | — | 
| machine-learning | — | — | — | — | — | 
| pkg-scanner | — | — | — | — | — | 

 A ✓ berarti setiap pemindai dalam grup tersebut berjalan secara default untuk jenis artefak tersebut. A `—` berarti grup tidak dalam set default, jadi pemindainya hanya berjalan jika dipilih secara eksplisit melalui atau. `--scanners` `--additional-scanners` 

 Detail penting: 
+ **`custom`**selalu dalam set default - plugin khusus yang dimuat melalui `--plugin-dir` secara otomatis menerima `custom` grup, sehingga mereka berjalan secara default terlepas dari jenis artefak.
+ **`extra-ecosystems`**adalah default untuk`container`,`localhost`, dan `volume` memindai, tetapi tidak untuk`directory`,`archive`, atau `binary` memindai. Untuk jenis tersebut, Anda harus lulus `--additional-scanners` (dengan nama atau `extra-ecosystems` grup) untuk memasukkannya.
+ **`pkg-scanner`**bersifat informasional — ini menandai pemindai sebagai kolektor paket untuk ditampilkan`list-scanners`, tetapi tidak dengan sendirinya menyebabkan pemindai berjalan. Pasangkan dengan grup eksekusi (misalnya,`programming-language-packages`) di`get_scanner_groups()`.

 Misalnya, plugin yang kembali `{sbomgen.groups.EXTRA_ECOSYSTEMS, sbomgen.groups.PACKAGE_COLLECTOR}` akan berjalan secara default pada pemindaian kontainer, localhost, dan volume, tetapi akan memerlukan `--additional-scanners` (atau`--scanners`) pada pemindaian direktori, arsip, dan biner. 

## Aturan Tabrakan Plugin
<a name="sbomgen-plugin-developer-guide-plugin-collision-rules"></a>

 Sbomgen memberlakukan metadata unik di semua plugin yang dimuat untuk mencegah penimpaan diam dan memastikan integritas SBOM. Ketika tabrakan terdeteksi, plugin selanjutnya **dilewati** dan peringatan dicatat. 

### Apa yang diperiksa
<a name="sbomgen-plugin-developer-guide-what-is-checked"></a>


| **Metadata** | **Lingkup** | **Pada tabrakan** | 
| --- | --- | --- | 
| Nama acara Discovery (get\_event\_name) | Semua plugin penemuan | Plugin kedua dilewati | 
| Nama pemindai (get\_scanner\_name) | Semua plugin penemuan | Plugin kedua dilewati | 
| Nama kolektor (get\_collector\_name) | Semua plugin koleksi | Plugin kedua dilewati | 

### Apa yang diizinkan
<a name="sbomgen-plugin-developer-guide-what-is-allowed"></a>

 Beberapa plugin koleksi **dapat** berlangganan acara yang sama melalui`subscribe_to_event()`. Ini adalah pola fan-out yang dimaksudkan — satu plugin penemuan dapat memberi makan beberapa kolektor yang masing-masing melakukan hal yang berbeda (misalnya, satu mengekstrak paket, yang lain mendeteksi rahasia). 

### Menghindari tabrakan
<a name="sbomgen-plugin-developer-guide-avoiding-collisions"></a>

 Jika dua plugin menggunakan nama pemindai, nama acara, atau nama kolektor yang sama, yang kedua dimuat dilewati. Untuk mengatasi tabrakan, ganti nama metadata yang bertentangan dengan mendefinisikan fungsi penggantian yang sesuai di plugin Anda (,, atau). `get_scanner_name()` `get_event_name()` `get_collector_name()` 

### Contoh peringatan tabrakan
<a name="sbomgen-plugin-developer-guide-collision-warning-example"></a>

```
[custom:python-pip] SKIPPED: discovery event name "EventNameFoundPythonRequirements"
is already registered by [official:python-pip]. Each discovery plugin must have a
unique event name. Rename get_event_name() in your plugin to use a unique name.
```

 Peringatan memberi tahu Anda plugin mana yang dilewati, apa yang bertabrakan, plugin mana yang sudah memiliki nama itu, dan fungsi mana yang harus diubah. 

## Debugging
<a name="sbomgen-plugin-developer-guide-debugging"></a>

### Pencatatan konsol
<a name="sbomgen-plugin-developer-guide-console-logging"></a>

 Plugin dapat memancarkan pesan ke output konsol sbomgen menggunakan fungsi berikut: 


| **Fungsi** | **Tingkat** | **Terlihat secara default?** | 
| --- | --- | --- | 
| sbomgen.log\_debug(message) | DEBUG | Tidak - membutuhkan --verbose | 
| sbomgen.log\_info(message) | INFO | Ya | 
| sbomgen.log\_warn(message) | WARN | Ya | 
| sbomgen.log\_error(message) | ERROR | Ya | 

 Semua output log dari plugin secara otomatis diawali dengan sumber dan jalur plugin (misalnya,`[custom:python-pip]`), sehingga pesan dari plugin yang berbeda mudah dibedakan. `log_info`,`log_warn`, dan `log_error` selalu mencetak; `log_debug` hanya mencetak ketika sbomgen dipanggil dengan. `--verbose` 

```
function discover()
    sbomgen.log_info("starting discovery")
    local files = sbomgen.find_files_by_name({"requirements.txt"})
    sbomgen.log_debug(string.format("matched %d files", #files))
    if #files == 0 then
        sbomgen.log_warn("no requirements.txt files found")
    end
    return files
end
```

### Breakpoint
<a name="sbomgen-plugin-developer-guide-breakpoints"></a>

 Gunakan `sbomgen.breakpoint()` untuk menjeda eksekusi plugin dan memblokir sampai Anda menekan Enter. Ini bertindak sebagai debugger kasar - menggabungkannya dengan pernyataan log untuk memeriksa status pada titik-titik tertentu. 

```
function discover()
    local files = sbomgen.find_files_by_name({"requirements.txt"})

    sbomgen.log_info(string.format("about to inspect %d files", #files))
    sbomgen.breakpoint("before file inspection — press Enter to continue")

    local found = {}
    for _, f in ipairs(files) do
        if not f:match("[/\\]tests[/\\]") then
            table.insert(found, f)
        end
    end

    sbomgen.log_info(string.format("kept %d files after filtering", #found))
    sbomgen.breakpoint("after filtering — press Enter to continue")

    return found
end
```

 Pesan breakpoint dicetak ke stderr. Eksekusi berhenti sampai Anda menekan Enter, memberi Anda waktu untuk meninjau output log. 

### Masalah umum
<a name="sbomgen-plugin-developer-guide-common-issues"></a>


| **Gejala** | **Menyebabkan** | **Perbaiki** | 
| --- | --- | --- | 
| Plugin tidak dimuat | Hilang init.lua | Pastikan entrypoint ada pada kedalaman direktori yang benar | 
| “kehilangan fungsi yang diperlukan” | Kesalahan ketik dalam nama fungsi | Periksa bahwa get\_scanner\_nameget\_scanner\_description,get\_scanner\_groups,discover,get\_event\_name, get\_localhost\_scan\_pathsget\_collector\_name,collect,, subscribe\_to\_event didefinisikan | 
| Plugin koleksi tidak pernah dipanggil | Ketidakcocokan nama acara | Verifikasi get\_event\_name() dan subscribe\_to\_event() kembalikan string yang sama | 
| Tidak ada paket di SBOM | push\_packagetidak dipanggil atau bidang wajib hilang | Pastikanname,purl\_type, dan component\_type diatur dalam setiap push\_package panggilan (termasuk anak-anak). Gunakan sbomgen.component\_types.\* konstanta. | 
| Kesalahan runtime di plugin | Kesalahan Lua selama eksekusi | Periksa output sbomgen untuk pesan peringatan dengan detail kesalahan | 
| “SKIPPED: nama acara penemuan... sudah terdaftar” | Plugin lain menggunakan nama acara yang sama | Ganti nama get\_event\_name() menjadi nilai unik | 
| “SKIPPED: nama pemindai... sudah terdaftar” | Plugin lain menggunakan nama pemindai yang sama | Ganti nama get\_scanner\_name() menjadi nilai unik | 
| “SKIPPED: nama kolektor... sudah terdaftar” | Plugin lain menggunakan nama kolektor yang sama | Ganti nama get\_collector\_name() menjadi nilai unik | 

## Referensi API
<a name="sbomgen-plugin-developer-guide-api-reference"></a>

 Katalog fungsi lengkap dipertahankan dalam dokumen pendamping: 

 **→ [Referensi API Plugin](sbomgen-plugin-api-reference.md)** 

 Referensi API mencakup setiap `sbomgen.*` fungsi (file I/O, utilitas biner, output paket, regex, parsing terstruktur, registri Windows, logging, debugging), `testing.*` API yang tersedia dalam file pengujian, semua konstanta bawaan (,,,`platform`) `properties` `groups``component_types`, dan global siklus hidup plugin. 

## Penanganan Kesalahan
<a name="sbomgen-plugin-developer-guide-error-handling"></a>

 Fungsi API yang gagal mengembalikan dua nilai:`value, err`. Pada kesuksesan, `err` adalah`nil`. Pada kegagalan, nilai pertama adalah `nil` dan `err` merupakan string kesalahan. 

```
local content, err = sbomgen.read_file(path)
if err then
    sbomgen.log_error("failed to read " .. path .. ": " .. err)
    return
end
-- content is safe to use here
```

 Jika sebuah plugin memunculkan kesalahan Lua yang tidak tertangani, sbomgen mencatat peringatan dan melanjutkan dengan file atau plugin berikutnya. Plugin lain tidak terpengaruh. 

## Pembatasan Kotak Pasir
<a name="sbomgen-plugin-developer-guide-sandbox-restrictions"></a>

 Plugin berjalan di VM Lua kotak pasir dengan akses perpustakaan standar terbatas: 


| **Perpustakaan** | **Available** | **Catatan** | 
| --- | --- | --- | 
| base | ✓ | dofile, loadfileloadstring, dihapus | 
| string | ✓ | Manipulasi string penuh | 
| table | ✓ | Manipulasi meja penuh | 
| math | ✓ | Perpustakaan matematika lengkap | 
| package | ✓ | require()terbatas pada direktori plugin | 
| io | ✗ | Gunakan sbomgen.\* I/O fungsi sebagai gantinya | 
| os | ✗ | Diblokir untuk keamanan | 
| debug | ✗ | Diblokir untuk mencegah introspeksi VM | 
| coroutine | ✗ | Tidak dimuat | 

 Akses sistem file langsung melalui `io.open` atau `os.execute` tidak tersedia. Semua operasi file harus melalui `sbomgen` API, yang memastikan perilaku yang konsisten di seluruh jenis artefak dan mencegah plugin mengakses file di luar artefak. 

 `require()`dapat memuat modul hanya dari dalam pohon direktori plugin itu sendiri. Penjelajahan direktori induk seperti `require("../shared")` diblokir. 

## Berbagi Kode Antar Plugin
<a name="sbomgen-plugin-developer-guide-sharing-code-between-plugins"></a>

 Anda dapat menggunakan `require()` untuk memuat modul pembantu dari dalam direktori plugin Anda: 

```
my-ecosystem/
├── init.lua
└── helpers.lua
```

```
-- helpers.lua
local M = {}
function M.parse_version(s)
    return string.match(s, "(%d+%.%d+%.%d+)")
end
return M
```

```
-- init.lua
local helpers = require("helpers")

function subscribe_to_event() return "MyEvent" end

function collect(file_path)
    local content, err = sbomgen.read_file(file_path)
    if err then return end
    local version = helpers.parse_version(content)
    -- ...
end
```

 Subdirektori dengan juga `init.lua` didukung: 

```
my-ecosystem/
├── init.lua
└── parsers/
    └── init.lua
```

```
local parsers = require("parsers")
```

 `require()`dibatasi untuk direktori plugin Anda. Anda tidak dapat memuat modul dari plugin atau jalur sistem lain. Pustaka Lua pihak ketiga (misalnya, dari LuaRocks) tidak didukung - hanya modul pembantu lokal dalam direktori plugin yang dapat dimuat. 