blob: 8636fafa56f266c98ba1264fb13e4521b9665b5b [file] [log] [blame]
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.scriptbuilder.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.scriptbuilder.domain.Statements.interpret;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* Creates a run script
*
* @author Adrian Cole
*/
public class CreateFile implements Statement {
public static final String MARKER = "END_OF_FILE";
final String path;
final Iterable<String> lines;
final String marker;
public CreateFile(String path, Iterable<String> lines) {
this(path, lines, MARKER);
}
public CreateFile(String path, Iterable<String> lines, String marker) {
this.path = checkNotNull(path, "path");
this.lines = checkNotNull(lines, "lines");
this.marker = checkNotNull(marker, "marker");
checkState(Iterables.size(lines) > 0, "you must pass something to execute");
}
public static String escapeVarTokens(String toEscape, OsFamily family) {
Map<String, String> inputToEscape = Maps.newHashMap();
for (ShellToken token : ImmutableList.of(ShellToken.VARL, ShellToken.VARR)) {
if (!token.to(family).equals("")) {
String tokenS = "{" + token.toString().toLowerCase() + "}";
inputToEscape.put(tokenS, "{escvar}" + tokenS);
}
}
for (Entry<String, String> entry : inputToEscape.entrySet()) {
toEscape = toEscape.replace(entry.getKey(), entry.getValue());
}
return toEscape;
}
@Override
public Iterable<String> functionDependencies(OsFamily family) {
return Collections.emptyList();
}
@Override
public String render(OsFamily family) {
List<Statement> statements = Lists.newArrayList();
if (family == OsFamily.UNIX) {
StringBuilder builder = new StringBuilder();
hereFile(path, builder);
statements.add(interpret(builder.toString()));
} else {
for (String line : lines) {
statements.add(appendToFile(line, path, family));
}
}
return new StatementList(statements).render(family);
}
private void hereFile(String path, StringBuilder builder) {
builder.append("cat > ").append(path).append(" <<'").append(marker).append("'\n");
for (String line : lines) {
builder.append(line).append("\n");
}
builder.append(marker).append("\n");
}
private Statement appendToFile(String line, String path, OsFamily family) {
String quote = "";
if (!ShellToken.VQ.to(family).equals("")) {
quote = "'";
} else {
line = escapeVarTokens(line, family);
}
return interpret(addSpaceToEnsureWeDontAccidentallyRedirectFd(String.format("echo %s%s%s>>%s{lf}", quote, line,
quote, path)));
}
public static final Pattern REDIRECT_FD_PATTERN = Pattern.compile(".*[0-2]>>.*");
static String addSpaceToEnsureWeDontAccidentallyRedirectFd(String line) {
return REDIRECT_FD_PATTERN.matcher(line).matches() ? line.replace(">>", " >>") : line;
}
}