001
014
015 package com.liferay.portal.tools;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
018 import com.liferay.portal.kernel.util.ListUtil;
019 import com.liferay.portal.kernel.util.StringBundler;
020 import com.liferay.portal.kernel.util.StringUtil;
021 import com.liferay.portal.kernel.util.Validator;
022 import com.liferay.portal.util.FileImpl;
023
024 import java.io.File;
025 import java.io.IOException;
026 import java.io.InputStream;
027 import java.io.InputStreamReader;
028
029 import java.util.ArrayList;
030 import java.util.Collections;
031 import java.util.Iterator;
032 import java.util.List;
033
034
037 public class PluginsGitSvnSyncer {
038
039 public static void main(String[] args) {
040 String gitPluginsDirName = System.getProperty("git.plugins.dir");
041 String svnPluginsDirName = System.getProperty("svn.plugins.dir");
042 String syncTo = System.getProperty("sync.to");
043
044 new PluginsGitSvnSyncer(gitPluginsDirName, svnPluginsDirName, syncTo);
045 }
046
047 public PluginsGitSvnSyncer(
048 String gitPluginsDirName, String svnPluginsDirName, String syncTo) {
049
050 try {
051 if (!gitPluginsDirName.endsWith("/")) {
052 gitPluginsDirName = gitPluginsDirName + "/";
053 }
054
055 if (!svnPluginsDirName.endsWith("/")) {
056 svnPluginsDirName = svnPluginsDirName + "/";
057 }
058
059 if (syncTo.equals("git")) {
060 _updateGitIgnores(svnPluginsDirName, gitPluginsDirName);
061 }
062 else if (syncTo.equals("svn")) {
063 _updateSvnIgnores(gitPluginsDirName, svnPluginsDirName);
064 }
065 }
066 catch (Exception e) {
067 e.printStackTrace();
068 }
069 }
070
071 private String[] _exec(String cmd) throws Exception {
072 Runtime runtime = Runtime.getRuntime();
073
074 Process process = runtime.exec(cmd);
075
076 String[] stdout = _getExecOutput(process.getInputStream());
077 String[] stderr = _getExecOutput(process.getErrorStream());
078
079 if (stderr.length > 0) {
080 StringBundler sb = new StringBundler(stderr.length * 3 + 3);
081
082 sb.append("Received errors in executing '");
083 sb.append(cmd);
084 sb.append("'\n");
085
086 for (String err : stderr) {
087 sb.append("\t");
088 sb.append(err);
089 sb.append("\n");
090 }
091
092 throw new Exception(sb.toString());
093 }
094
095 return stdout;
096 }
097
098 private String[] _getExecOutput(InputStream is) throws IOException {
099 List<String> list = new ArrayList<String>();
100
101 UnsyncBufferedReader unsyncBufferedReader = null;
102
103 try {
104 unsyncBufferedReader = new UnsyncBufferedReader(
105 new InputStreamReader(is));
106
107 String line = unsyncBufferedReader.readLine();
108
109 while (line != null) {
110 line = line.trim();
111
112 if (Validator.isNotNull(line)) {
113 list.add(line);
114 }
115
116 line = unsyncBufferedReader.readLine();
117 }
118 }
119 finally {
120 if (unsyncBufferedReader != null) {
121 try {
122 unsyncBufferedReader.close();
123 }
124 catch (Exception e) {
125 }
126 }
127 }
128
129 return list.toArray(new String[] {});
130 }
131
132 private void _updateGitIgnores(String srcDirName, String destDirName)
133 throws Exception {
134
135 for (String pluginType : _PLUGIN_TYPES) {
136 String[] dirNames = _fileUtil.listDirs(srcDirName + pluginType);
137
138 for (String dirName : dirNames) {
139 if (dirName.equals(".svn")) {
140 continue;
141 }
142
143 for (String pluginDirName : _PLUGIN_DIR_NAMES) {
144 _updateGitIgnores(
145 srcDirName + pluginType + "/",
146 destDirName + pluginType + "/",
147 dirName + pluginDirName + "/");
148 }
149 }
150 }
151 }
152
153 private void _updateGitIgnores(
154 String srcDirName, String destDirName, String dirName)
155 throws Exception {
156
157 File gitIgnoreFile = new File(destDirName + dirName + ".gitignore");
158
159 if (!_fileUtil.exists(srcDirName + dirName + ".svn")) {
160 _fileUtil.delete(gitIgnoreFile);
161
162 return;
163 }
164
165 List<String> ignores = null;
166
167 if (!dirName.contains("/docroot/")) {
168 ignores = Collections.emptyList();
169 }
170 else {
171 ignores = ListUtil.fromArray(
172 _exec(_SVN_GET_IGNORES + srcDirName + dirName));
173 }
174
175 Collections.sort(ignores);
176
177 Iterator<String> itr = ignores.iterator();
178
179 while (itr.hasNext()) {
180 String ignore = itr.next();
181
182 if (ignore.equals("classes")) {
183 itr.remove();
184 }
185 }
186
187 if (!ignores.isEmpty()) {
188 String[] ignoresArray = ignores.toArray(new String[ignores.size()]);
189
190 _fileUtil.write(
191 destDirName + dirName + ".gitignore",
192 StringUtil.merge(ignoresArray, "\n"));
193 }
194 else {
195 _fileUtil.delete(gitIgnoreFile);
196 }
197 }
198
199 private void _updateSvnIgnores(String srcDirName, String destDirName)
200 throws Exception {
201
202 for (String pluginType : _PLUGIN_TYPES) {
203 String[] dirNames = _fileUtil.listDirs(srcDirName + pluginType);
204
205 for (String dirName : dirNames) {
206 for (String pluginDirName : _PLUGIN_DIR_NAMES) {
207 _updateSvnIgnores(
208 srcDirName + pluginType + "/",
209 destDirName + pluginType + "/",
210 dirName + pluginDirName + "/");
211 }
212 }
213 }
214 }
215
216 private void _updateSvnIgnores(
217 String srcDirName, String destDirName, String dirName)
218 throws Exception {
219
220 if (!_fileUtil.exists(destDirName + dirName)) {
221 return;
222 }
223
224 File gitIgnoreFile = new File(srcDirName + dirName + ".gitignore");
225 File svnDir = new File(destDirName + dirName + ".svn");
226
227 if (gitIgnoreFile.exists() && !svnDir.exists()) {
228 System.out.println(
229 "Invalid SVN directory " + destDirName + dirName);
230
231 return;
232 }
233
234 List<String> ignores = null;
235
236 if (!dirName.contains("/docroot")) {
237 ignores = new ArrayList<String>();
238
239 ignores.add("bin");
240 ignores.add("classes");
241 ignores.add("tmp");
242 }
243 else {
244 ignores = ListUtil.fromFile(gitIgnoreFile);
245
246 if (dirName.endsWith("/docroot/WEB-INF/")) {
247 if (!ignores.contains("classes")) {
248 ignores.add("classes");
249 }
250 }
251 }
252
253 Collections.sort(ignores);
254
255 if (ignores.isEmpty() && !svnDir.exists()) {
256 return;
257 }
258
259 if (ignores.isEmpty()) {
260 try {
261 _exec(_SVN_DEL_IGNORES + destDirName + dirName);
262 }
263 catch (Exception e) {
264 String message = e.getMessage();
265
266 if (!message.contains(
267 "svn: Attempting to delete nonexistent property " +
268 "'svn:ignore'")) {
269
270 throw e;
271 }
272 }
273
274 return;
275 }
276
277 File tempFile = File.createTempFile("svn-ignores-", null, null);
278
279 try {
280 String[] ignoresArray = ignores.toArray(
281 new String[ignores.size()]);
282
283 _fileUtil.write(tempFile, StringUtil.merge(ignoresArray, "\n"));
284
285 _exec(
286 _SVN_SET_IGNORES + "-F \"" + tempFile.getCanonicalPath() +
287 "\" \"" + destDirName + dirName + "\"");
288 }
289 finally {
290 _fileUtil.delete(tempFile);
291 }
292 }
293
294 private static final String[] _PLUGIN_DIR_NAMES = {
295 "", "/docroot", "/docroot/WEB-INF", "/docroot/WEB-INF/lib",
296 "/docroot/WEB-INF/tld"
297 };
298
299 private static final String[] _PLUGIN_TYPES = {
300 "clients", "ext", "hooks", "layouttpl", "portlets", "themes", "webs"
301 };
302
303 private static final String _SVN_DEL_IGNORES = "svn propdel svn:ignore ";
304
305 private static final String _SVN_GET_IGNORES = "svn propget svn:ignore ";
306
307 private static final String _SVN_SET_IGNORES = "svn propset svn:ignore ";
308
309 private static FileImpl _fileUtil = FileImpl.getInstance();
310
311 }