Skip to content

Commit 80a2507

Browse files
0.1.1 - Feature from file (#2)
Fix the `Read-FeatureFromFile` --------- Signed-off-by: Gilbert Sanchez <[email protected]>
1 parent 541d84e commit 80a2507

7 files changed

Lines changed: 155 additions & 34 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
## [0.1.1]
9+
10+
- `Read-FeatureFile` uses a new static method to read the file and set the
11+
FilePath.
12+
813
## [0.1.0] Initial Release
914

1015
### Added

Gatekeeper/Classes/FeatureFlag.ps1

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,23 @@ class FeatureFlag {
156156
}
157157

158158
# Example usage:
159-
# $json = Get-Content -Raw -Path 'd:\Gatekeeper\Gatekeeper\featureflag.json'
159+
# $json = Get-Content -Raw -Path 'd:\Gatekeeper\Gatekeeper\featureFlag.json'
160160
# $featureFlag = [FeatureFlag]::FromJson($json)
161161
static [FeatureFlag] FromJson([string]$json) {
162162
$data = ConvertFrom-Json $json -AsHashtable
163163
return [FeatureFlag]::new($data)
164164
}
165165

166+
static [FeatureFlag] FromFile([string]$filePath) {
167+
if (-not (Test-Path $filePath)) {
168+
throw "File not found: $filePath"
169+
}
170+
$json = Get-Content -Raw -Path $filePath
171+
$featureFlag = [FeatureFlag]::FromJson($json)
172+
$featureFlag.FilePath = $filePath
173+
return $featureFlag
174+
}
175+
166176
[void]Save() {
167177
if ($null -eq $this.FilePath) {
168178
throw "No file path specified to save FeatureFlag."

Gatekeeper/Gatekeeper.psd1

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,28 @@
99
@{
1010

1111
# Script module or binary module file associated with this manifest.
12-
RootModule = 'Gatekeeper.psm1'
12+
RootModule = 'Gatekeeper.psm1'
1313

1414
# Version number of this module.
15-
ModuleVersion = '0.1.0'
15+
ModuleVersion = '0.1.1'
1616

1717
# Supported PSEditions
1818
# CompatiblePSEditions = @()
1919

2020
# ID used to uniquely identify this module
21-
GUID = '7c2fb6fe-e024-4c39-b687-84fbe7473e3f'
21+
GUID = '7c2fb6fe-e024-4c39-b687-84fbe7473e3f'
2222

2323
# Author of this module
24-
Author = 'Gilbert Sanchez'
24+
Author = 'Gilbert Sanchez'
2525

2626
# Company or vendor of this module
27-
CompanyName = 'Gilbert Sanchez'
27+
CompanyName = 'Gilbert Sanchez'
2828

2929
# Copyright statement for this module
30-
Copyright = '(c) Gilbert Sanchez. All rights reserved.'
30+
Copyright = '(c) Gilbert Sanchez. All rights reserved.'
3131

3232
# Description of the functionality provided by this module
33-
Description = 'Helps implement feature flags in your PowerShell projects.'
33+
Description = 'Helps implement feature flags in your PowerShell projects.'
3434

3535
# Minimum version of the PowerShell engine required by this module
3636
# PowerShellVersion = ''
@@ -51,9 +51,9 @@
5151
# ProcessorArchitecture = ''
5252

5353
# Modules that must be imported into the global environment prior to importing this module
54-
RequiredModules = @(
54+
RequiredModules = @(
5555
@{
56-
ModuleName = 'Configuration'
56+
ModuleName = 'Configuration'
5757
ModuleVersion = '1.6.0'
5858
}
5959
)
@@ -62,7 +62,7 @@
6262
# RequiredAssemblies = @()
6363

6464
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
65-
ScriptsToProcess = @('Enums\Effect.ps1', 'Classes\Property.ps1', 'Classes\FeatureFlag.ps1')
65+
ScriptsToProcess = @('Enums\Effect.ps1', 'Classes\Property.ps1', 'Classes\FeatureFlag.ps1')
6666

6767
# Type files (.ps1xml) to be loaded when importing this module
6868
# TypesToProcess = @()
@@ -77,13 +77,13 @@
7777
FunctionsToExport = '*'
7878

7979
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
80-
CmdletsToExport = '*'
80+
CmdletsToExport = '*'
8181

8282
# Variables to export from this module
8383
VariablesToExport = '*'
8484

8585
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
86-
AliasesToExport = '*'
86+
AliasesToExport = '*'
8787

8888
# DSC resources to export from this module
8989
# DscResourcesToExport = @()
@@ -95,29 +95,29 @@
9595
# FileList = @()
9696

9797
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
98-
PrivateData = @{
98+
PrivateData = @{
9999

100100
PSData = @{
101101

102102
# Tags applied to this module. These help with module discovery in online galleries.
103-
Tags = @(
103+
Tags = @(
104104
'PSEdition_Core',
105105
'Windows',
106106
'Linux',
107107
'MacOS'
108108
)
109109

110110
# A URL to the license for this module.
111-
LicenseUri = 'https://github.com/HeyItsGilbert/Gatekeeper/blob/master/LICENSE'
111+
LicenseUri = 'https://github.com/HeyItsGilbert/Gatekeeper/blob/master/LICENSE'
112112

113113
# A URL to the main website for this project.
114-
ProjectUri = 'https://github.com/HeyItsGilbert/Gatekeeper/'
114+
ProjectUri = 'https://github.com/HeyItsGilbert/Gatekeeper/'
115115

116116
# A URL to an icon representing this module.
117-
IconUri = 'https://raw.githubusercontent.com/HeyItsGilbert/Gatekeeper/main/static/icon.png'
117+
IconUri = 'https://raw.githubusercontent.com/HeyItsGilbert/Gatekeeper/main/static/icon.png'
118118

119119
# ReleaseNotes of this module
120-
ReleaseNotes = 'https://github.com/HeyItsGilbert/Gatekeeper/blob/master/CHANGELOG.md'
120+
ReleaseNotes = 'https://github.com/HeyItsGilbert/Gatekeeper/blob/master/CHANGELOG.md'
121121

122122
# Prerelease string of this module
123123
# Prerelease = ''

Gatekeeper/Public/Read-FeatureFlag.ps1

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function Read-FeatureFlag {
2020
Read the feature from disk.
2121
#>
2222
[CmdletBinding()]
23-
[OutputType([System.Collections.Generic.List[PropertySet]])]
23+
[OutputType([FeatureFlag])]
2424
param (
2525
[Parameter(Mandatory, Position = 0, ParameterSetName = 'ByName')]
2626
[ValidateNotNullOrEmpty()]
@@ -29,9 +29,7 @@ function Read-FeatureFlag {
2929
[Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByFilePath')]
3030
$FilePath
3131
)
32-
begin {
33-
$featureFlags = [System.Collections.Generic.List[PropertySet]]::new()
34-
}
32+
begin {}
3533
process {
3634
if ($PSBoundParameters.ContainsKey('FilePath')) {
3735
Write-Verbose "Reading FeatureFlag from file: $FilePath"
@@ -40,13 +38,8 @@ function Read-FeatureFlag {
4038
$folder = Get-FeatureFlagFolder
4139
$FilePath = Join-Path $folder "$Name.json"
4240
}
43-
$json = Get-Content -Raw $FilePath
44-
$featureFlags.Add(
45-
([FeatureFlag]::FromJson($json))
46-
)
41+
[FeatureFlag]::FromFile($FilePath)
4742
}
4843

49-
end {
50-
return $featureFlags
51-
}
44+
end {}
5245
}

tests/NewFiles.tests.ps1

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,32 @@ BeforeDiscovery {
1919
}
2020
Describe 'File Creations' {
2121
BeforeAll {
22+
@(
23+
'PropertySet',
24+
'FeatureFlags',
25+
'Configuration'
26+
) | ForEach-Object {
27+
$folder = Join-Path -Path (Get-PSDrive TestDrive).Root -ChildPath $_
28+
if (-not (Test-Path -Path $folder)) {
29+
New-Item -Path $folder -ItemType Directory | Out-Null
30+
}
31+
}
32+
Mock -CommandName 'Get-PropertySetFolder' -ModuleName $env:BHProjectName {
33+
return (Join-Path -Path (Get-PSDrive TestDrive).Root -ChildPath 'PropertySet')
34+
}
35+
Mock -CommandName 'Get-FeatureFlagFolder' -ModuleName $env:BHProjectName {
36+
return (Join-Path -Path (Get-PSDrive TestDrive).Root -ChildPath 'FeatureFlags')
37+
}
38+
Mock -CommandName 'Get-ConfigurationPath' -ModuleName Configuration {
39+
return (Join-Path -Path (Get-PSDrive TestDrive).Root -ChildPath 'Configuration')
40+
}
2241
# Override the default file path for testing
23-
Mock Get-ConfigurationPath -ModuleName Configuration {
24-
return (Get-PSDrive TestDrive).Root
42+
$global:GatekeeperConfiguration = @{
43+
FilePaths = @{
44+
#Schemas = Join-Path (Get-PSDrive TestDrive).Root 'Schemas'
45+
FeatureFlags = Join-Path (Get-PSDrive TestDrive).Root 'FeatureFlags'
46+
PropertySet = Join-Path (Get-PSDrive TestDrive).Root 'PropertySet'
47+
}
2548
}
2649
}
2750
# I'm doing a no-no IMO, but this is probably fine.
@@ -39,8 +62,7 @@ Describe 'File Creations' {
3962
Context 'Feature Flag Creation' {
4063
BeforeAll {
4164
# Mock the Get-FeatureFlagFolder to return a test path
42-
Mock Get-FeatureFlagFolder -ModuleName Gatekeeper {
43-
65+
Mock Get-FeatureFlagFolder -ModuleName $env:BHProjectName {
4466
return (Get-PSDrive TestDrive).Root
4567
}
4668
$condition = New-Condition -Property 'UserRole' -Operator 'Equals' -Value 'Admin'

tests/Read-FeatureFlag.Tests.ps1

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
BeforeDiscovery {
2+
$manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest
3+
$outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output'
4+
$outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName
5+
$outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion
6+
$outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1"
7+
8+
# Get module commands
9+
# Remove all versions of the module from the session. Pester can't handle multiple versions.
10+
Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore
11+
Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop
12+
}
13+
Describe 'Read-FeatureFlag' {
14+
BeforeAll {
15+
$script:actual = Read-FeatureFlag -FilePath "$PSScriptRoot\fixtures\FeatureFlag.json"
16+
}
17+
It 'Throws file path error' {
18+
{ Read-FeatureFlag -FilePath 'fakePath.json' } | Should -Throw -ExpectedMessage 'File not found: fakePath.json'
19+
}
20+
It 'Returns a FeatureFlag object' {
21+
$script:actual | Should -BeOfType 'FeatureFlag'
22+
}
23+
It 'Has the correct property: <_.Name>' -ForEach @(
24+
@{ Name = 'Name'; Type = 'String'; Value = 'New Startup Sound' },
25+
@{ Name = 'Description'; Type = 'String'; Value = 'Roll out new screaming goat start up sound.' },
26+
@{ Name = 'Tags'; Type = 'String'; Value = @('Goat', 'Managed') },
27+
@{ Name = 'DefaultEffect'; Type = 'Effect'; Value = "Deny" }
28+
) {
29+
$script:actual.$($_.Name) | Should -BeOfType $_.Type
30+
$script:actual.$($_.Name) | Should -Be $_.Value
31+
}
32+
}

tests/fixtures/FeatureFlag.json

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"$schema": "../../Gatekeeper/Schemas/FeatureFlag.json",
3+
"Name": "New Startup Sound",
4+
"Description": "Roll out new screaming goat start up sound.",
5+
"Version": "1.0.0",
6+
"Author": "Your Name aka who to e-mail when customers are upset",
7+
"Tags": [
8+
"Goat",
9+
"Managed"
10+
],
11+
"DefaultEffect": "Deny",
12+
"Rules": [
13+
{
14+
"Name": "Audit staging",
15+
"Effect": "Audit",
16+
"Conditions": {
17+
"Property": "Environment",
18+
"Operator": "Equals",
19+
"Value": "Staging"
20+
}
21+
},
22+
{
23+
"Name": "Warn Production",
24+
"Effect": "Warn",
25+
"Conditions": {
26+
"Property": "Environment",
27+
"Operator": "Equals",
28+
"Value": "Production"
29+
}
30+
},
31+
{
32+
"Name": "Allow Staging and Complaint or 10%",
33+
"Effect": "Allow",
34+
"Conditions": {
35+
"AllOf": [
36+
{
37+
"AnyOf": [
38+
{
39+
"Property": "IsCompliant",
40+
"Operator": "Equals",
41+
"Value": "true"
42+
},
43+
{
44+
"Property": "Percent",
45+
"Operator": "LessThan",
46+
"Value": "11"
47+
}
48+
]
49+
},
50+
{
51+
"Property": "Environment",
52+
"Operator": "Equals",
53+
"Value": "Staging"
54+
}
55+
]
56+
}
57+
}
58+
]
59+
}

0 commit comments

Comments
 (0)