BuildScript
This commit is contained in:
@@ -16,6 +16,14 @@
|
||||
<version>${asys.version}</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.groupId}.${project.artifactId}-${project.version}</finalName>
|
||||
<plugins>
|
||||
|
||||
268
core/src/main/java/asys/core/buildscript/BuildScript.java
Normal file
268
core/src/main/java/asys/core/buildscript/BuildScript.java
Normal file
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* DmitriyMX <mail@dmitriymx.ru>
|
||||
* 2016-06-23
|
||||
*/
|
||||
package asys.core.buildscript;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
/**
|
||||
* Скрипт формирования окружения игрового сервера.<br><br>
|
||||
*
|
||||
* Команды:<br>
|
||||
* - <code>lnk [источник] [цель]</code> - создание ссылки;<br>
|
||||
* - <code>copy [источник] [цель]</code> - копирование;<br>
|
||||
* - <code>mkdir [путь]</code> - создание папки или древа папок;<br>
|
||||
* - <code>unpack [архив] [папка]</code> - распаковка архива в указанную папку;<br>
|
||||
* - <code>undoparent</code> - отменить запланированные действия вышестоящего скрипта.
|
||||
*/
|
||||
public class BuildScript {
|
||||
private Logger logger = LoggerFactory.getLogger(BuildScript.class);
|
||||
List<String[]> scriptLines = new ArrayList<>();
|
||||
private Map<String, String> variables;
|
||||
|
||||
public BuildScript(String script) throws UnknowCommandException {
|
||||
if (script == null || script.trim().isEmpty()) {
|
||||
logger.warn("Empty script!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (script.contains("\r\n")) {
|
||||
logger.warn("Finded CRLF! Replaced...");
|
||||
script = script.replaceAll("\r\n", "\n");
|
||||
}
|
||||
|
||||
for (String line : script.split("\n")) {
|
||||
scriptLines.add(parseCommandLine(line));
|
||||
}
|
||||
}
|
||||
|
||||
public void setVariables(Map<String, String> variables) {
|
||||
this.variables = variables;
|
||||
}
|
||||
|
||||
private String[] parseCommandLine(String line) throws UnknowCommandException {
|
||||
final StringTokenizer strTok = new StringTokenizer(line, " \"\'", true);
|
||||
final List<String> preArr = new ArrayList<>();
|
||||
byte state = 0; // 0-normal, 1-quoting1, 2-quoting2
|
||||
String buff = "";
|
||||
boolean foundCmd = false;
|
||||
|
||||
while (strTok.hasMoreTokens()) {
|
||||
String partLine = strTok.nextToken();
|
||||
|
||||
if (!foundCmd) {
|
||||
switch (partLine) {
|
||||
case "lnk":
|
||||
case "copy":
|
||||
case "mkdir":
|
||||
case "unpack":
|
||||
case "undoparent":
|
||||
foundCmd = true; // cmd correct;
|
||||
partLine = partLine.toLowerCase();
|
||||
break;
|
||||
default:
|
||||
foundCmd = false; // cmd correct;
|
||||
}
|
||||
|
||||
if (!foundCmd) {
|
||||
throw new UnknowCommandException(partLine);
|
||||
}
|
||||
}
|
||||
|
||||
if (partLine.equals("\"")) {
|
||||
if (state == 0) {
|
||||
state = 1;
|
||||
continue;
|
||||
} else if (state == 1){
|
||||
state = 0;
|
||||
preArr.add(buff);
|
||||
buff = "";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (partLine.equals("\'")) {
|
||||
if (state == 0) {
|
||||
state = 2;
|
||||
continue;
|
||||
} else if (state == 2){
|
||||
state = 0;
|
||||
preArr.add(buff);
|
||||
buff = "";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (state == 1 || state == 2) {
|
||||
buff += partLine;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (partLine.equals(" ")) continue;
|
||||
|
||||
preArr.add(partLine);
|
||||
}
|
||||
|
||||
return preArr.toArray(new String[preArr.size()]);
|
||||
}
|
||||
|
||||
public void execute() throws CommandException {
|
||||
for (String[] cmdline : scriptLines) {
|
||||
switch (cmdline[0]) {
|
||||
case "lnk": cmd_lnk(cmdline[1], cmdline[2]); break;
|
||||
case "copy": cmd_copy(cmdline[1], cmdline[2]); break;
|
||||
case "mkdir": cmd_mkdir(cmdline[1]); break;
|
||||
case "unpack": cmd_unpack(cmdline[1], cmdline[2]); break;
|
||||
case "undoparent": cmd_undo(); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String applyVariables(String string) {
|
||||
if (variables != null && !variables.isEmpty()) {
|
||||
for (Map.Entry<String, String> entry : variables.entrySet()) {
|
||||
string = string.replace("%"+entry.getKey()+"%", entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
/* Создание символьной ссылки */
|
||||
private void cmd_lnk(String source, String target) throws CommandException {
|
||||
try {
|
||||
Files.createSymbolicLink(
|
||||
Paths.get(applyVariables(target)),
|
||||
Paths.get(applyVariables(source)));
|
||||
} catch (IOException e) {
|
||||
throw new CommandException("LNK", e);
|
||||
}
|
||||
}
|
||||
|
||||
/* Коирование */
|
||||
private void cmd_copy(String source, String target) throws CommandException {
|
||||
//TODO надо изюавиться от излишних Path.toFile()
|
||||
Path sourcePath = Paths.get(applyVariables(source));
|
||||
if (!sourcePath.toFile().exists()) {
|
||||
throw new CommandException(String.format("COPY: source not found %s [%s]", source, sourcePath.toAbsolutePath()));
|
||||
}
|
||||
|
||||
Path targetPath = Paths.get(applyVariables(target));
|
||||
if (!targetPath.toFile().exists()) {
|
||||
if (sourcePath.toFile().isDirectory()) {
|
||||
try {
|
||||
FileUtils.copyDirectory(sourcePath.toFile(), targetPath.toFile());
|
||||
} catch (IOException e) {
|
||||
throw new CommandException("COPY: error copy directory", e);
|
||||
}
|
||||
} else if (sourcePath.toFile().isFile()) {
|
||||
try {
|
||||
FileUtils.copyFile(sourcePath.toFile(), targetPath.toFile());
|
||||
} catch (IOException e) {
|
||||
throw new CommandException("COPY: error copy file", e);
|
||||
}
|
||||
} else {
|
||||
throw new CommandException("COPY: unknow type source file");
|
||||
}
|
||||
} else {
|
||||
if (sourcePath.toFile().isDirectory()) {
|
||||
if (targetPath.toFile().isFile()) {
|
||||
throw new CommandException("COPY: can't be copy dir to file");
|
||||
} else {
|
||||
try {
|
||||
FileUtils.copyDirectory(sourcePath.toFile(), targetPath.toFile());
|
||||
} catch (IOException e) {
|
||||
throw new CommandException("COPY: error copy directory", e);
|
||||
}
|
||||
}
|
||||
} else if (sourcePath.toFile().isFile()) {
|
||||
if (targetPath.toFile().isDirectory()) {
|
||||
try {
|
||||
FileUtils.copyFileToDirectory(sourcePath.toFile(), targetPath.toFile());
|
||||
} catch (IOException e) {
|
||||
throw new CommandException("COPY: error copy file", e);
|
||||
}
|
||||
} else if (targetPath.toFile().isFile()) {
|
||||
try {
|
||||
FileUtils.copyFile(sourcePath.toFile(), targetPath.toFile());
|
||||
} catch (IOException e) {
|
||||
throw new CommandException("COPY: error copy file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Создание папки/древа папок
|
||||
* параметры: цель */
|
||||
private void cmd_mkdir(String dir) throws CommandException {
|
||||
File treeDir = Paths.get(applyVariables(dir)).toFile();
|
||||
if (treeDir.mkdirs() && !treeDir.exists()) {
|
||||
throw new CommandException(String.format("MKDIR: can't create dirs %s [%s]", dir, treeDir.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
|
||||
private void cmd_unpack(String source, String target) throws CommandException {
|
||||
Path sourcePath = Paths.get(applyVariables(source));
|
||||
if (!sourcePath.toFile().exists()) {
|
||||
throw new CommandException(String.format("UNPACK: source not found %s [%s]", source, sourcePath.toFile().getAbsolutePath()));
|
||||
}
|
||||
|
||||
if (!sourcePath.toFile().isFile()) {
|
||||
throw new CommandException(String.format("UNPACK: source is not file %s [%s]", source, sourcePath.toFile().getAbsolutePath()));
|
||||
}
|
||||
|
||||
Path targetPath = Paths.get(applyVariables(target));
|
||||
if (!targetPath.toFile().exists()) {
|
||||
if (targetPath.toFile().mkdirs() && !targetPath.toFile().exists()) {
|
||||
throw new CommandException(String.format("UNPACK: can't create dir %s [%s]", target, targetPath.toFile().getAbsolutePath()));
|
||||
}
|
||||
} else if (targetPath.toFile().exists() && targetPath.toFile().isFile()) {
|
||||
throw new CommandException(String.format("UNPACK: target can't be file %s [%s]", target, targetPath.toFile().getAbsolutePath()));
|
||||
}
|
||||
|
||||
// unzip
|
||||
byte[] buffer = new byte[65536];
|
||||
try {
|
||||
ZipInputStream zis = new ZipInputStream(new FileInputStream(sourcePath.toFile()));
|
||||
|
||||
ZipEntry ze;
|
||||
while ((ze = zis.getNextEntry()) != null) {
|
||||
String fileName = ze.getName();
|
||||
File newFile = new File(targetPath.toFile(), fileName);
|
||||
Files.createDirectories(Paths.get(newFile.getParent()));
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(newFile);
|
||||
int len;
|
||||
while ((len = zis.read(buffer)) > 0) {
|
||||
fos.write(buffer, 0, len);
|
||||
}
|
||||
fos.close();
|
||||
}
|
||||
|
||||
zis.closeEntry();
|
||||
zis.close();
|
||||
} catch (IOException e) {
|
||||
throw new CommandException("UNPACK", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void cmd_undo() {
|
||||
// empty
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* DmitriyMX <mail@dmitriymx.ru>
|
||||
* 2016-06-28
|
||||
*/
|
||||
package asys.core.buildscript;
|
||||
|
||||
class CommandException extends Exception {
|
||||
CommandException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
CommandException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* DmitriyMX <mail@dmitriymx.ru>
|
||||
* 2016-06-23
|
||||
*/
|
||||
package asys.core.buildscript;
|
||||
|
||||
class UnknowCommandException extends CommandException {
|
||||
UnknowCommandException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
219
core/src/test/java/asys/core/buildscript/TestBuildScript.java
Normal file
219
core/src/test/java/asys/core/buildscript/TestBuildScript.java
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* DmitriyMX <mail@dmitriymx.ru>
|
||||
* 2016-06-23
|
||||
*/
|
||||
package asys.core.buildscript;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class TestBuildScript {
|
||||
private static File tempDirectory;
|
||||
private Map<String, String> variables = new HashMap<>();
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeTestClass() throws IOException {
|
||||
tempDirectory = new File(FileUtils.getTempDirectory(), "test_buildscript");
|
||||
|
||||
if (tempDirectory.exists()) {
|
||||
if (tempDirectory.isDirectory()) {
|
||||
FileUtils.deleteDirectory(tempDirectory);
|
||||
if (tempDirectory.exists()) {
|
||||
throw new IOException(String.format("Can't delete temp directory [%s]", tempDirectory.getAbsolutePath()));
|
||||
}
|
||||
} else {
|
||||
if (!tempDirectory.delete()) {
|
||||
throw new IOException(String.format("Can't delete temp file [%s]", tempDirectory.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tempDirectory.mkdir()) {
|
||||
throw new IOException(String.format("Can't create temp dir [%s]", tempDirectory.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void beforeTest() throws IOException {
|
||||
variables.clear();
|
||||
variables.put("dir", tempDirectory.getAbsolutePath());
|
||||
|
||||
File[] files = tempDirectory.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
FileUtils.deleteDirectory(file);
|
||||
assertFalse(file.exists());
|
||||
} else {
|
||||
assertTrue(file.delete());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseCommandLine() throws UnknowCommandException {
|
||||
BuildScript buildScript = new BuildScript("lnk \"%distr%/spigot 1.8.8.jar\" '%srv%/spi 1 got.jar'");
|
||||
String[] partsLine = buildScript.scriptLines.get(0);
|
||||
|
||||
assertNotNull(partsLine);
|
||||
assertEquals(3, partsLine.length);
|
||||
assertEquals("lnk", partsLine[0]);
|
||||
assertEquals("%distr%/spigot 1.8.8.jar", partsLine[1]);
|
||||
assertEquals("%srv%/spi 1 got.jar", partsLine[2]);
|
||||
}
|
||||
|
||||
@Test(expected = UnknowCommandException.class)
|
||||
public void testUnknowCommand() throws UnknowCommandException {
|
||||
new BuildScript("ololo push pop");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteMkdir() throws CommandException, IOException {
|
||||
String script = "mkdir %dir%/someDir";
|
||||
BuildScript buildScript = new BuildScript(script);
|
||||
buildScript.setVariables(variables);
|
||||
buildScript.execute();
|
||||
|
||||
File dir = new File(tempDirectory, "someDir");
|
||||
assertTrue(dir.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteLnk() throws CommandException, IOException {
|
||||
String script = "mkdir %dir%/someDir\n" +
|
||||
"lnk %dir%/someDir %dir%/dirLink";
|
||||
BuildScript buildScript = new BuildScript(script);
|
||||
buildScript.setVariables(variables);
|
||||
buildScript.execute();
|
||||
|
||||
File dir = new File(tempDirectory, "someDir");
|
||||
assertTrue(dir.exists());
|
||||
assertTrue(dir.isDirectory());
|
||||
|
||||
File dirLink = new File(tempDirectory, "dirLink");
|
||||
assertTrue(dirLink.exists());
|
||||
assertTrue(dirLink.isDirectory());
|
||||
}
|
||||
|
||||
private void prepareTestExecuteCopy() throws IOException {
|
||||
File dir = new File(tempDirectory, "someDir");
|
||||
assertTrue(dir.mkdir());
|
||||
|
||||
FileWriter fw = new FileWriter(new File(dir, "file1"));
|
||||
fw.write("123\n456");
|
||||
fw.close();
|
||||
fw = new FileWriter(new File(dir, "file2"));
|
||||
fw.write("789\n101112");
|
||||
fw.close();
|
||||
assertTrue(new File(dir, "indir").mkdir());
|
||||
fw = new FileWriter(new File(dir, "indir/file3"));
|
||||
fw.write("131415\n161718");
|
||||
fw.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteCopy() throws CommandException, IOException {
|
||||
prepareTestExecuteCopy();
|
||||
|
||||
String script = "copy %dir%/someDir %dir%/newDir";
|
||||
BuildScript buildScript = new BuildScript(script);
|
||||
buildScript.setVariables(variables);
|
||||
buildScript.execute();
|
||||
|
||||
// проверка результатов
|
||||
File file = new File(tempDirectory, "newDir/file1");
|
||||
assertTrue(file.exists());
|
||||
assertTrue(file.isFile());
|
||||
|
||||
file = new File(tempDirectory, "newDir/file2");
|
||||
assertTrue(file.exists());
|
||||
assertTrue(file.isFile());
|
||||
|
||||
file = new File(tempDirectory, "newDir/indir");
|
||||
assertTrue(file.exists());
|
||||
assertTrue(file.isDirectory());
|
||||
|
||||
file = new File(tempDirectory, "newDir/indir/file3");
|
||||
assertTrue(file.exists());
|
||||
assertTrue(file.isFile());
|
||||
}
|
||||
|
||||
private void genListFile(List<String> list, File node, String sourcePathRoot) {
|
||||
if (node.isFile()) {
|
||||
String filePath = node.getAbsolutePath();
|
||||
list.add(filePath.substring(sourcePathRoot.length()+1, filePath.length()));
|
||||
} else if (node.isDirectory()) {
|
||||
File[] files = node.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
genListFile(list, file, sourcePathRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareTestExeuteUnzip() throws IOException {
|
||||
prepareTestExecuteCopy();
|
||||
|
||||
List<String> listFiles = new ArrayList<>();
|
||||
genListFile(listFiles, new File(tempDirectory, "someDir"), tempDirectory.getAbsolutePath());
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(new File(tempDirectory, "arch.zip"));
|
||||
ZipOutputStream zos = new ZipOutputStream(fos);
|
||||
byte[] buffer = new byte[16];
|
||||
|
||||
for (String fileStr : listFiles) {
|
||||
ZipEntry zipEntry = new ZipEntry(fileStr);
|
||||
zos.putNextEntry(zipEntry);
|
||||
|
||||
FileInputStream fis = new FileInputStream(tempDirectory.getAbsolutePath() + File.separator + fileStr);
|
||||
int len;
|
||||
while ((len = fis.read(buffer)) > 0) {
|
||||
zos.write(buffer, 0, len);
|
||||
}
|
||||
fis.close();
|
||||
}
|
||||
|
||||
zos.closeEntry();
|
||||
zos.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExeuteUnzip() throws CommandException, IOException {
|
||||
prepareTestExeuteUnzip();
|
||||
|
||||
String script = "unpack %dir%/arch.zip %dir%/unpack";
|
||||
BuildScript buildScript = new BuildScript(script);
|
||||
buildScript.setVariables(variables);
|
||||
buildScript.execute();
|
||||
|
||||
// проверка результатов
|
||||
File file = new File(tempDirectory, "unpack/someDir/file1");
|
||||
assertTrue(file.exists());
|
||||
assertTrue(file.isFile());
|
||||
|
||||
file = new File(tempDirectory, "unpack/someDir/file2");
|
||||
assertTrue(file.exists());
|
||||
assertTrue(file.isFile());
|
||||
|
||||
file = new File(tempDirectory, "unpack/someDir/indir");
|
||||
assertTrue(file.exists());
|
||||
assertTrue(file.isDirectory());
|
||||
|
||||
file = new File(tempDirectory, "unpack/someDir/indir/file3");
|
||||
assertTrue(file.exists());
|
||||
assertTrue(file.isFile());
|
||||
}
|
||||
}
|
||||
15
pom.xml
15
pom.xml
@@ -10,6 +10,7 @@
|
||||
<asys.version>0.2</asys.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<slf4j.version>1.7.20</slf4j.version>
|
||||
</properties>
|
||||
|
||||
<groupId>asys</groupId>
|
||||
@@ -25,13 +26,25 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.20</version>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.osgi</groupId>
|
||||
<artifactId>org.osgi.core</artifactId>
|
||||
<version>6.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
Reference in New Issue
Block a user