diff --git a/Test/include/callPrivateContext.ps1 b/Test/include/callPrivateContext.ps1 index c9e0ab0..9b9a1e8 100644 --- a/Test/include/callPrivateContext.ps1 +++ b/Test/include/callPrivateContext.ps1 @@ -14,10 +14,14 @@ if(-not $MODULE_PATH){ throw "Missing MODULE_PATH variable initialization. Check function Invoke-PrivateContext { param ( [Parameter(Mandatory, Position = 0)] - [scriptblock]$ScriptBlock + [scriptblock]$ScriptBlock, + [string]$ModulePath ) - $modulePath = $MODULE_PATH | Split-Path -Parent + if ([string]::IsNullOrEmpty($ModulePath)) { + $modulePath = $MODULE_PATH | Split-Path -Parent + } + $module = Import-Module -Name $modulePath -PassThru if ($null -eq $module) { diff --git a/Test/include/config.mock.ps1 b/Test/include/config.mock.ps1 index f6d5f95..5f5abc6 100644 --- a/Test/include/config.mock.ps1 +++ b/Test/include/config.mock.ps1 @@ -9,29 +9,40 @@ if(-not $MODULE_NAME){ throw "Missing MODULE_NAME varaible initialization. Check for module.helerp.ps1 file." } $MOCK_CONFIG_PATH = "test_config_path" -$CONFIG_INVOKE_GET_ROOT_PATH_CMD = "Invoke-$($MODULE_NAME)GetConfigRootPath" +$CONFIG_INVOKE_GET_ROOT_PATH_CMD = "Invoke-{modulename}GetConfigRootPath" function Mock_Config{ param( [Parameter(Position=0)][string] $key = "config", - [Parameter(Position=1)][object] $Config + [Parameter(Position=1)][object] $Config, + [Parameter(Position=2)][string] $ModuleName, + [Parameter(Position=3)][string] $MockPath = $MOCK_CONFIG_PATH ) # Remove mock config path if exists - if(Test-Path $MOCK_CONFIG_PATH){ - Remove-Item -Path $MOCK_CONFIG_PATH -ErrorAction SilentlyContinue -Recurse -Force + if(Test-Path $MockPath){ + Remove-Item -Path $fullpath -ErrorAction SilentlyContinue -Recurse -Force } # create mock config path - New-Item -Path $MOCK_CONFIG_PATH -ItemType Directory -Force + New-Item -Path $MockPath -ItemType Directory -Force + + # make full and not relative path + $fullpath = $MockPath | Resolve-Path # if $config is not null save it to a file if($null -ne $Config){ - $configfile = Join-Path -Path $MOCK_CONFIG_PATH -ChildPath "$key.json" + $configfile = Join-Path -Path $fullpath -ChildPath "$key.json" $Config | ConvertTo-Json -Depth 10 | Set-Content $configfile } + if([string]::IsNullOrWhiteSpace($ModuleName)){ + $moduleName = $MODULE_NAME + } + + $invokefunction = $CONFIG_INVOKE_GET_ROOT_PATH_CMD -replace "{modulename}", $moduleName + # Mock invoke call - MockCallToString $CONFIG_INVOKE_GET_ROOT_PATH_CMD -OutString $MOCK_CONFIG_PATH + MockCallToString $invokefunction -OutString $fullpath } \ No newline at end of file diff --git a/Test/public/addIncludeToWorkspace.test.ps1 b/Test/public/addIncludeToWorkspace.test.ps1 index 3b2d1a5..f9b226e 100644 --- a/Test/public/addIncludeToWorkspace.test.ps1 +++ b/Test/public/addIncludeToWorkspace.test.ps1 @@ -233,37 +233,44 @@ $targetPS1 = $moduleRootPath | Join-Path -ChildPath "public\addIncludeToWorkspac function Test_ResolveSourceDestinationPath{ - $DestinationModuleName = "TargetModule" - $SourceModuleName = "SourceModule" - $LocalModuleName = "LocalModule" - - $IncludeHelperModulePath = (Get-Module -name Includehelper).Path | Split-Path -parent - - New-ModuleV3 -Name $DestinationModuleName ; $DestinationModulePath = $DestinationModuleName | Convert-Path - New-ModuleV3 -Name $SourceModuleName ; $SourceModulePath = $SourceModuleName | Convert-Path - New-ModuleV3 -Name $LocalModuleName ; $LocalModulePath = $LocalModuleName | Convert-Path - - $LocalModuleName | Set-Location - - # Act Null / Null - Soruce:Include to Destination:local - $resultsource,$resultdestination = Resolve-SourceDestinationPath - Assert-AreEqualPath -Presented $resultsource -Expected $IncludeHelperModulePath - Assert-AreEqualPath -Presented $resultdestination -Expected $LocalModulePath - - # Act Source / Null - Source: Path to Destination: local - $resultsource,$resultdestination = Resolve-SourceDestinationPath -SourceModulePath $SourceModulePath - Assert-AreEqualPath -Presented $resultsource -Expected $SourceModulePath - Assert-AreEqualPath -Presented $resultdestination -Expected $LocalModulePath - - # Act Null / Destination sourceI:Include to Destination: Path - $resultsource,$resultdestination = Resolve-SourceDestinationPath -DestinationModulePath $DestinationModulePath - Assert-AreEqualPath -Presented $resultsource -Expected $IncludeHelperModulePath - Assert-AreEqualPath -Presented $resultdestination -Expected $DestinationModulePath - - # Act Sorce / Destination - Source: Path to Destination: Path - $resultsource,$resultdestination = Resolve-SourceDestinationPath -SourceModulePath $SourceModulePath -DestinationModulePath $DestinationModulePath - Assert-AreEqualPath -Presented $resultsource -Expected $SourceModulePath - Assert-AreEqualPath -Presented $resultdestination -Expected $DestinationModulePath + Invoke-PrivateContext { + + $DestinationModuleName = "TargetModule" + $SourceModuleName = "SourceModule" + $LocalModuleName = "LocalModule" + + # Includehelper root folder + $local = $PSScriptRoot + $IncludeHelperModulePath = $local | Split-Path -Parent | Split-Path -Parent + + # TEsting modules + New-ModuleV3 -Name $DestinationModuleName ; $DestinationModulePath = $DestinationModuleName | Convert-Path + New-ModuleV3 -Name $SourceModuleName ; $SourceModulePath = $SourceModuleName | Convert-Path + New-ModuleV3 -Name $LocalModuleName ; $LocalModulePath = $LocalModuleName | Convert-Path + + # Set location to test module + $LocalModuleName | Set-Location + + # Act Null / Null - Soruce:Include to Destination:local + $resultsource,$resultdestination = Resolve-SourceDestinationPath + Assert-AreEqualPath -Presented $resultsource -Expected $IncludeHelperModulePath + Assert-AreEqualPath -Presented $resultdestination -Expected $LocalModulePath + + # Act Source / Null - Source: Path to Destination: local + $resultsource,$resultdestination = Resolve-SourceDestinationPath -SourceModulePath $SourceModulePath + Assert-AreEqualPath -Presented $resultsource -Expected $SourceModulePath + Assert-AreEqualPath -Presented $resultdestination -Expected $LocalModulePath + + # Act Null / Destination sourceI:Include to Destination: Path + $resultsource,$resultdestination = Resolve-SourceDestinationPath -DestinationModulePath $DestinationModulePath + Assert-AreEqualPath -Presented $resultsource -Expected $IncludeHelperModulePath + Assert-AreEqualPath -Presented $resultdestination -Expected $DestinationModulePath + + # Act Sorce / Destination - Source: Path to Destination: Path + $resultsource,$resultdestination = Resolve-SourceDestinationPath -SourceModulePath $SourceModulePath -DestinationModulePath $DestinationModulePath + Assert-AreEqualPath -Presented $resultsource -Expected $SourceModulePath + Assert-AreEqualPath -Presented $resultdestination -Expected $DestinationModulePath + } } diff --git a/Test/public/config.test.ps1 b/Test/public/config.test.ps1 index 1a1ac91..ea7aa42 100644 --- a/Test/public/config.test.ps1 +++ b/Test/public/config.test.ps1 @@ -4,9 +4,21 @@ function Test_ConfigInclude{ Set-IncludeHelperConfigValue -Name "config_name" -Value "test_config_value" + # Add Value String + $value = "Some value" + Set-IncludeHelperConfigValue -Name "TestKey" -Value $value $result = Get-IncludeHelperConfig + Assert-AreEqual -Expected $value -Presented $result.TestKey - Assert-AreEqual -Expected "test_config_value" -Presented $result.config_name + # Add Value Hashtable + $htable = @{ Key1 = "Value1"; Key2 = "Value2" } + Set-IncludeHelperConfigValue -Name "TestHashtable" -Value $htable + $result = Get-IncludeHelperConfig + Assert-AreEqual -Expected $htable.Key1 -Presented $result.TestHashtable.Key1 + Assert-AreEqual -Expected $htable.Key2 -Presented $result.TestHashtable.Key2 + + # Previuse value still there + Assert-AreEqual -Expected $value -Presented $result.TestKey } diff --git a/Test/public/dependencies.test.ps1 b/Test/public/dependencies.test.ps1 index 4a50ed0..d580f51 100644 --- a/Test/public/dependencies.test.ps1 +++ b/Test/public/dependencies.test.ps1 @@ -13,11 +13,11 @@ function Test_ImportDepepency_Already_loaded{ Mock_ImportModule -Name $name -Folder $modulesFolder #Act - Set-IncludeHelperVerbose + Enable-IncludeHelperVerbose Start-MyTranscript $result = Import-Dependency -Name $name -Verbose -Confirm:$false $tt = Stop-MyTranscript - Clear-IncludeHelperVerbose + Disable-IncludeHelperVerbose #Assert verbose message Assert-AreEqual -Expected $name -Presented $result.Name @@ -42,11 +42,11 @@ function Test_ImportDepepency_SideBySide{ Mock_ImportModule -Name $name -Folder $modulesFolder # Act - Set-IncludeHelperVerbose + Enable-IncludeHelperVerbose Start-MyTranscript $result = Import-Dependency -Name $name -Verbose -Confirm:$false $tt = Stop-MyTranscript - Clear-IncludeHelperVerbose + Disable-IncludeHelperVerbose # Assert module output Assert-AreEqual -Expected $name -Presented $result.Name @@ -77,11 +77,11 @@ function Test_ImportDepepency_Import_From_Module_Manager{ #Act - Set-IncludeHelperVerbose + Enable-IncludeHelperVerbose Start-MyTranscript $output = Import-Dependency -Name $name -Verbose -Confirm:$false $result = Stop-MyTranscript - Clear-IncludeHelperVerbose + Disable-IncludeHelperVerbose #Assert verbose message Assert-AreEqual -Expected $name -Presented $output.Name @@ -119,11 +119,11 @@ function Test_ImportDepepency_Install_From_Gallery{ MockCallExpression -Command "Install-Module -Name $name -AllowPrerelease -Force" -Expression $expression #Act - Set-IncludeHelperVerbose + Enable-IncludeHelperVerbose Start-MyTranscript $output = Import-Dependency -Name $name -Verbose -Confirm:$false $result = Stop-MyTranscript - Clear-IncludeHelperVerbose + Disable-IncludeHelperVerbose #Assert verbose message Assert-AreEqual -Expected $name -Presented $output.Name @@ -154,11 +154,11 @@ function Test_ImportDependency_Clone_From_GitHub{ Mock_ImportModule -Name $name -Folder $modulesFolder - Set-IncludeHelperVerbose + Enable-IncludeHelperVerbose Start-MyTranscript $output = Import-Dependency -Name $name -Verbose -Confirm:$false $result = Stop-MyTranscript - Clear-IncludeHelperVerbose + Disable-IncludeHelperVerbose #Assert verbose message Assert-AreEqual -Expected $name -Presented $output.Name diff --git a/Test/public/featureflag.test.ps1 b/Test/public/featureflag.test.ps1 new file mode 100644 index 0000000..12cd516 --- /dev/null +++ b/Test/public/featureflag.test.ps1 @@ -0,0 +1,140 @@ +function Test_FeatureFlag_Success{ + Mock_Config + + Invoke-PrivateContext{ + + $ffName = "ff1" + $configFilePath = Invoke-MyCommand -Command "Invoke-IncludeHelperGetConfigRootPath" | Join-Path -ChildPath "config.json" + + $result = Test-FeatureFlag -Key $ffName + Assert-IsFalse -Condition $result + + # Calling Test-FeatureFlag will create entry on config.FeatureFlags + $config = Get-Content $configFilePath | ConvertFrom-Json -AsHashtable + Assert-IsFalse -Condition $config.FeatureFlags.$ffName + + Set-FeatureFlag $ffName + $result = Test-FeatureFlag -Key $ffName + Assert-IsTrue -Condition $result + + # Set flag adds $true to the config.FeatureFlags + $config = Get-Content $configFilePath| ConvertFrom-Json -AsHashtable + Assert-IsTrue -Condition $config.FeatureFlags.$ffName + + Clear-FeatureFlag $ffName + $result = tff $ffName + Assert-IsFalse -Condition $result + + # Clear flag sets the flag to $false in config.FeatureFlags + $config = Get-Content $configFilePath| ConvertFrom-Json -AsHashtable + Assert-IsFalse -Condition $config.FeatureFlags.$ffName + } +} + +function Test_RegisteredFeatureFlags_Success{ + + $modulename = "kk" + + # Create Module + New-ModuleV3 -Name $modulename + $fullpath = $modulename | Resolve-Path + + # update module with required code to run featureflags in it + Sync-IncludeWithModule -DestinationModulePath $fullpath + Get-IncludeFile invokeCommand.helper.ps1 | Add-IncludeToWorkspace -DestinationModulePath $fullpath + Get-IncludeFile MyWrite.ps1 | Add-IncludeToWorkspace -DestinationModulePath $fullpath + Get-IncludeFile config.ps1 | Add-IncludeToWorkspace -DestinationModulePath $fullpath + Get-IncludeFile featureflag.ps1 | Add-IncludeToWorkspace -DestinationModulePath $fullpath + Get-IncludeFile module.helper.ps1 | Add-IncludeToWorkspace -DestinationModulePath $fullpath + + # Add a fake Registered featureflags configuration + $reg = @{ + deprecated = @( + 'ff1' + 'ff2' + ) + } + $reg | ConvertTo-Json | Out-File -FilePath $fullPath/featureflags.json + + # Import module + Import-Module -Name $fullpath + # Mock config for module kk + Mock_Config -ModuleName $modulename -MockPath "kk_config" + + # Set feature flags in the kk config + Set-kkFeatureFlag ff1 + Set-kkFeatureFlag ff2 -Value $false + Set-kkFeatureFlag ff3 + + # Assert confirm that all 3 flags are set + $result = Get-kkFeatureFlags + Assert-Count -Expected 3 -Presented $result.Keys + Assert-Contains -Expected "ff1" -Presented $result.Keys + Assert-Contains -Expected "ff2" -Presented $result.Keys + Assert-Contains -Expected "ff3" -Presented $result.Keys + + # Act - Clear registered deprecated featureflags from config + Invoke-PrivateContext -ModulePath $fullpath { + Clear-FeatureFlagsRegistered + } + + # Assert confirm that deprecated flags are removed and ff3 remains + $result = Get-kkFeatureFlags + + Assert-Count -Expected 1 -Presented $result.Keys + Assert-Contains -Expected "ff3" -Presented $result.Keys + + # Not sure why but if we leave kk loaded it may interfere with other tests + # In particular when calling Resolve-SourceDestinationPath, that calls Get-ModuleRootPath, it will resolve to kk module.helper.ps1 code and not IncludeHelper module one + # resolving to the kk module path and not IncludeHelper module path. + Remove-Module -Name $modulename -Force +} + +function Test_RegisteredFeatureFlags__FFFunction_Success{ + + $modulename = "kk" + + # Mock config for module kk + Mock_Config -ModuleName $modulename -MockPath "kk_config" + + # Create Module + New-ModuleV3 -Name $modulename + $fullpath = $modulename | Resolve-Path + + # update module with required code to run featureflags in it + Sync-IncludeWithModule -DestinationModulePath $fullpath + Get-IncludeFile invokeCommand.helper.ps1 | Add-IncludeToWorkspace -DestinationModulePath $fullpath + Get-IncludeFile MyWrite.ps1 | Add-IncludeToWorkspace -DestinationModulePath $fullpath + Get-IncludeFile config.ps1 | Add-IncludeToWorkspace -DestinationModulePath $fullpath + Get-IncludeFile featureflag.ps1 | Add-IncludeToWorkspace -DestinationModulePath $fullpath + Get-IncludeFile module.helper.ps1 | Add-IncludeToWorkspace -DestinationModulePath $fullpath + + $functioncode = @" + +function Get-kkString { + if(TFF ff){ + return "ff" + } else { + return "kk" + } +} Export-ModuleMember -Function Get-kkString + +"@ + + $functioncode | Out-File -FilePath ./kk/public/getString.ps1 + + # Import module + Import-Module -Name $fullpath + + Set-kkFeatureFlag ff + $result = Get-kkFeatureFlags + Assert-IsTrue -Condition $result.ff + + $result = Get-kkString + Assert-AreEqual -Expected "ff" -Presented $result + + # Not sure why but if we leave kk loaded it may interfere with other tests + # In particular when calling Resolve-SourceDestinationPath, that calls Get-ModuleRootPath, it will resolve to kk module.helper.ps1 code and not IncludeHelper module one + # resolving to the kk module path and not IncludeHelper module path. + Remove-Module -Name $modulename -Force +} \ No newline at end of file diff --git a/Test/public/parameter.test.helper.test.ps1 b/Test/public/parameter.test.helper.test.ps1 index 033f488..71fc0a2 100644 --- a/Test/public/parameter.test.helper.test.ps1 +++ b/Test/public/parameter.test.helper.test.ps1 @@ -1,11 +1,11 @@ function Test_parameterstest{ - Set-IncludeHelperVerbose + Enable-IncludeHelperVerbose Start-MyTranscript $result = Get-DummyFunction @ErrorParameters @WarningParameters @InfoParameters $tt = Stop-MyTranscript - Clear-IncludeHelperVerbose + Disable-IncludeHelperVerbose # Assert result Assert-IsTrue -Condition $result @@ -25,11 +25,11 @@ function Test_parameterstest{ function Test_parameterstest_Verbose{ - Set-IncludeHelperVerbose + Enable-IncludeHelperVerbose Start-MyTranscript $result = Get-DummyFunction @ErrorParameters @WarningParameters @InfoParameters -Verbose $tt = Stop-MyTranscript - Clear-IncludeHelperVerbose + Disable-IncludeHelperVerbose # Assert result Assert-IsTrue -Condition $result diff --git a/include/MyWrite.ps1 b/include/MyWrite.ps1 index 94460f0..43173fc 100644 --- a/include/MyWrite.ps1 +++ b/include/MyWrite.ps1 @@ -126,8 +126,8 @@ function Enable-ModuleNameVerbose{ $moduleDebugVarName = $MODULE_NAME + "_VERBOSE" [System.Environment]::SetEnvironmentVariable($moduleDebugVarName, $flag) } -Copy-Item -path Function:Enable-ModuleNameVerbose -Destination Function:"Set-$($MODULE_NAME)Verbose" -Export-ModuleMember -Function "Set-$($MODULE_NAME)Verbose" +Copy-Item -path Function:Enable-ModuleNameVerbose -Destination Function:"Enable-$($MODULE_NAME)Verbose" +Export-ModuleMember -Function "Enable-$($MODULE_NAME)Verbose" function Disable-ModuleNameVerbose{ param() @@ -135,8 +135,8 @@ function Disable-ModuleNameVerbose{ $moduleDebugVarName = $MODULE_NAME + "_VERBOSE" [System.Environment]::SetEnvironmentVariable($moduleDebugVarName, $null) } -Copy-Item -path Function:Disable-ModuleNameVerbose -Destination Function:"Clear-$($MODULE_NAME)Verbose" -Export-ModuleMember -Function "Clear-$($MODULE_NAME)Verbose" +Copy-Item -path Function:Disable-ModuleNameVerbose -Destination Function:"Disable-$($MODULE_NAME)Verbose" +Export-ModuleMember -Function "Disable-$($MODULE_NAME)Verbose" function Test-MyDebug { param( diff --git a/include/callAPI.ps1 b/include/callAPI.ps1 index 90b1c3c..f7475a3 100644 --- a/include/callAPI.ps1 +++ b/include/callAPI.ps1 @@ -44,7 +44,9 @@ function Invoke-GraphQL { # Send the request $start = Get-Date ">>> Invoke-RestMethod - $apiUri" | writedebug - $response = Invoke-RestMethod -Uri $apiUri -Method Post -Body $body -Headers $headers -OutFile $OutFile + if([string]::IsNullOrWhiteSpace($OutFile)) + { $response = Invoke-RestMethod -Uri $apiUri -Method Post -Body $body -Headers $headers } + else { $response = Invoke-RestMethod -Uri $apiUri -Method Post -Body $body -Headers $headers -OutFile $OutFile } "<<< Invoke-RestMethod - $apiUri [ $(((Get-Date) - $start).TotalSeconds) seconds]" | writedebug # Trace response @@ -58,10 +60,12 @@ function Invoke-GraphQL { return $response } catch { + "[[THROW]]" | writedebug + $_.Exception.Message | ConvertTo-Json -Depth 100 | writedebug throw New-Object system.Exception("Error calling GraphQL",$_.Exception) } -} Export-ModuleMember -Function Invoke-GraphQL +} function Invoke-RestAPI { param( @@ -132,7 +136,7 @@ function Invoke-RestAPI { catch { throw } -} Export-ModuleMember -Function Invoke-RestAPI +} #################################################################################################### @@ -158,7 +162,7 @@ function Get-ApiHost { "Default host $DEFAULT_GH_HOST" | writedebug return $DEFAULT_GH_HOST -} Export-ModuleMember -Function Get-ApiHost +} #################################################################################################### @@ -198,7 +202,7 @@ function Get-ApiToken { } return $result -} Export-ModuleMember -Function Get-ApiToken +} #################################################################################################### @@ -228,3 +232,5 @@ function writedebug{ Write-MyDebug $Message -Section "api" } } + + diff --git a/include/config.ps1 b/include/config.ps1 index d7679e0..1e2b2d5 100644 --- a/include/config.ps1 +++ b/include/config.ps1 @@ -13,7 +13,9 @@ # # MODULE_NAME -$MODULE_NAME = ($PSScriptRoot | Split-Path -Parent | Get-ChildItem -Filter *.psd1 | Select-Object -First 1).BaseName +$MODULE_NAME_PATH = ($PSScriptRoot | Split-Path -Parent | Get-ChildItem -Filter *.psd1 | Select-Object -First 1) | Split-Path -Parent +$MODULE_NAME = $MODULE_NAME_PATH | Split-Path -LeafBase + if(-Not $MODULE_NAME){ throw "Module name not found. Please check the module structure." } $CONFIG_ROOT = [System.Environment]::GetFolderPath('UserProfile') | Join-Path -ChildPath ".helpers" -AdditionalChildPath $MODULE_NAME, "config" @@ -185,5 +187,4 @@ if( -not (Test-Path function:$destFunction )){ # Rename-Item -path Function:$function -NewName $destFunction Copy-Item -path Function:$function -Destination Function:$destFunction Export-ModuleMember -Function $destFunction -} - +} \ No newline at end of file diff --git a/include/dependencies.ps1 b/include/dependencies.ps1 index c8746fc..2c1538f 100644 --- a/include/dependencies.ps1 +++ b/include/dependencies.ps1 @@ -15,10 +15,9 @@ $MODULE_ROOT_PATH = $PSScriptRoot | split-path -Parent $MODULE_NAME = (Get-ChildItem -Path $MODULE_ROOT_PATH -Filter *.psd1 | Select-Object -First 1).BaseName -$DEPENDENCY_GETMYMODULEROOTPATH_INVOKE_FUNCTION_NAME = "Invoke-$($MODULE_NAME)RootPath" # SET MY INVOKE COMMAND ALIAS -Set-MyInvokeCommandAlias -Alias "GetMyModuleRootPath" -Command $DEPENDENCY_GETMYMODULEROOTPATH_INVOKE_FUNCTION_NAME +Set-MyInvokeCommandAlias -Alias "GetMyModuleRootPath" -Command "Invoke-$($MODULE_NAME)RootPath" Set-MyInvokeCommandAlias -Alias "CloneRepo" -Command 'git clone {url} {folder}' Set-MyInvokeCommandAlias -Alias "TestGitHubRepo" -Command 'Invoke-WebRequest -Uri "{url}" -Method Head -ErrorAction SilentlyContinue | ForEach-Object { $_.StatusCode -eq 200 }' Set-MyInvokeCommandAlias -Alias "FindModule" -Command 'Find-Module -Name {name} -AllowPrerelease -ErrorAction SilentlyContinue' @@ -28,24 +27,24 @@ Set-MyInvokeCommandAlias -Alias "GetModuleListAvailable" -Command 'Get-Module -N Set-MyInvokeCommandAlias -Alias "ImportModule" -Command 'Import-Module -Name {name} -Scope Global -Verbose:$false -PassThru' # This function will be renamed to avoid collision with other modules -function Invoke-MODULE_NAME_RootPath{ - [CmdletBinding()] - param() +# function Invoke-MyModuleRootPath{ +# [CmdletBinding()] +# param() - # We will asume that this include file will be on a public,private or include folder. - $root = $PSScriptRoot | split-path -Parent +# # We will asume that this include file will be on a public,private or include folder. +# $root = $PSScriptRoot | split-path -Parent - # confirm that in root folder we have a psd1 file - $psd1 = Get-ChildItem -Path $root -Filter *.psd1 -Recurse -ErrorAction SilentlyContinue +# # confirm that in root folder we have a psd1 file +# $psd1 = Get-ChildItem -Path $root -Filter *.psd1 -Recurse -ErrorAction SilentlyContinue - if(-Not $psd1){ - throw "Wrong root folder. Not PSD1 file found in [$root]. Modify Invoke-GetMyModuleRootPath to adjust location" - } +# if(-Not $psd1){ +# throw "Wrong root folder. Not PSD1 file found in [$root]. Modify Invoke-GetMyModuleRootPath to adjust location" +# } - return $root -} -Copy-Item -path Function:Invoke-MODULE_NAME_RootPath -Destination Function:$DEPENDENCY_GETMYMODULEROOTPATH_INVOKE_FUNCTION_NAME -Export-ModuleMember -Function $DEPENDENCY_GETMYMODULEROOTPATH_INVOKE_FUNCTION_NAME +# return $root +# } +# Copy-Item -path Function:Invoke-MyModuleRootPath -Destination Function:"Invoke-$($MODULE_NAME)RootPath" +# Export-ModuleMember -Function "Invoke-$($MODULE_NAME)RootPath" function Import-Dependency{ [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'High')] diff --git a/include/featureflag.ps1 b/include/featureflag.ps1 new file mode 100644 index 0000000..677a491 --- /dev/null +++ b/include/featureflag.ps1 @@ -0,0 +1,166 @@ +# Feature Flag +# +# Feature Flags management module +# +# This module will allow set Feature Flags to the module to quicker release +# features with less risk +# +# Include design description +# This module depends on Config Include +# Config module will depend on invokeCommand.helper.ps1, MyWrite.ps1, config.ps1, module.helper.ps1 +# +# As you se features keys they will be recorded on a config file. +# Deprecate the FF to have it removed from the config file when the FF is released (aka set functionality to GA with now FF. +# Use Clear-FeatureFlagsRegistered to remove deprecated FF from config + + +$MODULE_NAME_PATH = ($PSScriptRoot | Split-Path -Parent | Get-ChildItem -Filter *.psd1 | Select-Object -First 1) | Split-Path -Parent +$MODULE_NAME = $MODULE_NAME_PATH | Split-Path -LeafBase + +function Get-FeatureFlags{ + [CmdletBinding()] + param() + + $config = Get-Configuration + + if(! $config){ + return @{} + } + + if(! $config.FeatureFlags){ + $config.FeatureFlags = @{} + } + + return $config.FeatureFlags +} + +function Save-FeatureFlags{ + [CmdletBinding()] + param( + [Parameter(Mandatory,Position=0)][hashtable]$FeatureFlags + ) + + $result = Set-ModuleNameConfigValue -Name "FeatureFlags" -Value $FeatureFlags + + if(! $result){ + throw "Failed to save Feature Flags" + } +} + +function Test-FeatureFlag { + [CmdletBinding()] + [Alias("tff")] + param( + [Parameter(Mandatory,Position=0)][string]$Key + ) + + $ffs = Get-FeatureFlags + + $value = $ffs.$Key + + if($null -eq $value){ + Set-FeatureFlag -Key $Key -Value $false + return $false + } + + return $value +} + +function Set-FeatureFlag{ + [CmdletBinding()] + param( + [Parameter(Mandatory,Position=0)][string]$Key, + [Parameter()][bool]$Value = $true + + ) + + $featureFlags = Get-FeatureFlags + + $featureFlags.$Key = $Value + + Save-FeatureFlags $featureFlags + +} + +function Clear-FeatureFlag{ + [CmdletBinding()] + param( + [Parameter(Mandatory,Position=0)][string]$Key + + ) + + Set-FeatureFlag -Key $Key -Value $false + +} + +function Clear-FeatureFlagsRegistered{ + [cmdletbinding()] + param() + + $rffs = Get-ModuleNameRegisteredFeatureFlags + $ffs = (Get-FeatureFlags).Clone() + + $rffs.deprecated | ForEach-Object { + $ffs.Remove($_) + } + + Save-FeatureFlags $ffs + +} + +###### + +function Get-ModuleNameRegisteredFeatureFlags{ + [cmdletbinding()] + param() + + $ffPath = $MODULE_NAME_PATH | Join-Path -ChildPath "featureflags.json" + + if(! ($ffPath | Test-Path)){ + return + } + + $Json = Get-Content $ffPath + + $ff = $Json | ConvertFrom-Json + + return $ff + +} +$function = "Get-ModuleNameRegisteredFeatureFlags" +$destFunction = $function -replace "ModuleName", $MODULE_NAME +if( -not (Test-Path function:$destFunction )){ + Copy-Item -path Function:$function -Destination Function:$destFunction + Export-ModuleMember -Function $destFunction +} + +function Get-ModuleNameFeatureFlags{ + [cmdletbinding()] + param() + + $ffs = Get-FeatureFlags + + return $ffs +} +$function = "Get-ModuleNameFeatureFlags" +$destFunction = $function -replace "ModuleName", $MODULE_NAME +if( -not (Test-Path function:$destFunction )){ + Rename-Item -path Function:$function -NewName $destFunction + Export-ModuleMember -Function $destFunction +} + +function Set-ModuleNameFeatureFlag{ + [cmdletbinding()] + param( + [Parameter(Mandatory,Position=0)][string]$Key, + [Parameter()][bool]$Value = $true + ) + + Set-FeatureFlag -Key $Key -Value $Value +} +$function = "Set-ModuleNameFeatureFlag" +$destFunction = $function -replace "ModuleName", $MODULE_NAME +if( -not (Test-Path function:$destFunction )){ + Rename-Item -path Function:$function -NewName $destFunction + Export-ModuleMember -Function $destFunction +} diff --git a/public/syncIncludeWithModule.ps1 b/public/syncIncludeWithModule.ps1 index db2005a..fbe3d0c 100644 --- a/public/syncIncludeWithModule.ps1 +++ b/public/syncIncludeWithModule.ps1 @@ -1,9 +1,11 @@ function Sync-IncludeWithModule{ [CmdletBinding()] - param() + param( + [Parameter()][string]$DestinationModulePath + ) - Get-IncludeFile | Add-IncludeToWorkspace -IfExists + Get-IncludeFile | Add-IncludeToWorkspace -IfExists -DestinationModulePath $DestinationModulePath - Get-IncludeSystemFiles | Add-IncludeToWorkspace -IfExists + Get-IncludeSystemFiles | Add-IncludeToWorkspace -IfExists -DestinationModulePath $DestinationModulePath } Export-ModuleMember -Function Sync-IncludeWithModule \ No newline at end of file