La oss gå Command-Line programmer med Golang

Oversikt

Go Language er et spennende nytt språk som får stor popularitet for en god grunn. I denne opplæringen lærer du hvordan du skriver kommandolinjeprogrammer med Go. Prøveprogrammet heter multi-git, og det lar deg utføre git-kommandoer på flere lagre samtidig.

Rask introduksjon til Go

Go er et open-source C-lignende språk opprettet på Google av noen av de originale C og Unix hackere, som var motivert av deres misliker med C ++. Den viser i Go's design, som gjorde flere uortodokse valg som å unngå implementeringsarv, maler og unntak. Go er enkelt, pålitelig og effektivt. Den mest karakteristiske funksjonen er den eksplisitte støtten til samtidig programmering via såkalte goroutiner og kanaler.

Før du begynner å dissekere prøveprogrammet, følg den offisielle veiledningen for å gjøre deg klar for Go-utviklingen.

Go er et utrolig kraftig programmeringsspråk, lære alt fra å skrive enkle verktøy for å bygge skalerbare, fleksible webservere i hele kurset.

Multi-Git Programmet

Multi-Git-programmet er et enkelt, men nyttig Go-program. Hvis du jobber på et team hvor kodebase er delt over flere git-repositorier, må du ofte utføre endringer på tvers av flere lagre. Dette er et problem fordi git har ikke noe konsept for flere lagre. Alt kretser rundt et enkelt lager. 

Dette blir spesielt plagsomt hvis du bruker grener. Hvis du jobber med en funksjon som berører tre arkiver, må du opprette en funksjonavdeling i hver av disse lagrene, og husk å sjekke ut, trekke, skyve og slå sammen alle sammen samtidig. Dette er ikke trivielt. Multi-Git styrer et sett med repositorier og lar deg operere på hele settet samtidig. Vær oppmerksom på at den gjeldende versjonen av multi-git krever at du oppretter grenene individuelt, men jeg kan legge til denne funksjonen på et senere tidspunkt.

Ved å utforske måten multi-git er implementert, vil du lære mye om å skrive kommandolinjeprogrammer i Go.

Pakker og import

Go-programmer er organisert i pakker. Multi-Git-programmet består av en enkelt fil som heter main.go. Øverst på filen er pakkenavnet 'main' angitt, etterfulgt av en liste over import. Importen er andre pakker som brukes av multi-git.

pakke viktigste import ("flagg" "fmt" "log" "os" "strings" "os / exec")

For eksempel er fmt-pakken brukt for formatert I / O lik Cs printf og scanf. Go støtter installering av pakker fra en rekke kilder via gå og hent kommando. Når du installerer pakker, havner de opp i et navneområde under $ GOPATH miljøvariabel. Du kan installere pakker fra en rekke kilder som GitHub, Bitbucket, Google-kode, Launchpad og til og med IBM DevOps-tjenester via flere vanlige versjonskontrollformater som git, subversion, mercurial og bazaar.

Kommandolinjegrupper

Kommandolinjearguder er en av de vanligste formene for å gi input til programmer. De er enkle å bruke, lar deg kjøre og konfigurere programmet i en linje, og har god parsing-støtte på mange språk. Gå kall dem kommandolinje "flagg" og har flaggpakken for å angi og analysere kommandolinjeparametere (eller flagg). 

Vanligvis analyserer du kommandolinjeparametere i begynnelsen av programmet, og multi-git følger denne konvensjonen. Inngangspunktet er hoved() funksjon. De to første linjene definerer to flagg som heter "kommando" og "ignorere". Hvert flagg har et navn, en datatype, en standardverdi og en hjelpestreng. De flag.Parse () anrop vil analysere den faktiske kommandolinjen som sendes til programmet og vil fylle de definerte flaggene.

func main () command: = flag.String ("kommando", "", "Git-kommandoen") ignoreErrors: = flag.Bool ("ignore-errors", false, "Fortsett å kjøre etter feil hvis sant") .Parse ()

Det er også mulig å få tilgang til udefinerte argumenter via flag.Args () funksjon. Så flagg står for forhåndsdefinerte argumenter og "args" er ubehandlede argumenter. De ubehandlede argumentene er 0-baserte indeksert.

Miljøvariabler

En annen vanlig form for programkonfigurasjon er miljøvariabler. Når du bruker miljøvariabler, kan du kjøre det samme programmet flere ganger i samme miljø, og alle løpene bruker de samme miljøvariablene. 

