shellSplit splits a string like a shell would, respecting quotes Similar to Ruby's Shellwords.shellsplit
(input string)
| 114 | // shellSplit splits a string like a shell would, respecting quotes |
| 115 | // Similar to Ruby's Shellwords.shellsplit |
| 116 | func shellSplit(input string) ([]string, error) { |
| 117 | var tokens []string |
| 118 | var current strings.Builder |
| 119 | var inSingleQuote, inDoubleQuote bool |
| 120 | var escaped bool |
| 121 | |
| 122 | for _, r := range input { |
| 123 | // Handle escape sequences |
| 124 | if escaped { |
| 125 | current.WriteRune(r) |
| 126 | escaped = false |
| 127 | continue |
| 128 | } |
| 129 | |
| 130 | if r == '\\' { |
| 131 | escaped = true |
| 132 | continue |
| 133 | } |
| 134 | |
| 135 | // Handle quotes |
| 136 | if r == '\'' && !inDoubleQuote { |
| 137 | inSingleQuote = !inSingleQuote |
| 138 | continue |
| 139 | } |
| 140 | |
| 141 | if r == '"' && !inSingleQuote { |
| 142 | inDoubleQuote = !inDoubleQuote |
| 143 | continue |
| 144 | } |
| 145 | |
| 146 | // Handle spaces (word separators when not quoted) |
| 147 | if unicode.IsSpace(r) && !inSingleQuote && !inDoubleQuote { |
| 148 | if current.Len() > 0 { |
| 149 | tokens = append(tokens, current.String()) |
| 150 | current.Reset() |
| 151 | } |
| 152 | continue |
| 153 | } |
| 154 | |
| 155 | // Regular character |
| 156 | current.WriteRune(r) |
| 157 | } |
| 158 | |
| 159 | // Add last token if exists |
| 160 | if current.Len() > 0 { |
| 161 | tokens = append(tokens, current.String()) |
| 162 | } |
| 163 | |
| 164 | // Check for unclosed quotes |
| 165 | if inSingleQuote || inDoubleQuote { |
| 166 | return nil, fmt.Errorf("unclosed quote in string: %s", input) |
| 167 | } |
| 168 | |
| 169 | return tokens, nil |
| 170 | } |
| 171 | |
| 172 | // rubyStyleEscape escapes a Java option exactly like the Ruby buildpack |
| 173 | // |
no test coverage detected