-
-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
big module refactor, with 95 new tests! 🎉 * [x] Add a decent amount code coverage of all files in `pkg` directory. * [x] Refactor `pkg` code to expose a better API to use as module. * [x] Change semantics to have profiles as arguments instead of flag. #37 * [x] Allow to manage multiple profiles at once. Ex: `hostctl disable profile1 profile2... ` * [x] Add mutex to save file to avoid concurrency issues. Fixes #37 Fixes #39 Closes #47 Related to #45
- Loading branch information
Showing
76 changed files
with
3,189 additions
and
1,352 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,4 @@ hostctl | |
hostctl.exe | ||
.etchosts | ||
docs/public | ||
coverage.out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,50 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/guumaster/hostctl/pkg/host" | ||
) | ||
|
||
// addDomainsCmd represents the fromFile command | ||
var addDomainsCmd = &cobra.Command{ | ||
Use: "domains", | ||
Short: "Add content in your hosts file.", | ||
Use: "domains [domains] [flag]", | ||
Aliases: []string{"domain"}, | ||
Short: "Add content in your hosts file.", | ||
Long: ` | ||
Set content in your hosts file. | ||
If the profile already exists it will be added to it.`, | ||
PreRunE: func(cmd *cobra.Command, args []string) error { | ||
profile, _ := cmd.Flags().GetString("profile") | ||
|
||
if profile == "" { | ||
return host.MissingProfileError | ||
} | ||
|
||
if profile == "default" { | ||
return host.DefaultProfileError | ||
} | ||
return nil | ||
}, | ||
Args: commonCheckProfileOnly, | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
src, _ := cmd.Flags().GetString("host-file") | ||
ip, _ := cmd.Flags().GetString("ip") | ||
profile, _ := cmd.Flags().GetString("profile") | ||
quiet, _ := cmd.Flags().GetBool("quiet") | ||
name := args[0] | ||
routes := args[1:] | ||
|
||
h, err := host.NewFile(src) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err := host.AddFromArgs(&host.AddFromArgsOptions{ | ||
Domains: args, | ||
IP: ip, | ||
Dst: src, | ||
Profile: profile, | ||
Reset: false, | ||
}) | ||
err = h.AddRoutes(name, ip, routes) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return host.Enable(src, profile) | ||
err = h.Flush() | ||
if err != nil { | ||
return err | ||
} | ||
if !quiet { | ||
fmt.Fprintf(cmd.OutOrStdout(), "Domains '%s' added.\n\n", strings.Join(args[1:], ", ")) | ||
} | ||
return nil | ||
}, | ||
PostRunE: func(cmd *cobra.Command, args []string) error { | ||
return postActionCmd(cmd, args, removeDomainsCmd) | ||
return postActionCmd(cmd, args, removeDomainsCmd, true) | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package cmd | ||
|
||
import ( | ||
"bytes" | ||
"io/ioutil" | ||
"os" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func Test_AddDomains(t *testing.T) { | ||
cmd := rootCmd | ||
|
||
t.Run("Add domains", func(t *testing.T) { | ||
tmp := makeTempHostsFile(t, "addDomainCmd") | ||
defer os.Remove(tmp.Name()) | ||
b := bytes.NewBufferString("") | ||
|
||
cmd.SetOut(b) | ||
cmd.SetArgs([]string{"add", "domains", "profile1", "arg.domain.loc", "--host-file", tmp.Name()}) | ||
|
||
err := cmd.Execute() | ||
assert.NoError(t, err) | ||
|
||
out, err := ioutil.ReadAll(b) | ||
assert.NoError(t, err) | ||
|
||
actual := "\n" + string(out) | ||
expected := ` | ||
+----------+--------+-----------+----------------+ | ||
| PROFILE | STATUS | IP | DOMAIN | | ||
+----------+--------+-----------+----------------+ | ||
| profile1 | on | 127.0.0.1 | first.loc | | ||
| profile1 | on | 127.0.0.1 | second.loc | | ||
| profile1 | on | 127.0.0.1 | arg.domain.loc | | ||
+----------+--------+-----------+----------------+ | ||
` | ||
assert.Contains(t, actual, expected) | ||
}) | ||
|
||
t.Run("Add domains with IP", func(t *testing.T) { | ||
tmp := makeTempHostsFile(t, "addDomainCmd") | ||
defer os.Remove(tmp.Name()) | ||
b := bytes.NewBufferString("") | ||
|
||
cmd.SetOut(b) | ||
cmd.SetArgs([]string{"add", "domains", "profile1", "--ip", "5.5.5.5", "arg2.domain.loc", "--host-file", tmp.Name()}) | ||
|
||
err := cmd.Execute() | ||
assert.NoError(t, err) | ||
|
||
out, err := ioutil.ReadAll(b) | ||
assert.NoError(t, err) | ||
|
||
actual := "\n" + string(out) | ||
expected := ` | ||
+----------+--------+-----------+-----------------+ | ||
| PROFILE | STATUS | IP | DOMAIN | | ||
+----------+--------+-----------+-----------------+ | ||
| profile1 | on | 127.0.0.1 | first.loc | | ||
| profile1 | on | 127.0.0.1 | second.loc | | ||
| profile1 | on | 5.5.5.5 | arg2.domain.loc | | ||
+----------+--------+-----------+-----------------+ | ||
` | ||
assert.Contains(t, actual, expected) | ||
}) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package cmd | ||
|
||
import ( | ||
"io" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/guumaster/hostctl/pkg/host" | ||
) | ||
|
||
// addCmd represents the fromFile command | ||
var addCmd = &cobra.Command{ | ||
Use: "add-to [profile] [flags]", | ||
Aliases: []string{"add"}, | ||
Short: "Add content to a profile in your hosts file.", | ||
Long: ` | ||
Reads from a file and set content to a profile in your hosts file. | ||
If the profile already exists it will be added to it.`, | ||
Args: commonCheckArgs, | ||
RunE: makeAddReplace("add"), | ||
PostRunE: func(cmd *cobra.Command, args []string) error { | ||
return postActionCmd(cmd, args, removeCmd, true) | ||
}, | ||
} | ||
|
||
// replaceCmd represents the setFromFile command | ||
var replaceCmd = &cobra.Command{ | ||
Use: "replace [profile] [domains] [flags]", | ||
Aliases: []string{"set"}, | ||
Short: "Replace content to a profile in your hosts file.", | ||
Long: ` | ||
Reads from a file and set content to a profile in your hosts file. | ||
If the profile already exists it will be overwritten. | ||
`, | ||
Args: commonCheckArgs, | ||
RunE: makeAddReplace("replace"), | ||
PostRunE: postRunListOnly, | ||
} | ||
|
||
func init() { | ||
|
||
addCmd.Flags().StringP("from", "f", "", "file to read") | ||
addCmd.PersistentFlags().DurationP("wait", "w", -1, "Enables a profile for a specific amount of time") | ||
rootCmd.AddCommand(addCmd) | ||
|
||
replaceCmd.Flags().StringP("from", "f", "", "file to read") | ||
rootCmd.AddCommand(replaceCmd) | ||
|
||
addDomainsCmd.Flags().String("ip", "127.0.0.1", "domains ip") | ||
addCmd.AddCommand(addDomainsCmd) | ||
|
||
} | ||
|
||
func makeAddReplace(action string) func(cmd *cobra.Command, profiles []string) error { | ||
actionFn := func(h *host.File, p *host.Profile) error { | ||
return h.AddProfile(*p) | ||
} | ||
if action == "replace" { | ||
actionFn = func(h *host.File, p *host.Profile) error { | ||
return h.ReplaceProfile(*p) | ||
} | ||
} | ||
|
||
return func(cmd *cobra.Command, profiles []string) error { | ||
src, _ := cmd.Flags().GetString("host-file") | ||
from, _ := cmd.Flags().GetString("from") | ||
|
||
in := cmd.InOrStdin() | ||
|
||
var r io.Reader | ||
var err error | ||
if isPiped() || in != os.Stdin { | ||
r = in | ||
} else { | ||
r, err = os.Open(from) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
p, err := host.NewProfileFromReader(r) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
h, err := host.NewFile(src) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
p.Name = profiles[0] | ||
p.Status = host.Enabled | ||
|
||
err = actionFn(h, p) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return h.Flush() | ||
} | ||
|
||
} |
Oops, something went wrong.