package jetbrains.mps.vcs.platform.mergedriver; /*Generated by MPS */ import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import java.io.File; import com.intellij.openapi.project.Project; import com.intellij.openapi.application.PathManager; import org.jetbrains.annotations.NotNull; import jetbrains.mps.vcs.platform.util.PluginUtil; import com.intellij.openapi.ui.Messages; import jetbrains.mps.vcs.core.mergedriver.MergeDriverMain; import com.intellij.openapi.util.SystemInfo; import java.util.List; import jetbrains.mps.internal.collections.runtime.ListSequence; import java.util.ArrayList; import jetbrains.mps.util.StringsIO; import jetbrains.mps.internal.collections.runtime.IWhereFilter; import jetbrains.mps.internal.collections.runtime.Sequence; import java.io.IOException; import org.apache.log4j.Level; import java.io.FileNotFoundException; /*package*/ class GitGlobalInstaller extends AbstractInstaller { private static final Logger LOG = LogManager.getLogger(GitGlobalInstaller.class); private File myConfigFile; private File myScriptFile; public GitGlobalInstaller(Project project) { super(project); myConfigFile = new File(System.getProperty("user.home") + File.separator + ".gitconfig"); myScriptFile = new File(PathManager.getConfigPath() + File.separator + "mps-merger.sh"); } @NotNull @Override protected AbstractInstaller.State install(boolean dryRun) { if (!(PluginUtil.isGitPluginEnabled())) { return AbstractInstaller.State.NOT_ENABLED; } // TODO rewrite it using git4idea util classes if (!(myConfigFile.exists())) { if (dryRun) { return AbstractInstaller.State.NOT_INSTALLED; } else { String msg = String.format("Git config (%s) file is not present. Do you want to create it?", myConfigFile.getAbsolutePath()); if (Messages.showYesNoDialog(myProject, msg, "No Git Config", Messages.getQuestionIcon()) != 0) { return AbstractInstaller.State.NOT_INSTALLED; } } } if (!(dryRun)) { // copy driver files to the proper place MergeDriverPacker.getInstance().pack(myProject); } AbstractInstaller.State createScriptResult = ScriptGenerator.generateScript(myProject, MergeDriverMain.NO_FILETYPE, ScriptGenerator.GIT, myScriptFile, dryRun); if (createScriptResult != AbstractInstaller.State.INSTALLED) { return createScriptResult; } String scriptPath = myScriptFile.getAbsolutePath(); if (SystemInfo.isWindows) { scriptPath = CommandLineGenerator.adaptPathForMsysGit(scriptPath); } List<String> newConfigLines = ListSequence.fromList(new ArrayList<String>()); ListSequence.fromList(newConfigLines).addElement("[merge \"mps\"]"); ListSequence.fromList(newConfigLines).addElement("\tname = MPS merge driver"); ListSequence.fromList(newConfigLines).addElement(String.format("\tdriver = \"\\\"%s\\\" %%O %%A %%B %%L\"", scriptPath)); List<String> configLines = StringsIO.readLines(myConfigFile); int sectionStart = ListSequence.fromList(configLines).indexOf(ListSequence.fromList(configLines).findFirst(new IWhereFilter<String>() { public boolean accept(String line) { return line.trim().matches("\\[merge\\s+\"mps\"\\]"); } })); if (sectionStart != -1) { int toSkip = sectionStart + 1; Iterable<String> skipped = ListSequence.fromList(configLines).skip(toSkip); int sectionEnd = Sequence.fromIterable(skipped).indexOf(Sequence.fromIterable(skipped).findFirst(new IWhereFilter<String>() { public boolean accept(String line) { return line.trim().startsWith("["); } })); if (sectionEnd == -1) { // last section sectionEnd = ListSequence.fromList(configLines).count(); } else { sectionEnd = sectionEnd + toSkip; } List<String> section = ListSequence.fromList(configLines).page(sectionStart, sectionEnd).where(new IWhereFilter<String>() { public boolean accept(String line) { return !(line.trim().isEmpty()); } }).toListSequence(); boolean equal = ListSequence.fromList(section).count() == ListSequence.fromList(newConfigLines).count(); if (equal) { for (int i = 0; i < ListSequence.fromList(section).count(); i++) { if (neq_btx4zt_a0a0a0g0t0e(ListSequence.fromList(section).getElement(i), ListSequence.fromList(newConfigLines).getElement(i))) { equal = false; break; } } } if (equal) { if (!(dryRun)) { showSuccessfullInfoMessage(); } return AbstractInstaller.State.INSTALLED; } else { if (dryRun) { return AbstractInstaller.State.OUTDATED; } else { configLines = ListSequence.fromList(configLines).take(sectionStart).concat(ListSequence.fromList(newConfigLines)).concat(ListSequence.fromList(configLines).skip(sectionEnd)).toListSequence(); } } } else { if (dryRun) { return AbstractInstaller.State.NOT_INSTALLED; } ListSequence.fromList(configLines).addElement(""); ListSequence.fromList(configLines).addSequence(ListSequence.fromList(newConfigLines)); } try { StringsIO.writeLines(myConfigFile, configLines); showSuccessfullInfoMessage(); return AbstractInstaller.State.INSTALLED; } catch (IOException e) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("Writing gitconfig file failed", e); } String msg = e.getMessage() + "."; if (SystemInfo.isWindows && e instanceof FileNotFoundException) { msg += " Try unsetting hidden attribute for that file in Windows Explorer."; } Messages.showErrorDialog(myProject, "Writing gitconfig file failed. " + msg, "Writing .gitconfig Failed"); return AbstractInstaller.State.NOT_INSTALLED; } } private void showSuccessfullInfoMessage() { Messages.showInfoMessage(myProject, String.format("Successfully updated %s", myConfigFile.getAbsolutePath()), "Global Git Merge Driver Installed"); } @Override public String getActionTitle() { return "Git global merge driver setting (~/.gitconfig)"; } @Override public String getAffectedVcsName() { return "Git"; } private static boolean neq_btx4zt_a0a0a0g0t0e(Object a, Object b) { return !(((a != null ? a.equals(b) : a == b))); } }