1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.jclouds.scriptbuilder.domain;
20
21 import static com.google.common.base.Preconditions.checkNotNull;
22 import static com.google.common.base.Preconditions.checkState;
23 import static org.jclouds.scriptbuilder.domain.Statements.interpret;
24
25 import java.util.Collections;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Map.Entry;
29 import java.util.regex.Pattern;
30
31 import com.google.common.collect.ImmutableList;
32 import com.google.common.collect.Iterables;
33 import com.google.common.collect.Lists;
34 import com.google.common.collect.Maps;
35
36
37
38
39
40
41 public class AppendFile implements Statement {
42 public static final String MARKER = "END_OF_FILE";
43
44 final String path;
45 final Iterable<String> lines;
46 final String marker;
47
48 public AppendFile(String path, Iterable<String> lines) {
49 this(path, lines, MARKER);
50 }
51
52 public AppendFile(String path, Iterable<String> lines, String marker) {
53 this.path = checkNotNull(path, "path");
54 this.lines = checkNotNull(lines, "lines");
55 this.marker = checkNotNull(marker, "marker");
56 checkState(Iterables.size(lines) > 0, "you must pass something to execute");
57 }
58
59 public static String escapeVarTokens(String toEscape, OsFamily family) {
60 Map<String, String> inputToEscape = Maps.newHashMap();
61 for (ShellToken token : ImmutableList.of(ShellToken.VARL, ShellToken.VARR)) {
62 if (!token.to(family).equals("")) {
63 String tokenS = "{" + token.toString().toLowerCase() + "}";
64 inputToEscape.put(tokenS, "{escvar}" + tokenS);
65 }
66 }
67 for (Entry<String, String> entry : inputToEscape.entrySet()) {
68 toEscape = toEscape.replace(entry.getKey(), entry.getValue());
69 }
70 return toEscape;
71 }
72
73 @Override
74 public Iterable<String> functionDependencies(OsFamily family) {
75 return Collections.emptyList();
76 }
77
78 @Override
79 public String render(OsFamily family) {
80 List<Statement> statements = Lists.newArrayList();
81 if (family == OsFamily.UNIX) {
82 StringBuilder builder = new StringBuilder();
83 hereFile(path, builder);
84 statements.add(interpret(builder.toString()));
85 } else {
86 for (String line : lines) {
87 statements.add(appendToFile(line, path, family));
88 }
89 }
90 return new StatementList(statements).render(family);
91 }
92
93 private void hereFile(String path, StringBuilder builder) {
94 builder.append("cat >> ").append(path).append(" <<'").append(marker).append("'\n");
95 for (String line : lines) {
96 builder.append(line).append("\n");
97 }
98 builder.append(marker).append("\n");
99 }
100
101 private Statement appendToFile(String line, String path, OsFamily family) {
102 String quote = "";
103 if (!ShellToken.VQ.to(family).equals("")) {
104 quote = "'";
105 } else {
106 line = escapeVarTokens(line, family);
107 }
108 return interpret(addSpaceToEnsureWeDontAccidentallyRedirectFd(String.format("echo %s%s%s>>%s{lf}", quote, line,
109 quote, path)));
110 }
111
112 public static final Pattern REDIRECT_FD_PATTERN = Pattern.compile(".*[0-2]>>.*");
113
114 static String addSpaceToEnsureWeDontAccidentallyRedirectFd(String line) {
115 return REDIRECT_FD_PATTERN.matcher(line).matches() ? line.replace(">>", " >>") : line;
116 }
117
118 }