Multi-git bruker to miljøvariabler: "MG_ROOT" og "MG_REPOS". Multi-git er utviklet for å administrere en gruppe git-repositories som har en felles foreldre katalog. Det er "MG_ROOT". Beholdernavnene er angitt i "MG_REPOS" som en kommaseparert streng. For å lese verdien av en miljøvariabel kan du bruke os.Getenv () funksjon.

 // Få klarte repos fra miljøvariabler root: = os.Getenv ("MG_ROOT") hvis root [len (root) - 1]! = '/' Root + = "/" repo_names: = strings.Split .Getenv ("MG_REPOS"), ",")

Verifisering av arkivlisten

Nå som det fant rotkatalogen og navnene på alle repositoriene, kontrollerer multi-git at hvert lagringssted eksisterer under rot, og at det virkelig er et git-repository. Tjekken er så enkel som å lete etter en .git-underkatalog for hvert arkivkatalog.

Først er en rekke strenger som heter "repos" definert. Så det iterates over alle repo navnene og konstruerer en lagerplass ved å sammenkoble rotkatalogen og repo-navnet. Hvis [Os.Stat ()] () Anropet mislykkes for .git-underkatalogen, det logger feilen og avslutter. Ellers lagres depotbanen til repos-arrayet.

 var repos [] string // Verifiser alle reposer og er faktisk git repos (har .git sub-dir) for _, r: = range repo_names path: = root + r _, err: = os.Stat "/.git") hvis err! = null log.Fatal (err) repos = legg til (repos, bane)

Go har et unikt feilhåndteringsanlegg hvor funksjoner ofte returnerer både en returverdi og et feilobjekt. Sjekk ut hvordan os.Stat () returnerer to verdier. I så fall brukes "_" plassholderen til å holde det faktiske resultatet fordi du bare bryr deg om feilen. Go er veldig streng og krever at navngitte variabler skal brukes. Hvis du ikke planlegger å bruke en verdi, bør du tilordne den til «_» for å unngå kompileringsfeil.

Utføre Shell-kommandoer

På dette tidspunktet har du listen over lagringsbaner hvor vi vil utføre kommandoen git. Som du husker mottok vi kommandolinjen git som et enkelt kommandolinjeprengivelse (flagg) kalt "kommando". Dette må deles inn i en rekke komponenter (git-kommando, underkommando og alternativer). Hele kommandoen som en streng lagres også for visningsformål.

 // Bryt git-kommandoen i komponenter (nødvendig for å utføre) var git_components [] streng for _, komponent: = range strings.Split (* kommando, "") git_components = append (git_components, component) command_string: = "git "+ * kommando

Nå er du klar til å iterere over hvert lager og utføre kommandoen git i hver enkelt. "For ... range" loop konstruksjon brukes igjen. For det første endrer multi-git arbeidskatalogen til gjeldende målrepo "r" og skriver ut git-kommandoen. Deretter utfører den kommandoen ved hjelp av exec.Command () Fungerer og skriver ut kombinert utgang (både standardutgang og standardfeil). 

Til slutt kontrollerer den om det oppsto en feil under utførelsen. Hvis det oppstod en feil og ignoreErrors flagg er falsk og deretter multi-git bails ut. Årsaken til at det er mulig å ignorere feil er at noen ganger er det OK hvis kommandoer mislykkes på noen repos. For eksempel, hvis du vil sjekke ut en filial kalt "kul funksjon" på alle arkiver som har denne grenen, bryr du deg ikke om kassen mislykkes på repositorier som ikke har denne grenen.

 for _, r: = range repos // Gå til repo-katalogen os.Chdir (r); // Skriv ut kommandoen fmt.Printf ("[% s]% s \ n", r, command_string) // Kjør kommandoen ut, feil: = exec.Command ("git", git_components ...) .CombinedOutput () / / Skriv ut resultatet fmt.Println (streng (ut)) // Bail out hvis det oppstod en feil og IKKE ignorerer feil hvis feil! = Null &&! * IgnoreErrors os.Exit (1) fmt.Println ("Done . ")

Konklusjon

Go er et enkelt, men kraftig språk. Den er designet for storskala systemprogrammering, men fungerer også bra for små kommandolinjeprogrammer også. Go's minimal design er i sterk kontrast til andre moderne språk som Skala og Rust som er veldig kraftige og godt designet også, men har en veldig bratt læringskurve. Jeg oppfordrer deg til å prøve å gå og eksperimentere. Det er veldig morsomt.