Commit 60280bbf authored by Igor Drozdov's avatar Igor Drozdov

Pass readWriter to Command constructor

parent 58d8c769
......@@ -29,7 +29,7 @@ func findRootDir() (string, error) {
func execRuby(rootDir string, readWriter *readwriter.ReadWriter) {
cmd := &fallback.Command{RootDir: rootDir, Args: os.Args}
if err := cmd.Execute(readWriter); err != nil {
if err := cmd.Execute(); err != nil {
fmt.Fprintf(readWriter.ErrOut, "Failed to exec: %v\n", err)
os.Exit(1)
}
......@@ -56,7 +56,7 @@ func main() {
execRuby(rootDir, readWriter)
}
cmd, err := command.New(os.Args, config)
cmd, err := command.New(os.Args, config, readWriter)
if err != nil {
// For now this could happen if `SSH_CONNECTION` is not set on
// the environment
......@@ -66,7 +66,7 @@ func main() {
// The command will write to STDOUT on execution or replace the current
// process in case of the `fallback.Command`
if err = cmd.Execute(readWriter); err != nil {
if err = cmd.Execute(); err != nil {
fmt.Fprintf(readWriter.ErrOut, "%v\n", err)
os.Exit(1)
}
......
......@@ -10,10 +10,10 @@ import (
)
type Command interface {
Execute(*readwriter.ReadWriter) error
Execute() error
}
func New(arguments []string, config *config.Config) (Command, error) {
func New(arguments []string, config *config.Config, readWriter *readwriter.ReadWriter) (Command, error) {
args, err := commandargs.Parse(arguments)
if err != nil {
......@@ -21,18 +21,18 @@ func New(arguments []string, config *config.Config) (Command, error) {
}
if config.FeatureEnabled(string(args.CommandType)) {
return buildCommand(args, config), nil
return buildCommand(args, config, readWriter), nil
}
return &fallback.Command{RootDir: config.RootDir, Args: arguments}, nil
}
func buildCommand(args *commandargs.CommandArgs, config *config.Config) Command {
func buildCommand(args *commandargs.CommandArgs, config *config.Config, readWriter *readwriter.ReadWriter) Command {
switch args.CommandType {
case commandargs.Discover:
return &discover.Command{Config: config, Args: args}
return &discover.Command{Config: config, Args: args, ReadWriter: readWriter}
case commandargs.TwoFactorRecover:
return &twofactorrecover.Command{Config: config, Args: args}
return &twofactorrecover.Command{Config: config, Args: args, ReadWriter: readWriter}
}
return nil
......
......@@ -65,7 +65,7 @@ func TestNew(t *testing.T) {
restoreEnv := testhelper.TempEnv(tc.environment)
defer restoreEnv()
command, err := New(tc.arguments, tc.config)
command, err := New(tc.arguments, tc.config, nil)
assert.NoError(t, err)
assert.IsType(t, tc.expectedType, command)
......@@ -78,7 +78,7 @@ func TestFailingNew(t *testing.T) {
restoreEnv := testhelper.TempEnv(map[string]string{})
defer restoreEnv()
_, err := New([]string{}, &config.Config{})
_, err := New([]string{}, &config.Config{}, nil)
assert.Error(t, err, "Only ssh allowed")
})
......
......@@ -12,18 +12,19 @@ import (
type Command struct {
Config *config.Config
Args *commandargs.CommandArgs
ReadWriter *readwriter.ReadWriter
}
func (c *Command) Execute(readWriter *readwriter.ReadWriter) error {
func (c *Command) Execute() error {
response, err := c.getUserInfo()
if err != nil {
return fmt.Errorf("Failed to get username: %v", err)
}
if response.IsAnonymous() {
fmt.Fprintf(readWriter.Out, "Welcome to GitLab, Anonymous!\n")
fmt.Fprintf(c.ReadWriter.Out, "Welcome to GitLab, Anonymous!\n")
} else {
fmt.Fprintf(readWriter.Out, "Welcome to GitLab, @%s!\n", response.Username)
fmt.Fprintf(c.ReadWriter.Out, "Welcome to GitLab, @%s!\n", response.Username)
}
return nil
......
......@@ -78,10 +78,14 @@ func TestExecute(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
cmd := &Command{Config: &config.Config{GitlabUrl: url}, Args: tc.arguments}
buffer := &bytes.Buffer{}
cmd := &Command{
Config: &config.Config{GitlabUrl: url},
Args: tc.arguments,
ReadWriter: &readwriter.ReadWriter{Out: buffer},
}
err := cmd.Execute(&readwriter.ReadWriter{Out: buffer})
err := cmd.Execute()
assert.NoError(t, err)
assert.Equal(t, tc.expectedOutput, buffer.String())
......@@ -118,10 +122,14 @@ func TestFailingExecute(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
cmd := &Command{Config: &config.Config{GitlabUrl: url}, Args: tc.arguments}
buffer := &bytes.Buffer{}
cmd := &Command{
Config: &config.Config{GitlabUrl: url},
Args: tc.arguments,
ReadWriter: &readwriter.ReadWriter{Out: buffer},
}
err := cmd.Execute(&readwriter.ReadWriter{Out: buffer})
err := cmd.Execute()
assert.Empty(t, buffer.String())
assert.EqualError(t, err, tc.expectedError)
......
......@@ -4,8 +4,6 @@ import (
"os"
"path/filepath"
"syscall"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/command/readwriter"
)
type Command struct {
......@@ -22,7 +20,7 @@ const (
RubyProgram = "gitlab-shell-ruby"
)
func (c *Command) Execute(*readwriter.ReadWriter) error {
func (c *Command) Execute() error {
rubyCmd := filepath.Join(c.RootDir, "bin", RubyProgram)
// Ensure rubyArgs[0] is the full path to gitlab-shell-ruby
......
......@@ -49,7 +49,7 @@ func TestExecuteExecsCommandSuccesfully(t *testing.T) {
fake.Setup()
defer fake.Cleanup()
require.NoError(t, cmd.Execute(nil))
require.NoError(t, cmd.Execute())
require.True(t, fake.Called)
require.Equal(t, fake.Filename, "/tmp/bin/gitlab-shell-ruby")
require.Equal(t, fake.Args, []string{"/tmp/bin/gitlab-shell-ruby", "foo", "bar"})
......@@ -64,12 +64,12 @@ func TestExecuteExecsCommandOnError(t *testing.T) {
fake.Setup()
defer fake.Cleanup()
require.Error(t, cmd.Execute(nil))
require.Error(t, cmd.Execute())
require.True(t, fake.Called)
}
func TestExecuteGivenNonexistentCommand(t *testing.T) {
cmd := &Command{RootDir: "/tmp/does/not/exist", Args: fakeArgs}
require.Error(t, cmd.Execute(nil))
require.Error(t, cmd.Execute())
}
......@@ -13,31 +13,32 @@ import (
type Command struct {
Config *config.Config
Args *commandargs.CommandArgs
ReadWriter *readwriter.ReadWriter
}
func (c *Command) Execute(readWriter *readwriter.ReadWriter) error {
if c.canContinue(readWriter) {
c.displayRecoveryCodes(readWriter)
func (c *Command) Execute() error {
if c.canContinue() {
c.displayRecoveryCodes()
} else {
fmt.Fprintln(readWriter.Out, "\nNew recovery codes have *not* been generated. Existing codes will remain valid.")
fmt.Fprintln(c.ReadWriter.Out, "\nNew recovery codes have *not* been generated. Existing codes will remain valid.")
}
return nil
}
func (c *Command) canContinue(readWriter *readwriter.ReadWriter) bool {
func (c *Command) canContinue() bool {
question :=
"Are you sure you want to generate new two-factor recovery codes?\n" +
"Any existing recovery codes you saved will be invalidated. (yes/no)"
fmt.Fprintln(readWriter.Out, question)
fmt.Fprintln(c.ReadWriter.Out, question)
var answer string
fmt.Fscanln(readWriter.In, &answer)
fmt.Fscanln(c.ReadWriter.In, &answer)
return answer == "yes"
}
func (c *Command) displayRecoveryCodes(readWriter *readwriter.ReadWriter) {
func (c *Command) displayRecoveryCodes() {
codes, err := c.getRecoveryCodes()
if err == nil {
......@@ -47,9 +48,9 @@ func (c *Command) displayRecoveryCodes(readWriter *readwriter.ReadWriter) {
"\n\nDuring sign in, use one of the codes above when prompted for\n" +
"your two-factor code. Then, visit your Profile Settings and add\n" +
"a new device so you do not lose access to your account again.\n"
fmt.Fprint(readWriter.Out, messageWithCodes)
fmt.Fprint(c.ReadWriter.Out, messageWithCodes)
} else {
fmt.Fprintf(readWriter.Out, "\nAn error occurred while trying to generate new recovery codes.\n%v\n", err)
fmt.Fprintf(c.ReadWriter.Out, "\nAn error occurred while trying to generate new recovery codes.\n%v\n", err)
}
}
......
......@@ -122,9 +122,13 @@ func TestExecute(t *testing.T) {
output := &bytes.Buffer{}
input := bytes.NewBufferString(tc.answer)
cmd := &Command{Config: &config.Config{GitlabUrl: url}, Args: tc.arguments}
cmd := &Command{
Config: &config.Config{GitlabUrl: url},
Args: tc.arguments,
ReadWriter: &readwriter.ReadWriter{Out: output, In: input},
}
err := cmd.Execute(&readwriter.ReadWriter{Out: output, In: input})
err := cmd.Execute()
assert.NoError(t, err)
assert.Equal(t, tc.expectedOutput, output.String())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment