blob: 57aa87ee5caa5b586b3bbc0a8e1533f6ad5e95a3 [file] [log] [blame]
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/util/glob.dart';
import 'package:path/path.dart' as path;
/// Filter paths against a set of [_ignorePatterns] relative to a [root]
/// directory. Paths outside of [root] are also ignored.
class PathFilter {
/// The path context to use when manipulating paths.
final path.Context pathContext;
/// Path that all ignore patterns are relative to.
final String root;
/// List of ignore patterns that paths are tested against.
final List<Glob> _ignorePatterns = new List<Glob>();
/// Construct a new path filter rooted at [root] with [ignorePatterns].
/// If [pathContext] is not specified, then the system path context is used.
PathFilter(this.root, List<String> ignorePatterns, [path.Context pathContext])
: this.pathContext = pathContext ?? path.context {
setIgnorePatterns(ignorePatterns);
}
/// Returns true if [path] should be ignored. A path is ignored if it is not
/// contained in [root] or matches one of the ignore patterns.
/// [path] is absolute or relative to [root].
bool ignored(String path) {
path = _canonicalize(path);
return !_contained(path) || _match(path);
}
/// Set the ignore patterns.
void setIgnorePatterns(List<String> ignorePatterns) {
_ignorePatterns.clear();
if (ignorePatterns != null) {
for (var ignorePattern in ignorePatterns) {
_ignorePatterns.add(new Glob(pathContext.separator, ignorePattern));
}
}
}
@override
String toString() {
StringBuffer sb = new StringBuffer();
for (Glob pattern in _ignorePatterns) {
sb.write('$pattern ');
}
sb.writeln('');
return sb.toString();
}
/// Returns the absolute path of [path], relative to [root].
String _canonicalize(String path) =>
pathContext.normalize(pathContext.join(root, path));
/// Returns true when [path] is contained inside [root].
bool _contained(String path) => path.startsWith(root);
/// Returns true if [path] matches any ignore patterns.
bool _match(String path) {
path = _relative(path);
for (Glob glob in _ignorePatterns) {
if (glob.matches(path)) {
return true;
}
}
return false;
}
/// Returns the relative portion of [path] from [root].
String _relative(String path) => pathContext.relative(path, from: root);
}