func HOME() string {
	var h string
	if runtime.GOOS == "windows" {
		h = os.Getenv("HOMEPATH")
	} else {
		h = os.Getenv("HOME")
	}
	if h == "" {
		log.Fatal("home directory not set")
	}
	return h
}
HOME returns the value of $HOME (or its equivalent on windows).
Logs a fatal error if the home directory isn't set.
package main
import (
	"bufio"
	"context"
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"runtime"
	"strings"
	"text/tabwriter"
	"github.com/nishanths/lyft-go"
	"googlemaps.github.io/maps"
)
const help = `usage: lyft [flags] [ride|place] [subcommand args...]
Flags
  -type <ride-type>  Ride type: line, lyft, premier, lux, or luxsuv (default line).
  -dry-run           Dry-run; don't actually create or modify rides (default false).
  -to <place>        Use saved place as the end location for the ride.
  -notify            Show desktop notifications (default false), macOS only.
  -from <place>      Use saved place as the start location for the ride.
  -watch             Watch ride status updates (default false).
The ride subcommand can create, cancel, and track the status of rides.
  lyft ride create
  lyft ride cancel <ride-id>
  lyft ride status <ride-id>
The place subcommand can save ride start and end locations for future use.
  lyft place add    <name>
  lyft place remove <name>...
  lyft place show   [name]
The program uses the following environment variables.
  GOOG_GEOCODE_KEY
  LYFT_CLIENT_ID
  LYFT_CLIENT_SECRET
See https://godoc.org/github.com/nishanths/lyft for details.
`
func usage() {
	fmt.Fprint(os.Stderr, help)
	os.Exit(2)
}
const (
	rootDir      = ".lyft"
	internalFile = "internal.json"
	placesFile   = "places.json"
)
const (
	permRootDir = 0740
	permDir     = 0750
	permFile    = 0640
)
func main() {
	log.SetFlags(0)
	car := flag.String("type", "line", "")
	startPlace := flag.String("from", "", "")
	endPlace := flag.String("to", "", "")
	notifications := flag.Bool("notify", false, "")
	dryRun := flag.Bool("dry-run", false, "")
	watch := flag.Bool("watch", false, "")
	flag.Usage = usage
	flag.Parse()
	args := flag.Args()
	if len(args) == 0 {
		usage()
	}
	flags := Flags{
		car:           *car,
		startPlace:    *startPlace,
		endPlace:      *endPlace,
		notifications: *notifications,
		dryRun:        *dryRun,
		watch:         *watch || *notifications,
	}
	switch args[0] {
	case "ride":
		cmdRide(args[1:], flags)
	case "place":
		cmdPlace(args[1:])
	default:
		usage()
	}
}
// Flags is the command line flags collected together to make it easy
// to pass around as a single argument.
type Flags struct {
	car           string
	startPlace    string
	endPlace      string
	notifications bool
	dryRun        bool
	watch         bool
}
// rideType returns the ride type for the specified flag,
// or exits with a fatal error if the ride type is invalid.
func (f Flags) rideType() string {
	s := flagToRideType(f.car)
	if s == "" {
		log.Fatalf("unknown ride type %q", f.car)
	}
	return s
}
// flagToRideType returns the ride type for the flag argument,
// or an empty string if a matching ride type wasn't found.
func flagToRideType(r string) string {
	switch r {
	case "line":
		return lyft.RideTypeLine
	case "lyft":
		return lyft.RideTypeLyft
	case "premier":
		return lyft.RideTypePremier
	case "lux":
		return lyft.RideTypeLux
	case "luxsuv":
		return lyft.RideTypeLuxSUV
	}
	return ""
}
type Location struct {
	Lat     float64
	Lng     float64
	Address string
}
func parseLocationInput(str string, mapsc func() *maps.Client) (Location, error) {
	if len(strings.Split(str, ",")) == 2 {
		ll, err := maps.ParseLatLng(str)
		if err == nil {
			return Location{ll.Lat, ll.Lng, ""}, nil
		}
	}
	loc, err := locationFromStreetAddress(str, mapsc())
	if err != nil {
		return Location{}, fmt.Errorf("failed to determine coordinates for address %q: %s", "", err)
	}
	return loc, nil
}
func locationFromStreetAddress(a string, mapsc *maps.Client) (Location, error) {
	ctx := context.TODO()
	results, err := mapsc.Geocode(ctx, &maps.GeocodingRequest{Address: a})
	if err != nil {
		return Location{}, err
	}
	if len(results) == 0 {
		return Location{}, errors.New("zero results for address")
	}
	return Location{
		results[0].Geometry.Location.Lat,
		results[0].Geometry.Location.Lng,
		results[0].FormattedAddress,
	}, nil
}