Go ile Basit Bir Ticket Takip CLI Uygulaması Nasıl Geliştirilir?
Go programlama diliyle kendi basit ticket takip CLI uygulamanızı nasıl geliştireceğinizi öğrenin. Bu rehberde, sıfırdan bir CLI aracı oluşturup iş akışınızı optimize edin. Kendi görev takip sisteminizi kurarak verimliliğinizi artırın ve Go’nun güçlü yeteneklerini keşfedin.
Günümüzün hızla değişen iş dünyasında, verimlilik ve otomasyon her zamankinden daha önemli hale gelmiştir. Projeleri yönetmek, görevleri takip etmek ve ekibinizle uyum içinde çalışmak çoğu zaman manuel ve zaman alıcı süreçler gerektirebilir. Peki ya kendi özel ihtiyaçlarınıza göre tasarlanmış, hızlı ve etkili bir bilet takip sistemi oluşturabilseydiniz? İşte tam da bu noktada Komut Satırı Arayüzü (CLI) uygulamaları devreye giriyor. Özellikle Go programlama diliyle geliştirilen CLI uygulamaları, sunduğu performans, basitlik ve çapraz platform desteği sayesinde benzersiz avantajlar sağlar.
Go, yani Golang, Google tarafından geliştirilen, modern sistemler ve ağ uygulamaları için tasarlanmış statik tipli, derlenmiş bir programlama dilidir. Minimalist sözdizimi ve güçlü standart kütüphaneleri sayesinde, özellikle CLI araçları ve mikro servisler gibi performans odaklı uygulamalar geliştirmek için mükemmel bir seçimdir. Geliştiriciler genellikle Go’yu, yüksek eşzamanlılık (concurrency) yetenekleri ve hızlı derleme süreleri nedeniyle tercih ederler. Ayrıca, Go uygulamaları genellikle tek bir derlenmiş ikili dosya olarak dağıtılabilir, bu da dağıtım ve yönetim süreçlerini inanılmaz derecede basitleştirir. Böylelikle, geliştirdiğiniz ticket takip uygulamasını kolayca diğer ekip üyeleriyle paylaşabilir ve onların da hızlıca kullanmaya başlamasını sağlayabilirsiniz.
Bir ticket takip CLI uygulaması geliştirmek, sadece görevlerinizi düzenlemenize yardımcı olmakla kalmaz, aynı zamanda Go dilinde pratik beceriler kazanmanız için harika bir fırsat sunar. Dosya işlemleri, veri yapıları, komut satırı argümanları ve temel hata yönetimi gibi kritik programlama kavramlarını gerçek bir proje üzerinde uygulayarak öğrenmek, bilginizi pekiştirmenin en iyi yollarından biridir. Bu rehber boyunca, basit ama işlevsel bir ticket takip uygulamasını adım adım nasıl inşa edeceğinizi öğrenecek, böylece hem kendi kişisel verimliliğinizi artıracak hem de Go ekosistemine sağlam bir giriş yapacaksınız. Haydi başlayalım!
CLI Nedir ve Go Neden İdeal Bir Seçimdir?
Komut Satırı Arayüzü (CLI), kullanıcıların bilgisayarla metin tabanlı komutlar aracılığıyla etkileşim kurmasını sağlayan bir programdır. Grafiksel Kullanıcı Arayüzlerinin (GUI) aksine, CLI’lar genellikle daha hızlı, daha az kaynak tüketen ve otomasyon senaryoları için çok daha güçlüdür. Bir CLI uygulaması kullanarak, fare veya dokunmatik ekran yerine klavye ile belirli görevleri gerçekleştirebilir, betikler (scriptler) oluşturarak tekrarlayan işleri otomatikleştirebilirsiniz. Örneğin, günlük görevlerinizi hızlıca ekleyebilir, durumlarını güncelleyebilir veya tamamlanan işleri listeleyebilirsiniz; tüm bunlar sadece birkaç tuş vuruşuyla mümkün olur. Bu, özellikle sistem yöneticileri, geliştiriciler ve terminalde çalışmayı seven herkes için paha biçilmez bir avantajdır.
Peki, böylesine bir CLI uygulamasını geliştirmek için Go neden bu kadar cazip bir seçenektir? Öncelikle, Go’nun derlenmiş bir dil olması, çalıştırılabilir dosyaların hızlı ve verimli olmasını sağlar. Bu, kullanıcıların uygulamanızı anında ve herhangi bir ek bağımlılık yüklemeden çalıştırması anlamına gelir. Ayrıca, Go’nun güçlü standart kütüphanesi, dosya sistemine erişim, JSON işleme, ağ iletişimi ve komut satırı argümanlarını ayrıştırma gibi CLI geliştirmek için gereken tüm temel bileşenleri hazır olarak sunar. Bu, üçüncü taraf kütüphanelere olan bağımlılığı azaltır ve projeyi daha hafif tutar.
Go’nun eşzamanlılık modeli (gorutinler ve kanallar aracılığıyla), karmaşık görevlerin bile basit ve okunaklı bir şekilde ele alınmasına olanak tanır, ancak basit bir ticket takip CLI için bu özelliğe çok sık ihtiyaç duymayabiliriz. Daha da önemlisi, Go’nun basit ve anlaşılır sözdizimi, kodu kolayca okuyabilir ve sürdürebilir hale getirir. Bu da, projeye yeni başlayanlar için öğrenme eğrisini düşürürken, deneyimli geliştiricilerin de hızlıca prototip oluşturmasına ve üretim seviyesinde uygulamalar geliştirmesine olanak tanır. Kısacası, Go, hem hız hem de kullanım kolaylığı açısından CLI uygulamaları için mükemmel bir platform sunar.
Uygulamanızı Adım Adım Oluşturun: Ticket Takip CLI
Proje Yapısı ve Veri Modeli Nasıl Tasarlanır?
Herhangi bir yazılım projesinde, sağlam bir temel oluşturmak başarının anahtarıdır. Ticket takip CLI uygulamamız için de bu durum geçerlidir. Öncelikle, projemizin dizin yapısını oluşturacak ve ardından uygulamamızın temel veri modelini tanımlayacağız. Bu adımlar, kodunuzun düzenli kalmasını sağlayacak ve gelecekteki geliştirmeleri kolaylaştıracaktır. Uygulamamızın temel amacı, ticketları oluşturmak, listelemek, güncellemek ve silmek olduğundan, bu ticketları nasıl saklayacağımızı düşünmeliyiz. Basitlik ve okunabilirlik adına, verilerimizi JSON formatında bir dosyada saklayacağız. Bu yaklaşım, karmaşık bir veritabanı kurulumuna ihtiyaç duymadan hızlıca işlevsel bir uygulama geliştirmemizi sağlayacaktır.
Proje yapısı için, ana dizinde birkaç dosya barındıracağız: main.go uygulama giriş noktamız olacak, ticket.go ise ticket veri yapısını ve bu yapıya özel metodları içerecek. Ayrıca, verilerimizi saklayacağımız tickets.json adında bir dosya da olacak. Bu basit yapı, projenin büyümesi durumunda bile kolayca yönetilebilir kalacaktır.
Şimdi, ticket.go dosyasında kullanacağımız Ticket yapısını tanımlayalım. Bu yapı, her bir biletin sahip olacağı özellikleri (ID, Başlık, Açıklama, Durum, Oluşturma Tarihi) içerecektir. JSON dosyamızda bu verileri saklayacağımız için, yapımızın alanlarını JSON etiketleriyle işaretlememiz gerekmektedir. Bu etiketler, Go’nun encoding/json paketiyle çalışırken, alan isimlerinin JSON formatında nasıl görünmesi gerektiğini belirtir. Aşağıdaki kod bloğu, Ticket yapımızın nasıl görüneceğini göstermektedir:
package main
import "time"
// Ticket, bir biletin yapısını temsil eder.
type Ticket struct {
ID int json:"id"
Title string json:"title"
Description string json:"description"
Status string json:"status" // Örn: "Open", "InProgress", "Closed"
CreatedAt time.Time json:"created_at"
}
// Yeni bir ticket oluşturan yardımcı fonksiyon.
func NewTicket(id int, title, description string) *Ticket {
return &Ticket{
ID: id,
Title: title,
Description: description,
Status: "Open",
CreatedAt: time.Now(),
}
}
Yukarıdaki Ticket yapısında, her alanın json:"alan_adı" şeklinde bir etikete sahip olduğunu görebilirsiniz. Bu etiketler, Go'nun JSON kodlama/kod çözme işlemleri sırasında doğru alanları eşleştirmesine yardımcı olur. Örneğin, ID alanı JSON dosyasında id olarak saklanacaktır. NewTicket fonksiyonu ise yeni bir bilet oluştururken varsayılan değerleri (örneğin, başlangıç durumu "Open" ve oluşturulma tarihi) atamak için bir kolaylık sağlar. Bu temel yapı ile, uygulamamızın tüm bilet verilerini düzenli ve tutarlı bir şekilde yönetebileceğiz. Projemizin temelini attığımıza göre, artık bilet ekleme ve listeleme işlevlerine geçebiliriz.
Ticket yapısını ve ilgili fonksiyonlarını ayrı bir pakete taşımak (internal/ticket gibi) kodun daha modüler ve yönetilebilir olmasını sağlar. Bu, özellikle uygulamanızın boyutu arttıkça sürdürülebilirliği artırır.
Ticket Oluşturma ve Listeleme Fonksiyonları Nasıl Yazılır?
Şimdi sıra geldi CLI uygulamamızın en temel işlevlerini hayata geçirmeye: yeni ticketlar oluşturmak ve mevcut ticketları listelemek. Bu fonksiyonlar, kullanıcıların sistemle ilk etkileşim kuracakları noktalar olacaktır. Öncelikle, tickets.json dosyasından ticket verilerini okuyacak ve bu verileri güncelledikten sonra tekrar dosyaya yazacak yardımcı fonksiyonlara ihtiyacımız olacak. Bu işlemler için Go'nun os, io/ioutil (Go 1.16 sonrası os paketiyle birlikte io.ReadFile ve io.WriteFile kullanmak daha yaygın) ve encoding/json paketlerini kullanacağız.
Veri okuma ve yazma işlemlerini merkezi hale getirmek, kod tekrarını önler ve hata yönetimini kolaylaştırır. İşte bu amaçla kullanacağımız loadTickets ve saveTickets fonksiyonları:
package main
import (
"encoding/json"
"fmt"
"io/ioutil" // Go 1.16+ için os.ReadFile tercih edilebilir
"os"
"strconv"
"time"
)
const dataFile = "tickets.json"
// loadTickets, JSON dosyasından tüm ticketları yükler.
func loadTickets() ([]Ticket, error) {
var tickets []Ticket
// Dosyanın var olup olmadığını kontrol et
if _, err := os.Stat(dataFile); os.IsNotExist(err) {
return tickets, nil // Dosya yoksa boş liste döndür, hata değil
}
data, err := ioutil.ReadFile(dataFile) // os.ReadFile(dataFile) Go 1.16+
if err != nil {
return nil, fmt.Errorf("biletler yüklenirken hata oluştu: %w", err)
}
if len(data) == 0 {
return tickets, nil // Boş dosya ise boş liste döndür
}
err = json.Unmarshal(data, &tickets)
if err != nil {
return nil, fmt.Errorf("JSON ayrıştırma hatası: %w", err)
}
return tickets, nil
}
// saveTickets, ticket listesini JSON dosyasına kaydeder.
func saveTickets(tickets []Ticket) error {
data, err := json.MarshalIndent(tickets, "", " ")
if err != nil {
return fmt.Errorf("JSON formatına dönüştürürken hata oluştu: %w", err)
}
err = ioutil.WriteFile(dataFile, data, 0644) // os.WriteFile(dataFile, data, 0644) Go 1.16+
if err != nil {
return fmt.Errorf("biletler dosyaya yazılırken hata oluştu: %w", err)
}
return nil
}
// addTicket, yeni bir ticket ekler.
func addTicket(title, description string) {
tickets, err := loadTickets()
if err != nil {
fmt.Printf("Hata: %v\n", err)
return
}
// Yeni ID oluştur
newID := 1
if len(tickets) > 0 {
newID = tickets[len(tickets)-1].ID + 1
}
newTicket := NewTicket(newID, title, description)
tickets = append(tickets, *newTicket)
err = saveTickets(tickets)
if err != nil {
fmt.Printf("Hata: %v\n", err)
return
}
fmt.Printf("Yeni ticket başarıyla eklendi: ID %d, Başlık: %s\n", newTicket.ID, newTicket.Title)
}
// listTickets, tüm ticketları listeler.
func listTickets() {
tickets, err := loadTickets()
if err != nil {
fmt.Printf("Hata: %v\n", err)
return
}
if len(tickets) == 0 {
fmt.Println("Henüz hiç ticket bulunmamaktadır.")
return
}
fmt.Println("\nTüm Ticketlar:")
fmt.Println("--------------------------------------------------")
for _, t := range tickets {
fmt.Printf("ID: %d\n", t.ID)
fmt.Printf("Başlık: %s\n", t.Title)
fmt.Printf("Açıklama: %s\n", t.Description)
fmt.Printf("Durum: %s\n", t.Status)
fmt.Printf("Oluşturuldu: %s\n", t.CreatedAt.Format("02-01-2006 15:04:05"))
fmt.Println("--------------------------------------------------")
}
}
Yukarıdaki kodda, loadTickets fonksiyonu, tickets.json dosyasını okuyarak JSON verisini Go Ticket dilimlerine (slice) dönüştürür. Eğer dosya yoksa, uygulamanın çökmesini engellemek için boş bir dilim döndürür. saveTickets ise tam tersini yapar; Ticket dilimini alır, JSON formatına dönüştürür ve dosyaya yazar. MarshalIndent kullanmamızın sebebi, JSON çıktısının daha okunabilir (girintili) olmasını sağlamaktır. addTicket fonksiyonu yeni bir ticket oluşturur, benzersiz bir ID atar ve listeye ekleyerek dosyaya kaydeder. Son olarak, listTickets fonksiyonu tüm mevcut ticketları yükler ve kullanıcıya okunabilir bir formatta sunar. Bu iki temel işlevle, uygulamamızın iskeletini büyük ölçüde tamamlamış olduk.
Ticket Durumunu Güncelleme ve Silme İşlevleri Nasıl Eklenir?
Uygulamamızın tam teşekküllü bir ticket takip aracı olabilmesi için, mevcut ticketları güncelleyebilme ve gerektiğinde silebilme yeteneklerine sahip olması gerekmektedir. Bu işlevler, bir ticket'ın yaşam döngüsü boyunca yönetilmesine olanak tanır. Örneğin, bir görev "Açık" durumdan "Devam Ediyor" veya "Tamamlandı" durumuna geçebilir; yahut yanlışlıkla girilmiş bir ticket tamamen kaldırılması gerekebilir. Bu bölümde, updateTicket ve deleteTicket fonksiyonlarını nasıl oluşturacağımızı ele alacağız. Bu fonksiyonlar, kullanıcıdan ticket ID'si alacak ve ilgili ticket üzerinde gerekli değişiklikleri yapacak.
Güncelleme işlevi, belirli bir ID'ye sahip ticket'ı bulup, başlığını, açıklamasını veya durumunu değiştirebilmelidir. Silme işlevi ise yine belirli bir ID'ye sahip ticket'ı listeden tamamen çıkarmalıdır. Her iki işlem de, loadTickets ile mevcut tüm ticketları okuyarak başlar, gerekli manipülasyonları yapar ve ardından saveTickets ile güncellenmiş listeyi dosyaya geri yazar. Bu süreç, veri bütünlüğünü korurken esnek bir yönetim sağlar.
package main
// updateTicket, belirli bir ID'ye sahip ticket'ın başlığını, açıklamasını veya durumunu günceller.
func updateTicket(id int, newTitle, newDescription, newStatus string) {
tickets, err := loadTickets()
if err != nil {
fmt.Printf("Hata: %v\n", err)
return
}
found := false
for i, t := range tickets {
if t.ID == id {
if newTitle != "" {
tickets[i].Title = newTitle
}
if newDescription != "" {
tickets[i].Description = newDescription
}
if newStatus != "" {
// Durum kontrolü yapılabilir (örn: "Open", "InProgress", "Closed")
tickets[i].Status = newStatus
}
found = true
break
}
}
if !found {
fmt.Printf("ID %d ile ticket bulunamadı.\n", id)
return
}
err = saveTickets(tickets)
if err != nil {
fmt.Printf("Hata: %v\n", err)
return
}
fmt.Printf("Ticket ID %d başarıyla güncellendi.\n", id)
}
// deleteTicket, belirli bir ID'ye sahip ticket'ı siler.
func deleteTicket(id int) {
tickets, err := loadTickets()
if err != nil {
fmt.Printf("Hata: %v\n", err)
return
}
foundIndex := -1
for i, t := range tickets {
if t.ID == id {
foundIndex = i
break
}
}
if foundIndex == -1 {
fmt.Printf("ID %d ile ticket bulunamadı.\n", id)
return
}
// Ticket'ı listeden sil
tickets = append(tickets[:foundIndex], tickets[foundIndex+1:]...)
err = saveTickets(tickets)
if err != nil {
fmt.Printf("Hata: %v\n", err)
return
}
fmt.Printf("Ticket ID %d başarıyla silindi.\n", id)
}
updateTicket fonksiyonunda, kullanıcının yalnızca değiştirmek istediği alanları belirtmesine izin veriyoruz. Eğer newTitle, newDescription veya newStatus boş değilse, ilgili alan güncellenir. Bu, kısmi güncellemeleri mümkün kılar. deleteTicket fonksiyonu ise, belirtilen ID'ye sahip ticket'ı bulduğunda, Go'nun slice manipülasyon yeteneklerini kullanarak onu dilimden çıkarır. append(tickets[:foundIndex], tickets[foundIndex+1:]...) ifadesi, bulunan indeksin öncesindeki ve sonrasındaki dilimleri birleştirerek aradaki elemanı etkili bir şekilde siler.
Bu güncellemelerle birlikte, ticket takip CLI uygulamamız artık tam bir CRUD (Create, Read, Update, Delete) işlevselliğine sahip. Kullanıcılar, ticketları ekleyebilir, listeleyebilir, mevcut olanları değiştirebilir ve artık gerekmeyenleri silebilirler. Bu, uygulamanın gerçek dünya senaryolarında kullanılabilirliğini önemli ölçüde artırır. Bir sonraki adım, kullanıcıların bu işlevlere komut satırı üzerinden nasıl erişeceğini düzenlemek olacaktır.
Komut Satırı Argümanlarını İşleme ve Uygulamayı Genişletme
Şimdiye kadar tüm temel işlevleri kodladık, ancak kullanıcılar bu işlevlere henüz komut satırı üzerinden doğrudan erişemiyorlar. Bir CLI uygulamasının gücü, kullanıcıların farklı komutlar ve argümanlar aracılığıyla çeşitli eylemleri tetikleyebilmesinden gelir. Go'nun standart kütüphanesindeki flag paketi, basit komut satırı argümanlarını ayrıştırmak için harika bir araçtır. Daha karmaşık senaryolar için ise cobra veya urfave/cli gibi üçüncü taraf kütüphaneler daha gelişmiş özellikler sunar.
Bu bölümde, os.Args dilimini kullanarak uygulamamızı komut satırından yönetilebilir hale getireceğiz. Kullanıcılarımız artık go run main.go add "Yeni Başlık" "Açıklama" veya go run main.go list gibi komutlarla etkileşim kurabilecekler. main.go dosyamız, komut satırı argümanlarını okuyacak ve buna göre ilgili fonksiyonları çağıracak mantığı içerecektir. Bu, uygulamamızı çok daha kullanışlı ve etkileşimli hale getirecektir.
İşte main.go dosyamızın ilk taslağı, os.Args ile komutları nasıl işleyeceğimizi gösteriyor:
package main
import (
"bufio"
"fmt"
"os"
"strings"
"strconv"
)
// Kullanıcıdan tek satırlık girdi almak için yardımcı fonksiyon
func getUserInput(prompt string) string {
fmt.Print(prompt)
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
return strings.TrimSpace(scanner.Text())
}
func main() {
if len(os.Args) < 2 {
printUsage()
return
}
command := os.Args[1]
switch command {
case "add":
if len(os.Args) < 4 {
fmt.Println("Kullanım: add ")
return
}
title := os.Args[2]
description := os.Args[3]
addTicket(title, description)
case "list":
listTickets()
case "update":
if len(os.Args) < 3 {
fmt.Println("Kullanım: update [yeni_başlık] [yeni_açıklama] [yeni_durum]")
return
}
id, err := strconv.Atoi(os.Args[2])
if err != nil {
fmt.Println("Hata: Geçersiz ID formatı.")
return
}
var newTitle, newDescription, newStatus string
if len(os.Args) > 3 {
newTitle = os.Args[3]
}
if len(os.Args) > 4 {
newDescription = os.Args[4]
}
if len(os.Args) > 5 {
newStatus = os.Args[5]
}
updateTicket(id, newTitle, newDescription, newStatus)
case "delete":
if len(os.Args) < 3 {
fmt.Println("Kullanım: delete ")
return
}
id, err := strconv.Atoi(os.Args[2])
if err != nil {
fmt.Println("Hata: Geçersiz ID formatı.")
return
}
deleteTicket(id)
default:
printUsage()
}
}
func printUsage() {
fmt.Println("Kullanım:")
fmt.Println(" add - Yeni bir ticket ekler.")
fmt.Println(" list - Tüm ticketları listeler.")
fmt.Println(" update [başlık] [açıklama] [durum] - Belirli bir ticket'ı günceller.")
fmt.Println(" delete - Belirli bir ticket'ı siler.")
}
Yukarıdaki main fonksiyonu, os.Args dilimini kullanarak komut satırı argümanlarını okur. os.Args[0] her zaman programın adını, os.Args[1] ise ilk komutu (örneğin "add", "list") içerir. Bir switch ifadesi ile komutları ayrıştırıyoruz ve ilgili fonksiyonları çağırıyoruz. Her komutun kendi kullanım mesajı ve argüman doğrulama kontrolü bulunur. strconv.Atoi fonksiyonu string olan ID'yi integer'a dönüştürmek için kullanılır.
Gerçek dünya senaryosunda, bu CLI aracı küçük bir geliştirme ekibinin günlük görevlerini yönetmek için kullanılabilir. Örneğin, bir ekip üyesi yeni bir hata raporu geldiğinde go run main.go add "Hata: Giriş Ekranı Yavaş" "Kullanıcılar giriş ekranının yüklenmesinin uzun sürdüğünü belirtiyor." komutuyla hızla bir ticket oluşturabilir. Başka bir üye, üzerinde çalıştığı bir ticket'ın durumunu go run main.go update 5 "" "" "InProgress" komutuyla kolayca "Devam Ediyor" olarak güncelleyebilir. Bu, ekip içi iletişimi hızlandırır ve görevlerin şeffaflığını artırır. Böylece, küçük ölçekli projelerde veya kişisel görev yönetiminde büyük faydalar sağlayabiliriz.
İleri Düzey İpuçları ve En İyi Uygulamalar: Daha Sağlam Bir CLI İçin Neler Yapmalı?
Basit bir ticket takip CLI uygulaması geliştirdik, ancak modern bir yazılım projesini daha sağlam, sürdürülebilir ve ölçeklenebilir hale getirmek için bazı ileri düzey ipuçları ve en iyi uygulamaları göz önünde bulundurmak önemlidir. Bu bölümde, uygulamanızı bir sonraki seviyeye taşıyacak bazı kritik konulara değineceğiz: hata yönetimi, test yazma, sürüm kontrolü ve derleme/dağıtım. Bu pratik bilgiler, sadece bu proje için değil, gelecekteki tüm Go projelerinizde de size rehberlik edecektir.
-
Daha Kapsamlı Hata Yönetimi: Uygulamamızda şu an için basit
fmt.Printfile hataları gösteriyoruz. Ancak, gerçek bir uygulamada hataları daha strukture edilmiş bir şekilde ele almak faydalıdır. Go'nunerrorspaketi (errors.Wrap,errors.Causegibi) veyagithub.com/pkg/errorsgibi üçüncü taraf kütüphaneler, hata zincirlerini takip etmenize ve daha anlamlı hata mesajları sunmanıza yardımcı olabilir. Örneğin, bir dosya okuma hatası meydana geldiğinde, sadece "Hata oluştu" demek yerine, "tickets.json dosyası okunamadı: izinler yetersiz" gibi daha detaylı bilgi vermek kullanıcı için çok daha değerlidir. -
Birim (Unit) Testleri Yazmak: Yazdığınız her fonksiyonun beklenen şekilde çalıştığından emin olmak için testler yazmak vazgeçilmezdir. Go, test paketi ile yerleşik bir test çerçevesi sunar.
_test.gouzantılı dosyalar oluşturarak fonksiyonlarınızı test edebilirsiniz. Örneğin,addTicketfonksiyonunun yeni bir ticket eklediğinden velistTickets'ın doğru formatta çıktı verdiğinden emin olmak için testler yazabilirsiniz.package main import ( "os" "testing" ) func TestAddTicket(t *testing.T) { // Test öncesi temizlik os.Remove(dataFile) addTicket("Test Başlık", "Test Açıklama") tickets, err := loadTickets() if err != nil { t.Fatalf("TestAddTicket hatası: %v", err) } if len(tickets) != 1 { t.Errorf("Beklenen 1 ticket, %d bulundu", len(tickets)) } if tickets[0].Title != "Test Başlık" { t.Errorf("Beklenen başlık 'Test Başlık', '%s' bulundu", tickets[0].Title) } } // Diğer test fonksiyonları buraya eklenebilir - Sürüm Kontrolü ve Git Kullanımı: Herhangi bir yazılım projesinde Git gibi bir sürüm kontrol sistemi kullanmak, yaptığınız değişiklikleri takip etmenizi, farklı özellikler üzerinde paralel olarak çalışmanızı ve gerektiğinde önceki sürümlere geri dönmenizi sağlar. Projenizi bir Git deposunda barındırmak, işbirliğini de kolaylaştırır.
-
Çapraz Platform Derleme ve Dağıtım: Go'nun en güçlü özelliklerinden biri, uygulamanızı farklı işletim sistemleri ve mimariler için kolayca derleyebilmesidir. Örneğin, Windows için
GOOS=windows GOARCH=amd64 go build -o ticket-tracker.exekomutunu kullanarak bir.exedosyası oluşturabilirsiniz. Bu, uygulamanızın farklı ortamlarda sorunsuz çalışmasını sağlar. - Kullanıcı Dostu Hata Mesajları: Hata durumlarında, kullanıcıya ne olduğunu ve nasıl düzeltebileceğini anlatan açık ve anlaşılır mesajlar sunmak önemlidir. Teknik terimlerden kaçının ve kullanıcının anlayabileceği bir dil kullanın.
Bu ipuçları, basit bir prototipi daha profesyonel ve güvenilir bir araca dönüştürmenize yardımcı olacaktır. Unutmayın, iyi bir yazılım sadece çalışmakla kalmaz, aynı zamanda kolayca bakım yapılabilir ve genişletilebilir olmalıdır.
Sonuç ve Sıkça Sorulan Sorular
Bu kapsamlı rehber boyunca, Go programlama dilini kullanarak sıfırdan basit ama işlevsel bir ticket takip CLI uygulaması geliştirdik. Go'nun sade sözdizimi, güçlü standart kütüphanesi ve çapraz platform desteği sayesinde, hızlı ve etkili bir araç oluşturmanın ne kadar kolay olduğunu gördük. Proje yapısından başlayarak, Ticket veri modelini tanımladık, JSON dosyaları kullanarak verilerimizi kalıcı hale getirdik. Ardından, ticketları ekleme, listeleme, güncelleme ve silme gibi temel CRUD işlemlerini başarıyla uyguladık. Son olarak, os.Args ile komut satırı argümanlarını nasıl işleyeceğimizi ve uygulamamızı nasıl daha kullanıcı dostu hale getirebileceğimizi öğrendik. Bu yolculuk, Go'nun temel prensiplerini ve pratik uygulamalarını derinlemesine anlamanıza yardımcı olmuştur.
Geliştirdiğimiz bu uygulama, kişisel görev yönetimi için veya küçük bir ekibin basit ticket ihtiyaçlarını karşılamak için harika bir başlangıç noktası olabilir. Ayrıca, öğrendiğiniz bu bilgileri daha karmaşık CLI araçları geliştirmek veya mevcut Go projelerinizi zenginleştirmek için bir temel olarak kullanabilirsiniz. Go'nun sunduğu imkanlar oldukça geniş; dosya sistemleriyle etkileşimden ağ programlamaya kadar birçok alanda güçlü çözümler üretebilirsiniz. Gelecekte, bu uygulamaya kullanıcı arayüzü eklemek, veritabanı entegrasyonu yapmak veya bulut hizmetleriyle senkronizasyon gibi özellikler ekleyerek çok daha gelişmiş bir araç haline getirebilirsiniz. Unutmayın, öğrenme sürekli bir süreçtir ve her yeni proje, bilginizi pekiştirmenin ve yeteneklerinizi genişletmenin harika bir yoludur.
Sıkça Sorulan Sorular
- Go ile geliştirilen CLI uygulamaları neden bu kadar hızlıdır?
- Go, derlenmiş bir dildir, yani kaynak kodunuz doğrudan makine koduna dönüştürülür. Bu, uygulamaların ek bir çalışma zamanı ortamına ihtiyaç duymadan doğrudan ve hızlı bir şekilde çalışmasını sağlar. Ayrıca, Go'nun etkili bellek yönetimi ve çöp toplama mekanizmaları da performansa katkıda bulunur.
- JSON yerine farklı bir veri depolama yöntemi kullanabilir miyim?
- Evet, kesinlikle! Basitlik için JSON kullandık, ancak uygulamanızı daha ölçeklenebilir hale getirmek isterseniz SQLite gibi gömülü bir veritabanı (örneğin,
github.com/mattn/go-sqlite3kütüphanesi ile) kullanabilirsiniz. Daha büyük projeler için PostgreSQL veya MySQL gibi harici veritabanları ile entegrasyon da mümkündür. Seçim, projenizin ihtiyaçlarına ve büyüklüğüne bağlıdır. - Uygulamayı mobil uyumlu hale getirmek için ne yapmalıyım?
- Bu makale bir CLI uygulaması geliştirmeye odaklandığı için, doğrudan mobil uyumlu bir kullanıcı arayüzü (UI) yoktur. Ancak, eğer bu CLI'ın bir mobil veya web tabanlı arayüzü olsaydı, CSS medya sorguları (media queries) kullanarak farklı ekran boyutlarına ve cihazlara uyum sağlayabilirdiniz. Örneğin,
@media screen and (max-width: 600px) { /* mobil stiller */ }gibi kurallar, içeriğin küçük ekranlarda daha iyi görünmesini sağlar. Go CLI uygulaması mobil bir UI'ye doğrudan sahip olmadığı için, mobil uyumluluk bu bağlamda bir web veya mobil frontend ile ilişkilidir. - Uygulamama yeni komutlar eklemek zor mu?
- Hayır, oldukça kolaydır. Yeni bir komut eklemek için öncelikle bu komutun yapacağı işlevi bir Go fonksiyonu olarak yazmanız gerekir (tıpkı
addTicketveyalistTicketsgibi). Ardından,main.godosyasındakiswitch commandbloğuna yeni komutunuzu (case "yenikomut":) ve ilgili fonksiyon çağrısını eklemeniz yeterlidir. Eğer çok sayıda komut ekleyecekseniz,cobragibi daha gelişmiş bir CLI kütüphanesi kullanmak daha düzenli bir yapı sağlar. - Performans için Go'daki eşzamanlılığı (concurrency) nasıl kullanabilirim?
- Go'nun eşzamanlılık özellikleri (gorutinler ve kanallar) genellikle paralel işleme gerektiren durumlarda kullanılır. Örneğin, çok sayıda ticket'ı aynı anda işlememiz veya uzun süren bir işlemi arka planda çalıştırmamız gerektiğinde gorutinler devreye girebilir. Basit bir dosya tabanlı ticket takip sistemi için doğrudan ihtiyaç duymayabilirsiniz, ancak ağ istekleri veya yoğun veri işleme gibi durumlarda uygulamanızın yanıt verme hızını önemli ölçüde artırabilirler.
