Skip to content

Commit 0742b20

Browse files
authored
Blacklist → denylist, whitelist → allowlist (#20)
Since this is an incompatible change, also bump up version to 2.0.0 (major version change, to signal incompatible API).
1 parent 1a2e1f3 commit 0742b20

10 files changed

+109
-95
lines changed

FeatureFlags.PowerShell.nuspec

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
<package>
33
<metadata>
44
<id>FeatureFlags.PowerShell</id>
5-
<version>1.0.1</version>
5+
<version>2.0.0</version>
66
<title>PowerShell Feature Flags</title>
77
<authors>Andrea Spadaccini,Nick Hara</authors>
88
<owners>Andrea Spadaccini</owners>
99
<license type="expression">MIT</license>
1010
<projectUrl>https://github.com/microsoft/PowerShell-FeatureFlags/</projectUrl>
1111
<requireLicenseAcceptance>false</requireLicenseAcceptance>
1212
<description>PowerShell module containing a Feature Flags implementation based on a local config file.</description>
13-
<releaseNotes>Fixed bug with the "probability" condition (issue #18).</releaseNotes>
13+
<releaseNotes>Renamed blacklist to denylist, whitelist to allowlist. Incompatible with 1.0.x.</releaseNotes>
1414
<copyright>Copyright 2020 Microsoft</copyright>
1515
<repository type="git" url="https://github.com/microsoft/PowerShell-FeatureFlags.git" branch="master" />
1616
</metadata>

FeatureFlags.psd1

0 Bytes
Binary file not shown.

FeatureFlags.psm1

+15-15
Original file line numberDiff line numberDiff line change
@@ -219,24 +219,24 @@ function Test-FeatureConditions
219219
)
220220
# Conditions are evaluated in the order they are presented in the configuration file.
221221
foreach ($condition in $conditions) {
222-
# Each condition object can have only one of the whitelist, blacklist or probability
222+
# Each condition object can have only one of the allowlist, denylist or probability
223223
# attributes set. This invariant is enforced by the JSON schema, which uses the "oneof"
224-
# strategy to choose between whitelist, blacklist or probability and, for each of these
224+
# strategy to choose between allowlist, denylist or probability and, for each of these
225225
# condition types, only allows the homonym attribute to be set.
226-
if ($null -ne $condition.whitelist) {
227-
Write-Verbose "Checking the whitelist condition"
228-
# The predicate must match any of the regexes in the whitelist in order to
229-
# consider the whitelist condition satisfied.
230-
$matchesWhitelist = Test-RegexList $predicate @($condition.whitelist)
231-
if (-not $matchesWhitelist) {
226+
if ($null -ne $condition.allowlist) {
227+
Write-Verbose "Checking the allowlist condition"
228+
# The predicate must match any of the regexes in the allowlist in order to
229+
# consider the allowlist condition satisfied.
230+
$matchesallowlist = Test-RegexList $predicate @($condition.allowlist)
231+
if (-not $matchesallowlist) {
232232
return $false
233233
}
234-
} elseif ($null -ne $condition.blacklist) {
235-
Write-Verbose "Checking the blacklist condition"
236-
# The predicate must not match all of the regexes in the blacklist in order to
237-
# consider the blacklist condition satisfied.
238-
$matchesBlacklist = Test-RegexList $predicate @($condition.blacklist)
239-
if ($matchesBlacklist) {
234+
} elseif ($null -ne $condition.denylist) {
235+
Write-Verbose "Checking the denylist condition"
236+
# The predicate must not match all of the regexes in the denylist in order to
237+
# consider the denylist condition satisfied.
238+
$matchesdenylist = Test-RegexList $predicate @($condition.denylist)
239+
if ($matchesdenylist) {
240240
return $false
241241
}
242242
} elseif ($null -ne $condition.probability) {
@@ -250,7 +250,7 @@ function Test-FeatureConditions
250250
return $false
251251
}
252252
} else {
253-
throw "${condition} is not a supported condition type (blacklist, whitelist or probability)."
253+
throw "${condition} is not a supported condition type (denylist, allowlist or probability)."
254254
}
255255
}
256256
return $true

README.md

+23-23
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ Imagine to have a feature flag configuration file called `features.json`:
4949
{
5050
"stages": {
5151
"test": [
52-
{"whitelist": ["test.*", "dev.*"]}
52+
{"allowlist": ["test.*", "dev.*"]}
5353
],
5454
"canary": [
55-
{"whitelist": ["prod-canary"]}
55+
{"allowlist": ["prod-canary"]}
5656
],
5757
"prod": [
58-
{"whitelist": ["prod.*"]},
59-
{"blacklist": ["prod-canary"]}
58+
{"allowlist": ["prod.*"]},
59+
{"denylist": ["prod-canary"]}
6060
]
6161
},
6262
"features": {
@@ -122,13 +122,13 @@ An example lifecycle of a feature flag might be the following:
122122

123123
Here is how these example stages could be implemented:
124124

125-
* Stage 1 can be implemented with a `blacklist` condition with value `.*`.
126-
* Stages 2 and 3 can be implemented with `whitelist` conditions.
125+
* Stage 1 can be implemented with a `denylist` condition with value `.*`.
126+
* Stages 2 and 3 can be implemented with `allowlist` conditions.
127127
* Stages 4 and 5 can be implemented with `probability` conditions.
128128

129129
## Conditions
130130

131-
There are two types of conditions: *deterministic* (whitelist and blacklist,
131+
There are two types of conditions: *deterministic* (allowlist and denylist,
132132
regex-based) and *probabilistic* (probability, expressed as a number between
133133
0 and 1). Conditions can be repeated if multiple instances are required.
134134

@@ -138,9 +138,9 @@ in the configuration file, for the feature to be considered enabled.
138138
If any condition is not met, evaluation of conditions stops and the feature
139139
is considered disabled.
140140

141-
### Whitelist
141+
### Allow list
142142

143-
The `whitelist` condition allows to specify a list of regular expressions; if the
143+
The `allowlist` condition allows to specify a list of regular expressions; if the
144144
predicate matches any of the expressions, then the condition is met and the evaluation
145145
moves to the next condition, if there is any.
146146

@@ -150,9 +150,9 @@ unintended matches, it's recommended to always anchor the regex.
150150

151151
So, for example, `"^storage$"` will only match `"storage"` and not `"storage1"`.
152152

153-
### Blacklist
153+
### Deny list
154154

155-
The `blacklist` condition is analogous to the whitelist condition, except that if
155+
The `denylist` condition is analogous to the allowlist condition, except that if
156156
the predicate matches any of the expressions the condition is considered not met
157157
and the evaluation stops.
158158

@@ -172,25 +172,25 @@ the following example:
172172
```json
173173
{
174174
"stages": {
175-
"whitelist-first": [
176-
{"whitelist": ["storage.*"]},
175+
"allowlist-first": [
176+
{"allowlist": ["storage.*"]},
177177
{"probability": 0.1}
178178
],
179179
"probability-first": [
180180
{"probability": 0.1}
181-
{"whitelist": ["storage.*"]},
181+
{"allowlist": ["storage.*"]},
182182
]
183183
}
184184
}
185185
```
186186

187-
The first stage definition, `whitelist-first`, will evaluate the `probability` condition
188-
only if the predicate first passes the whitelist.
187+
The first stage definition, `allowlist-first`, will evaluate the `probability` condition
188+
only if the predicate first passes the allowlist.
189189

190190
The second stage definition, `probability-first`, will instead first evaluate
191-
the `probability` condition, and then apply the whitelist.
191+
the `probability` condition, and then apply the allowlist.
192192

193-
Assuming there are predicates that do not match the whitelist, the second stage definition
193+
Assuming there are predicates that do not match the allowlist, the second stage definition
194194
is more restrictive than the first one, leading to fewer positive evaluations of the
195195
feature flag.
196196

@@ -231,19 +231,19 @@ for comments. Don't add comments to your feature flag configuration file.
231231
],
232232
// Examples of deterministic stages.
233233
"all-storage": [
234-
{"whitelist": [".*Storage.*"]},
234+
{"allowlist": [".*Storage.*"]},
235235
],
236236
"storage-except-important": [
237-
{"whitelist": [".*Storage.*"]},
238-
{"blacklist": [".*StorageImportant.*"]},
237+
{"allowlist": [".*Storage.*"]},
238+
{"denylist": [".*StorageImportant.*"]},
239239
],
240240
// Example of mixed roll-out stage.
241241
// This stage will match on predicates containing the word "Storage"
242242
// but not the word "StorageImportant", and then will consider the feature
243243
// enabled in 50% of the cases.
244244
"50-percent-storage-except-StorageImportant": [
245-
{"whitelist": [".*Storage.*"]},
246-
{"blacklist": ["StorageImportant"]},
245+
{"allowlist": [".*Storage.*"]},
246+
{"denylist": ["StorageImportant"]},
247247
{"probability": 0.5},
248248
],
249249
},

examples/features.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
22
"stages": {
33
"test": [
4-
{"whitelist": ["test.*", "dev.*"]}
4+
{"allowlist": ["test.*", "dev.*"]}
55
],
66
"canary": [
7-
{"whitelist": ["prod-canary"]}
7+
{"allowlist": ["prod-canary"]}
88
],
99
"prod": [
10-
{"whitelist": ["prod.*"]},
11-
{"blacklist": ["prod-canary"]}
10+
{"allowlist": ["prod.*"]},
11+
{"denylist": ["prod-canary"]}
1212
]
1313
},
1414
"features": {

featureflags.schema.json

+10-9
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,30 @@
2929
"required": ["stages"],
3030
"additionalProperties": false,
3131
"definitions": {
32-
"whitelist": {
32+
"allowlist": {
3333
"type": "object",
3434
"properties": {
35-
"whitelist": {
35+
"allowlist": {
3636
"type": "array",
3737
"items": {
3838
"type": "string"
3939
}
4040
}
4141
},
42-
"required": ["whitelist"],
42+
"required": ["allowlist"],
4343
"additionalProperties": false
4444
},
45-
"blacklist": {
45+
"denylist": {
4646
"type": "object",
4747
"properties": {
48-
"blacklist": {
48+
"denylist": {
4949
"type": "array",
5050
"items": {
5151
"type": "string"
5252
}
5353
}
5454
},
55-
"required": ["blacklist"],
55+
"required": ["denylist"],
5656
"additionalProperties": false
5757
},
5858
"probability": {
@@ -70,11 +70,12 @@
7070
"conditions": {
7171
"type": "array",
7272
"items": {
73-
"oneOf": [{
74-
"$ref": "#/definitions/whitelist"
73+
"oneOf": [
74+
{
75+
"$ref": "#/definitions/allowlist"
7576
},
7677
{
77-
"$ref": "#/definitions/blacklist"
78+
"$ref": "#/definitions/denylist"
7879
},
7980
{
8081
"$ref": "#/definitions/probability"

0 commit comments

Comments
 (0)