1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.maven.shared.utils.cli.shell;
20
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import org.apache.maven.shared.utils.Os;
25
26 /**
27 * @author Jason van Zyl
28 */
29 public class BourneShell extends Shell {
30
31 /**
32 * Create instance of BourneShell.
33 */
34 public BourneShell() {
35 setUnconditionalQuoting(true);
36 setShellCommand("/bin/sh");
37 setArgumentQuoteDelimiter('\'');
38 setExecutableQuoteDelimiter('\'');
39 setSingleQuotedArgumentEscaped(true);
40 setSingleQuotedExecutableEscaped(false);
41 setQuotedExecutableEnabled(true);
42 }
43
44 /**
45 * {@inheritDoc}
46 */
47 public String getExecutable() {
48 if (Os.isFamily(Os.FAMILY_WINDOWS)) {
49 return super.getExecutable();
50 }
51
52 return quoteOneItem(super.getExecutable(), true);
53 }
54
55 /** {@inheritDoc} */
56 public List<String> getShellArgsList() {
57 List<String> shellArgs = new ArrayList<String>();
58 List<String> existingShellArgs = super.getShellArgsList();
59
60 if ((existingShellArgs != null) && !existingShellArgs.isEmpty()) {
61 shellArgs.addAll(existingShellArgs);
62 }
63
64 shellArgs.add("-c");
65
66 return shellArgs;
67 }
68
69 /** {@inheritDoc} */
70 public String[] getShellArgs() {
71 String[] shellArgs = super.getShellArgs();
72 if (shellArgs == null) {
73 shellArgs = new String[0];
74 }
75
76 if ((shellArgs.length > 0) && !shellArgs[shellArgs.length - 1].equals("-c")) {
77 String[] newArgs = new String[shellArgs.length + 1];
78
79 System.arraycopy(shellArgs, 0, newArgs, 0, shellArgs.length);
80 newArgs[shellArgs.length] = "-c";
81
82 shellArgs = newArgs;
83 }
84
85 return shellArgs;
86 }
87
88 /** {@inheritDoc} */
89 protected String getExecutionPreamble() {
90 if (getWorkingDirectoryAsString() == null) {
91 return null;
92 }
93
94 String dir = getWorkingDirectoryAsString();
95
96 return "cd " + quoteOneItem(dir, false) + " && ";
97 }
98
99 /**
100 * <p>Unify quotes in a path for the Bourne Shell.</p>
101 * <pre>
102 * BourneShell.quoteOneItem(null) = null
103 * BourneShell.quoteOneItem("") = ''
104 * BourneShell.quoteOneItem("/test/quotedpath'abc") = '/test/quotedpath'"'"'abc'
105 * BourneShell.quoteOneItem("/test/quoted path'abc") = '/test/quoted pat'"'"'habc'
106 * BourneShell.quoteOneItem("/test/quotedpath\"abc") = '/test/quotedpath"abc'
107 * BourneShell.quoteOneItem("/test/quoted path\"abc") = '/test/quoted path"abc'
108 * BourneShell.quoteOneItem("/test/quotedpath\"'abc") = '/test/quotedpath"'"'"'abc'
109 * BourneShell.quoteOneItem("/test/quoted path\"'abc") = '/test/quoted path"'"'"'abc'
110 * </pre>
111 *
112 * @param path not null path.
113 * @return the path unified correctly for the Bourne shell.
114 */
115 protected String quoteOneItem(String path, boolean isExecutable) {
116 if (path == null) {
117 return null;
118 }
119
120 return "'" + path.replace("'", "'\"'\"'") + "'";
121 }
122 }