Pertama, sedikit latar belakang. Pada awal 2010-an, saya membuat utilitas konverter kecil untuk file BIN dari emulator BK-0010 ke file WAV. Utilitas ini ditulis dalam Python dengan tujuan portabilitas maksimum, ia bekerja tanpa masalah dan saya lupa sebentar. Tetapi pada tahun 2016, pengguna muncul, yang tidak tahu tentang Python dan cara menginstalnya. Dia menginginkan monolit yang dapat dieksekusi sederhana yang akan "hanya bekerja" Permintaannya tampak logis bagi saya, dan saya memutuskan untuk mengolah utilitas sebagai satu set file biner yang dapat dieksekusi untuk platform utama.

Python dan Java tidak memberikan kesempatan seperti itu (kecuali tentu saja ada keinginan untuk mengembang utilitas oleh puluhan megabyte). Secara potensial, solusinya dapat dibuat dalam C / C ++, tetapi dengan cakupan yang ditargetkan dari platform, kesulitan dengan kompilasi silang akan melampaui waktu yang diberikan untuk tugas (dan saya harus mendukung perakitan silang untuk Windows, Linux dan MacOS dalam 64 dan 32 bit opsi). Jadi saya menarik perhatian pada bahasa Go, yang mulai populer, yang pada saat itu sudah cukup matang dan satu-satunya yang, tanpa "menari dengan rebana," memberikan semua kompilasi silang yang diperlukan langsung dari kotak (!) .
Satu ketidaknyamanan yang sangat mengganggu saya tentang Go (terutama sebagai pengembang Java) adalah kurangnya perhatian dalam mengatur struktur proyek Go dan kebutuhan untuk terus-menerus menyesuaikan lingkungan. Mungkin para pengembang Go awalnya merencanakan untuk penggunaan tertentu atau ada fokus pada wadah, tetapi saya terbiasa dengan yang βenakβ dan karena alat utama saya di Jawa adalah Maven , saya memutuskan untuk membuat plug-in yang membuat panggilan ke utilitas dan perintah GoSDK dengan generasi otomatis dari yang diperlukan. variabel lingkungan.
Itu tidak menarik untuk membuat plugin sederhana yang akan memanggil utilitas go, dan saya memutuskan untuk pergi dari langkah - menginstal GoSDK pada platform host. Segera setelah start, keberadaan GoSDK diperiksa di direktori konfigurasinya (saya memilih path default ~/.mvnGoLang
) dan, dengan tidak adanya versi yang diperlukan, arsip GoSDK secara otomatis diunduh dan dibuka dari situs resmi . Ini memungkinkan kami membuat proyek Go portabel tanpa khawatir tentang apakah alat versi yang diperlukan sudah diinstal sebelumnya dan dikonfigurasi. Tentu saja, dengan banyak pengaturan, saya melihat kemungkinan menggunakan versi pra-instal dan menambahkan pengaturan untuk semua langkah dalam proses, karena untuk banyak masalah seperti menonaktifkan verifikasi sertifikat SSL atau umumnya membuat permintaan HTTP di luar (seperti untuk proyek Keycloak ) sangat penting .
Langkah selanjutnya, saya membungkus Maven-tujuan (sasaran) semua perintah utilitas yang disediakan saat itu. Karena ada kemungkinan bahwa perintah baru lain akan muncul dengan versi baru GoSDK, tugas custom
ditambahkan yang memungkinkan pengguna untuk menentukan perintah yang diinginkan sendiri. Secara default, dalam kerangka fase-maven (fase), tugas dijalankan dalam urutan berikut:
- bersihkan sebagai
default-clean
dalam fase clean - fix as
default-fix
dalam fase validasi - dapatkan sebagai
default-get
dalam fase inisialisasi - menghasilkan sebagai
default-generate
dalam fase menghasilkan-sumber - fmt sebagai
default-fmt
dalam fase proses-sumber - uji sebagai uji
default-test
pada fase uji - build as
default-build
dalam fase paket - sebagai
default-install
tugas internal mvninstall dijalankan pada fase instalasi - instal sebagai
default-deploy
di fase deploy
Salah satu langkah dasar dapat dinonaktifkan dengan menerjemahkan tugas ke fase tidak ada:
<execution> <id>default-fix</id> <phase>none</phase> </execution>
Dalam implementasi internal, tugas dibagi menjadi "bekerja dengan dependensi" dan "tidak memerlukan resolusi dependensi", setelah munculnya dukungan untuk mode modul, sebagian besar bermigrasi ke "bekerja dengan dependensi".
Struktur proyek Go-maven, saya mencoba untuk lebih dekat dengan struktur folder standar yang diterima untuk Go (mis. /src
dan /bin
di root proyek). Tetapi karena Maven dipenjara untuk Java, itu tidak mungkin secara langsung untuk "mematahkan" pendekatannya untuk mengatur struktur proyek dan membuat langkah ini tidak terlihat oleh pengguna, sehingga konfigurasi dasar dari plugin terlihat sedikit tidak biasa bahkan bagi banyak yang akrab dengan pakar:
<build> ```${basedir}/src</sourceDirectory> <directory>${basedir}/bin</directory> <plugins> <plugin> <groupId>com.igormaznitsa</groupId> <artifactId>mvn-golang-wrapper</artifactId> <version>2.3.3</version> <extensions>true</extensions> <configuration> <goVersion>1.12.9</goVersion> </configuration> </plugin> </plugins> </build>
PERINGATAN! Untuk beberapa alasan, HabR dapat menampilkan bagian <sourceDirectory>${basedir}/src</sourceDirectory>
ketika memformat XML
Seperti yang Anda lihat, Anda harus langsung menentukan folder sumber /src
dan folder dengan hasil /bin
. Di satu sisi, ini adalah minus, di sisi lain, kemungkinan mengubah lokasi mereka.
Seluruh pom.xml minimalis untuk proyek modul-tunggal, ala Hello world, adalah sebagai berikut:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.igormaznitsa</groupId> <artifactId>mvn-golang-helloworld</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>mvn-golang</packaging> <build> ```${basedir}/src</sourceDirectory> <directory>${basedir}/bin</directory> <plugins> <plugin> <groupId>com.igormaznitsa</groupId> <artifactId>mvn-golang-wrapper</artifactId> <version>2.3.3</version> <extensions>true</extensions> <configuration> <goVersion>1.12.9</goVersion> </configuration> </plugin> </plugins> </build> </project>
Harap dicatat bahwa pengemasan proyek ini disebut sebagai mvn-golang . Konfigurasi ini cukup untuk membangun file yang dapat dieksekusi dan meletakkannya di folder bin yang dihasilkan berdasarkan teks sumber dalam folder src. Go build cache juga akan dibuat di /bin
(sebagai /bin/.goBuildCache
secara default) dan akan dihapus dengan bersih dengan folder sementara ini.
Pada fase instal , tugas mvninstall
internal mvninstall
, yang hanya mengemas seluruh proyek dalam arsip zip dan menempatkannya dalam repositori maven sebagai artefak yang dihasilkan. Awalnya, saya baru saja menyimpan artefak ini, tetapi dari versi 2.3.2, sebuah mekanisme ditambahkan untuk mendukung mereka sebagai dependensi pakar standar dan menjadi mungkin untuk mengembangkan proyek dengan "berbagi" kode umum melalui repositori pakar. Jelas bahwa menempatkan hasil biner yang dihasilkan ke dalam repositori sebagai artefak adalah ide yang buruk karena persyaratan lintas-platform dan oleh karena itu isi folder /bin
tidak dikemas dalam artefak.
Menghubungkan proyek lain dengan pengemasan mvn-golang
sebagai ketergantungan maven terlihat seperti ini:
<dependency> <groupId>com.igormaznitsa</groupId> <artifactId>mvn-go-test-mix-terminal</artifactId> <version>1.0.0-SNAPSHOT</version> <type>mvn-golang</type> </dependency>
Dengan versi 2.3.3, dukungan ditambahkan untuk bekerja dengan mekanisme modul Go , tetapi secara default tidak diaktifkan (untuk kompatibilitas mundur) dan diaktifkan menggunakan parameter konfigurasi:
<moduleMode>true</moduleMode>
Ketika mekanisme modul Go masih pada tahap percobaan, saya menambahkan dukungan untuk bekerja dengan versi ketergantungan melalui panggilan langsung ke utilitas CVS, contoh uji dibuat . Tapi sekarang saya berpikir bahwa mekanisme seperti itu tidak lagi menarik dan lebih menguntungkan untuk menggunakan dependensi standar melalui modul. Selain itu, plugin ini dapat go.mod
file go.mod
pada saat membangun proyek, menggantikan jalur ke folder lokal jika pekerjaan sedang berlangsung dalam kerangka proyek multi-modul.
Karena Maven menyediakan kemungkinan standardisasi menggunakan arketipe, saya membuat dua arketipe:
- com.igormaznitsa: mvn-golang-hello: 2.3.3 untuk arketipe modul tunggal sederhana
- com.igormaznitsa: mvn-golang-hello-multi: 2.3.3 untuk proyek multi-modul dengan kode sumber bersama
Contoh bekerja dengan pola dasar proyek modul tunggal dapat dilihat pada animasi di bawah ini
.
Anda juga dapat mengkloning proyek "Hello World" dan bermain-main:
git clone https://github.com/raydac/mvn-golang-example.git

