Bash: Membuat Generator File dengan Template

Khoironi Kurnia Syah
Sainseni
Published in
3 min readJul 28, 2023
Photo by Gabriel Heinzer on Unsplash

Sering kali kita menulis hal yang berulang misalnya ketika membuat file baru dan isinya mirip-mirip saja, sebenarnya hal itu dapat diakali dengan membuat sebuah generator. Kenapa generator? ya karena “hal yang berulang” bisa kita jadikan sebuah template dan hanya mengganti atau menambahkan beberapa hal yang sifatnya dinamis.

Kasus dan Persiapan

Kasus sederhana yang saya alami belakangan adalah file migration untuk database yang isinya mirip kecuali di beberapa bagian.

Di sini kita akan membuat tiga file dan dibungkus dalam sebuah folder scripts, yaitu:

  • migration.sh sebagai file utama atau entrypoint
  • functions.sh file untuk menyimpan fungsi-fungsi
  • create.template.ts template yang akan kita gunakan

Template file migration dengan $TABLE_NAME sebagai variabel yang nantinya bisa diganti dengan nilai lain.

import { Kysely, sql } from 'kysely';

const tableName = '$TABLE_NAME';

export async function up(db: Kysely<any>): Promise<void> {
await db.schema
.createTable(tableName)
.addColumn('id', 'uuid', (col) =>
col.primaryKey().defaultTo(sql`gen_random_uuid()`)
)
.execute();
}

export async function down(db: Kysely<any>): Promise<void> {
await db.schema.dropTable(tableName).execute();
}

Kenapa menggunakan bash? Saya pikir karena tugasnya sederhana jadi bash saja sudah cukup.

Membuat Generator

File utama untuk menjalankan perintah migrasi memiliki opsi perintah yang diambil dari argumen ketika mengeksekusi file ini (di sini hanya create dan *). Opsi * bisa dibaca sebagai semua perintah atau dalam kasus algoritma ini bisa dibaca sebagai else, default atau sejenisnya.

Nilai $1 diambil dari parameter kedua, $2 parameter ketiga, dan seterusnya menyesuaikan index ketika mengeksekusi sebuah file. Contohnya ketika mengeksekusi file:

./migration.sh create

./migration.sh sebagai parameter pertama ($0) sedangkan create sebagai parameter kedua ($1).

Fungsi create_migration_with_template yang diimport dari file functions.sh dipanggil dengan argumen $file_name dan $table_name.

Note: ada tambahan opsi (walaupun belum rapi) -t untuk memberi nama tabel di migration. Kenapa tidak memakai getops? Sudah dicoba tetapi agak ribet di struktur kode yang saya buat ini, jadi saya akali saja sementara.

#!/usr/bin/env sh

. scripts/functions.sh

create(){
if [ -z "$2" ]; then
echo "Error: Please provide a file name."
echo "Usage: $0 create <file_name> [-t] <table_name>"
exit 1
fi

file_name="$2"
table_name="$2"

echo "Creating migration file for '$file_name'..."

if [ "$3" = "-t" ] && [ -n "$4" ]; then
table_name="$4"
fi

create_migration_with_template "$file_name" "$table_name"
}

case $1 in
'create')
create "$@"
;;
*)
echo "Usage: $0 { create table_name }"
;;
esac

File functions.sh menyimpan fungsi-fungsi yang akan digunakan dan dipanggil di file utama. Kenapa dipisah? agar rapi saja (menurut saya).

Mengganti variabel pada template yang telah kita buat dengan menulis perintah sed “s|\$TABLE_NAME|$table_name|g” yang artinya mengganti string dengan nilai $TABLE_NAME dengan nilai dari variable $table_name.

#!/usr/bin/env sh

migration_output_path="libs/api/database/src/lib/migrations"
migration_template_create_path="scripts/templates/create.template.ts"

create_migration_with_template() {
file_name="$1"
table_name="$2"

migration_file="$migration_output_path/$(date '+%Y_%m_%d_%H%M%S')_$file_name.ts"
template_content=$(cat "$migration_template_create_path")
content_with_variable=$(echo "$template_content" | sed "s|\$TABLE_NAME|$table_name|g")
echo "$content_with_variable" > "$migration_file"

echo "Migration file for '$1' created successfully!"
echo "Path: $migration_file"
}

Karena contoh project ini ada di ekosistem Javascript / Typescript jadi kita bisa definisikan perintah di package.json pada properti scripts untuk mempermudah atau mempersingkat perintah yang akan dijalankan.

{
"scripts": {
"migrate:create": "./scripts/migration.sh create"
}
}

Jadi untuk membuat file migration kita dapat menjalankan perintah berikut (contoh dengan pnpm):

pnpm migrate:create <file_name> -t <table_name>

OR

pnpm migrate:create <table_name|file_name>
Run Bash Script
Hasil Generate Dengan Bash

Catatan

Mungkin ada yang tidak bisa menjalankan program bash tersebut karena tidak memiliki hak akses untuk dieksekusi sebagai sebuah program, solusinya adalah dengan menjalankan perintah berikut untuk memberi hak akses eksekusi (executeable) semua file di folder scripts.

sudo chmod +x ./scripts/*

Penutup

Jadi begitulah contoh pembuatan generator file dengan template menggunakan bash, ini hanya tulisan iseng karena saya sedang tidak ada task di kerjaan saya, hehe. Tulisan selanjutnya akan berfokus pada CI/CD, DevOps, Deployment, Infrastructure menggunakan repository atau project di atas.

Terima kasih

--

--