-
Notifications
You must be signed in to change notification settings - Fork 361
/
Copy pathExclusions.cs
150 lines (131 loc) · 5.38 KB
/
Exclusions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace Microsoft.SignCheck.Verification
{
public class Exclusions
{
private static readonly char[] _wildCards = new char[] { '*', '?' };
private List<Exclusion> _exclusions = new List<Exclusion>();
public int Count
{
get
{
return _exclusions.Count;
}
}
public Exclusions()
{
}
/// <summary>
/// Creates a collection of <see cref="Exclusion"/>s from a text file.
/// </summary>
/// <param name="path">Path to a file that contains exclusion entries.</param>
public Exclusions(string path)
{
if (File.Exists(path))
{
using (StreamReader fileReader = File.OpenText(path))
{
string line = fileReader.ReadLine();
while (line != null)
{
if (!String.IsNullOrEmpty(line))
{
Add(new Exclusion(line));
}
line = fileReader.ReadLine();
}
}
}
}
public void Add(Exclusion exclusion)
{
if (!_exclusions.Contains(exclusion))
{
_exclusions.Add(exclusion);
}
}
public void Clear()
{
_exclusions.Clear();
}
public bool Contains(Exclusion exclusion)
{
return _exclusions.Contains(exclusion);
}
/// <summary>
/// Return true if an exclusion matches the file path, parent file container or the path in the container
/// </summary>
/// <param name="path">The path of the file on disk.</param>
/// <param name="parent">The parent (container) of the file.</param>
/// <param name="containerPath">The path of the file in the container. May be null if the file is not embedded in a container.</param>
/// <returns></returns>
public bool IsExcluded(string path, string parent, string containerPath)
{
// 1. The file/container path matches a file part of the exclusion and the parent matches the parent part of the exclusion.
// Example: bar.dll;*.zip --> Exclude any occurrence of bar.dll that is in a zip file
// bar.dll;foo.zip --> Exclude bar.dll only if it is contained inside foo.zip
if (_exclusions.Any(e => (IsMatch(e.FilePatterns, path) || IsMatch(e.FilePatterns, containerPath)) && (IsMatch(e.ParentFiles, parent))))
{
return true;
}
// 2. The file/container path matches the file part of the exclusion and there is no parent exclusion.
// Example: *.dll;; --> Exclude any file with a .dll extension
if (_exclusions.Any(e => (IsMatch(e.FilePatterns, path) || IsMatch(e.FilePatterns, containerPath)) && (e.ParentFiles.All(pf => String.IsNullOrEmpty(pf)))))
{
return true;
}
// 3. There is no file exclusion, but a parent exclusion matches.
// Example: ;foo.zip; --> Exclude any file in foo.zip. This is similar to using *;foo.zip;
return _exclusions.Any(e => (e.FilePatterns.All(fp => String.IsNullOrEmpty(fp)) && IsMatch(e.ParentFiles, parent)));
}
/// <summary>
/// Returns true if any <see cref="Exclusion.FilePatterns"/> matches the value of <paramref name="path"/>.
/// </summary>
/// <param name="path">The value to match against any <see cref="Exclusion.FilePatterns"/>.</param>
/// <returns></returns>
public bool IsFileExcluded(string path)
{
return _exclusions.Any(e => IsMatch(e.FilePatterns, path));
}
/// <summary>
/// Returns true if any <see cref="Exclusion.ParentFiles"/> matches the value of <paramref name="parent"/>.
/// </summary>
/// <param name="parent">The value to match against any <see cref="Exclusion.ParentFiles"/>.</param>
/// <returns></returns>
public bool IsParentExcluded(string parent)
{
return _exclusions.Any(e => IsMatch(e.ParentFiles, parent));
}
private bool IsMatch(string[] patterns, string value)
{
return patterns.Any(p => IsMatch(p, value));
}
private bool IsMatch(string pattern, string value)
{
if (String.IsNullOrEmpty(pattern) || String.IsNullOrEmpty(value))
{
return false;
}
if (pattern.IndexOfAny(_wildCards) > -1)
{
string regexPattern = Utils.ConvertToRegexPattern(pattern);
return Regex.IsMatch(value, regexPattern, RegexOptions.IgnoreCase);
}
else
{
return String.Equals(pattern, value, StringComparison.OrdinalIgnoreCase);
}
}
public bool Remove(Exclusion exclusion)
{
return false;
}
}
}