Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Going all-inwith Go
for CLIapps
AboutMe
» Tom Elliott
» Engineer @ Yext
» https://telliott.io
» @theotherelliott
AboutYext
» Location data management
» 90 engineers
» 200+ microservices in Java
& Go
» http://www.yext.com
» http://githu...
Agenda
» Who Uses Go For CLI?
» Why Go for CLI?
» Tools at Yext
» Standard Library
» 3rd Party Packages
» Distribution
» U...
Who Uses Go for CLI?
Who Uses Go for CLI?
Why Go
for CLI?
WhyGo for CLI?
» Familiarity
» Code Reuse
» Cross-platform
» Distribution Flexibility
ToolsAt
Yext
srv
Internal tool for building, testing and deploying
Yext services
$ srv build Pages
$ srv test Pages unit
$ srv publish ...
sites-cfg
Internal configuration tool for sites managed by
Pages
$ sites-cfg listsites
$ sites-cfg validate stores.enterpri...
Edward
https://github.com/yext/edward
Open source tool to manage local instances of service
$ edward start pages
$ edward ...
Standard
Library
Flags
import "flag"
Define and parse command-line flags
var port = flag.Int("port", 8080, "Port number for service")
flag.Parse...
Directorytreewalking
import "path/filepath"
Call filepath.Walk with a starting dir and a visitor function.
To find all .c file...
Process Execution
import "os/exec"
Run other command-line processes:
cmd := exec.Command("echo", "hello")
err := cmd.Run()...
EnvironmentVariables
import "os"
Getenv / Setenv:
os.Setenv("MYKEY", "VALUE")
value := os.Getenv("MYKEY")
ExpandEnv:
expan...
Platform-Specific Code
Build tags:
// +build !linux,!darwin
package main
func init() { macOS_or_Linux_only() }
File names:
...
3rd Party
Packages
CLI
$ go get github.com/urfave/cli
import "urfave/cli"
» Framework for command-line applications
» Familiar command, args ...
gopsutil
$ go get github.com/shirou/gopsutil
import "shirou/gopsutil"
» go port of Python's psutil
» Helps retrieve inform...
Distribution
Distribution
» go get
» Build from source
» Pre-built binary
go get
Use go get to download and build as with any package
$ go get <package>
Updates:
$ go get -u <package>
Example:
» E...
go get
Pros:
» No overhead, just push to a repo
» Handles dependencies and installation
» Cross-platform by default
Cons:
...
Build from source
» Download source
» Provide instructions
» Build with Makefile or similar
Example:
* sites-cfg
* Hugo
Build from source
Pros:
» Allows a more complicated build process
» Easy to support private repos
» Can tailor to a famila...
Pre-builtbinary
» Cross-compile and distribute directly
» Can use package managers like homebrew for quick
install
» Or di...
Pre-builtbinary
Pros:
» No dependency on go
» Greater choice of distribution channels
» Simpler version management
Cons:
»...
UpdateNotification
Update Notification
Alerting users who installed using go get
» Tag commits in Git with a version number: x.y.z
» Marked as...
Checking for Updates
import "github.com/hashicorp/go-version"
func UpdateAvailable(repo, currentVersion) (bool, string, er...
WhatCould
You Do?
ThankYou» http://www.yext.com
» https://telliott.io
» @theotherelliott
Going All-In With Go For CLI Apps
Prochain SlideShare
Chargement dans…5
×

Going All-In With Go For CLI Apps

3 187 vues

Publié le

An exploration of how Yext adopted Go for building command line tools, the language features and third-party packages that helped along the way, and how we manage distribution to an 90-strong team.

Publié dans : Logiciels
  • Soyez le premier à commenter

Going All-In With Go For CLI Apps

  1. 1. Going all-inwith Go for CLIapps
  2. 2. AboutMe » Tom Elliott » Engineer @ Yext » https://telliott.io » @theotherelliott
  3. 3. AboutYext » Location data management » 90 engineers » 200+ microservices in Java & Go » http://www.yext.com » http://github.com/yext » http://engblog.yext.com/
  4. 4. Agenda » Who Uses Go For CLI? » Why Go for CLI? » Tools at Yext » Standard Library » 3rd Party Packages » Distribution » Update Notification
  5. 5. Who Uses Go for CLI?
  6. 6. Who Uses Go for CLI?
  7. 7. Why Go for CLI?
  8. 8. WhyGo for CLI? » Familiarity » Code Reuse » Cross-platform » Distribution Flexibility
  9. 9. ToolsAt Yext
  10. 10. srv Internal tool for building, testing and deploying Yext services $ srv build Pages $ srv test Pages unit $ srv publish Pages all release » Wrapper around build, test and deployment tools » Simplifies CI configuration » Reproducible
  11. 11. sites-cfg Internal configuration tool for sites managed by Pages $ sites-cfg listsites $ sites-cfg validate stores.enterpriseclient.com » Query configuration of sites in system » Validate site repo without pushing » Uses existing client code to interact with RPC services
  12. 12. Edward https://github.com/yext/edward Open source tool to manage local instances of service $ edward start pages $ edward stop pages $ edward tail sites-admin » Simplifies dev workflow with many microservices » Build & launch services individually or as a group » Auto-generate configuration for go & Docker services
  13. 13. Standard Library
  14. 14. Flags import "flag" Define and parse command-line flags var port = flag.Int("port", 8080, "Port number for service") flag.Parse() » Supports all primitive types » Get remaining arguments with flag.Args() » Output usage with -help
  15. 15. Directorytreewalking import "path/filepath" Call filepath.Walk with a starting dir and a visitor function. To find all .c files: func main() { _ = filepath.Walk(os.Args[1], visit) } func visit(path string, f os.FileInfo, err error) error { if filepath.Ext(path) == ".c" { fmt.Println(path) } return nil }
  16. 16. Process Execution import "os/exec" Run other command-line processes: cmd := exec.Command("echo", "hello") err := cmd.Run() » Redirect stdin/stdout » Wait for completion, or run in the background
  17. 17. EnvironmentVariables import "os" Getenv / Setenv: os.Setenv("MYKEY", "VALUE") value := os.Getenv("MYKEY") ExpandEnv: expanded := os.ExpandEnv("$GOPATH/github.com/user/repo")
  18. 18. Platform-Specific Code Build tags: // +build !linux,!darwin package main func init() { macOS_or_Linux_only() } File names: dns_windows.go
  19. 19. 3rd Party Packages
  20. 20. CLI $ go get github.com/urfave/cli import "urfave/cli" » Framework for command-line applications » Familiar command, args and flags form myapp -flag1 value command1 arg1 arg2 » Auto-generated help text » Hidden commands
  21. 21. gopsutil $ go get github.com/shirou/gopsutil import "shirou/gopsutil" » go port of Python's psutil » Helps retrieve information on running processes and system resource usage » At Yext, is used to monitor forked processes and check for local open ports
  22. 22. Distribution
  23. 23. Distribution » go get » Build from source » Pre-built binary
  24. 24. go get Use go get to download and build as with any package $ go get <package> Updates: $ go get -u <package> Example: » Edward
  25. 25. go get Pros: » No overhead, just push to a repo » Handles dependencies and installation » Cross-platform by default Cons: » Always pulls the latest commit » Limits build complexity (by design) » Difficult to use for closed-source
  26. 26. Build from source » Download source » Provide instructions » Build with Makefile or similar Example: * sites-cfg * Hugo
  27. 27. Build from source Pros: » Allows a more complicated build process » Easy to support private repos » Can tailor to a familar workflow Cons: » Requires more detailed instruction » More build tools complicates cross-platform distribution » Additional build dependencies
  28. 28. Pre-builtbinary » Cross-compile and distribute directly » Can use package managers like homebrew for quick install » Or distribute binary via download page Examples: * srv * Docker * Hugo
  29. 29. Pre-builtbinary Pros: » No dependency on go » Greater choice of distribution channels » Simpler version management Cons: » Overhead » Building binaries » Setting up distribution channels » Must decide on supported platforms
  30. 30. UpdateNotification
  31. 31. Update Notification Alerting users who installed using go get » Tag commits in Git with a version number: x.y.z » Marked as releases in GitHub » Compare current version to tags on Git remote, alert if a newer version is available
  32. 32. Checking for Updates import "github.com/hashicorp/go-version" func UpdateAvailable(repo, currentVersion) (bool, string, error) { output, _ := exec.Command( "git", "ls-remote", "-t", "git://"+repo ).CombinedOutput() // Parse tag from output in the form [0-9]+.[0-9]+.[0-9]+ latestVersion, _ = findLatestVersionTag(output) remote, _ := version.NewVersion(latestVersion) local, _ := version.NewVersion(currentVersion) return local.LessThan(remote), remote, nil }
  33. 33. WhatCould You Do?
  34. 34. ThankYou» http://www.yext.com » https://telliott.io » @theotherelliott

×