diff options
| author | Modestas Vainius <modestas@vainius.eu> | 2011-04-24 22:46:23 +0300 | 
|---|---|---|
| committer | Modestas Vainius <modestas@vainius.eu> | 2011-04-24 22:46:23 +0300 | 
| commit | c630dd763cf6ec096489bea551ca959540969c94 (patch) | |
| tree | 64cfc7d592950bb22167892760aa74e322066042 | |
| parent | 197979b6a641b8b5fa4856c700b1235491c73a41 (diff) | |
| download | svn2git-c630dd763cf6ec096489bea551ca959540969c94.tar svn2git-c630dd763cf6ec096489bea551ca959540969c94.tar.gz svn2git-c630dd763cf6ec096489bea551ca959540969c94.tar.bz2 svn2git-c630dd763cf6ec096489bea551ca959540969c94.tar.xz svn2git-c630dd763cf6ec096489bea551ca959540969c94.zip  | |
Support substitutions for repository/branch names.
This patch adds support for 's///' style substitutions for the
repository/branch names in the match rulesets. Useful when e.g. eliminating
characters not supported in git branch names.
Syntax:
match /...
    repository some_repo
    substitute repository s/pattern/replacement/
    branch some_branch
    substitute branch s/pattern/replacement/
end match
| -rw-r--r-- | src/ruleparser.cpp | 60 | ||||
| -rw-r--r-- | src/ruleparser.h | 11 | ||||
| -rw-r--r-- | src/svn.cpp | 6 | 
3 files changed, 77 insertions, 0 deletions
diff --git a/src/ruleparser.cpp b/src/ruleparser.cpp index eb309bf..8cd71a6 100644 --- a/src/ruleparser.cpp +++ b/src/ruleparser.cpp @@ -77,6 +77,48 @@ const QList<Rules::Match> Rules::matchRules() const      return m_matchRules;  } +Rules::Match::Substitution Rules::parseSubstitution(const QString &string) +{ +    if (string.at(0) != 's' || string.length() < 5) +        return Match::Substitution(); + +    const QChar sep = string.at(1); + +    if (string.at(string.length() - 1) != sep) +        return Match::Substitution(); + +    int i = 2, end = 0; +    Match::Substitution subst; + +    // Separator might have been escaped with a backslash +    while (i > end) { +        int backslashCount = 0; +        if ((end = string.indexOf(sep, i)) > -1) { +            for (i = end - 1; i >= 2; i--) { +                if (string.at(i) == '\\') +                    backslashCount++; +                else +                    break; +            } +        } else { +            return Match::Substitution(); // error +        } + +        if (backslashCount % 2 != 0) { +            // Separator was escaped. Search for another one +            i = end + 1; +        } +    } + +    // Found the end of the pattern +    subst.pattern = QRegExp(string.mid(2, end - 2)); +    if (!subst.pattern.isValid()) +        return Match::Substitution(); // error +    subst.replacement = string.mid(end + 1, string.length() - 1 - end - 1); + +    return subst; +} +  void Rules::load()  {      load(filename); @@ -93,7 +135,9 @@ void Rules::load(const QString &filename)      QRegExp matchLine("match\\s+(.*)", Qt::CaseInsensitive);      QRegExp matchActionLine("action\\s+(\\w+)", Qt::CaseInsensitive);      QRegExp matchRepoLine("repository\\s+(\\S+)", Qt::CaseInsensitive); +    QRegExp matchRepoSubstLine("substitute repository\\s+(.+)$", Qt::CaseInsensitive);      QRegExp matchBranchLine("branch\\s+(\\S+)", Qt::CaseInsensitive); +    QRegExp matchBranchSubstLine("substitute branch\\s+(.+)$", Qt::CaseInsensitive);      QRegExp matchRevLine("(min|max) revision (\\d+)", Qt::CaseInsensitive);      QRegExp matchAnnotateLine("annotated\\s+(\\S+)", Qt::CaseInsensitive);      QRegExp matchPrefixLine("prefix\\s+(\\S+)", Qt::CaseInsensitive); @@ -175,6 +219,22 @@ void Rules::load(const QString &filename)                  } else if (matchBranchLine.exactMatch(line)) {                      match.branch = matchBranchLine.cap(1);                      continue; +                } else if (matchRepoSubstLine.exactMatch(line)) { +                    Match::Substitution subst = parseSubstitution(matchRepoSubstLine.cap(1)); +                    if (!subst.isValid()) { +                        qFatal("Malformed substitution in rules file: line %d: %s", +                            lineNumber, qPrintable(origLine)); +                    } +                    match.repo_substs += subst; +                    continue; +                } else if (matchBranchSubstLine.exactMatch(line)) { +                    Match::Substitution subst = parseSubstitution(matchBranchSubstLine.cap(1)); +                    if (!subst.isValid()) { +                        qFatal("Malformed substitution in rules file: line %d: %s", +                            lineNumber, qPrintable(origLine)); +                    } +                    match.branch_substs += subst; +                    continue;                  } else if (matchRevLine.exactMatch(line)) {                      if (matchRevLine.cap(1) == "min")                          match.minRevision = matchRevLine.cap(2).toInt(); diff --git a/src/ruleparser.h b/src/ruleparser.h index 9d21937..26dfa72 100644 --- a/src/ruleparser.h +++ b/src/ruleparser.h @@ -57,9 +57,19 @@ public:      struct Match : Rule      { +        struct Substitution { +            QRegExp pattern; +            QString replacement; + +            bool isValid() { return !pattern.isEmpty(); } +            QString& apply(QString &string) { return string.replace(pattern, replacement); } +        }; +          QRegExp rx;          QString repository; +        QList<Substitution> repo_substs;          QString branch; +        QList<Substitution> branch_substs;          QString prefix;          int minRevision;          int maxRevision; @@ -83,6 +93,7 @@ public:      const QList<Repository> repositories() const;      const QList<Match> matchRules() const; +    Match::Substitution parseSubstitution(const QString &string);      void load();  private: diff --git a/src/svn.cpp b/src/svn.cpp index 09495be..c103728 100644 --- a/src/svn.cpp +++ b/src/svn.cpp @@ -214,11 +214,17 @@ static void splitPathName(const Rules::Match &rule, const QString &pathName, QSt      if (repository_p) {          *repository_p = svnprefix;          repository_p->replace(rule.rx, rule.repository); +        foreach (Rules::Match::Substitution subst, rule.repo_substs) { +            subst.apply(*repository_p); +        }      }      if (branch_p) {          *branch_p = svnprefix;          branch_p->replace(rule.rx, rule.branch); +        foreach (Rules::Match::Substitution subst, rule.branch_substs) { +            subst.apply(*branch_p); +        }      }      if (path_p) {  | 
