Berkas yang sudah rapi formatnya berkat gofmt masih menyisakan satu sumber kerapian yang kerap dilupakan: blok import. Daftar import yang tidak terurut, import yang sudah tidak terpakai, dan import yang lupa ditulis membuat kompilasi gagal atau code review berkepanjangan. Tool goimports menyelesaikan ketiganya sekaligus: perintah ini mengurutkan import ke urutan standar, membuang import yang tidak digunakan, dan mencari lalu menambahkan import yang hilang. Pada chapter ini kita akan menginstal goimports, lalu mengujinya pada berkas yang daftar import-nya sengaja dibuat berantakan.
Tiga Tugas goimports dalam Satu Perintah #
goimports dibangun di atas mesin gofmt, sehingga seluruh perbaikan format gofmt tetap berlaku, ditambah penataan khusus import:
| Masalah pada blok import | Tindakan goimports |
|---|---|
| Import tidak terurut alfabetis | Diurutkan, stdlib dan pihak ketiga dikelompokkan terpisah |
| Import dinyatakan tetapi tidak dipakai | Dibuang dari blok import |
| Package dipakai tetapi tidak diimpor | Dicari di module/GOPATH lalu ditambahkan |
Karena goimports memformat lebih banyak hal daripada gofmt, banyak tim menjadikan goimports pemformat utama — hasil akhirnya selalu kompatibel dengan pemeriksaan gofmt -l.
Instalasi goimports #
goimports tidak ikut serta dalam distribusi standar Go, tetapi instalasinya hanya satu perintah go install:
go install golang.org/x/tools/cmd/goimports@latestPerintah tersebut berhasil dijalankan pada lingkungan penulisan chapter ini (prosesnya cepat karena goimports hanya satu modul kecil). Binary hasil instalasi muncul di direktori $GOBIN atau $(go env GOPATH)/bin sehingga goimports dapat dipanggil langsung dari shell:
goimports -hOutput yang Dihasilkan:
usage: goimports [flags] [path ...]
-cpuprofile string
CPU profile output
-d display diffs instead of rewriting files
-e report all errors (not just the first 10 on different lines)
-format-only
if true, don't fix imports and only format. In this mode, goimports is effectively gofmt, with the addition that imports are grouped into sections.
-l list files whose formatting differs from goimport's
-local string
put imports beginning with this string after 3rd-party packages; comma-separated list
-memprofile string
memory profile output
-memrate int
if > 0, sets runtime.MemProfileRate
-srcdir dir
choose imports as if source code is from dir. When operating on a single file, dir may instead be the complete file name.
-trace string
trace profile output
-v verbose logging
-w write result to (source) file instead of stdoutDemo: Mengurutkan dan Membuang Import #
Kita siapkan modul kecil bernama example.com/importdemo dengan satu berkas main.go. Blok import-nya sengaja diacak urutannya (strings duluan, errors menyusup di tengah) dan memuat dua import yang tidak dipakai program:
package main
import (
"strings"
"errors"
"fmt"
"os"
)
func main() {
nama := strings.TrimSpace(" Budi ")
fmt.Println(fmt.Sprintf("Halo, %s!", nama))
}Program hanya memakai strings dan fmt, sehingga errors dan os akan dibuang. Perintah goimports -l melaporkan berkas yang butuh dirapikan:
goimports -l .Output yang Dihasilkan:
main.goSebelum menulis ulang berkas, kita periksa dulu diff yang diusulkan goimports:
goimports -d main.goOutput yang Dihasilkan:
diff -u main.go.orig main.go
--- main.go.orig
+++ main.go
@@ -1,10 +1,8 @@
package main
import (
- "strings"
- "errors"
"fmt"
- "os"
+ "strings"
)
func main() {Mari kita baca diff di atas baris demi baris:
- Baris
- "strings"dan+ "strings": importstringspindah posisi — dari baris pertama blok ke baris setelahfmt— karena urutan alfabetis menempatkanfmtsebelumstrings. - Baris
- "errors"dan- "os": kedua import ini dibuang karena program tidak memanggil packageerrorsmaupunossama sekali. - Blok hasil akhir hanya berisi
fmtlalustrings: dua baris tersisa itulah satu-satunya package yang benar-benar dipakai.
Menambahkan Import yang Hilang #
Kasus kedua adalah kebalikannya: kita memakai sebuah package tetapi lupa mengimpornya. Berkas sapa.go berikut memanggil strings.TrimSpace padahal blok import hanya memuat fmt:
package main
import "fmt"
func sapa(nama string) string {
return fmt.Sprintf("Halo, %s!", strings.TrimSpace(nama))
}Dalam kondisi seperti ini kompilasi akan gagal dengan galat undefined: strings. goimports memperbaikinya dengan menambahkan import yang hilang sekaligus mengubah bentuk blok menjadi bentuk berkurung:
goimports -d sapa.goOutput yang Dihasilkan:
diff -u sapa.go.orig sapa.go
--- sapa.go.orig
+++ sapa.go
@@ -1,6 +1,9 @@
package main
-import "fmt"
+import (
+ "fmt"
+ "strings"
+)
func sapa(nama string) string {
return fmt.Sprintf("Halo, %s!", strings.TrimSpace(nama))goimports menemukan strings dari standard library secara otomatis. Untuk package pihak ketiga, pencarian dilakukan terhadap module aktif — package yang belum berada di go.mod tetap perlu go get lebih dulu.
Menulis Ulang dan Memverifikasi #
Sekarang kita terapkan seluruh perbaikan lalu memverifikasi hasilnya tiga lapis: daftar berkas kotor, kompilasi, dan eksekusi:
goimports -w .
goimports -l .
go run .Output yang Dihasilkan:
Halo, Budi!Baris goimports -l . tidak mencetak apa pun — semua berkas sudah rapi. Program kemudian berjalan mulus dan mencetak Halo, Budi!, membuktikan penataan import tidak mengubah perilaku program.
Berkas contoh.go pada bagian bawah halaman memperlihatkan hasil akhir proses ini: import berkurut fmt dan strings, tubuh program memakai keduanya. Seluruh berkas berbunyi:
package main
import (
"fmt"
"strings"
)
func main() {
nama := strings.TrimSpace(" Budi ")
fmt.Printf("Halo, %s!\n", nama)
}Jalankan berkas tersebut dengan perintah berikut:
go run contoh.goOutput yang Dihasilkan:
Halo, Budi!Dengan format dan import yang terjaga otomatis, saat berikutnya kode dibuka oleh anggota tim lain akan langsung terbaca familiar. Pembersihan tampilan selesai; pemeriksaan kualitas yang mendalam dimulai dari go vet pada chapter berikutnya.
Referensi #
- goimports — perintah di golang.org/x/tools — dokumentasi resmi perintah goimports.
- Dokumentasi perintah gofmt — basis format yang dipakai goimports.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
contoh.go
Unduh berkaspackage main
import (
"fmt"
"strings"
)
func main() {
nama := strings.TrimSpace(" Budi ")
fmt.Printf("Halo, %s!\n", nama)
}