Skip to content

Commit c630dd7

Browse files
committed
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
1 parent 197979b commit c630dd7

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

src/ruleparser.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,48 @@ const QList<Rules::Match> Rules::matchRules() const
7777
return m_matchRules;
7878
}
7979

80+
Rules::Match::Substitution Rules::parseSubstitution(const QString &string)
81+
{
82+
if (string.at(0) != 's' || string.length() < 5)
83+
return Match::Substitution();
84+
85+
const QChar sep = string.at(1);
86+
87+
if (string.at(string.length() - 1) != sep)
88+
return Match::Substitution();
89+
90+
int i = 2, end = 0;
91+
Match::Substitution subst;
92+
93+
// Separator might have been escaped with a backslash
94+
while (i > end) {
95+
int backslashCount = 0;
96+
if ((end = string.indexOf(sep, i)) > -1) {
97+
for (i = end - 1; i >= 2; i--) {
98+
if (string.at(i) == '\\')
99+
backslashCount++;
100+
else
101+
break;
102+
}
103+
} else {
104+
return Match::Substitution(); // error
105+
}
106+
107+
if (backslashCount % 2 != 0) {
108+
// Separator was escaped. Search for another one
109+
i = end + 1;
110+
}
111+
}
112+
113+
// Found the end of the pattern
114+
subst.pattern = QRegExp(string.mid(2, end - 2));
115+
if (!subst.pattern.isValid())
116+
return Match::Substitution(); // error
117+
subst.replacement = string.mid(end + 1, string.length() - 1 - end - 1);
118+
119+
return subst;
120+
}
121+
80122
void Rules::load()
81123
{
82124
load(filename);
@@ -93,7 +135,9 @@ void Rules::load(const QString &filename)
93135
QRegExp matchLine("match\\s+(.*)", Qt::CaseInsensitive);
94136
QRegExp matchActionLine("action\\s+(\\w+)", Qt::CaseInsensitive);
95137
QRegExp matchRepoLine("repository\\s+(\\S+)", Qt::CaseInsensitive);
138+
QRegExp matchRepoSubstLine("substitute repository\\s+(.+)$", Qt::CaseInsensitive);
96139
QRegExp matchBranchLine("branch\\s+(\\S+)", Qt::CaseInsensitive);
140+
QRegExp matchBranchSubstLine("substitute branch\\s+(.+)$", Qt::CaseInsensitive);
97141
QRegExp matchRevLine("(min|max) revision (\\d+)", Qt::CaseInsensitive);
98142
QRegExp matchAnnotateLine("annotated\\s+(\\S+)", Qt::CaseInsensitive);
99143
QRegExp matchPrefixLine("prefix\\s+(\\S+)", Qt::CaseInsensitive);
@@ -175,6 +219,22 @@ void Rules::load(const QString &filename)
175219
} else if (matchBranchLine.exactMatch(line)) {
176220
match.branch = matchBranchLine.cap(1);
177221
continue;
222+
} else if (matchRepoSubstLine.exactMatch(line)) {
223+
Match::Substitution subst = parseSubstitution(matchRepoSubstLine.cap(1));
224+
if (!subst.isValid()) {
225+
qFatal("Malformed substitution in rules file: line %d: %s",
226+
lineNumber, qPrintable(origLine));
227+
}
228+
match.repo_substs += subst;
229+
continue;
230+
} else if (matchBranchSubstLine.exactMatch(line)) {
231+
Match::Substitution subst = parseSubstitution(matchBranchSubstLine.cap(1));
232+
if (!subst.isValid()) {
233+
qFatal("Malformed substitution in rules file: line %d: %s",
234+
lineNumber, qPrintable(origLine));
235+
}
236+
match.branch_substs += subst;
237+
continue;
178238
} else if (matchRevLine.exactMatch(line)) {
179239
if (matchRevLine.cap(1) == "min")
180240
match.minRevision = matchRevLine.cap(2).toInt();

src/ruleparser.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,19 @@ class Rules
5757

5858
struct Match : Rule
5959
{
60+
struct Substitution {
61+
QRegExp pattern;
62+
QString replacement;
63+
64+
bool isValid() { return !pattern.isEmpty(); }
65+
QString& apply(QString &string) { return string.replace(pattern, replacement); }
66+
};
67+
6068
QRegExp rx;
6169
QString repository;
70+
QList<Substitution> repo_substs;
6271
QString branch;
72+
QList<Substitution> branch_substs;
6373
QString prefix;
6474
int minRevision;
6575
int maxRevision;
@@ -83,6 +93,7 @@ class Rules
8393

8494
const QList<Repository> repositories() const;
8595
const QList<Match> matchRules() const;
96+
Match::Substitution parseSubstitution(const QString &string);
8697
void load();
8798

8899
private:

src/svn.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,17 @@ static void splitPathName(const Rules::Match &rule, const QString &pathName, QSt
214214
if (repository_p) {
215215
*repository_p = svnprefix;
216216
repository_p->replace(rule.rx, rule.repository);
217+
foreach (Rules::Match::Substitution subst, rule.repo_substs) {
218+
subst.apply(*repository_p);
219+
}
217220
}
218221

219222
if (branch_p) {
220223
*branch_p = svnprefix;
221224
branch_p->replace(rule.rx, rule.branch);
225+
foreach (Rules::Match::Substitution subst, rule.branch_substs) {
226+
subst.apply(*branch_p);
227+
}
222228
}
223229

224230
if (path_p) {

0 commit comments

Comments
 (0)