git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [JGIT PATCH v2 14/24] Added the class IgnoreRuleListFactory.

From
FKFlorian Köberle <florianskarten@web.de>
Date
May 13, 2008, 10:19 UTC
Message-ID
<48296B41.9020105@web.de>
In-Reply-To
<20080513010844.GE29038@spearce.org>
Shawn O. Pearce wrote:
Show 42 quoted lines
> Florian Koeberle <florianskarten@web.de> wrote:
>> +/**
>> + * This class can be used to create lists of {@link Rule} objects from lines of
>> + * .gitignore like files.
>> + * 
>> + */
>> +class IgnoreRuleListFactory {
>> +
>> +	List<Rule> createIgnoreRuleList(Iterable<String> lineIterable) {
>> +		LinkedList<Rule> rules = new LinkedList<Rule>();
>> +		for (String line : lineIterable) {
>> +			final String trimmedLine = line.trim();
>> +			if (trimmedLine.startsWith("#")) {
>> +				continue;
>> +			}
>> +			if (trimmedLine.length() == 0) {
>> +				continue;
>> +			}
>> +			rules.add(0, createRule(trimmedLine));
>> +		}
>> +		return rules;
>> +	}
>> +
>> +	List<Rule> createIgnoreRuleList(List<File> files)
>> +			throws FileNotFoundException {
>> +		final List<String> lines = new ArrayList<String>();
>> +		for (File file : files) {
>> +			Scanner scanner = new Scanner(file);
>> +			try {
>> +				while (scanner.hasNextLine()) {
>> +					lines.add(scanner.nextLine());
>> +				}
>> +			} finally {
>> +				scanner.close();
>> +			}
>> +		}
>> +		return createIgnoreRuleList(lines);
>> +	}
> 
> Why go through all this work to buffer the lines we don't care about
> (starting with # or are blank) when we could just discard them in the
> inside of createIgnoreRuleList and then create the rule right away?

I did this to reduce complexity and to increase modularity. The method createIgnoreRuleList(Iterable<String> lineIterable) can now be tested without the need to create files. Also it is so possible to read the patterns from different sources.

If you worry about memory usuage I could create some kind of RulesBuilder class:

public class RulesBuilder {
	private final List<Rule> rules;
	private RuleListToObjectConverter converter;
	// method used by tests:
	public void addIgnoreRule(String ignoreRuleLine) {
		
	}
  	public void addIgnoreRuleFile(File) {
		// reads file and calls addIgnoreRule
	}
	public void addIncludeRuleOfAddCommand(String pattern) {
	}
	public void addIgnoreGitDirectoryRule() {
	}
	public Rules buildRules() {
		return converter.convertToObject(rules);
	}
}
This would have the advantages:
* all Rule creating code at one place.
* There is no need to keep the original lines in memory.
* It's easy to create rules for testing purposes.
* It's easy to create Factories like AddRulesFactory.
Show 21 quoted lines
> 
>> +	private Rule createRule(String trimmedLine) {
>> +		final boolean exclude;
>> +		String patternString;
>> +		if (trimmedLine.startsWith("!")) {
>> +			exclude = false;
>> +			patternString = trimmedLine.substring(1);
>> +		} else {
>> +			exclude = true;
>> +			patternString = trimmedLine;
>> +		}
> 
> I suspect this code would be easier to follow if you just accepted
> changing the method parameter, such as:
> 
> 	private Rule createRule(String pattern) {
> 		boolean exclude = true;
> 		if (pattern.startsWith("!)) {
> 			pattern = pattern.substring(1);
> 			exclude = false;
> 		}

If I remember correctly Intellij IDEA marks per default cases where you change a parameter. So it looks like that there are style guides which are against the practice of changing the values of parameters.

That and the fact that you can't make exclude final now where the reason why I wrote it the otherway.

Show 23 quoted lines
> 
>> +		final boolean matchDirectoriesOnly;
>> +		if (patternString.endsWith("/")) {
>> +			matchDirectoriesOnly = true;
>> +			patternString = patternString.substring(0,
>> +					patternString.length() - 1);
>> +		} else {
>> +			matchDirectoriesOnly = false;
>> +		}
>> +
>> +		final FilePattern pattern;
>> +		if (patternString.contains("/")) {
>> +			if (patternString.startsWith("/")) {
>> +				patternString = patternString.substring(1);
>> +			}
> 
> "foo/bar" will always end up in this code-path and will not match
> in all levels of the tree if I follow your code correctly.
> 
> An ignore rule in the top level of "foo/bar" should ignore any entry
> named "bar" within a directory "foo" at any level of the tree, even
> if it is 35 directories down from the root.  Isn't ComplexFilePattern
> about the absolute (starts with "/") cases only?
Yes, ComplexFilePattern is about that cases only.
I implemented it that way, becasue git behave the same way:
* create the follwing file: a/a/b/test.txt
* add the line "a/b" to .gitignore
* add a and notice that it adds the test.txt file.
Show 12 quoted lines
> 
>> +			final StringTokenizer stringTokenizer = new StringTokenizer(
>> +					patternString, "/");
>> +			final List<String> patternList = new ArrayList<String>();
>> +			while (stringTokenizer.hasMoreTokens()) {
>> +				final String token = stringTokenizer.nextToken();
>> +				patternList.add(token);
>> +			}
> 
> StringTokenizer is more-or-less replaced by String.split("/"), with
> the split method being the more preferred method of doing this.
> 
Ok
Previous: Shawn O. PearceNext: Shawn O. Pearce
Message 28 of 46 in “Implementation of a file tree iteration using ignore rules.”
  1. 0/24 Implementation of a file tree iteration using ignore rules.Florian Koeberle, May 12, 2008
  2. 01/24 Start of an implementation of a git like command line tool.Florian Koeberle, May 12, 2008
  3. 02/24 Formatted Repository class.Florian Koeberle, May 12, 2008
  4. 03/24 Formatted Constats class.Florian Koeberle, May 12, 2008
  5. 04/24 Added path related constats to Constats class.Florian Koeberle, May 12, 2008
  6. Shawn O. PearceMay 12, 2008
  7. Florian KöberleMay 23, 2008
  8. 05/24 Added WorkTree class which can be constructed over Repository.Florian Koeberle, May 12, 2008
  9. Shawn O. PearceMay 13, 2008
  10. Robin RosenbergMay 13, 2008
  11. Shawn O. PearceMay 14, 2008
  12. 06/24 Added a "init" command to the git like command line tool.Florian Koeberle, May 12, 2008
  13. 07/24 Added findWorkTree method to Repository class.Florian Koeberle, May 12, 2008
  14. Shawn O. PearceMay 13, 2008
  15. Florian KöberleMay 23, 2008
  16. Miklos VajnaMay 23, 2008
  17. Shawn O. PearceMay 23, 2008
  18. Robin RosenbergMay 23, 2008
  19. 08/24 Added the interface FilePattern.Florian Koeberle, May 12, 2008
  20. 09/24 Added the class Rule.Florian Koeberle, May 12, 2008
  21. 10/24 Added the iterface Rules.Florian Koeberle, May 12, 2008
  22. 11/24 Added the class FNMatchPattern.Florian Koeberle, May 12, 2008
  23. Shawn O. PearceMay 13, 2008
  24. 12/24 Added the class GlobalFilePatternFlorian Koeberle, May 12, 2008
  25. 13/24 Added the class ComplexFilePattern.Florian Koeberle, May 12, 2008
  26. 14/24 Added the class IgnoreRuleListFactory.Florian Koeberle, May 12, 2008
  27. Shawn O. PearceMay 13, 2008
  28. Florian KöberleMay 13, 2008
  29. Shawn O. PearceMay 14, 2008
  30. 15/24 Added a Rules interface implementation and a factory for it.Florian Koeberle, May 12, 2008
  31. 16/24 Added test class OverallIgnoreRulestest.Florian Koeberle, May 12, 2008
  32. 17/24 Added the class TreeFilePattern.Florian Koeberle, May 12, 2008
  33. Shawn O. PearceMay 13, 2008
  34. 18/24 Added InvalidPatternException and PathNotInProjectDirectoryExceptionFlorian Koeberle, May 12, 2008
  35. 19/24 Added the class AddRuleListFactory.Florian Koeberle, May 12, 2008
  36. Shawn O. PearceMay 13, 2008
  37. Florian KöberleMay 13, 2008
  38. Robin RosenbergMay 13, 2008
  39. Shawn O. PearceMay 14, 2008
  40. 20/24 Added class AddRulesFactory.Florian Koeberle, May 12, 2008
  41. 21/24 Added the class LightFileTreeIterator and a test for it.Florian Koeberle, May 12, 2008
  42. Paolo BonziniMay 14, 2008
  43. 22/24 Added class LightFileTreeIterable.Florian Koeberle, May 12, 2008
  44. 23/24 Added the test class AddCommandIterationTest.Florian Koeberle, May 12, 2008
  45. 24/24 Added a "add" command to the git like command line tool.Florian Koeberle, May 12, 2008
  46. Miklos VajnaMay 12, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.