annotate src/org/tmatesoft/hg/repo/HgIgnore.java @ 338:3cfa4d908fc9

Add options to control DataAccessProvider, allow to turn off use of file memory mapping in particular to solve potential sharing violation (os file handle gets released on MappedByteByffer being GC'd, not on FileChannel.close())
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 15 Nov 2011 04:47:03 +0100
parents 3d41dc148d14
children 863356c2847e
rev   line source
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
1 /*
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
2 * Copyright (c) 2010-2011 TMate Software Ltd
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
3 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
4 * This program is free software; you can redistribute it and/or modify
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
5 * it under the terms of the GNU General Public License as published by
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
6 * the Free Software Foundation; version 2 of the License.
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
7 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
8 * This program is distributed in the hope that it will be useful,
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
11 * GNU General Public License for more details.
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
12 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
13 * For information on how to redistribute this software under
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
14 * the terms of a license other than GNU General Public License
102
a3a2e5deb320 Updated contact address to support@hg4j.com
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 91
diff changeset
15 * contact TMate Software at support@hg4j.com
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
17 package org.tmatesoft.hg.repo;
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
18
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
19 import java.io.BufferedReader;
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
20 import java.io.File;
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
21 import java.io.FileReader;
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
22 import java.io.IOException;
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
23 import java.util.ArrayList;
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
24 import java.util.Collections;
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
25 import java.util.List;
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
26 import java.util.regex.Pattern;
335
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
27 import java.util.regex.PatternSyntaxException;
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
28
141
8248aae33f7d Adopt FileIterator moving towards WCStatusCollector parameterizing. Improved path handling, move 'em around
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 114
diff changeset
29 import org.tmatesoft.hg.util.Path;
8248aae33f7d Adopt FileIterator moving towards WCStatusCollector parameterizing. Improved path handling, move 'em around
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 114
diff changeset
30
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
31 /**
141
8248aae33f7d Adopt FileIterator moving towards WCStatusCollector parameterizing. Improved path handling, move 'em around
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 114
diff changeset
32 * Handling of ignored paths according to .hgignore configuration
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
33 *
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
34 * @author Artem Tikhomirov
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 15
diff changeset
35 * @author TMate Software Ltd.
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
36 */
289
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
37 public class HgIgnore implements Path.Matcher {
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
38
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
39 private List<Pattern> entries;
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
40
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
41 HgIgnore() {
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
42 entries = Collections.emptyList();
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
43 }
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
44
335
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
45 /* package-local */List<String> read(File hgignoreFile) throws IOException {
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
46 if (!hgignoreFile.exists()) {
335
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
47 return null;
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
48 }
269
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
49 BufferedReader fr = new BufferedReader(new FileReader(hgignoreFile));
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
50 try {
335
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
51 return read(fr);
269
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
52 } finally {
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
53 fr.close();
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
54 }
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
55 }
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
56
335
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
57 /* package-local */List<String> read(BufferedReader content) throws IOException {
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
58 ArrayList<String> errors = new ArrayList<String>();
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
59 ArrayList<Pattern> result = new ArrayList<Pattern>(entries); // start with existing
269
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
60 String syntax = "regexp"; // or "glob"
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
61 String line;
269
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
62 while ((line = content.readLine()) != null) {
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
63 line = line.trim();
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
64 if (line.startsWith("syntax:")) {
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
65 syntax = line.substring("syntax:".length()).trim();
269
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
66 if (!"regexp".equals(syntax) && !"glob".equals(syntax)) {
335
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
67 errors.add(line);
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
68 continue;
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
69 //throw new IllegalStateException(line);
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
70 }
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
71 } else if (line.length() > 0) {
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
72 // shall I account for local paths in the file (i.e.
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
73 // back-slashed on windows)?
269
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
74 int x, s = 0;
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
75 while ((x = line.indexOf('#', s)) >= 0) {
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
76 if (x > 0 && line.charAt(x-1) == '\\') {
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
77 // remove escape char
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
78 line = line.substring(0, x-1).concat(line.substring(x));
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
79 s = x; // with exclusion of char at [x], s now points to what used to be at [x+1]
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
80 } else {
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
81 line = line.substring(0, x).trim();
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
82 }
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
83 }
269
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
84 if (line.length() == 0) {
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
85 continue;
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
86 }
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
87 if ("glob".equals(syntax)) {
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
88 // hgignore(5)
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
89 // (http://www.selenic.com/mercurial/hgignore.5.html) says slashes '\' are escape characters,
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
90 // hence no special treatment of Windows path
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
91 // however, own attempts make me think '\' on Windows are not treated as escapes
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
92 line = glob2regex(line);
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
93 }
335
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
94 try {
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
95 result.add(Pattern.compile(line)); // case-sensitive
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
96 } catch (PatternSyntaxException ex) {
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
97 errors.add(line + "@" + ex.getMessage());
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
98 }
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
99 }
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
100 }
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
101 result.trimToSize();
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
102 entries = result;
335
3d41dc148d14 Do not fail with exception on syntax errors in .hgignore
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 289
diff changeset
103 return errors.isEmpty() ? null : errors;
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
104 }
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
105
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
106 // note, #isIgnored(), even if queried for directories and returned positive reply, may still get
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
107 // a file from that ignored folder to get examined. Thus, patterns like "bin" shall match not only a folder,
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
108 // but any file under that folder as well
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
109 // Alternatively, file walker may memorize folder is ignored and uses this information for all nested files. However,
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
110 // this approach would require walker (a) return directories (b) provide nesting information. This may become
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
111 // troublesome when one walks not over io.File, but Eclipse's IResource or any other custom VFS.
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
112 //
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
113 //
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
114 // might be interesting, although looks like of no direct use in my case
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
115 // @see http://stackoverflow.com/questions/1247772/is-there-an-equivalent-of-java-util-regex-for-glob-type-patterns
289
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
116 //
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
117 // TODO consider refactoring to reuse in PathGlobMatcher#glob2regexp
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
118 private static String glob2regex(String line) {
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
119 assert line.length() > 0;
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
120 StringBuilder sb = new StringBuilder(line.length() + 10);
269
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
121 if (line.charAt(0) != '*') {
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
122 sb.append('^'); // help avoid matcher.find() to match 'bin' pattern in the middle of the filename
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
123 }
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
124 int start = 0, end = line.length() - 1;
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
125 // '*' at the beginning and end of a line are useless for Pattern
114
46291ec605a0 Filters to read and initialize according to configuration files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
126 // XXX although how about **.txt - such globs can be seen in a config, are they valid for HgIgnore?
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
127 while (start <= end && line.charAt(start) == '*') start++;
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
128 while (end > start && line.charAt(end) == '*') end--;
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
129
269
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
130 int inCurly = 0;
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
131 for (int i = start; i <= end; i++) {
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
132 char ch = line.charAt(i);
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
133 if (ch == '.' || ch == '\\') {
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
134 sb.append('\\');
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
135 } else if (ch == '?') {
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
136 // simple '.' substitution might work out, however, more formally
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
137 // a char class seems more appropriate to avoid accidentally
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
138 // matching a subdirectory with ? char (i.e. /a/b?d against /a/bad, /a/bed and /a/b/d)
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
139 // @see http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_13_03
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
140 // quote: "The slash character in a pathname shall be explicitly matched by using one or more slashes in the pattern;
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
141 // it shall neither be matched by the asterisk or question-mark special characters nor by a bracket expression"
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
142 sb.append("[^/]");
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
143 continue;
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
144 } else if (ch == '*') {
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
145 sb.append("[^/]*?");
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
146 continue;
269
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
147 } else if (ch == '{') {
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
148 // XXX in fact, need to respect if last char was escaping ('\\'), then don't need to treat this as special
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
149 // see link at javadoc above for reasonable example
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
150 inCurly++;
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
151 sb.append('(');
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
152 continue;
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
153 } else if (ch == '}') {
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
154 if (inCurly > 0) {
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
155 inCurly--;
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
156 sb.append(')');
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
157 continue;
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
158 }
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
159 } else if (ch == ',' && inCurly > 0) {
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
160 sb.append('|');
7af843ecc378 Respect glob pattern with alternatives {a,b}
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 225
diff changeset
161 continue;
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
162 }
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
163 sb.append(ch);
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
164 }
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
165 return sb.toString();
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
166 }
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
167
289
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
168 /**
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
169 * @param path file or directory name in question
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
170 * @return <code>true</code> if matches repository configuration of ignored files.
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
171 */
141
8248aae33f7d Adopt FileIterator moving towards WCStatusCollector parameterizing. Improved path handling, move 'em around
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 114
diff changeset
172 public boolean isIgnored(Path path) {
91
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
173 for (Pattern p : entries) {
c2ce1cfaeb9e ignore file with regex and 'honest' glob support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
174 if (p.matcher(path).find()) {
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
175 return true;
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
176 }
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
177 }
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
178 return false;
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
179 }
289
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
180
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
181 /**
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
182 * A handy wrap of {@link #isIgnored(Path)} into {@link Path.Matcher}. Yields same result as {@link #isIgnored(Path)}.
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
183 * @return <code>true</code> if file is deemed ignored.
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
184 */
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
185 public boolean accept(Path path) {
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
186 return isIgnored(path);
086a326f181f Provide public access to ignored files configuration to use in alternative file walkers
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 271
diff changeset
187 }
15
865bf07f381f Basic hgignore handling
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
188 }