package jetbrains.mps.vcs.core.mergedriver; /*Generated by MPS */ import java.io.File; import jetbrains.mps.core.platform.Platform; import jetbrains.mps.core.platform.PlatformFactory; import jetbrains.mps.core.platform.PlatformOptionsBuilder; import jetbrains.mps.vcs.util.MergeDriverBackupUtil; import jetbrains.mps.internal.collections.runtime.Sequence; import jetbrains.mps.internal.collections.runtime.IWhereFilter; import java.io.Reader; import java.io.BufferedReader; import java.io.FileReader; import java.io.FileNotFoundException; import java.io.IOException; import jetbrains.mps.util.FileUtil; import org.jetbrains.annotations.Nullable; import jetbrains.mps.internal.collections.runtime.ISelector; import java.util.Properties; import org.apache.log4j.PropertyConfigurator; public class MergeDriverMain { private static final String CONFLICT_START = "<<<<<<<"; private static final String CONFLICT_END = ">>>>>>>"; private static final String CONFLICT_SEPARATOR = "======="; public static final String LOG_PROPERTY = "mps.mergedriver.log"; public static final String SVN_OPTION = "--svn"; public static final String GIT_OPTION = "--git"; public static final String NO_FILETYPE = "undefined"; private MergeDriverMain() { } public static void main(String[] args) { byte[] conflictStart = CONFLICT_START.getBytes(); byte[] conflictEnd = CONFLICT_END.getBytes(); byte[] conflictSeparator = CONFLICT_SEPARATOR.getBytes(); if (args.length < 5) { System.err.println("Usage <merger> <filetype> --<vcs> <base> <current> <other> "); System.exit(2); } String filetype = args[0]; if (NO_FILETYPE.equals(filetype)) { filetype = null; } File baseFile = new File(args[2]); File currentFile = new File(args[3]); File otherFile = new File(args[4]); boolean overwrite = false; if (SVN_OPTION.equals(args[1])) { if (args.length >= 8) { conflictStart = (CONFLICT_START + " " + args[6]).getBytes(); conflictEnd = (CONFLICT_END + " " + args[7]).getBytes(); } } else if (GIT_OPTION.equals(args[1])) { overwrite = true; } else { System.exit(2); return; } configureLog4j(); Platform platform = PlatformFactory.initPlatform(PlatformOptionsBuilder.PERSISTENCE); String systemPath = new File(System.getProperty(LOG_PROPERTY)).getParentFile().getParentFile().getAbsolutePath(); MergeDriverBackupUtil.setMergeBackupDirPath(systemPath + File.separator + "merge-backup"); File[] files = {baseFile, currentFile, otherFile}; AbstractContentMerger merger = selectMerger(filetype, files); if (merger == null) { merger = (SVN_OPTION.equals(args[1]) ? new TextMerger() : new SimpleMerger()); } boolean convertCRLF = GIT_OPTION.equals(args[1]) && !(hasCRLF(Sequence.fromIterable(Sequence.fromArray(files)).findFirst(new IWhereFilter<File>() { public boolean accept(File f) { return f != null; } }))); int status = FileMerger.mergeFiles(merger, baseFile, currentFile, otherFile, conflictStart, conflictEnd, conflictSeparator, overwrite, convertCRLF); platform.dispose(); System.exit(status); } public static boolean hasCRLF(File f) { // getting directlry from the file, but can get from git core.autcrlf + core.eol Reader r = null; try { r = new BufferedReader(new FileReader(f)); for (int c = 0; c != -1; c = r.read()) { if (c == '\r' && r.read() == '\n') { return true; } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { FileUtil.closeFileSafe(r); } return false; } @Nullable private static AbstractContentMerger selectMerger(final String filetype, File... files) { FileType fileType = Sequence.fromIterable(Sequence.fromArray(files)).select(new ISelector<File, FileType>() { public FileType select(File f) { return FileType.get(filetype, f); } }).findFirst(new IWhereFilter<FileType>() { public boolean accept(FileType f) { return f != null; } }); if (fileType == null) { return null; } switch (fileType) { case MODEL_HEADER: case MODEL_ROOT: case MODEL: return new CompositeMerger(new ModelMerger((filetype != null ? filetype : fileType.getSuffix())), new SimpleMerger()); case LANGUAGE: case SOLUTION: case DEVKIT: case PROJECT: return new CompositeMerger(new TextMerger(), new SimpleMerger()); case TRACE_CACHE: case GENERATOR_DEPENDENCIES: return new EmptyMerger(); case JAVA_DEPENDENCIES: return new JavaDependenciesMerger(); default: return new TextMerger(); } } private static void configureLog4j() { String logPath = System.getProperty(LOG_PROPERTY); if ((logPath == null || logPath.length() == 0)) { return; } Properties p = new Properties(); p.setProperty("log4j.rootLogger", "info, file"); p.setProperty("log4j.appender.file", "org.apache.log4j.RollingFileAppender"); p.setProperty("log4j.appender.file.File", logPath); p.setProperty("log4j.appender.file.Append", "true"); p.setProperty("log4j.appender.file.MaxFileSize", "2MB"); p.setProperty("log4j.appender.file.MaxBackupIndex", "2"); p.setProperty("log4j.appender.file.layout", "org.apache.log4j.PatternLayout"); p.setProperty("log4j.appender.file.layout.conversionPattern", "%d{DATE} %5p %t %c{1}:%M:%L - %m%n"); PropertyConfigurator.configure(p); } }