diff --git a/Changelog.md b/Changelog.md index ccf5b9f..43c62b6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,13 @@ This page is a list of _notable_ changes made in each version. Every time a tip is added the patch version is incremented, so there will be a lot of patch version changes not documented here. +## v1.1.0 - February 4, 2024 + +Features: + +- Added an `ExpiryDate` property to the `PowerShellTip` class to allow tips to be automatically removed after a certain date. + This is useful for tips that are no longer relevant after a certain date, such as tips about a specific event or conference. + ## v1.0.0 - October 16, 2023 Features: diff --git a/build/Convert-PowerShellTipFilesToJsonFile.ps1 b/build/Convert-PowerShellTipFilesToJsonFile.ps1 index 8aaf3c4..d711f01 100644 --- a/build/Convert-PowerShellTipFilesToJsonFile.ps1 +++ b/build/Convert-PowerShellTipFilesToJsonFile.ps1 @@ -27,6 +27,7 @@ Write-Verbose "Finding all PowerShell tip files in '$powerShellTipsDirectoryPath [System.Collections.ArrayList] $tips = @() [int] $numberOfTipFiles = $tipFilePaths.Count +[int] $numberOfExpiredTipFiles = 0 Write-Verbose "Reading in and validating $numberOfTipFiles PowerShell tip files." foreach ($tipFilePath in $tipFilePaths) @@ -37,13 +38,22 @@ foreach ($tipFilePath in $tipFilePaths) $tip.TrimAllProperties() $tip.Validate() + + if ($tip.ExpiryDate -lt [DateTime]::Today) + { + Write-Verbose "Skipping expired tip: $($tip.Title)" + $numberOfExpiredTipFiles++ + continue + } + $tips.Add($tip) > $null } [int] $numberOfTips = $tips.Count -if ($numberOfTips -ne $numberOfTipFiles) +[int] $numberOfNonExpiredTipFiles = $numberOfTipFiles - $numberOfExpiredTipFiles +if ($numberOfTips -ne $numberOfNonExpiredTipFiles) { - throw "Found $numberOfTipFiles tip files, but read in $numberOfTips tips. The number of tip files and tips should match." + throw "Found $numberOfNonExpiredTipFiles non-expired tip files ($numberOfTipFiles files, but $numberOfExpiredTipFiles were expired), but read in $numberOfTips tips. The number of non-expired tip files and tips should match." } if ($numberOfTips -eq 0) diff --git a/deploy/Invoke-SmokeTests.ps1 b/deploy/Invoke-SmokeTests.ps1 index 0402a38..be75820 100644 --- a/deploy/Invoke-SmokeTests.ps1 +++ b/deploy/Invoke-SmokeTests.ps1 @@ -1,9 +1,15 @@ # These tests are runs as part of the deployment process to ensure the newly published module is working as expected. # These tests run against the installed module, not the source code, so they do not use mocks and are more of a real-world test. # Since mocks are not used, we must be careful to not rely on state stored on the machine, such as the module Configuration file. +# To run these tests on your local machine, see the comments in the BeforeAll block. BeforeAll { Import-Module -Name tiPS -Force + + # To run these tests on your local machine, comment out the Import-Module command above and uncomment the one below. + # Do this to use the module version from source code, not the installed version. + # This is necessary to test functionality that you've added to the module, but have not yet published and installed. + # Import-Module "$PSScriptRoot\..\src\tiPS" -Force } Describe 'Get-PowerShellTip' { @@ -34,6 +40,12 @@ Describe 'Get-PowerShellTip' { $allTips | Should -Not -BeNullOrEmpty $allTips.Count | Should -BeGreaterThan 2 } + + It 'Should not return any expired tips, as they should have been removed during initialization' { + $allTips = Get-PowerShellTip -All + $expiredTips = $allTips.Values | Where-Object { $_.ExpiryDate -lt [DateTime]::Today } + $expiredTips | Should -BeNullOrEmpty + } } } diff --git a/src/CSharpClasses/tiPSClasses/PowerShellTip.cs b/src/CSharpClasses/tiPSClasses/PowerShellTip.cs index 1f85195..919bf55 100644 --- a/src/CSharpClasses/tiPSClasses/PowerShellTip.cs +++ b/src/CSharpClasses/tiPSClasses/PowerShellTip.cs @@ -23,6 +23,7 @@ public class PowerShellTip public string Example { get; set; } public string[] Urls { get; set; } public TipCategory Category { get; set; } + public DateTime ExpiryDate { get; set; } public PowerShellTip() { @@ -32,6 +33,7 @@ public PowerShellTip() Example = string.Empty; Urls = Array.Empty(); Category = TipCategory.Other; + ExpiryDate = DateTime.MaxValue; } public string Id diff --git a/src/PowerShellTips/2023-10-03-powershell-devops-global-summit-2024.ps1 b/src/PowerShellTips/2023-10-03-powershell-devops-global-summit-2024.ps1 index 7341b4b..c0a8d46 100644 --- a/src/PowerShellTips/2023-10-03-powershell-devops-global-summit-2024.ps1 +++ b/src/PowerShellTips/2023-10-03-powershell-devops-global-summit-2024.ps1 @@ -12,6 +12,7 @@ $tip.Urls = @( 'https://sessionize.com/pshsummit24/' ) $tip.Category = [tiPS.TipCategory]::Community # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.ExpiryDate = [DateTime]::Parse('2024-04-11') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. # Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. # Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. diff --git a/src/PowerShellTips/2023-10-09-powershell-conference-europe-2024.ps1 b/src/PowerShellTips/2023-10-09-powershell-conference-europe-2024.ps1 index 4bd459e..cc8ed6d 100644 --- a/src/PowerShellTips/2023-10-09-powershell-conference-europe-2024.ps1 +++ b/src/PowerShellTips/2023-10-09-powershell-conference-europe-2024.ps1 @@ -11,6 +11,7 @@ $tip.Urls = @( 'https://psconf.eu/' ) $tip.Category = [tiPS.TipCategory]::Community # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.ExpiryDate = [DateTime]::Parse('2024-06-27') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. # Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. # Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. diff --git a/src/PowerShellTips/2023-10-09-psconfeu-2023-minicon.ps1 b/src/PowerShellTips/2023-10-09-psconfeu-2023-minicon.ps1 index 76bd835..8b52dcf 100644 --- a/src/PowerShellTips/2023-10-09-psconfeu-2023-minicon.ps1 +++ b/src/PowerShellTips/2023-10-09-psconfeu-2023-minicon.ps1 @@ -12,6 +12,7 @@ $tip.Urls = @( 'https://app.gather.town/events/It0l-Wx8TQmTI93yQvs-' ) $tip.Category = [tiPS.TipCategory]::Community # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.ExpiryDate = [DateTime]::Parse('2023-10-24') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. # Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. # Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. diff --git a/src/tiPS/Classes/PowerShellTip.Tests.ps1 b/src/tiPS/Classes/PowerShellTip.Tests.ps1 index 38d0531..51eade8 100644 --- a/src/tiPS/Classes/PowerShellTip.Tests.ps1 +++ b/src/tiPS/Classes/PowerShellTip.Tests.ps1 @@ -10,6 +10,7 @@ Describe 'Trimming all tip properties' { $ValidTip.Example = 'Example' $ValidTip.Urls = @('https://Url1.com', 'http://Url2.com') $ValidTip.Category = 'Community' + $ValidTip.ExpiryDate = [DateTime]::MaxValue } It 'Should not change any of the properties' { @@ -41,6 +42,7 @@ Describe 'Trimming all tip properties' { $ValidTip.Example = 'Example' $ValidTip.Urls = @('https://Url1.com', 'http://Url2.com') $ValidTip.Category = 'Community' + $ValidTip.ExpiryDate = [DateTime]::MaxValue } It 'Should trim the leading and trailing whitespace from all of the properties' { @@ -78,6 +80,7 @@ Describe 'Validating a PowerShellTip' { $ValidTip.Example = 'Example' $ValidTip.Urls = @('https://Url1.com', 'http://Url2.com') $ValidTip.Category = 'Community' + $ValidTip.ExpiryDate = [DateTime]::MaxValue } It 'Should throw an error when the CreatedDate has not been set' { @@ -131,6 +134,7 @@ Describe 'Validating a PowerShellTip' { $ValidTip.Example = 'Example' $ValidTip.Urls = @('https://Url1.com', 'http://Url2.com') $ValidTip.Category = 'Community' + $ValidTip.ExpiryDate = [DateTime]::MaxValue } It 'Should not throw an error when all properties are valid' { @@ -150,6 +154,7 @@ Describe 'Getting the Id property' { $ValidTip.Example = 'Example' $ValidTip.Urls = @('https://Url1.com', 'http://Url2.com') $ValidTip.Category = 'Community' + $ValidTip.ExpiryDate = [DateTime]::MaxValue } It 'Should create the Id properly from the other property values' { @@ -178,6 +183,7 @@ Describe 'Checking if URLs are provided' { $ValidTip.Example = 'Example' $ValidTip.Urls = @('https://Url1.com', 'http://Url2.com') $ValidTip.Category = 'Community' + $ValidTip.ExpiryDate = [DateTime]::MaxValue } It 'Should return true when URLs are supplied' { diff --git a/src/tiPS/PowerShellTips.json b/src/tiPS/PowerShellTips.json index 95f8052..4aa02ce 100644 --- a/src/tiPS/PowerShellTips.json +++ b/src/tiPS/PowerShellTips.json @@ -7,7 +7,8 @@ "Urls": [ "https://github.com/PowerShell/PowerShell" ], - "Category": 0 + "Category": 0, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-07-17T00:00:00", @@ -17,7 +18,8 @@ "Urls": [ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/set-strictmode" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-08-28T00:00:00", @@ -28,7 +30,8 @@ "https://learn.microsoft.com/powershell/module/psreadline/about/about_psreadline", "https://learn.microsoft.com/powershell/module/microsoft.powershell.core/get-history" ], - "Category": 7 + "Category": 7, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-05T00:00:00", @@ -39,7 +42,8 @@ "https://powershellexplained.com/2018-12-23-Powershell-null-everything-you-wanted-to-know/", "https://stackoverflow.com/a/60996703/602585" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-06T00:00:00", @@ -49,7 +53,8 @@ "Urls": [ "https://woshub.com/powershell-commands-history/" ], - "Category": 7 + "Category": 7, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-06T00:00:00", @@ -59,7 +64,8 @@ "Urls": [ "https://blog.danskingdom.com/PowerShell-intellisense-on-the-command-line/" ], - "Category": 7 + "Category": 7, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-11T00:00:00", @@ -69,7 +75,8 @@ "Urls": [ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_requires" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-11T00:00:00", @@ -81,7 +88,8 @@ "https://powershell.org/series/powershell-community-call/", "https://www.youtube.com/@powershellanddscteamchanne5739" ], - "Category": 0 + "Category": 0, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-11T00:00:00", @@ -92,7 +100,8 @@ "https://www.powershellgallery.com/packages/ImportExcel", "https://github.com/dfinke/ImportExcel" ], - "Category": 2 + "Category": 2, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-12T00:00:00", @@ -103,7 +112,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-content", "https://4sysops.com/archives/parse-log-files-with-powershell/" ], - "Category": 3 + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-16T00:00:00", @@ -114,7 +124,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/out-gridview", "https://woshub.com/using-out-gridview-table-powershell/" ], - "Category": 3 + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-17T00:00:00", @@ -125,7 +136,8 @@ "https://devblogs.microsoft.com/powershell/announcing-psreadline-2-1-with-predictive-intellisense/", "https://learn.microsoft.com/en-us/powershell/module/psreadline/" ], - "Category": 7 + "Category": 7, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-18T00:00:00", @@ -135,7 +147,8 @@ "Urls": [ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing?view=powershell-7.3#line-continuation" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-19T00:00:00", @@ -147,7 +160,8 @@ "https://adamtheautomator.com/powershell-splatting/", "https://4sysops.com/archives/use-splatting-and-psboundparameters-to-pass-parameters-in-powershell/" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-21T00:00:00", @@ -158,7 +172,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules#here-strings", "https://devblogs.microsoft.com/scripting/maximizing-the-power-of-here-string-in-powershell-for-configuration-data" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-21T00:00:00", @@ -170,7 +185,8 @@ "https://devblogs.microsoft.com/powershell/checking-for-bound-parameters/", "https://www.reza-aghaei.com/how-to-determine-if-a-parameter-is-passed-to-a-powershell-cmdlet/" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-22T00:00:00", @@ -180,7 +196,8 @@ "Urls": [ "https://learn.microsoft.com/en-us/powershell/scripting/dev-cross-plat/performance/script-authoring-considerations?view=powershell-7.3#array-addition" ], - "Category": 4 + "Category": 4, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-23T00:00:00", @@ -190,7 +207,8 @@ "Urls": [ "https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-arrays?view=powershell-7.3#create-an-array" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-23T00:00:00", @@ -200,7 +218,8 @@ "Urls": [ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables#psversiontable" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-23T00:00:00", @@ -211,7 +230,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_enum#enumerations-as-flags", "https://arcanecode.com/2021/12/06/fun-with-powershell-enum-flags/" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-09-29T00:00:00", @@ -221,7 +241,8 @@ "Urls": [ "https://www.linkedin.com/feed/update/urn:li:activity:7113300637735407618/" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-02T00:00:00", @@ -232,7 +253,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/new-temporaryfile", "https://learn.microsoft.com/en-us/dotnet/api/system.io.path.gettempfilename#system-io-path-gettempfilename" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-02T00:00:00", @@ -244,7 +266,8 @@ "https://xainey.github.io/2016/powershell-classes-and-concepts/", "https://blog.danskingdom.com/PowerShell-class-definition-pros-cons-and-performance-comparison/" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-03T00:00:00", @@ -255,7 +278,8 @@ "https://www.powershellsummit.org/", "https://sessionize.com/pshsummit24/" ], - "Category": 0 + "Category": 0, + "ExpiryDate": "2024-04-11T00:00:00" }, { "CreatedDate": "2023-10-03T00:00:00", @@ -266,7 +290,8 @@ "https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-switch#-file", "https://twitter.com/dfinke/status/1698733677285388581" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-07T00:00:00", @@ -278,7 +303,8 @@ "https://devblogs.microsoft.com/powershell/secretmanagement-and-secretstore-are-generally-available/", "https://www.pdq.com/blog/how-to-manage-powershell-secrets-with-secretsmanagement/" ], - "Category": 5 + "Category": 5, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-08T00:00:00", @@ -290,7 +316,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/read-host", "https://www.pdq.com/blog/secure-password-with-powershell-encrypting-credentials-part-1/" ], - "Category": 5 + "Category": 5, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-09T00:00:00", @@ -300,18 +327,8 @@ "Urls": [ "https://psconf.eu/" ], - "Category": 0 - }, - { - "CreatedDate": "2023-10-09T00:00:00", - "Title": "PSConfEU 2023 MiniCon", - "TipText": "The PSConfEU 2023 MiniCon will be held on October 24, 2023. Save the date!\r\n\r\nPSConfEU 2023 MiniCon is a free virtual event open to all of the PowerShell community. Wherever you are, join and say hi! There will be multiple sessions in several tracks, and many speakers and leaders of the community will be there to talk to you!", - "Example": "", - "Urls": [ - "https://psconf.eu/", - "https://app.gather.town/events/It0l-Wx8TQmTI93yQvs-" - ], - "Category": 0 + "Category": 0, + "ExpiryDate": "2024-06-27T00:00:00" }, { "CreatedDate": "2023-10-11T00:00:00", @@ -322,7 +339,8 @@ "https://learn.microsoft.com/en-us/dotnet/api/system.io.filestream", "https://claytonerrington.com/blog/creating-a-test-file" ], - "Category": 8 + "Category": 8, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-11T00:00:00", @@ -333,7 +351,8 @@ "https://learn.microsoft.com/en-us/dotnet/api/system.uri", "https://twitter.com/devopsjeremy/status/1709773064563744888?s=46&t=-Ox1iPV67-4Vqb8wIZ275A" ], - "Category": 8 + "Category": 8, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-14T00:00:00", @@ -344,7 +363,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_calculated_properties", "https://4sysops.com/archives/add-a-calculated-property-with-select-object-in-powershell/" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-20T00:00:00", @@ -354,7 +374,8 @@ "Urls": [ "https://github.com/PowerShell/GraphicalTools/" ], - "Category": 2 + "Category": 2, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-21T00:00:00", @@ -365,7 +386,8 @@ "https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.runtimeinformation.frameworkdescription", "https://twitter.com/JeffHicks/status/1705007619499237525" ], - "Category": 3 + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-21T00:00:00", @@ -375,7 +397,8 @@ "Urls": [ "https://jdhitsolutions.com/blog/essential-powershell-resources/" ], - "Category": 8 + "Category": 8, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-24T00:00:00", @@ -386,7 +409,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_trap", "https://www.sconstantinou.com/powershell-trap/" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-28T00:00:00", @@ -398,7 +422,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/write-eventlog", "https://devblogs.microsoft.com/scripting/how-to-use-powershell-to-write-to-event-logs/" ], - "Category": 3 + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-10-31T00:00:00", @@ -408,7 +433,8 @@ "Urls": [ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/select-object" ], - "Category": 3 + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-11-01T00:00:00", @@ -419,7 +445,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-member", "https://linuxhint.com/use-get-member-powershell/" ], - "Category": 3 + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-11-05T00:00:00", @@ -431,7 +458,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/set-clipboard", "https://adamtheautomator.com/powershell-copy-to-clipboard/" ], - "Category": 3 + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-11-10T00:00:00", @@ -442,7 +470,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/add-member", "https://ilovepowershell.com/powershell-modern/ultimate-guide-to-using-powershell-add-member-cmdlet/" ], - "Category": 3 + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2023-11-18T00:00:00", @@ -453,7 +482,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators#ternary-operator--if-true--if-false", "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_if#using-the-ternary-operator-syntax" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2024-01-07T00:00:00", @@ -464,7 +494,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-7.4#null-coalescing-operator-", "https://toastit.dev/2020/03/10/ps7now-null-conditional/" ], - "Category": 6 + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999" }, { "CreatedDate": "2024-01-17T00:00:00", @@ -474,6 +505,7 @@ "Urls": [ "https://discord.gg/powershell" ], - "Category": 0 + "Category": 0, + "ExpiryDate": "9999-12-31T23:59:59.9999999" } ] diff --git a/src/tiPS/Private/ReadAllPowerShellTipsFromJsonFile.ps1 b/src/tiPS/Private/ReadAllPowerShellTipsFromJsonFile.ps1 index 6a89924..ada7120 100644 --- a/src/tiPS/Private/ReadAllPowerShellTipsFromJsonFile.ps1 +++ b/src/tiPS/Private/ReadAllPowerShellTipsFromJsonFile.ps1 @@ -16,6 +16,11 @@ function ReadAllPowerShellTipsFromJsonFile [System.Collections.Specialized.OrderedDictionary] $tipDictionary = [System.Collections.Specialized.OrderedDictionary]::new() foreach ($tip in $tipObjects) { + if ($tip.ExpiryDate -lt [DateTime]::Today) + { + Write-Verbose "Skipping adding expired tip: $($tip.Title)" + continue + } $tipDictionary[$tip.Id] = $tip } diff --git a/src/tiPS/Private/TipsAlreadyShownFunctions.Tests.ps1 b/src/tiPS/Private/TipsAlreadyShownFunctions.Tests.ps1 index 32b7bb5..5036d56 100644 --- a/src/tiPS/Private/TipsAlreadyShownFunctions.Tests.ps1 +++ b/src/tiPS/Private/TipsAlreadyShownFunctions.Tests.ps1 @@ -12,6 +12,7 @@ InModuleScope -ModuleName tiPS { # Must use InModuleScope to call private functi $newTip.Example = $tip.Example $newTip.Urls = $tip.Urls $newTip.Category = $tip.Category + $newTip.ExpiryDate = $tip.ExpiryDate return $newTip } } @@ -34,6 +35,7 @@ InModuleScope -ModuleName tiPS { # Must use InModuleScope to call private functi $validTip.Example = 'Example' $validTip.Urls = @('https://Url1.com', 'http://Url2.com') $validTip.Category = 'Community' + $validTip.ExpiryDate = [DateTime]::MaxValue # Clone our valid tip to make multiple instances. [tiPS.PowerShellTip] $testTip1 = CloneTip -tip $validTip diff --git a/src/tiPS/Public/Get-PowerShellTip.Tests.ps1 b/src/tiPS/Public/Get-PowerShellTip.Tests.ps1 index 1d9e6c6..b45bd8e 100644 --- a/src/tiPS/Public/Get-PowerShellTip.Tests.ps1 +++ b/src/tiPS/Public/Get-PowerShellTip.Tests.ps1 @@ -48,14 +48,17 @@ Describe 'Get-PowerShellTip' { } Context 'Given the All switch' { - It 'Should return all tips' { + It 'Should return all non-expired tips' { [PSCustomObject[]] $allTipsFromJsonFile = GetAllTipsFromJsonFile - [int] $numberOfTipsInJsonFile = $allTipsFromJsonFile.Count + [int] $numberOfNonExpiredTipsInJsonFile = $allTipsFromJsonFile | + Where-Object { $_.ExpiryDate -ge [DateTime]::Today } | + Measure-Object | + Select-Object -ExpandProperty Count $allTips = Get-PowerShellTip -All $allTips | Should -Not -BeNullOrEmpty - $allTips.Count | Should -Be $numberOfTipsInJsonFile + $allTips.Count | Should -Be $numberOfNonExpiredTipsInJsonFile } It 'Should return the tips ordered by Created Date from oldest to newest' { @@ -159,6 +162,7 @@ InModuleScope -ModuleName tiPS { # Must use InModuleScope to access script-level $ValidTip.Example = 'Example' $ValidTip.Urls = @('https://Url1.com', 'http://Url2.com') $ValidTip.Category = 'Community' + $ValidTip.ExpiryDate = [DateTime]::MaxValue } Context 'When all of the tips have been shown' { diff --git a/tools/New-PowerShellTip.ps1 b/tools/New-PowerShellTip.ps1 index d4face3..d316e20 100644 --- a/tools/New-PowerShellTip.ps1 +++ b/tools/New-PowerShellTip.ps1 @@ -52,7 +52,9 @@ Example code to demonstrate the tip. This can also be multiple lines if needed. 'https://ToLearnMoreAboutTheTip' ) `$tip.Category = [tiPS.TipCategory]::Other # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +#`$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. +# Category meanings: # Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. # Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. # Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc.