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[list.size()]);
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 for (int i = 0; i < ignoresArray.length; i++) {
191 String ignore = ignoresArray[i];
192
193 if (Validator.isNotNull(ignore) && !ignore.startsWith("/")) {
194 ignoresArray[i] = "/" + ignore;
195 }
196 }
197
198 _fileUtil.write(
199 destDirName + dirName + ".gitignore",
200 StringUtil.merge(ignoresArray, "\n"));
201 }
202 else {
203 _fileUtil.delete(gitIgnoreFile);
204 }
205 }
206
207 private void _updateSvnIgnores(String srcDirName, String destDirName)
208 throws Exception {
209
210 for (String pluginType : _PLUGIN_TYPES) {
211 String[] dirNames = _fileUtil.listDirs(srcDirName + pluginType);
212
213 for (String dirName : dirNames) {
214 for (String pluginDirName : _PLUGIN_DIR_NAMES) {
215 _updateSvnIgnores(
216 srcDirName + pluginType + "/",
217 destDirName + pluginType + "/",
218 dirName + pluginDirName + "/");
219 }
220 }
221 }
222 }
223
224 private void _updateSvnIgnores(
225 String srcDirName, String destDirName, String dirName)
226 throws Exception {
227
228 if (!_fileUtil.exists(destDirName + dirName)) {
229 return;
230 }
231
232 File gitIgnoreFile = new File(srcDirName + dirName + ".gitignore");
233 File svnDir = new File(destDirName + dirName + ".svn");
234
235 if (gitIgnoreFile.exists() && !svnDir.exists()) {
236 System.out.println(
237 "Invalid SVN directory " + destDirName + dirName);
238
239 return;
240 }
241
242 List<String> ignores = null;
243
244 if (!dirName.contains("/docroot")) {
245 ignores = new ArrayList<String>();
246
247 ignores.add("bin");
248 ignores.add("classes");
249 ignores.add("tmp");
250 }
251 else {
252 ignores = ListUtil.fromFile(gitIgnoreFile);
253
254 for (int i = 0; i < ignores.size(); i++) {
255 String ignore = ignores.get(i);
256
257 if (ignore.startsWith("/")) {
258 ignore = ignore.substring(1);
259 }
260
261 ignores.set(i, ignore);
262 }
263
264 if (dirName.endsWith("/docroot/WEB-INF/")) {
265 if (!ignores.contains("classes")) {
266 ignores.add("classes");
267 }
268 }
269 }
270
271 Collections.sort(ignores);
272
273 if (ignores.isEmpty() && !svnDir.exists()) {
274 return;
275 }
276
277 if (ignores.isEmpty()) {
278 try {
279 _exec(_SVN_DEL_IGNORES + destDirName + dirName);
280 }
281 catch (Exception e) {
282 String message = e.getMessage();
283
284 if (!message.contains(
285 "svn: Attempting to delete nonexistent property " +
286 "'svn:ignore'")) {
287
288 throw e;
289 }
290 }
291
292 return;
293 }
294
295 File tempFile = File.createTempFile("svn-ignores-", null, null);
296
297 try {
298 String[] ignoresArray = ignores.toArray(new String[ignores.size()]);
299
300 _fileUtil.write(tempFile, StringUtil.merge(ignoresArray, "\n"));
301
302 _exec(
303 _SVN_SET_IGNORES + "-F \"" + tempFile.getCanonicalPath() +
304 "\" \"" + destDirName + dirName + "\"");
305 }
306 finally {
307 _fileUtil.delete(tempFile);
308 }
309 }
310
311 private static final String[] _PLUGIN_DIR_NAMES = {
312 "", "/docroot", "/docroot/WEB-INF", "/docroot/WEB-INF/lib",
313 "/docroot/WEB-INF/tld"
314 };
315
316 private static final String[] _PLUGIN_TYPES = {
317 "clients", "ext", "hooks", "layouttpl", "portlets", "themes", "webs"
318 };
319
320 private static final String _SVN_DEL_IGNORES = "svn propdel svn:ignore ";
321
322 private static final String _SVN_GET_IGNORES = "svn propget svn:ignore ";
323
324 private static final String _SVN_SET_IGNORES = "svn propset svn:ignore ";
325
326 private static FileImpl _fileUtil = FileImpl.getInstance();
327
328 }