/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.tools;
import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.util.FileImpl;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* @author Brian Wing Shun Chan
*/
public class PluginsGitSvnSyncer {
public static void main(String[] args) {
String gitPluginsDirName = System.getProperty("git.plugins.dir");
String svnPluginsDirName = System.getProperty("svn.plugins.dir");
String syncTo = System.getProperty("sync.to");
new PluginsGitSvnSyncer(gitPluginsDirName, svnPluginsDirName, syncTo);
}
public PluginsGitSvnSyncer(
String gitPluginsDirName, String svnPluginsDirName, String syncTo) {
try {
if (!gitPluginsDirName.endsWith("/")) {
gitPluginsDirName = gitPluginsDirName + "/";
}
if (!svnPluginsDirName.endsWith("/")) {
svnPluginsDirName = svnPluginsDirName + "/";
}
if (syncTo.equals("git")) {
_updateGitIgnores(svnPluginsDirName, gitPluginsDirName);
}
else if (syncTo.equals("svn")) {
_updateSvnIgnores(gitPluginsDirName, svnPluginsDirName);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
private String[] _exec(String cmd) throws Exception {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(cmd);
String[] stdout = _getExecOutput(process.getInputStream());
String[] stderr = _getExecOutput(process.getErrorStream());
if (stderr.length > 0) {
StringBundler sb = new StringBundler(stderr.length * 3 + 3);
sb.append("Received errors in executing '");
sb.append(cmd);
sb.append("'\n");
for (String err : stderr) {
sb.append("\t");
sb.append(err);
sb.append("\n");
}
throw new Exception(sb.toString());
}
return stdout;
}
private String[] _getExecOutput(InputStream is) throws IOException {
List<String> list = new ArrayList<>();
UnsyncBufferedReader unsyncBufferedReader = null;
try {
unsyncBufferedReader = new UnsyncBufferedReader(
new InputStreamReader(is));
String line = unsyncBufferedReader.readLine();
while (line != null) {
line = line.trim();
if (Validator.isNotNull(line)) {
list.add(line);
}
line = unsyncBufferedReader.readLine();
}
}
finally {
if (unsyncBufferedReader != null) {
try {
unsyncBufferedReader.close();
}
catch (Exception e) {
}
}
}
return list.toArray(new String[list.size()]);
}
private void _updateGitIgnores(String srcDirName, String destDirName)
throws Exception {
for (String pluginType : _PLUGIN_TYPES) {
String[] dirNames = _fileUtil.listDirs(srcDirName + pluginType);
for (String dirName : dirNames) {
if (dirName.equals(".svn")) {
continue;
}
for (String pluginDirName : _PLUGIN_DIR_NAMES) {
_updateGitIgnores(
srcDirName + pluginType + "/",
destDirName + pluginType + "/",
dirName + pluginDirName + "/");
}
}
}
}
private void _updateGitIgnores(
String srcDirName, String destDirName, String dirName)
throws Exception {
File gitIgnoreFile = new File(destDirName + dirName + ".gitignore");
if (!_fileUtil.exists(srcDirName + dirName + ".svn")) {
_fileUtil.delete(gitIgnoreFile);
return;
}
List<String> ignores = null;
if (!dirName.contains("/docroot/")) {
ignores = Collections.emptyList();
}
else {
ignores = ListUtil.fromArray(
_exec(_SVN_GET_IGNORES + srcDirName + dirName));
}
Collections.sort(ignores);
Iterator<String> itr = ignores.iterator();
while (itr.hasNext()) {
String ignore = itr.next();
if (ignore.equals("classes")) {
itr.remove();
}
}
if (!ignores.isEmpty()) {
String[] ignoresArray = ignores.toArray(new String[ignores.size()]);
for (int i = 0; i < ignoresArray.length; i++) {
String ignore = ignoresArray[i];
if (Validator.isNotNull(ignore) && !ignore.startsWith("/")) {
ignoresArray[i] = "/" + ignore;
}
}
_fileUtil.write(
destDirName + dirName + ".gitignore",
StringUtil.merge(ignoresArray, "\n"));
}
else {
_fileUtil.delete(gitIgnoreFile);
}
}
private void _updateSvnIgnores(String srcDirName, String destDirName)
throws Exception {
for (String pluginType : _PLUGIN_TYPES) {
String[] dirNames = _fileUtil.listDirs(srcDirName + pluginType);
for (String dirName : dirNames) {
for (String pluginDirName : _PLUGIN_DIR_NAMES) {
_updateSvnIgnores(
srcDirName + pluginType + "/",
destDirName + pluginType + "/",
dirName + pluginDirName + "/");
}
}
}
}
private void _updateSvnIgnores(
String srcDirName, String destDirName, String dirName)
throws Exception {
if (!_fileUtil.exists(destDirName + dirName)) {
return;
}
File gitIgnoreFile = new File(srcDirName + dirName + ".gitignore");
File svnDir = new File(destDirName + dirName + ".svn");
if (gitIgnoreFile.exists() && !svnDir.exists()) {
System.out.println(
"Invalid SVN directory " + destDirName + dirName);
return;
}
List<String> ignores = null;
if (!dirName.contains("/docroot")) {
ignores = new ArrayList<>();
ignores.add("bin");
ignores.add("classes");
ignores.add("tmp");
}
else {
ignores = ListUtil.fromFile(gitIgnoreFile);
for (int i = 0; i < ignores.size(); i++) {
String ignore = ignores.get(i);
if (ignore.startsWith("/")) {
ignore = ignore.substring(1);
}
ignores.set(i, ignore);
}
if (dirName.endsWith("/docroot/WEB-INF/")) {
if (!ignores.contains("classes")) {
ignores.add("classes");
}
}
}
Collections.sort(ignores);
if (ignores.isEmpty() && !svnDir.exists()) {
return;
}
if (ignores.isEmpty()) {
try {
_exec(_SVN_DEL_IGNORES + destDirName + dirName);
}
catch (Exception e) {
String message = e.getMessage();
if (!message.contains(
"svn: Attempting to delete nonexistent property " +
"'svn:ignore'")) {
throw e;
}
}
return;
}
File tempFile = _fileUtil.createTempFile("svn-ignores-", "tmp");
try {
String[] ignoresArray = ignores.toArray(new String[ignores.size()]);
_fileUtil.write(tempFile, StringUtil.merge(ignoresArray, "\n"));
_exec(
_SVN_SET_IGNORES + "-F \"" + tempFile.getCanonicalPath() +
"\" \"" + destDirName + dirName + "\"");
}
finally {
_fileUtil.delete(tempFile);
}
}
private static final String[] _PLUGIN_DIR_NAMES = {
"", "/docroot", "/docroot/WEB-INF", "/docroot/WEB-INF/lib",
"/docroot/WEB-INF/tld"
};
private static final String[] _PLUGIN_TYPES = {
"clients", "ext", "hooks", "layouttpl", "portlets", "themes", "webs"
};
private static final String _SVN_DEL_IGNORES = "svn propdel svn:ignore ";
private static final String _SVN_GET_IGNORES = "svn propget svn:ignore ";
private static final String _SVN_SET_IGNORES = "svn propset svn:ignore ";
private static final FileImpl _fileUtil = FileImpl.getInstance();
}