package org.bndtools.versioncontrol.ignores.plugin.git; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; import java.util.LinkedList; import java.util.List; import org.bndtools.api.NamedPlugin; import org.bndtools.versioncontrol.ignores.manager.api.VersionControlIgnoresPlugin; import org.osgi.service.component.annotations.Component; @Component public class GitVersionControlIgnoresPlugin implements VersionControlIgnoresPlugin { private static final String GITIGNORE_FILE_NAME = ".gitignore"; /** * Fully read an ignore file, including comments. * * @param ignoreFile * The ignore file * @return null when the ignore file is null, when the ignore file doesn't exist or when the ignore file is empty. A * non-empty list of lines as read from the ignore file otherwise. * @throws IOException * When the ignore file could not be fully read (for example due to the ignore file not being an regular * file or due to an IOException) */ private List<String> readIgnoreFile(File ignoreFile) throws IOException { if (ignoreFile == null || !ignoreFile.exists()) { return null; } List<String> result = new LinkedList<String>(); int lineNr = 0; try (BufferedReader reader = Files.newBufferedReader(ignoreFile.toPath(), Charset.forName("UTF-8"))) { String line; while ((line = reader.readLine()) != null) { result.add(line); lineNr++; } } catch (Exception e) { throw new IOException(String.format("Error reading ignore file %s on line %d", ignoreFile.getAbsolutePath(), lineNr), e); } if (result.isEmpty()) { return null; } return result; } /* * VersionControlIgnoresPlugin */ @Override public NamedPlugin getInformation() { return new GitVersionControlIgnoresPluginInformation(); } @Override public boolean canStoreEmptyDirectories() { return false; } @Override public boolean matchesRepositoryProviderId(String repositoryProviderId) { return "org.eclipse.egit.core.GitProvider".equals(repositoryProviderId); } @Override public void addIgnores(File dstDir, List<String> ignores) throws Exception { if (dstDir == null) { return; } List<String> newIgnores = ignores; if (newIgnores == null) { newIgnores = new LinkedList<String>(); } /* create the directory of the ignore file, when needed */ if (!dstDir.exists() && !dstDir.mkdirs()) { throw new IOException("Could not create directory " + dstDir.getPath()); } File ignoreFile = new File(dstDir, GITIGNORE_FILE_NAME); List<String> ignoresToAppend; if (!ignoreFile.exists()) { ignoresToAppend = newIgnores; } else { /* read the current ignores */ List<String> currentIgnores = readIgnoreFile(ignoreFile); /* * add new ignores to the current ignores, but only if the current * ignores did not contain them */ if (currentIgnores == null) { ignoresToAppend = newIgnores; } else { for (String newIgnore : newIgnores) { if (!currentIgnores.contains(newIgnore)) { currentIgnores.add(newIgnore); } } ignoresToAppend = currentIgnores; } /* exit when we have no new ignores to write */ if (ignoresToAppend.isEmpty()) { return; } } /* write out the ignore file */ try (BufferedWriter writer = Files.newBufferedWriter(ignoreFile.toPath(), Charset.forName("UTF-8"))) { for (String ignoreToAppend : ignoresToAppend) { writer.write(ignoreToAppend); writer.newLine(); } writer.flush(); } catch (Exception e) { throw new IOException(String.format("Error appending %s to ignore file %s", ignoresToAppend, ignoreFile.getAbsolutePath()), e); } } }