From 30577a4c4d1dda97edcc93391a71f54c5599c54e Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Tue, 5 Mar 2019 16:16:16 -0500 Subject: [PATCH] Support dirs with spaces. Allow running atlantis plan -d "dir with spaces" to target a directory that contains spaces. Fixes #423 --- server/events/comment_parser.go | 24 ++++++++++++++++-------- server/events/comment_parser_test.go | 17 ++++++++++++++++- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/server/events/comment_parser.go b/server/events/comment_parser.go index 6845e20d87..58b018878f 100644 --- a/server/events/comment_parser.go +++ b/server/events/comment_parser.go @@ -15,6 +15,7 @@ package events import ( "fmt" + "github.com/flynn-archive/go-shlex" "io/ioutil" "net/url" "path/filepath" @@ -103,9 +104,10 @@ func (e *CommentParser) Parse(comment string, vcsHost models.VCSHostType) Commen return CommentParseResult{Ignore: true} } - // strings.Fields strips out newlines but that's okay since we've removed - // multiline strings above. - args := strings.Fields(comment) + args, err := shlex.Split(comment) + if err != nil { + return CommentParseResult{CommentResponse: fmt.Sprintf("```\nError parsing command: %s\n```", err)} + } if len(args) < 1 { return CommentParseResult{Ignore: true} } @@ -178,7 +180,7 @@ func (e *CommentParser) Parse(comment string, vcsHost models.VCSHostType) Commen // Now parse the flags. // It's safe to use [2:] because we know there's at least 2 elements in args. - err := flagSet.Parse(args[2:]) + err = flagSet.Parse(args[2:]) if err == pflag.ErrHelp { return CommentParseResult{CommentResponse: fmt.Sprintf("```\nUsage of %s:\n%s\n```", command, flagSet.FlagUsagesWrapped(usagesCols))} } @@ -256,22 +258,28 @@ func (e *CommentParser) BuildApplyComment(repoRelDir string, workspace string, p } func (e *CommentParser) buildFlags(repoRelDir string, workspace string, project string) string { + // Add quotes if dir has spaces. + if strings.Contains(repoRelDir, " ") { + repoRelDir = fmt.Sprintf("%q", repoRelDir) + } + switch { // If project is specified we can just use its name. case project != "": return fmt.Sprintf(" -%s %s", projectFlagShort, project) + case repoRelDir == DefaultRepoRelDir && workspace == DefaultWorkspace: // If it's the root and default workspace then we just need to specify one // of the flags and the other will get defaulted. - case repoRelDir == DefaultRepoRelDir && workspace == DefaultWorkspace: return fmt.Sprintf(" -%s %s", dirFlagShort, DefaultRepoRelDir) - // If dir is the default then we just need to specify workspace. case repoRelDir == DefaultRepoRelDir: + // If dir is the default then we just need to specify workspace. return fmt.Sprintf(" -%s %s", workspaceFlagShort, workspace) - // If workspace is the default then we just need to specify the dir. case workspace == DefaultWorkspace: + // If workspace is the default then we just need to specify the dir. + return fmt.Sprintf(" -%s %s", dirFlagShort, repoRelDir) - // Otherwise we have to specify both flags. default: + // Otherwise we have to specify both flags. return fmt.Sprintf(" -%s %s -%s %s", dirFlagShort, repoRelDir, workspaceFlagShort, workspace) } } diff --git a/server/events/comment_parser_test.go b/server/events/comment_parser_test.go index 493be6bd0e..4913a7fbc5 100644 --- a/server/events/comment_parser_test.go +++ b/server/events/comment_parser_test.go @@ -445,7 +445,7 @@ func TestParse_Parsing(t *testing.T) { "", "", false, - `"\";echo" "\"hi"`, + `";echo hi"`, "", }, { @@ -514,6 +514,14 @@ func TestParse_Parsing(t *testing.T) { "", "", }, + { + "-d \"dir with space\"", + "", + "dir with space", + false, + "", + "", + }, } for _, test := range cases { for _, cmdName := range []string{"plan", "apply"} { @@ -610,6 +618,13 @@ func TestBuildPlanApplyComment(t *testing.T) { expPlanFlags: "-d dir -w workspace -- arg1 arg2 arg3", expApplyFlags: "-d dir -w workspace", }, + { + repoRelDir: "dir with spaces", + workspace: "default", + project: "", + expPlanFlags: "-d \"dir with spaces\"", + expApplyFlags: "-d \"dir with spaces\"", + }, } for _, c := range cases {