All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openapitools.codegen.ignore.rules.Rule Maven / Gradle / Ivy

There is a newer version: 7.7.0
Show newest version
/*
 * Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
 * Copyright 2018 SmartBear Software
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.openapitools.codegen.ignore.rules;

import java.util.List;

public abstract class Rule {

    public enum Operation {EXCLUDE, INCLUDE, NOOP, EXCLUDE_AND_TERMINATE}

    // The original rule
    private final String definition;

    private final List syntax;

    Rule(List syntax, String definition) {
        this.syntax = syntax;
        this.definition = definition;
    }

    public abstract Boolean matches(String relativePath);

    public String getDefinition() {
        return this.definition;
    }

    protected String getPattern() {
        if(syntax == null) return this.definition;

        StringBuilder sb = new StringBuilder();
        for (Part current : syntax) {
            switch (current.getToken()) {
                case MATCH_ALL:
                case MATCH_ANY:
                case ESCAPED_EXCLAMATION:
                case ESCAPED_SPACE:
                case PATH_DELIM:
                case TEXT:
                case DIRECTORY_MARKER:
                    sb.append(current.getValue());
                    break;
                case NEGATE:
                case ROOTED_MARKER:
                case COMMENT:
                    break;
            }
        }
        return sb.toString();
    }

    /**
     * Whether or not the rule should be negated. !foo means foo should be removed from previous matches.
     * Example: **\/*.bak excludes all backup. Adding !/test.bak will include test.bak in the project root.
     * 

* NOTE: It is not possible to re-include a file if a parent directory of that file is excluded. * * @return {@code true} if the rule is negated (inverse), otherwise {@code false} (normal). */ public Boolean getNegated() { return this.syntax != null && this.syntax.size() > 0 && this.syntax.get(0).getToken() == IgnoreLineParser.Token.NEGATE; } public Operation evaluate(String relativePath) { if (Boolean.TRUE.equals(matches(relativePath))) { if(Boolean.TRUE.equals(this.getNegated())) { return this.getIncludeOperation(); } return this.getExcludeOperation(); } return Operation.NOOP; } protected Operation getIncludeOperation(){ return Operation.INCLUDE; } protected Operation getExcludeOperation(){ return Operation.EXCLUDE; } public static Rule create(String definition) { // NOTE: Comments that start with a : (e.g. //:) are pulled from git documentation for .gitignore // see: https://github.com/git/git/blob/90f7b16b3adc78d4bbabbd426fb69aa78c714f71/Documentation/gitignore.txt Rule rule = null; if (definition.equals(".")) { return new InvalidRule(null, definition, "Pattern '.' is invalid."); } else if (definition.equals("!.")) { return new InvalidRule(null, definition, "Pattern '!.' is invalid."); } else if (definition.startsWith("..")) { return new InvalidRule(null, definition, "Pattern '..' is invalid."); } try { List result = IgnoreLineParser.parse(definition); Boolean directoryOnly = null; if (result.size() == 0) { return rule; } else if (result.size() == 1) { // single-character filename only Part part = result.get(0); if (IgnoreLineParser.Token.MATCH_ANY.equals(part.getToken())) { rule = new RootedFileRule(result, definition); } else { rule = new FileRule(result, definition); } } else { IgnoreLineParser.Token head = result.get(0).getToken(); //: An optional prefix "`!`" which negates the pattern; any //: matching file excluded by a previous pattern will become //: included again. It is not possible to re-include a file if a parent //: directory of that file is excluded. Git doesn't list excluded //: directories for performance reasons, so any patterns on contained //: files have no effect, no matter where they are defined. //: Put a backslash ("`\`") in front of the first "`!`" for patterns //: that begin with a literal "`!`", for example, "`\!important!.txt`". // see this.getNegated(); //: If the pattern ends with a slash, it is removed for the //: purpose of the following description, but it would only find //: a match with a directory. In other words, `foo/` will match a //: directory `foo` and paths underneath it, but will not match a //: regular file or a symbolic link `foo` (this is consistent //: with the way how pathspec works in general in Git). directoryOnly = IgnoreLineParser.Token.DIRECTORY_MARKER.equals(result.get(result.size() - 1).getToken()); if (directoryOnly) { rule = new DirectoryRule(result, definition); } else if (IgnoreLineParser.Token.PATH_DELIM.equals(head)) { //: A leading slash matches the beginning of the pathname. //: For example, "/{asterisk}.c" matches "cat-file.c" but not //: "mozilla-sha1/sha1.c". rule = new RootedFileRule(result, definition); } else { // case 1 //: If the pattern does not contain a slash '/', Git treats it as //: a shell glob pattern and checks for a match against the //: pathname relative to the location of the `.gitignore` file //: (relative to the toplevel of the work tree if not from a //: `.gitignore` file). // case 2 //: Otherwise, Git treats the pattern as a shell glob suitable //: for consumption by fnmatch(3) with the FNM_PATHNAME flag: //: wildcards in the pattern will not match a / in the pathname. //: For example, "Documentation/{asterisk}.html" matches //: "Documentation/git.html" but not "Documentation/ppc/ppc.html" //: or "tools/perf/Documentation/perf.html". // case 3 //: Two consecutive asterisks ("`**`") in patterns matched against //: full pathname may have special meaning: //: //: - A leading "`**`" followed by a slash means match in all //: directories. For example, "`**/foo`" matches file or directory //: "`foo`" anywhere, the same as pattern "`foo`". "`**/foo/bar`" //: matches file or directory "`bar`" anywhere that is directly //: under directory "`foo`". //: //: - A trailing "`/**`" matches everything inside. For example, //: "`abc/**`" matches all files inside directory "`abc`", relative //: to the location of the `.gitignore` file, with infinite depth. //: //: - A slash followed by two consecutive asterisks then a slash //: matches zero or more directories. For example, "`a/**/b`" //: matches "`a/b`", "`a/x/b`", "`a/x/y/b`" and so on. //: //: - Other consecutive asterisks are considered invalid. rule = new FileRule(result, definition); } } } catch (ParserException e) { return new InvalidRule(null, definition, e.getMessage()); } return rule; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy