comparison src/org/tmatesoft/hg/repo/HgIgnore.java @ 335:3d41dc148d14

Do not fail with exception on syntax errors in .hgignore
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 10 Nov 2011 05:44:12 +0100
parents 086a326f181f
children 863356c2847e
comparison
equal deleted inserted replaced
334:15e1961719f2 335:3d41dc148d14
22 import java.io.IOException; 22 import java.io.IOException;
23 import java.util.ArrayList; 23 import java.util.ArrayList;
24 import java.util.Collections; 24 import java.util.Collections;
25 import java.util.List; 25 import java.util.List;
26 import java.util.regex.Pattern; 26 import java.util.regex.Pattern;
27 import java.util.regex.PatternSyntaxException;
27 28
28 import org.tmatesoft.hg.util.Path; 29 import org.tmatesoft.hg.util.Path;
29 30
30 /** 31 /**
31 * Handling of ignored paths according to .hgignore configuration 32 * Handling of ignored paths according to .hgignore configuration
39 40
40 HgIgnore() { 41 HgIgnore() {
41 entries = Collections.emptyList(); 42 entries = Collections.emptyList();
42 } 43 }
43 44
44 /* package-local */void read(File hgignoreFile) throws IOException { 45 /* package-local */List<String> read(File hgignoreFile) throws IOException {
45 if (!hgignoreFile.exists()) { 46 if (!hgignoreFile.exists()) {
46 return; 47 return null;
47 } 48 }
48 BufferedReader fr = new BufferedReader(new FileReader(hgignoreFile)); 49 BufferedReader fr = new BufferedReader(new FileReader(hgignoreFile));
49 try { 50 try {
50 read(fr); 51 return read(fr);
51 } finally { 52 } finally {
52 fr.close(); 53 fr.close();
53 } 54 }
54 } 55 }
55 56
56 /* package-local */void read(BufferedReader content) throws IOException { 57 /* package-local */List<String> read(BufferedReader content) throws IOException {
58 ArrayList<String> errors = new ArrayList<String>();
57 ArrayList<Pattern> result = new ArrayList<Pattern>(entries); // start with existing 59 ArrayList<Pattern> result = new ArrayList<Pattern>(entries); // start with existing
58 String syntax = "regexp"; // or "glob" 60 String syntax = "regexp"; // or "glob"
59 String line; 61 String line;
60 while ((line = content.readLine()) != null) { 62 while ((line = content.readLine()) != null) {
61 line = line.trim(); 63 line = line.trim();
62 if (line.startsWith("syntax:")) { 64 if (line.startsWith("syntax:")) {
63 syntax = line.substring("syntax:".length()).trim(); 65 syntax = line.substring("syntax:".length()).trim();
64 if (!"regexp".equals(syntax) && !"glob".equals(syntax)) { 66 if (!"regexp".equals(syntax) && !"glob".equals(syntax)) {
65 throw new IllegalStateException(line); 67 errors.add(line);
68 continue;
69 //throw new IllegalStateException(line);
66 } 70 }
67 } else if (line.length() > 0) { 71 } else if (line.length() > 0) {
68 // shall I account for local paths in the file (i.e. 72 // shall I account for local paths in the file (i.e.
69 // back-slashed on windows)? 73 // back-slashed on windows)?
70 int x, s = 0; 74 int x, s = 0;
85 // (http://www.selenic.com/mercurial/hgignore.5.html) says slashes '\' are escape characters, 89 // (http://www.selenic.com/mercurial/hgignore.5.html) says slashes '\' are escape characters,
86 // hence no special treatment of Windows path 90 // hence no special treatment of Windows path
87 // however, own attempts make me think '\' on Windows are not treated as escapes 91 // however, own attempts make me think '\' on Windows are not treated as escapes
88 line = glob2regex(line); 92 line = glob2regex(line);
89 } 93 }
90 result.add(Pattern.compile(line)); // case-sensitive 94 try {
95 result.add(Pattern.compile(line)); // case-sensitive
96 } catch (PatternSyntaxException ex) {
97 errors.add(line + "@" + ex.getMessage());
98 }
91 } 99 }
92 } 100 }
93 result.trimToSize(); 101 result.trimToSize();
94 entries = result; 102 entries = result;
103 return errors.isEmpty() ? null : errors;
95 } 104 }
96 105
97 // note, #isIgnored(), even if queried for directories and returned positive reply, may still get 106 // note, #isIgnored(), even if queried for directories and returned positive reply, may still get
98 // a file from that ignored folder to get examined. Thus, patterns like "bin" shall match not only a folder, 107 // a file from that ignored folder to get examined. Thus, patterns like "bin" shall match not only a folder,
99 // but any file under that folder as well 108 // but any file under that folder as well