diff --git a/cmd/main.go b/cmd/main.go index 9c781b2..6c9b6dc 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -86,9 +86,27 @@ func main() { Flags: app.Flags, }, { - Name: "fix", + Name: "del", // Usage: "add a task to the list", - Action: hostess.Fix, + Action: hostess.Del, + Flags: app.Flags, + }, + { + Name: "has", + // Usage: "add a task to the list", + Action: hostess.Has, + Flags: app.Flags, + }, + { + Name: "off", + // Usage: "add a task to the list", + Action: hostess.Off, + Flags: app.Flags, + }, + { + Name: "on", + // Usage: "add a task to the list", + Action: hostess.On, Flags: app.Flags, }, { @@ -97,6 +115,24 @@ func main() { Action: hostess.Ls, Flags: app.Flags, }, + { + Name: "fix", + // Usage: "add a task to the list", + Action: hostess.Fix, + Flags: app.Flags, + }, + { + Name: "dump", + // Usage: "add a task to the list", + Action: hostess.Dump, + Flags: app.Flags, + }, + { + Name: "apply", + // Usage: "add a task to the list", + Action: hostess.Apply, + Flags: app.Flags, + }, } // switch flag.Arg(0) { diff --git a/commands.go b/commands.go index 312a31b..aaf1b56 100644 --- a/commands.go +++ b/commands.go @@ -7,34 +7,40 @@ import ( "strings" ) +// MaybeErrorln will print an error message unless -q is passed func MaybeErrorln(c *cli.Context, message string) { if !c.Bool("q") { os.Stderr.WriteString(fmt.Sprintf("%s: %s\n", c.Command.Name, message)) } } +// MaybeError will print an error message unless -q is passed and then exit func MaybeError(c *cli.Context, message string) { MaybeErrorln(c, message) os.Exit(1) } +// MaybePrintln will print a message unless -s is passed func MaybePrintln(c *cli.Context, message string) { if !c.Bool("s") { fmt.Println(message) } } +// MaybeLoadHostFile will try to load, parse, and return a Hostfile. If we +// encounter errors we will terminate, unless -f is passed. func MaybeLoadHostFile(c *cli.Context) *Hostfile { hostsfile, errs := LoadHostFile() if len(errs) > 0 && !c.Bool("f") { for _, err := range errs { MaybeErrorln(c, err.Error()) } - MaybeError(c, "Errors while parsing hostsfile") + MaybeError(c, "Errors while parsing hostsfile. Try using fix -f") } return hostsfile } +// ShowEnabled turns a boolean into a string (On) or (Off) func ShowEnabled(on bool) string { if on { return "(On)" @@ -43,10 +49,13 @@ func ShowEnabled(on bool) string { } } +// ShowHostname turns a Hostname into a string for display func ShowHostname(hostname Hostname) string { return fmt.Sprintf("%s -> %s %s", hostname.Domain, hostname.Ip, ShowEnabled(hostname.Enabled)) } +// StrPadRight adds spaces to the right of a string until it reaches l length. +// If the input string is already that long, do nothing. func StrPadRight(s string, l int) string { return s + strings.Repeat(" ", l-len(s)) } @@ -58,7 +67,11 @@ func Add(c *cli.Context) { hostsfile := MaybeLoadHostFile(c) hostname := Hostname{c.Args()[0], c.Args()[1], true} - err := hostsfile.Add(hostname) + var err error + if !hostsfile.Contains(hostname) { + err = hostsfile.Add(hostname) + } + if err == nil { if c.Bool("n") { fmt.Println(hostsfile.Format()) @@ -71,27 +84,61 @@ func Add(c *cli.Context) { } } -func Del(c *cli.Context) error { - return nil +func Del(c *cli.Context) { + if len(c.Args()) != 1 { + MaybeError(c, "expected ") + } + domain := c.Args()[0] + hostsfile := MaybeLoadHostFile(c) + + found := hostsfile.ContainsDomain(domain) + if found { + hostsfile.Delete(domain) + if c.Bool("n") { + fmt.Println(hostsfile.Format()) + } else { + MaybePrintln(c, fmt.Sprintf("Deleted %s", domain)) + hostsfile.Save() + } + } else { + MaybePrintln(c, fmt.Sprintf("%s not found in %s", domain, GetHostsPath())) + } } -func Has(c *cli.Context) error { - return nil +func Has(c *cli.Context) { + if len(c.Args()) != 1 { + MaybeError(c, "expected ") + } + domain := c.Args()[0] + hostsfile := MaybeLoadHostFile(c) + + found := hostsfile.ContainsDomain(domain) + if found { + MaybePrintln(c, fmt.Sprintf("Found %s in %s", domain, GetHostsPath())) + } else { + MaybeError(c, fmt.Sprintf("%s not found in %s", domain, GetHostsPath())) + } + } -func Off(c *cli.Context) error { - return nil +func Off(c *cli.Context) { + if len(c.Args()) != 1 { + MaybeError(c, "expected ") + } + } -func On(c *cli.Context) error { - return nil +func On(c *cli.Context) { + if len(c.Args()) != 1 { + MaybeError(c, "expected ") + } } func Ls(c *cli.Context) { - hostfile := MaybeLoadHostFile(c) + hostsfile := MaybeLoadHostFile(c) maxdomain := 0 maxip := 0 - for _, hostname := range hostfile.Hosts { + for _, hostname := range hostsfile.Hosts { dlen := len(hostname.Domain) if dlen > maxdomain { maxdomain = dlen @@ -102,8 +149,8 @@ func Ls(c *cli.Context) { } } - for _, domain := range hostfile.ListDomains() { - hostname := hostfile.Hosts[domain] + for _, domain := range hostsfile.ListDomains() { + hostname := hostsfile.Hosts[domain] fmt.Printf("%s -> %s %s\n", StrPadRight(hostname.Domain, maxdomain), StrPadRight(hostname.Ip, maxip), @@ -121,18 +168,18 @@ whitespace and comments will be removed. ` func Fix(c *cli.Context) { - hostfile := MaybeLoadHostFile(c) + hostsfile := MaybeLoadHostFile(c) if c.Bool("n") { - fmt.Println(hostfile.Format()) + fmt.Println(hostsfile.Format()) } else { - hostfile.Save() + hostsfile.Save() } } -func Dump(c *cli.Context) error { - return nil +func Dump(c *cli.Context) { + } -func Apply(c *cli.Context) error { - return nil +func Apply(c *cli.Context) { + } diff --git a/hostess.go b/hostess.go index 28eb39f..ecb5427 100644 --- a/hostess.go +++ b/hostess.go @@ -137,6 +137,13 @@ func (h *Hostname) Format() string { return r } +func (a *Hostname) Equals(b Hostname) bool { + if a.Domain == b.Domain && a.Ip == b.Ip { + return true + } + return false +} + // Hostfile represents /etc/hosts (or a similar file, depending on OS), and // includes a list of Hostnames. Hostfile includes type Hostfile struct { @@ -319,6 +326,24 @@ func (h *Hostfile) Save() error { return nil } +func (h *Hostfile) Contains(b Hostname) bool { + for _, a := range h.Hosts { + if a.Equals(b) { + return true + } + } + return false +} + +func (h *Hostfile) ContainsDomain(search string) bool { + for _, hostname := range h.Hosts { + if hostname.Domain == search { + return true + } + } + return false +} + func (h *Hostfile) Add(host Hostname) error { host_f, found := h.Hosts[host.Domain] if found {