changeset 408:e732521a9eb4 smartgit3

Issue 28: support hgignore entries with syntax prefix
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 16 Mar 2012 15:06:44 +0100
parents 30922c728341
children 0f5696623512
files src/org/tmatesoft/hg/repo/HgIgnore.java test/org/tmatesoft/hg/test/TestIgnore.java
diffstat 2 files changed, 48 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgIgnore.java	Fri Mar 16 12:51:03 2012 +0100
+++ b/src/org/tmatesoft/hg/repo/HgIgnore.java	Fri Mar 16 15:06:44 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011 TMate Software Ltd
+ * Copyright (c) 2010-2012 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -55,15 +55,17 @@
 	}
 
 	/* package-local */List<String> read(BufferedReader content) throws IOException {
+		final String REGEXP = "regexp", GLOB = "glob";
+		final String REGEXP_PREFIX = REGEXP + ":", GLOB_PREFIX = GLOB + ":";
 		ArrayList<String> errors = new ArrayList<String>();
 		ArrayList<Pattern> result = new ArrayList<Pattern>(entries); // start with existing
-		String syntax = "regexp"; // or "glob"
+		String syntax = REGEXP;
 		String line;
 		while ((line = content.readLine()) != null) {
 			line = line.trim();
 			if (line.startsWith("syntax:")) {
 				syntax = line.substring("syntax:".length()).trim();
-				if (!"regexp".equals(syntax) && !"glob".equals(syntax)) {
+				if (!REGEXP.equals(syntax) && !GLOB.equals(syntax)) {
 					errors.add(line);
 					continue;
 					//throw new IllegalStateException(line);
@@ -81,17 +83,31 @@
 						line = line.substring(0, x).trim();
 					}
 				}
+				// due to the nature of Mercurial implementation, lines prefixed with syntax kind
+				// are processed correctly (despite the fact hgignore(5) suggest "syntax:<kind>" as the 
+				// only way to specify it). lineSyntax below leaves a chance for the line to switch 
+				// syntax in use without affecting default kind.
+				String lineSyntax;
+				if (line.startsWith(GLOB_PREFIX)) {
+					line = line.substring(GLOB_PREFIX.length()).trim();
+					lineSyntax = GLOB;
+				} else if (line.startsWith(REGEXP_PREFIX)) {
+					line = line.substring(REGEXP_PREFIX.length()).trim();
+					lineSyntax = REGEXP;
+				} else {
+					lineSyntax = syntax;
+				}
 				if (line.length() == 0) {
 					continue;
 				}
-				if ("glob".equals(syntax)) {
+				if (GLOB.equals(lineSyntax)) {
 					// hgignore(5)
 					// (http://www.selenic.com/mercurial/hgignore.5.html) says slashes '\' are escape characters,
 					// hence no special  treatment of Windows path
 					// however, own attempts make me think '\' on Windows are not treated as escapes
 					line = glob2regex(line);
 				} else {
-					assert "regexp".equals(syntax);
+					assert REGEXP.equals(lineSyntax);
 					// regular expression patterns need not match start of the line unless demanded explicitly 
 					line = line.charAt(0) == '^' ? line : ".*" + line;
 				}
--- a/test/org/tmatesoft/hg/test/TestIgnore.java	Fri Mar 16 12:51:03 2012 +0100
+++ b/test/org/tmatesoft/hg/test/TestIgnore.java	Fri Mar 16 15:06:44 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 TMate Software Ltd
+ * Copyright (c) 2011-2012 TMate Software Ltd
  *  
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,6 +16,8 @@
  */
 package org.tmatesoft.hg.test;
 
+import static org.tmatesoft.hg.util.Path.create;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
@@ -152,4 +154,28 @@
 			errorCollector.assertTrue(p.toString(), !hgIgnore.isIgnored(p));
 		}
 	}
+
+	@Test
+	public void testSyntaxPrefixAtLine() throws Exception {
+		String s = "glob:*.c\nregexp:.*\\.d";
+		HgIgnore hgIgnore = HgInternals.newHgIgnore(new StringReader(s));
+		Path[] toPass = new Path[] {
+				create("a/c"),
+				create("a/d"),
+				create("a/d.a"),
+				create("a/d.e"),
+		};
+		Path[] toIgnore = new Path[] {
+				create("a.c"),
+				create("a.d"),
+				create("src/a.c"),
+				create("src/a.d"),
+		};
+		for (Path p : toIgnore) {
+			errorCollector.assertTrue("Shall ignore " + p, hgIgnore.isIgnored(p));
+		}
+		for (Path p : toPass) {
+			errorCollector.assertTrue("Shall pass " + p, !hgIgnore.isIgnored(p));
+		}
+	}
 }