/** * This file is part of git-as-svn. It is subject to the license terms * in the LICENSE file found in the top-level directory of this distribution * and at http://www.gnu.org/licenses/gpl-2.0.html. No part of git-as-svn, * including this file, may be copied, modified, propagated, or distributed * except according to the terms contained in the LICENSE file. */ package svnserver.repository.git.prop; import org.eclipse.jgit.errors.InvalidPatternException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tmatesoft.svn.core.SVNProperty; import org.tmatesoft.svn.core.internal.wc.SVNFileUtil; import svnserver.repository.git.path.Wildcard; import svnserver.repository.git.path.matcher.path.AlwaysMatcher; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.regex.PatternSyntaxException; /** * Factory for properties, generated by .gitattributes. * * @author Artem V. Navrotskiy <bozaro@users.noreply.github.com> */ @SuppressWarnings("UnusedDeclaration") public final class GitAttributesFactory implements GitPropertyFactory { @NotNull private static final Logger log = LoggerFactory.getLogger(GitAttributesFactory.class); @NotNull private static final String EOL_PREFIX = "eol="; @NotNull private static final String FILTER_PREFIX = "filter="; @NotNull @Override public String getFileName() { return ".gitattributes"; } @NotNull @Override public GitProperty[] create(@NotNull String content) throws IOException { final List<GitProperty> properties = new ArrayList<>(); for (String line : content.split("(?:#[^\n]*)?\n")) { final String[] tokens = line.trim().split("\\s+"); try { final Wildcard wildcard = new Wildcard(tokens[0]); processProperty(properties, wildcard, SVNProperty.MIME_TYPE, getMimeType(tokens)); processProperty(properties, wildcard, SVNProperty.EOL_STYLE, getEol(tokens)); final String filter = getFilter(tokens); if (filter != null) { properties.add(new GitFilterProperty(wildcard.getMatcher(), filter)); } } catch (InvalidPatternException | PatternSyntaxException e) { log.warn("Found invalid git pattern: {}", line); } } return properties.toArray(new GitProperty[properties.size()]); } @NotNull @Override public GitProperty[] rootDefaults() { return new GitProperty[]{ new GitFileProperty(AlwaysMatcher.INSTANCE, SVNProperty.EOL_STYLE, SVNProperty.EOL_STYLE_NATIVE) }; } private static void processProperty(@NotNull List<GitProperty> properties, @NotNull Wildcard wildcard, @NotNull String property, @Nullable String value) { if (value == null) { return; } if (!value.isEmpty()) { if (wildcard.isSvnCompatible()) { properties.add(new GitAutoProperty(wildcard.getMatcher(), property, value)); } properties.add(new GitFileProperty(wildcard.getMatcher(), property, value)); } else { properties.add(new GitFileProperty(wildcard.getMatcher(), property, null)); } } @Nullable private String getMimeType(String[] tokens) { for (int i = 1; i < tokens.length; ++i) { String token = tokens[i]; if (token.startsWith("binary")) { return SVNFileUtil.BINARY_MIME_TYPE; } if (token.startsWith("-binary")) { return ""; } if (token.startsWith("text")) { return ""; } } return null; } @Nullable private String getEol(String[] tokens) { for (int i = 1; i < tokens.length; ++i) { final String token = tokens[i]; if (token.startsWith(EOL_PREFIX)) { switch (token.substring(EOL_PREFIX.length())) { case "lf": return SVNProperty.EOL_STYLE_LF; case "native": return SVNProperty.EOL_STYLE_NATIVE; case "cr": return SVNProperty.EOL_STYLE_CR; case "crlf": return SVNProperty.EOL_STYLE_CRLF; } } if (token.startsWith("binary")) { return ""; } if (token.startsWith("-text")) { return ""; } } return null; } @Nullable private String getFilter(String[] tokens) { for (int i = 1; i < tokens.length; ++i) { final String token = tokens[i]; if (token.startsWith(FILTER_PREFIX)) { return token.substring(FILTER_PREFIX.length()); } } return null; } }