Seringkali muncul pertanyaan yang masuk akal - mengapa semua ini diperlukan dan bonus apa yang diberikan oleh penggunaan Maven dalam proses membangun Proyek-Go? Saya akan mencoba menjawabnya poin demi poin:
- Maven adalah lingkungan proyek-bangunan lintas-platform yang sangat matang, didukung oleh hampir semua platform CI, misalnya Jenkins, menggunakan Go2XUnit Anda dapat mengonversi hasil tes ke format yang ditampilkan dengan melaporkan plugin.
- Maven adalah lintas-platform dan didukung oleh semua sistem operasi, yang termasuk dalam semua repositori. Kehadiran profil yang diaktifkan secara fleksibel memudahkan untuk menyesuaikan proses untuk berbagai platform.
- Maven memiliki sejumlah besar plugin , yang membuatnya mudah untuk mendapatkan efek sinergis, misalnya dengan menggabungkan Go dan GWT , menghubungkan ANTLR ke proyek , menghasilkan Go berdasarkan deskriptor Protobuf dan bahkan menambahkan preprocessing . Semua ini dapat diatur secara manual melalui file batch, tetapi jika ada plugin resmi yang didukung, maka lebih menguntungkan untuk menggunakannya.
- Proyek ini menjadi portabel antara mesin dan platform, dan beralih versi GoSDK dilakukan dengan mengubah satu baris.
- Kemudahan mengatur proyek multi-modul, dengan pemisahan kode sumber melalui repositori Maven.
- Alat ini akrab dan akrab bagi pengembang Java, yang memfasilitasi adaptasi mereka ketika beralih ke pengembangan di Golang atau ketika mengembangkan solusi Go + Java multibahasa.
- Ada kemungkinan pseudo-development on Go di lingkungan yang mendukung Maven, bahkan jika mereka tidak memiliki dukungan untuk platform ini, misalnya, di NetBeans IDE .
Kelemahan terbesar dari solusi, menurut saya, adalah satu di sini - sejumlah pengembang yang akrab dengan Maven di antara komunitas Golang. Bagi mereka yang beralih ke Golang dengan C / C ++, jelas bahwa sulit untuk menemukan sesuatu yang lebih dekat dan lebih mahal untuk dibuat, serta tidak ada yang membatalkan sistem Go-build "asli". Saya perhatikan bahwa untuk beberapa alasan, banyak pengembang tidak suka mencampur platform.
Jadi, saya secara singkat menunjukkan salah satu cara untuk menggunakan Maven ketika mengembangkan proyek Go menggunakan plugin mvn-golang-wrapper. Proyek plugin dirancang sebagai proyek OSS dan diposting di GitHub . Jika seseorang tertarik dan akan menggunakan proyek mereka, maka jangan ragu untuk bertanya dan "melaporkan bug." Saya mencoba membuat serangkaian contoh untuk berbagai kesempatan (di mana plugin sedang diuji), tetapi saya tidak bisa membahas semuanya.
Uji kasus dalam proyek plugin menggunakan versi dev, jadi jika Anda ingin membangunnya secara lokal setelah mengkloning proyek, Anda harus terlebih dahulu membangun versi dev plugin menggunakan perintah di direktori root proyek:
mvn install
setelah itu, Anda dapat masuk ke mvn-golang-examples
proyek mvn-golang-examples
dan membangunnya bersama
mvn clean install
Anda juga dapat mulai membangun semua contoh dari akar proyek, menggunakan
mvn clean install -Pexamples
Plugin ini mendukung perakitan multi-threaded proyek dan dapat dipercepat menggunakan argumen yang sesuai, memecah misalnya menjadi 6 utas
mvn clean install -Pexamples -T6
Selama pengembangan, proyek ini telah mengakumulasikan sejumlah "lonceng dan peluit" yang layak, yang saya putuskan untuk tidak dibahas dalam artikel singkat ini. Informasi tentang parameter dengan contoh konfigurasi kecil dapat ditemukan di mind map plugin ini (file sumber dalam format SciaReto ada di sini ):
