diff --git a/netrc/examples/good.netrc b/netrc/examples/good.netrc index 48bc4cf..41a8e5b 100644 --- a/netrc/examples/good.netrc +++ b/netrc/examples/good.netrc @@ -1,7 +1,7 @@ # I am a comment machine mail.google.com login joe@gmail.com - account gmail #end of line comment with trailing space + account justagmail #end of line comment with trailing space password somethingSecret # I am another comment diff --git a/netrc/netrc.go b/netrc/netrc.go index ceafc8c..0471f17 100644 --- a/netrc/netrc.go +++ b/netrc/netrc.go @@ -149,6 +149,35 @@ func (n *Netrc) insertMachineTokensBeforeDefault(m *Machine) { 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 diff --git a/netrc/netrc_test.go b/netrc/netrc_test.go index a1351c3..fe077d1 100644 --- a/netrc/netrc_test.go +++ b/netrc/netrc_test.go @@ -325,6 +325,57 @@ func TestNewMachineGoesBeforeDefault(t *testing.T) { } } +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 {