manually add dependency on go-getter

This commit is contained in:
Jingfang Liu
2018-08-14 14:20:19 -07:00
parent 70fb22cad6
commit b02f7775c5
270 changed files with 56453 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
# I am a comment
machine mail.google.com
login joe@gmail.com
account gmail
password somethingSecret
# I am another comment
default
login anonymous
password joe@example.com
machine ray login demo password mypassword

View File

@@ -0,0 +1,22 @@
# I am a comment
machine mail.google.com
login joe@gmail.com
account justagmail #end of line comment with trailing space
password somethingSecret
# I am another comment
macdef allput
put src/*
macdef allput2
put src/*
put src2/*
machine ray login demo password mypassword
machine weirdlogin login uname password pass#pass
default
login anonymous
password joe@example.com

510
vendor/github.com/bgentry/go-netrc/netrc/netrc.go generated vendored Normal file
View File

@@ -0,0 +1,510 @@
package netrc
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
"sync"
"unicode"
"unicode/utf8"
)
type tkType int
const (
tkMachine tkType = iota
tkDefault
tkLogin
tkPassword
tkAccount
tkMacdef
tkComment
tkWhitespace
)
var keywords = map[string]tkType{
"machine": tkMachine,
"default": tkDefault,
"login": tkLogin,
"password": tkPassword,
"account": tkAccount,
"macdef": tkMacdef,
"#": tkComment,
}
type Netrc struct {
tokens []*token
machines []*Machine
macros Macros
updateLock sync.Mutex
}
// FindMachine returns the Machine in n named by name. If a machine named by
// name exists, it is returned. If no Machine with name name is found and there
// is a ``default'' machine, the ``default'' machine is returned. Otherwise, nil
// is returned.
func (n *Netrc) FindMachine(name string) (m *Machine) {
// TODO(bgentry): not safe for concurrency
var def *Machine
for _, m = range n.machines {
if m.Name == name {
return m
}
if m.IsDefault() {
def = m
}
}
if def == nil {
return nil
}
return def
}
// MarshalText implements the encoding.TextMarshaler interface to encode a
// Netrc into text format.
func (n *Netrc) MarshalText() (text []byte, err error) {
// TODO(bgentry): not safe for concurrency
for i := range n.tokens {
switch n.tokens[i].kind {
case tkComment, tkDefault, tkWhitespace: // always append these types
text = append(text, n.tokens[i].rawkind...)
default:
if n.tokens[i].value != "" { // skip empty-value tokens
text = append(text, n.tokens[i].rawkind...)
}
}
if n.tokens[i].kind == tkMacdef {
text = append(text, ' ')
text = append(text, n.tokens[i].macroName...)
}
text = append(text, n.tokens[i].rawvalue...)
}
return
}
func (n *Netrc) NewMachine(name, login, password, account string) *Machine {
n.updateLock.Lock()
defer n.updateLock.Unlock()
prefix := "\n"
if len(n.tokens) == 0 {
prefix = ""
}
m := &Machine{
Name: name,
Login: login,
Password: password,
Account: account,
nametoken: &token{
kind: tkMachine,
rawkind: []byte(prefix + "machine"),
value: name,
rawvalue: []byte(" " + name),
},
logintoken: &token{
kind: tkLogin,
rawkind: []byte("\n\tlogin"),
value: login,
rawvalue: []byte(" " + login),
},
passtoken: &token{
kind: tkPassword,
rawkind: []byte("\n\tpassword"),
value: password,
rawvalue: []byte(" " + password),
},
accounttoken: &token{
kind: tkAccount,
rawkind: []byte("\n\taccount"),
value: account,
rawvalue: []byte(" " + account),
},
}
n.insertMachineTokensBeforeDefault(m)
for i := range n.machines {
if n.machines[i].IsDefault() {
n.machines = append(append(n.machines[:i], m), n.machines[i:]...)
return m
}
}
n.machines = append(n.machines, m)
return m
}
func (n *Netrc) insertMachineTokensBeforeDefault(m *Machine) {
newtokens := []*token{m.nametoken}
if m.logintoken.value != "" {
newtokens = append(newtokens, m.logintoken)
}
if m.passtoken.value != "" {
newtokens = append(newtokens, m.passtoken)
}
if m.accounttoken.value != "" {
newtokens = append(newtokens, m.accounttoken)
}
for i := range n.tokens {
if n.tokens[i].kind == tkDefault {
// found the default, now insert tokens before it
n.tokens = append(n.tokens[:i], append(newtokens, n.tokens[i:]...)...)
return
}
}
// didn't find a default, just add the newtokens to the end
n.tokens = append(n.tokens, newtokens...)
return
}
func (n *Netrc) RemoveMachine(name string) {
n.updateLock.Lock()
defer n.updateLock.Unlock()
for i := range n.machines {
if n.machines[i] != nil && n.machines[i].Name == name {
m := n.machines[i]
for _, t := range []*token{
m.nametoken, m.logintoken, m.passtoken, m.accounttoken,
} {
n.removeToken(t)
}
n.machines = append(n.machines[:i], n.machines[i+1:]...)
return
}
}
}
func (n *Netrc) removeToken(t *token) {
if t != nil {
for i := range n.tokens {
if n.tokens[i] == t {
n.tokens = append(n.tokens[:i], n.tokens[i+1:]...)
return
}
}
}
}
// Machine contains information about a remote machine.
type Machine struct {
Name string
Login string
Password string
Account string
nametoken *token
logintoken *token
passtoken *token
accounttoken *token
}
// IsDefault returns true if the machine is a "default" token, denoted by an
// empty name.
func (m *Machine) IsDefault() bool {
return m.Name == ""
}
// UpdatePassword sets the password for the Machine m.
func (m *Machine) UpdatePassword(newpass string) {
m.Password = newpass
updateTokenValue(m.passtoken, newpass)
}
// UpdateLogin sets the login for the Machine m.
func (m *Machine) UpdateLogin(newlogin string) {
m.Login = newlogin
updateTokenValue(m.logintoken, newlogin)
}
// UpdateAccount sets the login for the Machine m.
func (m *Machine) UpdateAccount(newaccount string) {
m.Account = newaccount
updateTokenValue(m.accounttoken, newaccount)
}
func updateTokenValue(t *token, value string) {
oldvalue := t.value
t.value = value
newraw := make([]byte, len(t.rawvalue))
copy(newraw, t.rawvalue)
t.rawvalue = append(
bytes.TrimSuffix(newraw, []byte(oldvalue)),
[]byte(value)...,
)
}
// Macros contains all the macro definitions in a netrc file.
type Macros map[string]string
type token struct {
kind tkType
macroName string
value string
rawkind []byte
rawvalue []byte
}
// Error represents a netrc file parse error.
type Error struct {
LineNum int // Line number
Msg string // Error message
}
// Error returns a string representation of error e.
func (e *Error) Error() string {
return fmt.Sprintf("line %d: %s", e.LineNum, e.Msg)
}
func (e *Error) BadDefaultOrder() bool {
return e.Msg == errBadDefaultOrder
}
const errBadDefaultOrder = "default token must appear after all machine tokens"
// scanLinesKeepPrefix is a split function for a Scanner that returns each line
// of text. The returned token may include newlines if they are before the
// first non-space character. The returned line may be empty. The end-of-line
// marker is one optional carriage return followed by one mandatory newline. In
// regular expression notation, it is `\r?\n`. The last non-empty line of
// input will be returned even if it has no newline.
func scanLinesKeepPrefix(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
// Skip leading spaces.
start := 0
for width := 0; start < len(data); start += width {
var r rune
r, width = utf8.DecodeRune(data[start:])
if !unicode.IsSpace(r) {
break
}
}
if i := bytes.IndexByte(data[start:], '\n'); i >= 0 {
// We have a full newline-terminated line.
return start + i, data[0 : start+i], nil
}
// If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF {
return len(data), data, nil
}
// Request more data.
return 0, nil, nil
}
// scanWordsKeepPrefix is a split function for a Scanner that returns each
// space-separated word of text, with prefixing spaces included. It will never
// return an empty string. The definition of space is set by unicode.IsSpace.
//
// Adapted from bufio.ScanWords().
func scanTokensKeepPrefix(data []byte, atEOF bool) (advance int, token []byte, err error) {
// Skip leading spaces.
start := 0
for width := 0; start < len(data); start += width {
var r rune
r, width = utf8.DecodeRune(data[start:])
if !unicode.IsSpace(r) {
break
}
}
if atEOF && len(data) == 0 || start == len(data) {
return len(data), data, nil
}
if len(data) > start && data[start] == '#' {
return scanLinesKeepPrefix(data, atEOF)
}
// Scan until space, marking end of word.
for width, i := 0, start; i < len(data); i += width {
var r rune
r, width = utf8.DecodeRune(data[i:])
if unicode.IsSpace(r) {
return i, data[:i], nil
}
}
// If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
if atEOF && len(data) > start {
return len(data), data, nil
}
// Request more data.
return 0, nil, nil
}
func newToken(rawb []byte) (*token, error) {
_, tkind, err := bufio.ScanWords(rawb, true)
if err != nil {
return nil, err
}
var ok bool
t := token{rawkind: rawb}
t.kind, ok = keywords[string(tkind)]
if !ok {
trimmed := strings.TrimSpace(string(tkind))
if trimmed == "" {
t.kind = tkWhitespace // whitespace-only, should happen only at EOF
return &t, nil
}
if strings.HasPrefix(trimmed, "#") {
t.kind = tkComment // this is a comment
return &t, nil
}
return &t, fmt.Errorf("keyword expected; got " + string(tkind))
}
return &t, nil
}
func scanValue(scanner *bufio.Scanner, pos int) ([]byte, string, int, error) {
if scanner.Scan() {
raw := scanner.Bytes()
pos += bytes.Count(raw, []byte{'\n'})
return raw, strings.TrimSpace(string(raw)), pos, nil
}
if err := scanner.Err(); err != nil {
return nil, "", pos, &Error{pos, err.Error()}
}
return nil, "", pos, nil
}
func parse(r io.Reader, pos int) (*Netrc, error) {
b, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
nrc := Netrc{machines: make([]*Machine, 0, 20), macros: make(Macros, 10)}
defaultSeen := false
var currentMacro *token
var m *Machine
var t *token
scanner := bufio.NewScanner(bytes.NewReader(b))
scanner.Split(scanTokensKeepPrefix)
for scanner.Scan() {
rawb := scanner.Bytes()
if len(rawb) == 0 {
break
}
pos += bytes.Count(rawb, []byte{'\n'})
t, err = newToken(rawb)
if err != nil {
if currentMacro == nil {
return nil, &Error{pos, err.Error()}
}
currentMacro.rawvalue = append(currentMacro.rawvalue, rawb...)
continue
}
if currentMacro != nil && bytes.Contains(rawb, []byte{'\n', '\n'}) {
// if macro rawvalue + rawb would contain \n\n, then macro def is over
currentMacro.value = strings.TrimLeft(string(currentMacro.rawvalue), "\r\n")
nrc.macros[currentMacro.macroName] = currentMacro.value
currentMacro = nil
}
switch t.kind {
case tkMacdef:
if _, t.macroName, pos, err = scanValue(scanner, pos); err != nil {
return nil, &Error{pos, err.Error()}
}
currentMacro = t
case tkDefault:
if defaultSeen {
return nil, &Error{pos, "multiple default token"}
}
if m != nil {
nrc.machines, m = append(nrc.machines, m), nil
}
m = new(Machine)
m.Name = ""
defaultSeen = true
case tkMachine:
if defaultSeen {
return nil, &Error{pos, errBadDefaultOrder}
}
if m != nil {
nrc.machines, m = append(nrc.machines, m), nil
}
m = new(Machine)
if t.rawvalue, m.Name, pos, err = scanValue(scanner, pos); err != nil {
return nil, &Error{pos, err.Error()}
}
t.value = m.Name
m.nametoken = t
case tkLogin:
if m == nil || m.Login != "" {
return nil, &Error{pos, "unexpected token login "}
}
if t.rawvalue, m.Login, pos, err = scanValue(scanner, pos); err != nil {
return nil, &Error{pos, err.Error()}
}
t.value = m.Login
m.logintoken = t
case tkPassword:
if m == nil || m.Password != "" {
return nil, &Error{pos, "unexpected token password"}
}
if t.rawvalue, m.Password, pos, err = scanValue(scanner, pos); err != nil {
return nil, &Error{pos, err.Error()}
}
t.value = m.Password
m.passtoken = t
case tkAccount:
if m == nil || m.Account != "" {
return nil, &Error{pos, "unexpected token account"}
}
if t.rawvalue, m.Account, pos, err = scanValue(scanner, pos); err != nil {
return nil, &Error{pos, err.Error()}
}
t.value = m.Account
m.accounttoken = t
}
nrc.tokens = append(nrc.tokens, t)
}
if err := scanner.Err(); err != nil {
return nil, err
}
if m != nil {
nrc.machines, m = append(nrc.machines, m), nil
}
return &nrc, nil
}
// ParseFile opens the file at filename and then passes its io.Reader to
// Parse().
func ParseFile(filename string) (*Netrc, error) {
fd, err := os.Open(filename)
if err != nil {
return nil, err
}
defer fd.Close()
return Parse(fd)
}
// Parse parses from the the Reader r as a netrc file and returns the set of
// machine information and macros defined in it. The ``default'' machine,
// which is intended to be used when no machine name matches, is identified
// by an empty machine name. There can be only one ``default'' machine.
//
// If there is a parsing error, an Error is returned.
func Parse(r io.Reader) (*Netrc, error) {
return parse(r, 1)
}
// FindMachine parses the netrc file identified by filename and returns the
// Machine named by name. If a problem occurs parsing the file at filename, an
// error is returned. If a machine named by name exists, it is returned. If no
// Machine with name name is found and there is a ``default'' machine, the
// ``default'' machine is returned. Otherwise, nil is returned.
func FindMachine(filename, name string) (m *Machine, err error) {
n, err := ParseFile(filename)
if err != nil {
return nil, err
}
return n.FindMachine(name), nil
}

559
vendor/github.com/bgentry/go-netrc/netrc/netrc_test.go generated vendored Normal file
View File

@@ -0,0 +1,559 @@
// Copyright © 2010 Fazlul Shahriar <fshahriar@gmail.com> and
// Copyright © 2014 Blake Gentry <blakesgentry@gmail.com>.
// See LICENSE file for license details.
package netrc
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
"testing"
)
var expectedMachines = []*Machine{
&Machine{Name: "mail.google.com", Login: "joe@gmail.com", Password: "somethingSecret", Account: "justagmail"},
&Machine{Name: "ray", Login: "demo", Password: "mypassword", Account: ""},
&Machine{Name: "weirdlogin", Login: "uname", Password: "pass#pass", Account: ""},
&Machine{Name: "", Login: "anonymous", Password: "joe@example.com", Account: ""},
}
var expectedMacros = Macros{
"allput": "put src/*",
"allput2": " put src/*\nput src2/*",
}
func eqMachine(a *Machine, b *Machine) bool {
return a.Name == b.Name &&
a.Login == b.Login &&
a.Password == b.Password &&
a.Account == b.Account
}
func testExpected(n *Netrc, t *testing.T) {
if len(expectedMachines) != len(n.machines) {
t.Errorf("expected %d machines, got %d", len(expectedMachines), len(n.machines))
} else {
for i, e := range expectedMachines {
if !eqMachine(e, n.machines[i]) {
t.Errorf("bad machine; expected %v, got %v\n", e, n.machines[i])
}
}
}
if len(expectedMacros) != len(n.macros) {
t.Errorf("expected %d macros, got %d", len(expectedMacros), len(n.macros))
} else {
for k, v := range expectedMacros {
if v != n.macros[k] {
t.Errorf("bad macro for %s; expected %q, got %q\n", k, v, n.macros[k])
}
}
}
}
var newTokenTests = []struct {
rawkind string
tkind tkType
}{
{"machine", tkMachine},
{"\n\n\tmachine", tkMachine},
{"\n machine", tkMachine},
{"default", tkDefault},
{"login", tkLogin},
{"password", tkPassword},
{"account", tkAccount},
{"macdef", tkMacdef},
{"\n # comment stuff ", tkComment},
{"\n # I am another comment", tkComment},
{"\n\t\n ", tkWhitespace},
}
var newTokenInvalidTests = []string{
" junk",
"sdfdsf",
"account#unspaced comment",
}
func TestNewToken(t *testing.T) {
for _, tktest := range newTokenTests {
tok, err := newToken([]byte(tktest.rawkind))
if err != nil {
t.Fatal(err)
}
if tok.kind != tktest.tkind {
t.Errorf("expected tok.kind %d, got %d", tktest.tkind, tok.kind)
}
if string(tok.rawkind) != tktest.rawkind {
t.Errorf("expected tok.rawkind %q, got %q", tktest.rawkind, string(tok.rawkind))
}
}
for _, tktest := range newTokenInvalidTests {
_, err := newToken([]byte(tktest))
if err == nil {
t.Errorf("expected error with %q, got none", tktest)
}
}
}
func TestParse(t *testing.T) {
r := netrcReader("examples/good.netrc", t)
n, err := Parse(r)
if err != nil {
t.Fatal(err)
}
testExpected(n, t)
}
func TestParseFile(t *testing.T) {
n, err := ParseFile("examples/good.netrc")
if err != nil {
t.Fatal(err)
}
testExpected(n, t)
_, err = ParseFile("examples/bad_default_order.netrc")
if err == nil {
t.Error("expected an error parsing bad_default_order.netrc, got none")
} else if !err.(*Error).BadDefaultOrder() {
t.Error("expected BadDefaultOrder() to be true, got false")
}
_, err = ParseFile("examples/this_file_doesnt_exist.netrc")
if err == nil {
t.Error("expected an error loading this_file_doesnt_exist.netrc, got none")
} else if _, ok := err.(*os.PathError); !ok {
t.Errorf("expected *os.Error, got %v", err)
}
}
func TestFindMachine(t *testing.T) {
m, err := FindMachine("examples/good.netrc", "ray")
if err != nil {
t.Fatal(err)
}
if !eqMachine(m, expectedMachines[1]) {
t.Errorf("bad machine; expected %v, got %v\n", expectedMachines[1], m)
}
if m.IsDefault() {
t.Errorf("expected m.IsDefault() to be false")
}
m, err = FindMachine("examples/good.netrc", "non.existent")
if err != nil {
t.Fatal(err)
}
if !eqMachine(m, expectedMachines[3]) {
t.Errorf("bad machine; expected %v, got %v\n", expectedMachines[3], m)
}
if !m.IsDefault() {
t.Errorf("expected m.IsDefault() to be true")
}
}
func TestNetrcFindMachine(t *testing.T) {
n, err := ParseFile("examples/good.netrc")
if err != nil {
t.Fatal(err)
}
m := n.FindMachine("ray")
if !eqMachine(m, expectedMachines[1]) {
t.Errorf("bad machine; expected %v, got %v\n", expectedMachines[1], m)
}
if m.IsDefault() {
t.Errorf("expected def to be false")
}
n = &Netrc{}
m = n.FindMachine("nonexistent")
if m != nil {
t.Errorf("expected nil, got %v", m)
}
}
func TestMarshalText(t *testing.T) {
// load up expected netrc Marshal output
expected, err := ioutil.ReadAll(netrcReader("examples/good.netrc", t))
if err != nil {
t.Fatal(err)
}
n, err := ParseFile("examples/good.netrc")
if err != nil {
t.Fatal(err)
}
result, err := n.MarshalText()
if err != nil {
t.Fatal(err)
}
if string(result) != string(expected) {
t.Errorf("expected:\n%q\ngot:\n%q", string(expected), string(result))
}
// make sure tokens w/ no value are not serialized
m := n.FindMachine("mail.google.com")
m.UpdatePassword("")
result, err = n.MarshalText()
if err != nil {
t.Fatal(err)
}
if strings.Contains(string(result), "\tpassword \n") {
fmt.Println(string(result))
t.Errorf("expected zero-value password token to not be serialzed")
}
}
var newMachineTests = []struct {
name string
login string
password string
account string
}{
{"heroku.com", "dodging-samurai-42@heroku.com", "octocatdodgeballchampions", "2011+2013"},
{"bgentry.io", "special@test.com", "noacct", ""},
{"github.io", "2@test.com", "", "acctwithnopass"},
{"someotherapi.com", "", "passonly", ""},
}
func TestNewMachine(t *testing.T) {
n, err := ParseFile("examples/good.netrc")
if err != nil {
t.Fatal(err)
}
testNewMachine(t, n)
n = &Netrc{}
testNewMachine(t, n)
// make sure that tokens without a value are not serialized at all
for _, test := range newMachineTests {
n = &Netrc{}
_ = n.NewMachine(test.name, test.login, test.password, test.account)
bodyb, _ := n.MarshalText()
body := string(bodyb)
// ensure desired values are present when they should be
if !strings.Contains(body, "machine") {
t.Errorf("NewMachine() %s missing keyword 'machine'", test.name)
}
if !strings.Contains(body, test.name) {
t.Errorf("NewMachine() %s missing value %q", test.name, test.name)
}
if test.login != "" && !strings.Contains(body, "login "+test.login) {
t.Errorf("NewMachine() %s missing value %q", test.name, "login "+test.login)
}
if test.password != "" && !strings.Contains(body, "password "+test.password) {
t.Errorf("NewMachine() %s missing value %q", test.name, "password "+test.password)
}
if test.account != "" && !strings.Contains(body, "account "+test.account) {
t.Errorf("NewMachine() %s missing value %q", test.name, "account "+test.account)
}
// ensure undesired values are not present when they shouldn't be
if test.login == "" && strings.Contains(body, "login") {
t.Errorf("NewMachine() %s contains unexpected value %q", test.name, "login")
}
if test.password == "" && strings.Contains(body, "password") {
t.Errorf("NewMachine() %s contains unexpected value %q", test.name, "password")
}
if test.account == "" && strings.Contains(body, "account") {
t.Errorf("NewMachine() %s contains unexpected value %q", test.name, "account")
}
}
}
func testNewMachine(t *testing.T, n *Netrc) {
for _, test := range newMachineTests {
mcount := len(n.machines)
// sanity check
bodyb, _ := n.MarshalText()
body := string(bodyb)
for _, value := range []string{test.name, test.login, test.password, test.account} {
if value != "" && strings.Contains(body, value) {
t.Errorf("MarshalText() before NewMachine() contained unexpected %q", value)
}
}
// test prefix for machine token
prefix := "\n"
if len(n.tokens) == 0 {
prefix = ""
}
m := n.NewMachine(test.name, test.login, test.password, test.account)
if m == nil {
t.Fatalf("NewMachine() returned nil")
}
if len(n.machines) != mcount+1 {
t.Errorf("n.machines count expected %d, got %d", mcount+1, len(n.machines))
}
// check values
if m.Name != test.name {
t.Errorf("m.Name expected %q, got %q", test.name, m.Name)
}
if m.Login != test.login {
t.Errorf("m.Login expected %q, got %q", test.login, m.Login)
}
if m.Password != test.password {
t.Errorf("m.Password expected %q, got %q", test.password, m.Password)
}
if m.Account != test.account {
t.Errorf("m.Account expected %q, got %q", test.account, m.Account)
}
// check tokens
checkToken(t, "nametoken", m.nametoken, tkMachine, prefix+"machine", test.name)
checkToken(t, "logintoken", m.logintoken, tkLogin, "\n\tlogin", test.login)
checkToken(t, "passtoken", m.passtoken, tkPassword, "\n\tpassword", test.password)
checkToken(t, "accounttoken", m.accounttoken, tkAccount, "\n\taccount", test.account)
// check marshal output
bodyb, _ = n.MarshalText()
body = string(bodyb)
for _, value := range []string{test.name, test.login, test.password, test.account} {
if !strings.Contains(body, value) {
t.Errorf("MarshalText() after NewMachine() did not include %q as expected", value)
}
}
}
}
func checkToken(t *testing.T, name string, tok *token, kind tkType, rawkind, value string) {
if tok == nil {
t.Errorf("%s not defined", name)
return
}
if tok.kind != kind {
t.Errorf("%s expected kind %d, got %d", name, kind, tok.kind)
}
if string(tok.rawkind) != rawkind {
t.Errorf("%s expected rawkind %q, got %q", name, rawkind, string(tok.rawkind))
}
if tok.value != value {
t.Errorf("%s expected value %q, got %q", name, value, tok.value)
}
if tok.value != value {
t.Errorf("%s expected value %q, got %q", name, value, tok.value)
}
}
func TestNewMachineGoesBeforeDefault(t *testing.T) {
n, err := ParseFile("examples/good.netrc")
if err != nil {
t.Fatal(err)
}
m := n.NewMachine("mymachine", "mylogin", "mypassword", "myaccount")
if m2 := n.machines[len(n.machines)-2]; m2 != m {
t.Errorf("expected machine %v, got %v", m, m2)
}
}
func TestRemoveMachine(t *testing.T) {
n, err := ParseFile("examples/good.netrc")
if err != nil {
t.Fatal(err)
}
tests := []string{"mail.google.com", "weirdlogin"}
for _, name := range tests {
mcount := len(n.machines)
// sanity check
m := n.FindMachine(name)
if m == nil {
t.Fatalf("machine %q not found", name)
}
if m.IsDefault() {
t.Fatalf("expected machine %q, got default instead", name)
}
n.RemoveMachine(name)
if len(n.machines) != mcount-1 {
t.Errorf("n.machines count expected %d, got %d", mcount-1, len(n.machines))
}
// make sure Machine is no longer returned by FindMachine()
if m2 := n.FindMachine(name); m2 != nil && !m2.IsDefault() {
t.Errorf("Machine %q not removed from Machines list", name)
}
// make sure tokens are not present in tokens list
for _, token := range []*token{m.nametoken, m.logintoken, m.passtoken, m.accounttoken} {
if token != nil {
for _, tok2 := range n.tokens {
if tok2 == token {
t.Errorf("token not removed from tokens list: %v", token)
break
}
}
}
}
bodyb, _ := n.MarshalText()
body := string(bodyb)
for _, value := range []string{m.Name, m.Login, m.Password, m.Account} {
if value != "" && strings.Contains(body, value) {
t.Errorf("MarshalText() after RemoveMachine() contained unexpected %q", value)
}
}
}
}
func TestUpdateLogin(t *testing.T) {
n, err := ParseFile("examples/good.netrc")
if err != nil {
t.Fatal(err)
}
tests := []struct {
exists bool
name string
oldlogin string
newlogin string
}{
{true, "mail.google.com", "joe@gmail.com", "joe2@gmail.com"},
{false, "heroku.com", "", "dodging-samurai-42@heroku.com"},
}
bodyb, _ := n.MarshalText()
body := string(bodyb)
for _, test := range tests {
if strings.Contains(body, test.newlogin) {
t.Errorf("MarshalText() before UpdateLogin() contained unexpected %q", test.newlogin)
}
}
for _, test := range tests {
m := n.FindMachine(test.name)
if m.IsDefault() == test.exists {
t.Errorf("expected machine %s to not exist, but it did", test.name)
} else {
if !test.exists {
m = n.NewMachine(test.name, test.newlogin, "", "")
}
if m == nil {
t.Errorf("machine %s was nil", test.name)
continue
}
m.UpdateLogin(test.newlogin)
m := n.FindMachine(test.name)
if m.Login != test.newlogin {
t.Errorf("expected new login %q, got %q", test.newlogin, m.Login)
}
if m.logintoken.value != test.newlogin {
t.Errorf("expected m.logintoken %q, got %q", test.newlogin, m.logintoken.value)
}
}
}
bodyb, _ = n.MarshalText()
body = string(bodyb)
for _, test := range tests {
if test.exists && strings.Contains(body, test.oldlogin) {
t.Errorf("MarshalText() after UpdateLogin() contained unexpected %q", test.oldlogin)
}
if !strings.Contains(body, test.newlogin) {
t.Errorf("MarshalText after UpdatePassword did not contain %q as expected", test.newlogin)
}
}
}
func TestUpdatePassword(t *testing.T) {
n, err := ParseFile("examples/good.netrc")
if err != nil {
t.Fatal(err)
}
tests := []struct {
exists bool
name string
oldpassword string
newpassword string
}{
{true, "ray", "mypassword", "supernewpass"},
{false, "heroku.com", "", "octocatdodgeballchampions"},
}
bodyb, _ := n.MarshalText()
body := string(bodyb)
for _, test := range tests {
if test.exists && !strings.Contains(body, test.oldpassword) {
t.Errorf("MarshalText() before UpdatePassword() did not include %q as expected", test.oldpassword)
}
if strings.Contains(body, test.newpassword) {
t.Errorf("MarshalText() before UpdatePassword() contained unexpected %q", test.newpassword)
}
}
for _, test := range tests {
m := n.FindMachine(test.name)
if m.IsDefault() == test.exists {
t.Errorf("expected machine %s to not exist, but it did", test.name)
} else {
if !test.exists {
m = n.NewMachine(test.name, "", test.newpassword, "")
}
if m == nil {
t.Errorf("machine %s was nil", test.name)
continue
}
m.UpdatePassword(test.newpassword)
m = n.FindMachine(test.name)
if m.Password != test.newpassword {
t.Errorf("expected new password %q, got %q", test.newpassword, m.Password)
}
if m.passtoken.value != test.newpassword {
t.Errorf("expected m.passtoken %q, got %q", test.newpassword, m.passtoken.value)
}
}
}
bodyb, _ = n.MarshalText()
body = string(bodyb)
for _, test := range tests {
if test.exists && strings.Contains(body, test.oldpassword) {
t.Errorf("MarshalText() after UpdatePassword() contained unexpected %q", test.oldpassword)
}
if !strings.Contains(body, test.newpassword) {
t.Errorf("MarshalText() after UpdatePassword() did not contain %q as expected", test.newpassword)
}
}
}
func TestNewFile(t *testing.T) {
var n Netrc
result, err := n.MarshalText()
if err != nil {
t.Fatal(err)
}
if string(result) != "" {
t.Errorf("expected empty result=\"\", got %q", string(result))
}
n.NewMachine("netrctest.heroku.com", "auser", "apassword", "")
result, err = n.MarshalText()
if err != nil {
t.Fatal(err)
}
expected := `machine netrctest.heroku.com
login auser
password apassword`
if string(result) != expected {
t.Errorf("expected result:\n%q\ngot:\n%q", expected, string(result))
}
}
func netrcReader(filename string, t *testing.T) io.Reader {
b, err := ioutil.ReadFile(filename)
if err != nil {
t.Fatal(err)
}
return bytes.NewReader(b)
}