Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactors from the Go Bootcamp #2

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
123 changes: 123 additions & 0 deletions NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
http://www.golangbootcamp.com/book/basic_concepts
https://github.com/mitchellh/gox
https://generalassemb.ly/los-angeles
https://gophercasts.io/
http://play.golang.org/

Other classes happening in here make it really loud.

last name at the end of the import is the package name!
externally visible things in a package are always capitalized. Capitalized functions are essentially public. Lower case are private.
all variables have a zero type when initialized. a bool is false, an integer is 0, etc.
variable shadowing an interesting concept. can be dangerous, but possibly useful(?). A locally scoped variable will override a higher scoped variable.

Silly, valid Go code.

const ever = true

for ever {

}

variables can be declared specifically in front of an if statement, and that variable will be in scope only for the if

if x := 5 + y; x < 10 {
return "horray!"
}

newton approximation. Kinda interesting / hard

package main

import (
"fmt"
"math"
)

const delta = 1e-5

func Sqrt(x float64) float64 {
z := 1.0
for {
nz := z - (z*z-x)/(2*z)
if d := nz - z; math.Abs(d) < delta {
return z
}
z = nz
}
}

func main() {
fmt.Println(Sqrt(9))
}


"Go compiles itself (the standard library) in less than one minute"

Classes have behavior, structs are a package of data and behavior. Behavior can be attached to any type.


Some sort-of useful debugging output
fmt.Printf("%+v", Vertex{1, 2})
fmt.Printf("%#v", Vertex{1, 2})
fmt.Printf("%q", Vertex{1, 2})
v := Vertex{Y: 2, X: 1}
fmt.Printf("%+v", v)

Go copies the object when you pass it around, so that is why you would want to prefer Pointers
Functions that want to modify an object passed in (as a side-effect), you need to pass through a pointer
Can you dangle a pointer by pointing to a variable, and losing scope to that variable? No, Go is garbage collected and that variable will continue to exist.

When you really code in Go, you will almost never use arrays. Really? You would use slices.
Slices are the powerful way to interact with arrays. Has len(), cap(), and append()
A for loop over a slice uses 2 parameters, index and value when using range

Table testing - https://code.google.com/p/go-tour/source/browse/wc/wc.go

Jeremy Saenz
Martini - reuseable web components in Go. Very cool.

Lambdas first class citizen. Neat little debug trick.
func main() {
hypot := func(x, y float64) float64 {
return math.Sqrt(x*x + y*y)
}

fmt.Printf("%T", hypot)
}
func(float64, float64) float64


Functions that return functions. Confusing but interesting.
fibbinocci closure is interesting

Difference between passing a pointer or a value to a defined function. http://tour.golang.org/#54. Pointers allow you to modify, values do not.

https://github.com/mitchellh/goxc + GOOS="OPERATING SYSTEM" go build a main package
GOOS="windows" /usr/local/Cellar/go/1.2/libexec/src/make.bash
for loop on GOOS to cross compile things

Kelsey Hightower - @kelseyhightower
http://www.freedesktop.org/software/systemd/man/systemd-nspawn.html
https://github.com/kelseyhightower/confd

http://www.reddit.com/r/golang/

Channel of channels.
Channels are interesting.
Each request sent to a Go web server is its own goroutine.

Don't use . when doing imports and aliases.



Lots of Ruby devs in here. Lots of web developers as well.

Systemd and your service just logs to stdout. forget about writing logs, just pipe them somewhere or allow some way to aggregate em.







44 changes: 0 additions & 44 deletions cmdutil/cmdutil.go

This file was deleted.

28 changes: 12 additions & 16 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
package main

import (
"log"
"os"

"github.com/GoBootcamp/clirescue/trackerapi"
"github.com/codegangsta/cli"
)

func main() {
app := cli.NewApp()

app.Name = "clirescue"
app.Usage = "CLI tool to talk to the Pivotal Tracker's API"

app.Commands = []cli.Command{
{
Name: "me",
Usage: "prints out Tracker's representation of your account",
Action: func(c *cli.Context) {
trackerapi.Me()
},
},
if len(os.Args) < 2 {
log.Fatal("Command required")
}
switch os.Args[1] {
case "login":
err := trackerapi.CacheCredentials()
if err != nil {
panic(err)
}
default:
log.Fatal("Unknown Command: ", os.Args[1])
}

app.Run(os.Args)
}
78 changes: 0 additions & 78 deletions trackerapi/me.go

This file was deleted.

85 changes: 85 additions & 0 deletions trackerapi/trackerapi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package trackerapi

import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/user"
"path/filepath"
)

const URL string = "https://www.pivotaltracker.com/services/v5/me"

var FileLocation string = fromHome("/.tracker")

func CacheCredentials() error {
apiToken, err := getAPIToken()
if err != nil {
return err
}
fmt.Println(string(apiToken))
return err
}

func getAPIToken() ([]byte, error) {

if _, err := os.Stat(FileLocation); err == nil {
return ioutil.ReadFile(FileLocation)
}

usr, pwd, err := getCredentials()
client := &http.Client{}
req, err := http.NewRequest("GET", URL, nil)
if err != nil {
return nil, err
}

req.SetBasicAuth(usr, pwd)
resp, err := client.Do(req)
if err != nil {
return nil, err
}

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}

var meResp struct {
APIToken []byte `json:"api_token"`
}

err = json.Unmarshal(body, &meResp)
if err != nil {
return nil, err
}
ioutil.WriteFile(FileLocation, []byte(meResp.APIToken), 0644)
return meResp.APIToken, nil
}

func getCredentials() (usr, pwd string, err error) {
fmt.Fprint(os.Stdout, "Username: ")
usr, err = readLine()

if err != nil {
return
}

silenceStty()
defer unsilenceStty()

fmt.Fprint(os.Stdout, "Password: ")
pwd, err = readLine()

return usr, pwd, err
}

func fromHome(file string) string {
usr, err := user.Current()
if err != nil {
panic(err)
}
return filepath.Join(usr.HomeDir, file)
}
13 changes: 7 additions & 6 deletions user/user.go → trackerapi/user.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package user
// Copyright 2013

func New() *User {
return new(User)
}
// Package pivotaluser represents a pivotal user
package trackerapi

type User struct {
// User represents a Pivotal Labs user.
type pivotalUser struct {
Username string
Password string
APIToken string
Expand All @@ -18,7 +18,8 @@ type User struct {
} `json:"time_zone"`
}

func (u *User) Login(name, pass string) {
// SetLogin sets the username and password.
func (u *pivotalUser) SetLogin(name, pass string) {
u.Username = name
u.Password = pass
}
Loading