From 912c4879d0cae92a17a28fc4523c4ac731a40b7b Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Thu, 2 Feb 2017 18:34:04 -0800 Subject: [PATCH] Built base module structure --- Chronometer/chronometer.psd1 | Bin 0 -> 7940 bytes Chronometer/chronometer.psm1 | 22 ++++ example.ps1 => ScratchFiles/example.ps1 | 0 profiler.ps1 => ScratchFiles/profiler.ps1 | 0 profiler2.ps1 => ScratchFiles/profiler2.ps1 | 0 profiler3.ps1 => ScratchFiles/profiler3.ps1 | 0 tests.ps1 => ScratchFiles/tests.ps1 | 0 Tests/Help.Tests.ps1 | 29 +++++ Tests/Project.Tests.ps1 | 25 +++++ appveyor.yml | 19 ++++ build.ps1 | 21 ++++ deploy.PSDeploy.ps1 | 29 +++++ psake.ps1 | 115 ++++++++++++++++++++ 13 files changed, 260 insertions(+) create mode 100644 Chronometer/chronometer.psd1 create mode 100644 Chronometer/chronometer.psm1 rename example.ps1 => ScratchFiles/example.ps1 (100%) rename profiler.ps1 => ScratchFiles/profiler.ps1 (100%) rename profiler2.ps1 => ScratchFiles/profiler2.ps1 (100%) rename profiler3.ps1 => ScratchFiles/profiler3.ps1 (100%) rename tests.ps1 => ScratchFiles/tests.ps1 (100%) create mode 100644 Tests/Help.Tests.ps1 create mode 100644 Tests/Project.Tests.ps1 create mode 100644 appveyor.yml create mode 100644 build.ps1 create mode 100644 deploy.PSDeploy.ps1 create mode 100644 psake.ps1 diff --git a/Chronometer/chronometer.psd1 b/Chronometer/chronometer.psd1 new file mode 100644 index 0000000000000000000000000000000000000000..545e5367daa280f2c889b86a7d4d25bfc38de60b GIT binary patch literal 7940 zcmeI1YfoE85Qg`2rT&K_@qwf&B;?k#Ql%gW32KreAZfoE-|EKLt_>kkmA~HheRe$A zvp(k-aD!S^6*4}T+1YpQGwVP9SPNf*A?$_sho%=IA9mO}TNYN3elkg#Yr|%#1{GIk1>H4Mi zord3p15WTV4$JtkH+=4eJM+)ouob>3tz`9+@OymXoQ{Nis$D1A1$oO-nWQHX6L>yU zD0+HlnrcZuGp%mxNs{eCcW2T}5&sWFQPt^Y#B->%V^QV$|6cS>y4@7!nGkQywd@kT ziTa&sXEajib1tfr__WZo-U6B=u^}lVSmb4R?uO04XL08v?KIIJdc$T|_aGdFr@BH9 zhG;goND+2Kc`ADJH4s8HSw~+4_I(m=h1;3!_QS58pGyn2*O~ZnkH?zt45Q5k+8@7T zmtK5=P23tuel++jybi|KWbK9f@}aHptt@+ApAAWVH#`>RjqpI2?}dlDI??+F+GRuh z+q&-Q>0_JW?#VX9 z{AJl>Qxx0sx1qihE~0ZPJowX8xd^Y?T##lrzE3&Bqb%7Ft@NT7wk4OnZ)qnYfDAGb z?{Um@c%^5+JVWF@*|ew0eh|@GUOpA}LYgh&eq>t9ujP9*PPRIavL^kT1l{mn@7vKo zT{fhE4&I*sXQJ`EIa|=tOVJa9r{Z#|HE43G)y^;1)lZQcKfH)L9K_Ts+%3;^_Ei%dRr)olMr_@K}!|@*Na))-6=wh`YDqLhdVcSFWYh^N~1ykW5}%cJ=H`64E(U<@7nT<>6^_*s1}x!(b21@&u;iybU&+?coeU;rRR>WAFQA~_m3))?M58+xg=F5 zd>TKXmebkNi*ZG_iOYmytz0w8eJ*k!YqiJRj`r#b3;pRpJeJFhG%eZ4y!j?@*CVP&pHDYF ztsucIWenzrt>{U~hWI45v#7;}%n)v^cC-_HI3X%B$MMR!=icS{3?gVanJMy3Smp|7~F11ex1x(7seVrvF@vSJnNS=xv;I*{RK{ z`X>sjysnCZ2_6j0>#HL8??$0b8q2g}9*}GCs=D9RbiN~RBmU`U>0GV5T`e1WKHe3# zcI?%1uJyR8{o0F|X~~dQOVGklcja1wuW;(v)?8&%3fZ#$tTxprM_8^BX}9`Xk>2NM z%GG^!BzrOUcQs8>U68pR1wGRs&YqV0JCd67H@6fBm`eQKYeQLQpS%9%vmBL<%7V49 zdm-B}0f5qKJZL!^-qjPs&eSneW#!JYP}zp`;N?jf&bb$GM>T}fd8V^uewC=7$t`Mf zohDRff%F?gAujyo*qf-FdQB^ig{mK|(vr7Mgx|ZKv#6o^uEO<7R8kG>1dWq}_6HL8b}E?B6-|sz*AVe?z~m&uc~f3wvPn0@m|7HhbB=LD2W$@GMbgtwp{Chbzyw<$)LI_WU&`*1+D47Ju;aAbo z7d30n<{PK`dpPL>>DDZkELVfWe8bLUmQBvhDEH?)uY>PU`{F%TkvQKV8wcrs9bou&^z!LzvmiBg=9gY0{KeRCV<6 I)9;CY0SJZ_1^@s6 literal 0 HcmV?d00001 diff --git a/Chronometer/chronometer.psm1 b/Chronometer/chronometer.psm1 new file mode 100644 index 0000000..1fa434a --- /dev/null +++ b/Chronometer/chronometer.psm1 @@ -0,0 +1,22 @@ +Write-Verbose "Importing Functions" + +# Import everything in sub folders folder +foreach($folder in @('private', 'public', 'classes')) +{ + $root = Join-Path -Path $PSScriptRoot -ChildPath $folder + if(Test-Path -Path $root) + { + Write-Verbose "processing folder $root" + $files = Get-ChildItem -Path $root -Filter *.ps1 + + # dot source each file + $files | where-Object{ $_.name -NotLike '*.Tests.ps1'} | + ForEach-Object{Write-Verbose $_.name; . $_.FullName} + } +} + +Export-ModuleMember -function (Get-ChildItem -Path "$PSScriptRoot\public\*.ps1").basename + +# Hack for my build system that had a conflit with the keyword node +New-Alias -Name 'DiGraph' -Value 'Graph' -ErrorAction SilentlyContinue +Export-ModuleMember -Alias 'DiGraph' diff --git a/example.ps1 b/ScratchFiles/example.ps1 similarity index 100% rename from example.ps1 rename to ScratchFiles/example.ps1 diff --git a/profiler.ps1 b/ScratchFiles/profiler.ps1 similarity index 100% rename from profiler.ps1 rename to ScratchFiles/profiler.ps1 diff --git a/profiler2.ps1 b/ScratchFiles/profiler2.ps1 similarity index 100% rename from profiler2.ps1 rename to ScratchFiles/profiler2.ps1 diff --git a/profiler3.ps1 b/ScratchFiles/profiler3.ps1 similarity index 100% rename from profiler3.ps1 rename to ScratchFiles/profiler3.ps1 diff --git a/tests.ps1 b/ScratchFiles/tests.ps1 similarity index 100% rename from tests.ps1 rename to ScratchFiles/tests.ps1 diff --git a/Tests/Help.Tests.ps1 b/Tests/Help.Tests.ps1 new file mode 100644 index 0000000..6f4d3fb --- /dev/null +++ b/Tests/Help.Tests.ps1 @@ -0,0 +1,29 @@ +$projectRoot = Resolve-Path "$PSScriptRoot\.." +$moduleRoot = Split-Path (Resolve-Path "$projectRoot\*\*.psm1") +$moduleName = Split-Path $moduleRoot -Leaf + +Import-Module (Join-Path $moduleRoot "$moduleName.psm1") -force + +Describe "Help tests for $moduleName" -Tags Build { + + $functions = Get-Command -Module $moduleName + $help = $functions | %{Get-Help $_.name} + foreach($node in $help) + { + Context $node.name { + + it "has a description" { + $node.description | Should Not BeNullOrEmpty + } + it "has an example" { + $node.examples | Should Not BeNullOrEmpty + } + foreach($parameter in $node.parameters.parameter) + { + it "parameter $($parameter.name) has a description" { + $parameter.Description.text | Should Not BeNullOrEmpty + } + } + } + } +} diff --git a/Tests/Project.Tests.ps1 b/Tests/Project.Tests.ps1 new file mode 100644 index 0000000..5ed72b3 --- /dev/null +++ b/Tests/Project.Tests.ps1 @@ -0,0 +1,25 @@ +$projectRoot = Resolve-Path "$PSScriptRoot\.." +$moduleRoot = Split-Path (Resolve-Path "$projectRoot\*\*.psd1") +$moduleName = Split-Path $moduleRoot -Leaf + +Describe "General project validation: $moduleName" -Tags Build { + + $scripts = Get-ChildItem $projectRoot -Include *.ps1,*.psm1,*.psd1 -Recurse + + # TestCases are splatted to the script so we need hashtables + $testCase = $scripts | Foreach-Object{@{file=$_}} + It "Script should be valid powershell" -TestCases $testCase { + param($file) + + $file.fullname | Should Exist + + $contents = Get-Content -Path $file.fullname -ErrorAction Stop + $errors = $null + $null = [System.Management.Automation.PSParser]::Tokenize($contents, [ref]$errors) + $errors.Count | Should Be 0 + } + + It "Module '$moduleName' can import cleanly" { + {Import-Module (Join-Path $moduleRoot "$moduleName.psm1") -force } | Should Not Throw + } +} diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..4918e7a --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,19 @@ +# See http://www.appveyor.com/docs/appveyor-yml for many more options + +environment: + NugetApiKey: + secure: sqj8QGRYue5Vq3vWm2GdcCttqyOkt7NOheKlnmIUq1UcgVrmQezFArp/2Z1+G3oT + +# Allow WMF5 (i.e. PowerShellGallery functionality) +os: WMF 5 + +# Skip on updates to the readme. +# We can force this by adding [skip ci] or [ci skip] anywhere in commit message +skip_commits: + message: /updated (readme|doc).*|update (readme|doc).*s/ + +build: false + +#Kick off the CI/CD pipeline +test_script: + - ps: . .\build.ps1 \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..ef97c13 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,21 @@ +<# +.Description +Installs and loads all the required modules for the build. +.Author +Warren F. (RamblingCookieMonster) +#> + +[cmdletbinding()] +param ($Task = 'Default') + +# Grab nuget bits, install modules, set build variables, start build. +Get-PackageProvider -Name NuGet -ForceBootstrap | Out-Null + +Install-Module Psake, PSDeploy, BuildHelpers -force +Install-Module Pester -Force -SkipPublisherCheck +Import-Module Psake, BuildHelpers + +Set-BuildEnvironment + +Invoke-psake -buildFile .\psake.ps1 -taskList $Task -nologo +exit ( [int]( -not $psake.build_success ) ) \ No newline at end of file diff --git a/deploy.PSDeploy.ps1 b/deploy.PSDeploy.ps1 new file mode 100644 index 0000000..65a21d9 --- /dev/null +++ b/deploy.PSDeploy.ps1 @@ -0,0 +1,29 @@ +# Generic module deployment. +# This stuff should be moved to psake for a cleaner deployment view + +# ASSUMPTIONS: + + # folder structure of: + # - RepoFolder + # - This PSDeploy file + # - ModuleName + # - ModuleName.psd1 + + # Nuget key in $ENV:NugetApiKey + + # Set-BuildEnvironment from BuildHelpers module has populated ENV:BHProjectName + +# find a folder that has psd1 of same name... + +if($ENV:BHProjectName -and $ENV:BHProjectName.Count -eq 1) +{ + Deploy Module { + By PSGalleryModule { + FromSource $ENV:BHProjectName + To PSGallery + WithOptions @{ + ApiKey = $ENV:NugetApiKey + } + } + } +} \ No newline at end of file diff --git a/psake.ps1 b/psake.ps1 new file mode 100644 index 0000000..45076bd --- /dev/null +++ b/psake.ps1 @@ -0,0 +1,115 @@ +# PSake makes variables declared here available in other scriptblocks +# Init some things +Properties { + # Find the build folder based on build system + $ProjectRoot = $ENV:BHProjectPath + if(-not $ProjectRoot) + { + $ProjectRoot = $PSScriptRoot + } + + $Timestamp = Get-date -uformat "%Y%m%d-%H%M%S" + $PSVersion = $PSVersionTable.PSVersion.Major + $TestFile = "TestResults_PS$PSVersion`_$TimeStamp.xml" + $lines = '----------------------------------------------------------------------' + + $Verbose = @{} + if($ENV:BHCommitMessage -match "!verbose") + { + $Verbose = @{Verbose = $True} + } +} + +Task Default -Depends Deploy + +Task Init { + $lines + Set-Location $ProjectRoot + "Build System Details:" + Get-Item ENV:BH* | Format-List + "`n" + "Check for node conflict" + Get-Command node | Select-Object * +} + +Task UnitTests -Depends Init { + $lines + 'Running quick unit tests to fail early if there is an error' + $TestResults = Invoke-Pester -Path $ProjectRoot\Tests\*unit* -PassThru -Tag Build -Show Failed + + if($TestResults.FailedCount -gt 0) + { + Write-Error "Failed '$($TestResults.FailedCount)' tests, build failed" + } + "`n" +} + +Task Test -Depends UnitTests { + $lines + "`n`tSTATUS: Testing with PowerShell $PSVersion" + + # Gather test results. Store them in a variable and file + $TestResults = Invoke-Pester -Path $ProjectRoot\Tests -PassThru -OutputFormat NUnitXml -OutputFile "$ProjectRoot\$TestFile" -Tag Build -Show Failed + + # In Appveyor? Upload our tests! #Abstract this into a function? + If($ENV:BHBuildSystem -eq 'AppVeyor') + { + "Uploading $ProjectRoot\$TestFile to AppVeyor" + "JobID: $env:APPVEYOR_JOB_ID" + (New-Object 'System.Net.WebClient').UploadFile( + "https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", + (Resolve-Path "$ProjectRoot\$TestFile" ) + ) + } + + Remove-Item "$ProjectRoot\$TestFile" -Force -ErrorAction SilentlyContinue + + # Failed tests? + # Need to tell psake or it will proceed to the deployment. Danger! + if($TestResults.FailedCount -gt 0) + { + Write-Error "Failed '$($TestResults.FailedCount)' tests, build failed" + } + "`n" +} + +Task Build -Depends Test { + $lines + + $functions = Get-ChildItem "$PSScriptRoot\$env:BHProjectName\Public\*.ps1" | + Where-Object{ $_.name -notmatch 'Tests'} | + Select-Object -ExpandProperty basename + + # Load the module, read the exported functions, update the psd1 FunctionsToExport + Set-ModuleFunctions -Name $env:BHPSModuleManifest -FunctionsToExport $functions + + # Bump the module version + $Version = Get-NextPSGalleryVersion -Name $env:BHProjectName + Update-Metadata -Path $env:BHPSModuleManifest -PropertyName ModuleVersion -Value $Version +} + +Task Deploy -Depends Build { + $lines + + # Gate deployment + if( + $ENV:BHBuildSystem -ne 'Unknown' -and + $ENV:BHBranchName -eq "master" -and + $ENV:BHCommitMessage -match '!deploy' + ) + { + $Params = @{ + Path = $ProjectRoot + Force = $true + } + + Invoke-PSDeploy @Verbose @Params + } + else + { + "Skipping deployment: To deploy, ensure that...`n" + + "`t* You are in a known build system (Current: $ENV:BHBuildSystem)`n" + + "`t* You are committing to the master branch (Current: $ENV:BHBranchName) `n" + + "`t* Your commit message includes !deploy (Current: $ENV:BHCommitMessage)" + } +}