Notices: This section not yet converted to new layout. Download stats are rolling back out.

Silk

0.2.0

Package test results are passing.

This package was approved by moderator flcdrg on 11/26/2016.

PowerShell module for publishing another module's help system as a website.

To install Silk, run the following command from the command line or from PowerShell:

C:\> choco install silk

To upgrade Silk, run the following command from the command line or from PowerShell:

C:\> choco upgrade silk

Files

Hide
  • LICENSE
  • NOTICE
  • RELEASE_NOTES.md Show
    # 0.2.0 (21 November 2016)
    
     * Improved `about_Silk` help topic.
     * Added example scripts `Invoke-Build.ps1`, `Publish-Module.ps1`, and `New-Website.ps1` to show how to use Silk.
    
  • Silk\bin\MarkdownSharp.dll Show
    md5: 6A2AA9E5FD90BC15B51CA32113271B34 | sha1: 36A6C7FFF88DED2F28E846320721BC2A758B9C29 | sha256: 605E6AD93DFEA7F777735558A01B286602C156D1062E7A5872F84410128E1B92 | sha512: 6037A6FCFBB13955E9554BDA72522A1F9406132A2D8986C71CA94724391525610E454DA4F5757E81A0DB57FAE75C0363EC47C69BD9BD00BDBB4FF91CF13CE6EA
  • Silk\bin\NuGet.exe Show
    md5: C0C47419C0641F4638E3758F4E997C2B | sha1: E412DEA7B234D73048213AB9391500501DEB46CD | sha256: 8339DEB284895BC2D8B41C762C9D967DD8A62E420E46B877457A4361DCF42068 | sha512: ADB5EE24A22B9E3C0C35E4C8C8332B1E55F87AF0232BD4AF3D72F4419FB9F33AB6456ED31965BD0FCF980C85F5CBE61EEA3B4442A135B603D93406B97204C0AE
  • Silk\en-US\about_Silk.help.txt Show
    NAME
        Silk
        
    SYNOPSIS
        Silk is a PowerShell module for authoring, building, and publishing
        PowerShell modules and creating a website from a module's help 
        topics.
    
    DESCRIPTION
    
        Silk is a PowerShell module for PowerShell module authors. Use it to:
    
        * Automatically version of your module
        * Easily build your module, including any compiled assemblies
        * Publish your module as a Chocolatey and/or NuGet package
        * Publish your module to the PowerShell gallery
        * Convert your module's help as a website
    
        If you look in Silk's Examples directory, you'll see three scripts 
        that demonstrate its capabilities:
    
        * `Invoke-Build.ps1` shows how to build and package your module with 
        Silk
        * `Publish-Module.ps1` shows how to publish your module to 
        Chocolatey, NuGet, and the PowerShell Gallery.
        * `Publish-Website.ps1` shows how to publish your module's help to a 
        website.
    
    
        ## Versioning and Building
    
        To get started, create a `build.ps1` file in the root of your 
        repository. In your `build.ps1` file, import Silk. Use Silk's 
        `Set-ModuleVersion` function to set your module's version and 
        compile any code.
    
            Set-ModuleVersion -ManifestPath "PATH TO MODULE'S *.psd1 FILE" `
                              -Version "VERSION TO BUILD" `
                              -ReleaseNotesPath 'PATH TO RELEASE NOTES FILE' 
                              
        `Set-ModuleVersion` will also set the version in a .nuspec file (for 
        creating Chocolatey and NuGet packages) and an AssemblyInfo.cs file 
        (for versioning your module's assembly. 
    
        `Set-ModuleVersion` will build a Visual Studio solution if you pass 
        its path via the `SolutionPath` parameter.
    
        Silk expects your release notes files to be written in Markdown. It 
        expects each level-1 header (marked with a single `#` at the 
        beginning of a line) to be a version number, and everything after 
        that header to the next level-1 header (or the end of the file) to 
        be the release notes for that version. When `Set-ModuleVersion` sets 
        the version in a release notes file, it only sets the first level-1 
        header it finds.
    
        See the `RELEASE_NOTES.md` included with the Silk module for an 
        example.
    
    
        # Packaging and Preparing to Release
    
        Silk can do the following actions to prepare your module for a 
        release:
    
        * The `Set-ReleaseNotesReleaseDate` function set the release date in 
        your release notes file.
        * The `Set-ModuleManifestMetadata` function sets the release notes 
        and tags fields in your module manifest (i.e. .psd1 file). 
        * Thge `Set-ModuleNuspec` function sets metadata in a .nuspec file 
        (for Chocolatey and NuGet packages). The .nuspec file's description, 
        version, tags, and copyright fields are set from your module's 
        manifest (i.e. .psd1) file. The .nuspec file's releaseNotes property 
        is pulled from your release notes file.
        * The `New-NugetPackage` function will create a NuGet package from a 
        .nuspec file.
        * The `New-ChocolateyPackage` function will create a Chocolatey 
        package from a .nuspec file. 
    
        ## Publishing/Releasing a Module
    
        Silk has the following functions you can use to publish/release your 
        module:
    
        * `Publish-NuGetPackage` will publish your module's .nupkg file to 
        nuget.org. (You create a .nupkg file from a .nuspec file with the 
        `New-NuGetPackage` function.)
        * `Pulish-ChocolateyPackage` will publish your module's .nupkg file 
        to chocolatey.org. (You create a .nupkg file from a .nuspec file 
        with the `New-ChocolateyPackage` function.
        * `Publish-PowerShellGalleryModule` will publish your module to the 
        PowerShell Gallery (https://powershellgallery.com).
    
        ## Creating a Website from a Module's Help Topics
    
        Silk has the following functions for generating a website from a 
        module's help topics. Silk assumes your help is written in Markdown.
    
        Silk will auto-link to commands inside your module. Surround your 
        module's command names, script names, and about topics in backticks, 
        and Silk will convert it to a link to that item's help topic. For 
        example, `about_Silk` will get converted to `<a 
        href="about_Silk.html">about_Silk</a>`.
    
        * `Convert-ModuleHelpToHtml` converts the help for each command in a 
        module to an .html page/file.
        * `New-ModuleHelpIndex` creates an index.html page that includes 
        links to a module's `about_` help topics, standalone scripts, and 
        commands. The commands are organized into three tabs: one organized 
        by tags, one organized alphabetically by command name, and one 
        organized alphabetically by verb.
        * `Convert-ABoutTopicToHtml` converts about topics to HTML pages.
    
    
  • Silk\Examples\Invoke-Build.ps1 Show
    <#
    .SYNOPSIS
    Sets the version number for the LibGit2 module.
    #>
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    [CmdletBinding()]
    param(
        [Version]
        # The version to build. If not supplied, build the version as currently defined.
        $Version,
    
        [Switch]
        # Build and create packages that will be published.
        $ForRelease
    )
    
    #Requires -Version 4
    Set-StrictMode -Version Latest
    $ErrorActionPreference = 'Stop'
    
    & (Join-Path -Path $PSScriptRoot -ChildPath 'Silk\Import-Silk.ps1' -Resolve)
    
    $manifestPath = Join-Path -Path $PSScriptRoot -ChildPath 'Silk\Silk.psd1'
    
    $manifest = Test-ModuleManifest -Path $manifestPath
    if( -not $manifest )
    {
        return
    }
    
    $nuspecPath = Join-Path -Path $PSScriptRoot -ChildPath 'Silk.nuspec' -Resolve
    $releaseNotesPath = Join-Path -Path $PSScriptRoot -ChildPath 'RELEASE_NOTES.md' -Resolve
    
    # If you need to compile an assembly or other code, add SolutionPath and AssemblyInfoPath parameters, e.g.
    #                 -SolutionPath (Join-Path -Path $PSScriptRoot -ChildPath 'Source\Silk.sln' -Resolve) `
    #                 -AssemblyInfoPath (Join-Path -Path $PSScriptRoot -ChildPath 'Source\Silk\Properties\AssemblyInfo.cs' -Resolve)
    Set-ModuleVersion -ManifestPath $manifestPath `
                      -Version $Version `
                      -ReleaseNotesPath $releaseNotesPath `
                      -NuspecPath $nuspecPath
    
    Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath 'Tools\Pester' -Resolve)
    
    $result = Invoke-Pester -Script (Join-Path -Path $PSScriptRoot -ChildPath 'Tests') -PassThru
    if( $result.FailedCount )
    {
        exit
    }
    
    if( -not $ForRelease )
    {
        return
    }
    
    $valid = Assert-ModuleVersion -ManifestPath $manifestPath -ReleaseNotesPath $releaseNotesPath -NuspecPath $nuspecPath -ExcludeAssembly 'LibGit2Sharp.dll'
    if( -not $valid )
    {
        Write-Error -Message ('Silk isn''t at the right version. Please use the -Version parameter to set the version.')
        return
    }
    
    Set-ReleaseNotesReleaseDate -ManifestPath $manifestPath -ReleaseNotesPath $releaseNotesPath
    
    $tags = @( 'powershell', 'module', 'help', 'tools' )
    
    Set-ModuleManifestMetadata -ManifestPath $manifestPath -Tag $tags -ReleaseNotesPath $releaseNotesPath
    
    $outputDirectory = Join-Path -Path $PSScriptRoot -ChildPath 'Output'
    if( (Test-Path -Path $outputDirectory -PathType Container) )
    {
        Get-ChildItem -Path $outputDirectory | Remove-Item -Recurse
    }
    else
    {
        New-Item -Path $outputDirectory -ItemType 'directory'
    }
    
    Set-ModuleNuspec -ManifestPath $manifestPath `
                     -NuspecPath $nuspecPath `
                     -ReleaseNotesPath $releaseNotesPath `
                     -Tags $tags `
                     -PackageID 'Silk.PowerShell' `
                     -PackageTitle 'Silk.PowerShell'
    
    
    New-NuGetPackage -OutputDirectory (Join-Path -Path $outputDirectory -ChildPath 'nuget.org') `
                     -ManifestPath $manifestPath `
                     -NuspecPath $nuspecPath `
                     -NuspecBasePath $PSScriptRoot `
                     -PackageName 'Silk.PowerShell'
    
    Set-ModuleNuspec -ManifestPath $manifestPath `
                     -NuspecPath $nuspecPath `
                     -ReleaseNotesPath $releaseNotesPath `
                     -Tags $tags `
                     -PackageID 'Silk' `
                     -PackageTitle 'Silk'
    
    New-ChocolateyPackage -OutputDirectory (Join-Path -Path $outputDirectory -ChildPath 'chocolatey.org') `
                          -ManifestPath $manifestPath `
                          -NuspecPath $nuspecPath
    
    $source = Join-Path -Path $PSScriptRoot -ChildPath 'Silk'
    $destination = Join-Path -Path $outputDirectory -ChildPath 'Silk'
    robocopy.exe $source $destination /MIR /NJH /NJS /NP /NDL /XD /XF '*.pdb'
    
    $examplesDir = Join-Path -Path $destination -ChildPath 'Examples'
    New-Item -Path $examplesDir -ItemType 'Directory'
    
    Get-ChildItem -Path (Join-Path -Path $PSScriptRoot -ChildPath 'build.ps1') |
        Copy-Item -Destination (Join-Path -Path $examplesDir -ChildPath 'Invoke-Build.ps1')
    
    Get-ChildItem -Path (Join-Path -Path $PSScriptRoot -ChildPath 'New-Website.ps1') |
        Copy-Item -Destination $examplesDir
    
    Get-ChildItem -Path (Join-Path -Path $PSScriptRoot -ChildPath 'Publish-Silk.ps1') |
        Copy-Item -Destination (Join-Path -Path $examplesDir -ChildPath 'Publish-Module.ps1')
    
    Get-ChildItem -Path 'RELEASE_NOTES.md','LICENSE','NOTICE' | Copy-Item -Destination $destination
    
  • Silk\Examples\New-Website.ps1 Show
    <#
    .SYNOPSIS
    Creates the get-libgit2.org website.
    
    .DESCRIPTION
    The `New-Website.ps1` script generates the get-libgit2.org website. It uses the Silk module for Markdown to HTML conversion.
    #>
    
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    [CmdletBinding()]
    param(
    )
    
    #Requires -Version 4
    Set-StrictMode -Version 'Latest'
    
    function Out-HtmlPage
    {
        param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
            [Alias('Html')]
            # The contents of the page.
            $Content,
    
            [Parameter(Mandatory=$true)]
            # The title of the page.
            $Title,
    
            [Parameter(Mandatory=$true)]
            # The path under the web root of the page.
            $VirtualPath
        )
    
        begin
        {
            Set-StrictMode -Version 'Latest'
        }
    
        process
        {
    
            $webRoot = Join-Path -Path $PSScriptRoot -ChildPath 'get-silk.org'
            $path = Join-Path -Path $webRoot -ChildPath $VirtualPath
            $templateArgs = @(
                                $Title,
                                $Content,
                                (Get-Date).Year
                            )
            @'
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
        <title>{0}</title>
        <link href="silk.css" type="text/css" rel="stylesheet" />
    	<link href="styles.css" type="text/css" rel="stylesheet" />
    </head>
    <body>
    
        <ul id="SiteNav">
    		<li><a href="index.html">Get-Silk</a></li>
    		<li><a href="documentation.html">-Documentation</a></li>
            <li><a href="releasenotes.html">-ReleaseNotes</a></li>
    		<li><a href="http://pshdo.com">-Blog</a></li>
            <li><a href="http://github.com/pshdo/Silk">-Project</a></li>
        </ul>
    
        {1}
    
    	<div class="Footer">
    		Copyright {2} <a href="http://pshdo.com">Aaron Jensen</a>.
    	</div>
    
    </body>
    </html>
    '@ -f $templateArgs | Set-Content -Path $path
        }
    
        end
        {
        }
    }
    
    $silkRoot = Join-Path -Path $PSScriptRoot -ChildPath '.\Silk' -Resolve
    
    if( (Get-Module -Name 'Blade') )
    {
        Remove-Module 'Blade'
    }
    
    $headingMap = @{ }
    
    & (Join-Path -Path $silkRoot -ChildPath 'Import-Silk.ps1' -Resolve)
    
    try
    {
        Convert-ModuleHelpToHtml -ModuleName 'Silk' -HeadingMap $headingMap -Script 'Import-Silk.ps1' |
            ForEach-Object { Out-HtmlPage -Title ('PowerShell - {0} - Silk' -f $_.Name) -VirtualPath ('{0}.html' -f $_.Name) -Content $_.Html }
    }
    finally
    {
    }
    
    $tagsPath = Join-Path -Path $PSScriptRoot -ChildPath 'tags.json'
    New-ModuleHelpIndex -TagsJsonPath $tagsPath -ModuleName 'Silk' -Script 'Import-Silk.ps1' |
         Out-HtmlPage -Title 'PowerShell - Silk Module Documentation' -VirtualPath '/documentation.html'
    
    $moduleTitle = 'Silk: PowerShell module for PowerShell module authors and projects'
    Get-Item -Path (Join-Path -Path $PSScriptRoot -ChildPath 'Silk\en-US\about_Silk.help.txt') |
        Convert-AboutTopicToHtml -ModuleName 'Silk' -Script 'Import-Silk.ps1' |
        ForEach-Object {
            $_ -replace '<h1>about_Silk</h1>','<h1>Silk</h1>'
        } |
        Out-HtmlPage -Title $moduleTitle -VirtualPath '/index.html'
    
    $releaseNotesPath = Join-Path -Path $PSScriptRoot -ChildPath 'RELEASE_NOTES.md' 
    Get-Content -Path $releaseNotesPath -Raw | 
        Edit-HelpText -ModuleName 'Silk' |
        Convert-MarkdownToHtml | 
        Out-HtmlPage -Title ('Release Notes - {0}' -f $moduleTitle) -VirtualPath '/releasenotes.html'
    
    $silkCssPath = Join-Path -Path $silkRoot -ChildPath 'Resources\silk.css' -Resolve
    $webroot = Join-Path -Path $PSScriptRoot -ChildPath 'get-silk.org'
    Copy-Item -Path $silkCssPath -Destination $webroot -Verbose
  • Silk\Examples\Publish-Module.ps1 Show
    <#
    .SYNOPSIS
    Packages and publishes Silk packages.
    
    .DESCRIPTION
    The `Publish-Silk.ps1` script packages and publishes a version of the Silk module. It uses the version defined in the Silk.psd1 file. Before publishing, it adds the current date to the version in the release notes, updates the module's website, then tags the latest revision with the version number. It then publishes the module to NuGet, Chocolatey, and the PowerShell Gallery. If the version of Silk being published already exists in a location, it is not re-published. If the PowerShellGet module isn't installed, the module is not publishes to the PowerShell Gallery.
    
    .EXAMPLE
    Publish-Silk.ps1
    
    Yup. That's it.
    #>
    
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    [CmdletBinding(SupportsShouldProcess=$true)]
    param(
    )
    
    #Requires -Version 4
    Set-StrictMode -Version Latest
    
    & (Join-Path -Path $PSScriptRoot -ChildPath 'Silk\Import-Silk.ps1' -Resolve)
    
    $silkRoot = Join-Path -Path $PSScriptRoot -ChildPath 'Output\Silk'
    $releaseNotesPath = Join-Path -Path $silkRoot -ChildPath 'RELEASE_NOTES.md' -Resolve
    
    $manifestPath = Join-Path -Path $silkRoot -ChildPath 'Silk.psd1'
    $manifest = Test-ModuleManifest -Path $manifestPath
    if( -not $manifest )
    {
        return
    }
    
    $nupkgPath = Join-Path -Path $PSScriptRoot `
                           -ChildPath ('Output\nuget.org\Silk.PowerShell.{0}.nupkg' -f $manifest.Version)
    Publish-NuGetPackage -NupkgPath $nupkgPath
    
    $nupkgPath = Join-Path -Path $PSScriptRoot `
                           -ChildPath ('Output\chocolatey.org\Silk.{0}.nupkg' -f $manifest.Version)
    Publish-ChocolateyPackage -NupkgPath $nupkgPath
    
    $tags = @( 'powershell', 'module', 'help', 'tools' )
    
    Publish-PowerShellGalleryModule -ManifestPath $manifestPath `
                                    -ModulePath $silkRoot `
                                    -ReleaseNotesPath $releaseNotesPath `
                                    -LicenseUri 'http://www.apache.org/licenses/LICENSE-2.0' `
                                    -ProjectUri 'http://get-silk.org' `
                                    -Tags $tags
    
  • Silk\Functions\Convert-AboutTopicToHtml.ps1 Show
    4
    function Convert-AboutTopicToHtml
    {
        <#
        .SYNOPSIS
        Converts an about topic into HTML.
    
        .DESCRIPTION
        The `Convert-AboutTopicToHtml` converts a PowerShell about topic into HTML. The about topic is expected to be [formatted like PowerShell's internal topics](https://msdn.microsoft.com/en-us/library/Dd878343.aspx):
    
            TOPIC
                about_<subject or module name>
            
            SHORT DESCRIPTION
                A short, one-line description of the topic contents.
            
            LONG DESCRIPTION
                A detailed, full description of the subject or purpose of the module.
            
            EXAMPLES
                Examples of how to use the module or how the subject feature works in practice.
            
            KEYWORDS
                Terms or titles on which you might expect your users to search for the information in this topic.
            
            SEE ALSO
                Text-only references for further reading. Hyperlinks cannot work in the Windows PowerShell console. 
        
        `Convert-AboutTopicToHtml` does the following:
        
         * Removes the `TOPIC` AND `SHORT DESCRIPTION` headers
         * Wraps the topic name in an <h1> tag
         * Renames the `LONG DESCRIPTION` heading to '<h2>Description</h2>
         * Wraps all other headers in <h2> elements.
         * Converts the bodies of each section to HTML 
    
        Lines that don't begin with spaces are assumed to be headers.
    
        Lines that begin with spaces are assumed to be content written in Markdown.
    
        The `SEE ALSO` section is parsed, one line at a time for links, command names, and other help topics, e.g.
    
            SEE ALSO
                https://msdn.microsoft.com/en-us/library/Dd878343.aspx
                about_Silk
                Convert-AboutTopicToHtml
    
        Would convert into a three item list, the first a link to the web, the second a link to the `about_Silk.html` topic, and the third to the `Convert-AboutTopicToHtml.html` page.
        #>
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            # The name of the help topic, include the `about_` prefix, or a `FileInfo` object representing the help topic, or the help topic as a giant string.
            $InputObject,
            
            [string]
            # The name of the topic you're converting. Only used if `InputObject` is the text of the about topic.
            $TopicName,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The name of the module being documented.
            $ModuleName,
    
            [string]
            # The heading used for the topic's name. Default is `TOPIC`.
            $TopicHeading = 'TOPIC',
    
            [string]
            # The heading used for the topic's short description. Default is `SHORT DESCRIPTION`.
            $ShortDescriptionHeading = 'SHORT DESCRIPTION',
    
            [string]
            # The heading used for the topic's long description. Default is `LONG DESCRIPTION`.
            $LongDescriptionHeading = 'LONG DESCRIPTION',
    
            [string]
            # The heading used for the topic's `See Also` section. Default is `SEE ALSO`.
            $SeeAlsoHeading = 'SEE ALSO',
    
            [hashtable]
            # A hashtable of headings to use. They key should be the section name. The value should be the heading name.
            $HeadingMap = @{},
    
            [string[]]
            # The names of any scripts in the module.
            $Script
        )
    
        begin
        {
            Set-StrictMode -Version 'Latest'
        }
    
        process
        {
    
            function Complete-Section
            {
                param(
                    [string]
                    $Heading,
    
                    [Parameter(Mandatory=$true)]
                    [AllowEmptyString()]
                    [string]
                    $Body
                )
    
                $Body = $Body.Trim()
                switch( $Heading )
                {
                    $TopicHeading
                    {
                        # We just don't want to do any Markdown conversion.
                    }
    
                    $SeeAlsoHeading
                    {
                        $lines = $Body -split ([Environment]::NewLine) | 
                                    Convert-RelatedLinkToHtml -ModuleName $ModuleName -Script $Script | 
                                    ForEach-Object { '<li>{0}</li>' -f $_ }
                        $Body = @'
        <ul>
            {0}
        </ul>
    '@ -f ($lines -join [Environment]::NewLine)
                    }
                    default
                    {
                        $Body = $Body | Edit-HelpText -ModuleName $ModuleName | Convert-MarkdownToHtml 
                    }
                }
    
                $topic | Add-Member -Name $Heading -MemberType NoteProperty -Value $Body
            }
    
            if( $InputObject -is [IO.FileInfo] )
            {
                [string[]]$lines = $InputObject | Get-Content
                $TopicName = $InputObject.BaseName -replace '\.help$' -f ''
            }
            elseif( $InputObject -is [string] -and $InputObject -match '^about_' )
            {
                [string[]]$lines = Get-Help -Name $InputObject
                if( -not $lines )
                {
                    Write-Error ('About topic ''{0}'' not found.' -f $InputObject)
                    return
                }
                $TopicName = $InputObject
            }
            else
            {
                $lines = $InputObject -split ([Environment]::NewLine)
            }
    
            $topic = [pscustomobject]@{ }
            $currentHeader = $null
            $currentContent = $null
            $sectionOrder = New-Object 'Collections.Generic.List[string]'
            $lastLineIdx = $lines.Count - 1
            for( $idx = 0; $idx -lt $lines.Count; ++$idx )
            {
                $line = $lines[$idx]
    
                if( -not $line -or $line -match '^\s+' )
                {
                    if( $line.StartsWith('    ') )
                    {
                        $line = $line -replace '^    ',''
                    }
                    elseif( $line.StartsWith('  ') )
                    {
                        $line = $line -replace '^  ',''
                    }
    
                    [void]$currentContent.AppendLine( $line )
                    if( $idx -eq $lastLineIdx )
                    {
                        Complete-Section -Heading $currentHeader -Body $currentContent.ToString()
                    }
    
                    continue
    
                }
                else
                {
                    # Header
                    if( $currentHeader )
                    {
                        Complete-Section -Heading $currentHeader -Body $currentContent.ToString()
                    }
    
                    $currentContent = New-Object 'Text.StringBuilder'
                    $currentHeader =  [Globalization.CultureInfo]::CurrentCulture.TextInfo.ToTitleCase( $line.ToLowerInvariant() )
                    $sectionOrder.Add( $currentHeader )
                }
            }
    
            if( -not ($topic | Get-Member -Name $TopicHeading) )
            {
                Write-Warning ('Topic ''{0}'' doesn''t have a ''{1}'' heading. Defaulting to {0}. Use the `TopicHeading` parameter to set the topic''s topic heading.' -f $TopicName,$TopicHeading)
                Complete-Section -Heading 'TOPIC' -Body $TopicName
            }
    
            if( -not ($topic | Get-Member -Name $ShortDescriptionHeading) )
            {
                Write-Warning ('Topic ''{0}'' doesn''t have a ''{1}'' heading. Use the `ShortDescription` parameter to set the topic''s SHORT DESCRIPTION heading.' -f $TopicName,$ShortDescriptionHeading)
                Complete-Section -Heading 'SHORT DESCRIPTION' -Body ''
            }
    
            if( -not $HeadingMap.ContainsKey($LongDescriptionHeading) )
            {
                $HeadingMap[$LongDescriptionHeading] = 'Description'
            }
    
            $content = New-Object 'Text.StringBuilder'
            foreach( $section in $sectionOrder )
            {
                if( $section -eq $TopicHeading -or $section -eq $ShortDescriptionHeading )
                {
                    continue
                }
    
                $heading = $section
                if( $HeadingMap.ContainsKey($section) )
                {
                    $heading = $HeadingMap[$section]
                }
                [void]$content.AppendLine( ('<h2>{0}</h2>' -f $heading) )
                [void]$content.AppendLine( $topic.$Section )
            }
    
            @'
        <h1>{0}</h1>
    
        {1}
    
        {2}
    
    '@ -f $topic.$TopicHeading,$topic.$ShortDescriptionHeading,$content
    
        }
    
        end
        {
        }
    }
  • Silk\Functions\Convert-HelpToHtml.ps1 Show
    function Convert-HelpToHtml 
    {
        <#
        .SYNOPSIS
        Converts a command's help topic to HTML.
    
        .DESCRIPTION
        The `Convert-HelpToHtml` function convert's a command's help topic to HTML. This HTML can then be used in a complete HTML page. It will output the following parts of a help topic, in the following order:
    
         * Name (in an `h1` element). You can override this name with the `DisplayName` parameter.
         * Synopsis
         * Syntax (which you can override with the `Syntax` parameter)
         * Description
         * Related Commands (i.e. `.LINK`)
         * Parameters
         * Parameters
         * Input Types (i.e. `.INPUTS`)
         * Return Types (i.e. `.OUTPUTS`)
         * Notes
         * Examples
    
        `Convert-HelpToHtml` converts all help text to HTML using [MarkdownSharp](https://code.google.com/p/markdownsharp/), a C# [Markdown](https://daringfireball.net/projects/markdown/) implementation. Markdown "allows you to write using an easy-to-read, easy-to-write plain text format, [that is converted] to structurally valid XHTML (or HTML)". This makes your help web-friendly.
    
        If you want to convert an entire module's help to HTML, including any scripts and DSC resources, use the `Convert-ModuleHelpToHtml` function. When converting help for a module, pass the module's name with the `ModuleName` parameter, and any of the module's commands or about topics found enclosed in backticks (Markdown's span of code indicators) will be converted to an anchor element whose `href` attribute is the command's name with a .html extension. For example, this help text:
    
        > Silk's `Convert-HelpToHtml` function converts help text written with Markdown into HTML.
    
        would get converted to
    
        > Silk's <a href="Convert-HelpToHtml.html">Convert-HelpToHtml</a> function converts help text written with Markdown into HTML.
    
        `Convert-HelpToHtml` assumes you'll take its output, wrap it in a full HTML page, and save all of these generated pages into the same directory. For example,
    
            $html = Convert-HelpToHtml -Name 'Convert-HelpToHtml' -ModuleName 'Silk'
            @"
            <!DOCTYPE html>
            <html>
            <head>
                <title>Convert-HelpToHTml</title>
                <link href="silk.css" type="text/css" rel="stylesheet" />
            </head>
            <body>
            $html
            </body>
            </html>
            "@ | Set-Content -Path (Join-Path -Path $webRoot -ChildPath 'Convert-HelpToHtml.html')
    
        `Convert-HelpToHtml` outputs HTML 5 (or tries to). For the best cross-browser compatability, make sure you define a doctype on each page. This is especially important for Internet Explorer. If you don't use a doctype, IE will display your pages in quirks mode, which won't display things correctly.
    
        Silk ships with a default cascading stylesheet (CSS) in the `Resources` directory. Copy this file into your webroot and link to it in each of your pages (via the `link` tag). To customize the appearance of your pages, we recommend you create your own stylesheet and link to it in each of your pages. Make all your style changes in yoru stylesheet. Future versions of Silk will contain fixes/enhancements to the default stylesheet. Using your own will make upgrading easier.
    
        .LINK
        https://daringfireball.net/projects/markdown/
    
        .LINK
        Convert-ModuleHelpToHtml
    
        .EXAMPLE
        Convert-HelpToHtml -Name 'Get-Module'
    
        Demonstrates how to use `Convert-HelpToHtml` to generate help for a command. You can pass multiple command names to the `Name` parameter.
    
        .EXAMPLE
        Get-Command -Module 'Silk' | Convert-HelpToHtml -ModuleName 'Silk'
    
        Demonstrates how you can pipe commands to `Convert-HelpToHtml` to generate help for them.
    
        .EXAMPLE
        Convert-HelpToHtml -Name 'Set-TargetResource' -DisplayName 'My_Dsc_Resource' -Syntax (Get-DscResource -Name 'My_Dsc_Resource' -Syntax)
    
        Demonstrates how you can document DSC resources. In this case, the resource's `Set-TargetResource` function contains the help to convert. Because the syntax for using a DSC resource is different than a PowerShell function/cmdlet, we pass the resource's syntax with the `Syntax` parameter.
        #>
    	param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string[]]
            # The name of the command(s) to document.
            $Name,
    
            [string]
            # The display name. When supplied, it is used as the command's name instead of `Name`. Useful if the command name being documented is different than its public name, e.g. DSC resources.
            $DisplayName,
    
            [string[]]
            # The syntax of the command. Useful when showing syntax for DSC resources.
            #
            # You can get the syntax for a DSC resource with the `Get-DscResource` cmdlet:
            # 
            #     Get-DscResource -Name 'My_Dsc_Resource' -Syntax
            $Syntax,
    
            [string]
            # The name of the module whose help is getting converted. Supplying this value will cause any of the module's cmdlets/functions surrounded by backticks (e.g. `Convert-HelpToHtml`) in help text to get replaced with an HTML link to that command's help topic.
            $ModuleName,
    
            [string[]]
            # The names of any scripts in the module. Supplying these values will cause any script names surround in backticks (e.g. `script.ps1`) in help text to get replaced with an HTML link to that script's help topic.
            $Script
        )
    
        begin
        {
            Set-StrictMode -Version 'Latest'
        }
    
        process
        {
    
            foreach( $commandName in $Name )
            {
                $html = New-Object 'Text.StringBuilder'
    
                $fullCommandName = $commandName
                if( (Get-Help -Name $commandName | Measure-Object).Count -gt 1 )
                {
                    $fullCommandName = '{0}\{1}' -f $ModuleName,$commandName
                }
                Write-Verbose -Message $fullCommandName
                $help = Get-Help -Name $fullCommandName -Full
    
                if( -not $DisplayName )
                {
                    $DisplayName = $commandName
                    if( [IO.Path]::IsPathRooted($DisplayName) )
                    {
                        $DisplayName = Split-Path -Leaf -Path $DisplayName
                    }
                }
            
                [void]$html.AppendFormat( '<h1>{0}</h1>{1}', $DisplayName, [Environment]::NewLine )
    
                $synopsis = $help.Synopsis | Convert-MarkdownToHtml
                if( $synopsis )
                {
                    [void]$html.AppendFormat( '<div class="Synopsis">{0}{1}{0}</div>{0}', [Environment]::NewLine, $synopsis )
                }
    
                if( -not $Syntax )
                {
                    $help.Syntax |
                        ForEach-Object { $_.syntaxItem } |
                        Where-Object { [IO.Path]::IsPathRooted($_.name) } |
                        ForEach-Object { $_.Name = Split-Path -Leaf -Path $_.name }
    
                    $Syntax = $help.Syntax | Out-HtmlString | Format-ForHtml | ForEach-Object { $_ -split "`n" }
                }
    
                if( $Syntax )
                {
                    [void]$html.AppendLine( @"
    
    <h2>Syntax</h2>
    <pre class="Syntax"><code>{0}</code></pre>
    "@ -f ($Syntax -join "</code></pre>$([Environment]::NewLine)<pre class=""Syntax""><code>") )
                }
    
                $description = $null
                if( $help | Get-Member -Name 'Description' )
                {    
                    $description = $help.Description | Out-HtmlString | Convert-MarkdownToHtml
                }
                if( $description )
                {
                    [void]$html.AppendLine( @"
    
    <h2>Description</h2>
    <div class="Description">
    $description
    </div>
    "@ )
                }
        
                [string[]]$relatedCommands = $help | Convert-RelatedLinkToHtml -ModuleName $ModuleName -Script $Script
        
                if( $relatedCommands )
                {
                    $relatedCommands = $relatedCommands | ForEach-Object { "<li>{0}</li>" -f $_ }
                    [void]$html.AppendLine( @"
    
    <h2>Related Commands</h2>
    
    <ul class="RelatedCommands">
    {0}
    </ul>
    "@ -f ($relatedCommands -join ([Environment]::NewLine)) )
                }
        
                $commonParameterNames = @{
                                            'Verbose' = $true;
                                            'Debug' = $true;
                                            'WarningAction' = $true;
                                            'WarningVariable' = $true;
                                            'ErrorAction' = $true;
                                            'ErrorVariable' = $true;
                                            'OutVariable' = $true;
                                            'OutBuffer' = $true;
                                            'WhatIf' = $true;
                                            'Confirm' = $true;
                                        }
                $hasCommonParameters = $false
                $parameters = $help | 
                                Select-Object -ExpandProperty 'Parameters' |
                                Where-Object { $_ | Get-Member -Name 'parameter' } |
                                Select-Object -ExpandProperty 'parameter' |
                                Where-Object { $_ } | 
                                ForEach-Object {
                                    if( $commonParameterNames.ContainsKey( $_.name ) )
                                    {
                                        $hasCommonParameters = $true
                                    }
                
                                    $defaultValue = '&nbsp;'
                                    if( $_ | Get-Member -Name 'DefaultValue' )
                                    {
                                        $defaultValue = $_.DefaultValue
                                    }
                                    $typeLink = Get-TypeDocumentationLink -CommandName $commandName -TypeName $_.type.name
                                    $paramDescription = $_ | 
                                                            Where-Object { $_ | Get-Member -name 'Description' } |
                                                            Select-Object -ExpandProperty 'Description' |
                                                            Out-HtmlString | 
                                                            Convert-MarkdownToHtml
                                @"
    <tr valign='top'>
    	<td>{0}</td>
    	<td>{1}</td>
    	<td class="ParamDescription">{2}</td>
    	<td>{3}</td>
    	<td>{4}</td>
        <td>{5}</td>
    </tr>
    "@ -f $_.Name,$typeLink,$paramDescription,$_.Required,$_.PipelineInput,$defaultValue
                        }
            
                if( $parameters )
                {
                    $commonParameters = ''
                    if( $hasCommonParameters )
                    {
                        $commonParameters = @"
    <tr valign="top">
        <td><a href="http://technet.microsoft.com/en-us/library/dd315352.aspx">CommonParameters</a></td>
        <td></td>
        <td>This cmdlet supports common parameters.  For more information type <br> <code>Get-Help about_CommonParameters</code>.</td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    "@
                    }
                    [void]$html.AppendLine( (@"
    
    <h2> Parameters </h2>
    <table id="Parameters">
    <tr>
    	<th>Name</th>
        <th>Type</th>
    	<th>Description</th>
    	<th>Required?</th>
    	<th>Pipeline Input</th>
    	<th>Default Value</th>
    </tr>
    {0}
    {1}
    </table>
    "@ -f ($parameters -join [Environment]::NewLine),$commonParameters))
                }
    
                $inputTypes = @()
                if( ($help | Get-Member -Name 'inputTypes') -and ($help.inputTypes | Get-Member 'inputType') )
                {
                    $inputTypes = $help.inputTypes.inputType |
                                        Where-Object {  ($_ | Get-Member -Name 'type') -and $_.type -and $_.type.name -match '^([^\s]+)\s*(.*)?$' } |
                                        ForEach-Object { 
                                            $typeLink = Get-TypeDocumentationLink -CommandName $commandName -TypeName $Matches[1].Trim('.')
                                            '{0}. {1}' -f $typeLink,$matches[2]
                                        } |
                                        Convert-MarkdownToHtml
                }
    
                if( $inputTypes )
                {
                    [void]$html.AppendLine( @"
    
    <h2>Input Types</h2>
    <div class="InputTypes">
    {0}
    </div>
    "@ -f ($inputTypes -join [Environment]::NewLine))
                }
        
                $returnValues [email protected]()
                if( ($help | Get-Member -Name 'returnValues') -and ($help.returnValues | Get-Member -Name 'returnValue') )
                {
                    $returnValues = $help.returnValues.returnValue |
                                        Where-Object {  ($_ | Get-Member -Name 'type') -and $_.type -and $_.type.name -match '^([^\s]+)\s*(.*)?$' } |
                                        ForEach-Object { 
                                            $typeLink = Get-TypeDocumentationLink -CommandName $commandName -TypeName $Matches[1].Trim('.')
                                            '{0}. {1}' -f $typeLink,$matches[2]
                                        } |
                                        Convert-MarkdownToHtml
                }
    
                if( $returnValues )
                {
                    [void]$html.AppendLine( @"
    
    <h2>Return Values</h2>
    <div class="ReturnValues">
    {0}
    </div>
    "@ -f ($returnValues -join [Environment]::NewLine))
                }
        
                $notes = ''
                if( $help | Get-Member -Name 'AlertSet' )
                {
                    $notes = $help.AlertSet | Out-HtmlString | ForEach-Object { $_ -replace "\r?\n    ",[Environment]::NewLine } | Convert-MarkdownToHtml
                }
    
                if( $notes )
                {
                    [void]$html.AppendLine( @"
    
    <h2>Notes</h2>
    <div class="Notes">
    {0}
    </div>
    "@ -f $notes)
                }
        
                $examples = @()
                if( $help | Get-Member -Name 'Examples' )
                {
                    $examples = $help.Examples |
                        Where-Object { $_ } |
                        Where-Object { $_ | Get-Member -Name 'example' } |
                        Select-Object -ExpandProperty 'example' |
                        ForEach-Object {
                            $title = $_.title.Trim(('-',' '))
                            $code = ''
                            if( $_.code )
                            {
                                $code = $_.code | Out-HtmlString
                                $code = '<pre><code>{0}</code></pre>' -f $code
                            }
                            $remarks = $_.remarks | Out-HtmlString | Convert-MarkdownToHtml
                            @"
    
    <h2>{0}</h2>
    {1}
    {2}
    "@ -f $title,$code,($remarks -join [Environment]::NewLine)
                    }
                }
    
                if( $examples )
                {
                    [void]$html.AppendLine( ($examples -join ([Environment]::NewLine * 2)) )
                }
    
                $html.ToString()
            }
        }
    
        end
        {
        }
    }
    
    
  • Silk\Functions\Convert-MarkdownToHtml.ps1 Show
    filter Convert-MarkdownToHtml
    {
        if( $_ )
        {
            $markdown.Transform( $_ ).Trim()
        }
    }
  • Silk\Functions\Convert-ModuleHelpToHtml.ps1 Show
    function Convert-ModuleHelpToHtml
    {
        <#
        .SYNOPSIS
        Converts a module's help into HTML.
    
        .DESCRIPTION
        The `Convert-ModuleHelpToHtml` function converts a module's help into HTML. It returns an object for each command and about help topic in the module. The object 
        #>
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # The name of the module whose help to convert.
            $ModuleName,
    
            [string[]]
            # Any scripts included in the module whose help should get generated. Scripts are assumed to be in the root of the module.
            $Script,
    
            [hashtable]
            # A hashtable of headings to use. They key should be the section name. The value should be the heading name. Only used when converting about help topics to HTML.
            $HeadingMap,
    
            [Switch]
            # Don't generate help for individual commands.
            $SkipCommandHelp
        )
    
        Set-StrictMode -Version 'Latest'
    
        $commands = Get-Command -Module $ModuleName -CommandType Cmdlet,Function,Filter 
    
        $moduleBase = Get-Module -Name $ModuleName |
                            Select-Object -ExpandProperty 'ModuleBase'
    
    
        $aboutTopics = @()
        if( (Test-Path -Path (Join-Path -Path $moduleBase -ChildPath 'en-US') -PathType Container) )
        {
            $aboutTopics = Get-ChildItem -Path $moduleBase -Filter 'en-US\about_*.help.txt'
        }
    
        $dscResources = Join-Path -Path $moduleBase -ChildPath 'DscResources' |
                            Where-Object { Test-Path -Path $_ -PathType Container } |
                            Get-ChildItem -Directory 
    
        $scripts = @()
        if( $Script ) 
        {
            $scripts = $Script | 
                            ForEach-Object { Join-Path -Path $moduleBase -ChildPath $_ } |
                            Get-Item
        }
    
        [int]$numCommands = $commands | Measure-Object | Select-Object -ExpandProperty 'Count'
        [int]$numScripts = $scripts | Measure-Object | Select-Object -ExpandProperty 'Count'
        [int]$numAboutTopics = $aboutTopics | Measure-Object | Select-Object -ExpandProperty 'Count'
        [int]$numDscResources = $dscResources | Measure-Object | Select-Object -ExpandProperty 'Count'
    
        [int]$numPages = $numAboutTopics + $numDscResources + $numScripts
        if( -not $SkipCommandHelp )
        {
            $numPages += $numCommands
        }
    
        $activity = 'Generating {0} Module HTML' -f $ModuleName
        $count = 0
        foreach( $command in $commands )
        {
            if( -not $SkipCommandHelp )
            {
                Write-Progress -Activity $activity -PercentComplete ($count++ / $numPages * 100) -CurrentOperation $command.Name -Status 'Commands'
                $html = Convert-HelpToHtml -Name $command.Name -Script $Script -ModuleName $ModuleName
                [pscustomobject]@{
                                    Name = $command.Name;
                                    Type = 'Command';
                                    Html = $html;
                                 }
            }
        }
    
        foreach( $scriptItem in $scripts )
        {
            Write-Progress -Activity $activity -PercentComplete ($count++ / $numPages * 100) -CurrentOperation $command.Name -Status 'Scripts'
            $html = Convert-HelpToHtml -Name $scriptItem.FullName -ModuleName $ModuleName -Script $Script
            [pscustomobject]@{
                                Name = $scriptItem.Name;
                                Type = 'Script'
                                Html = $html;
                             }
        }
    
        foreach( $aboutTopic in $aboutTopics )
        {
            $topicName = $aboutTopic.BaseName -replace '\.help',''
            Write-Progress -Activity $activity -PercentComplete ($count++ / $numPages * 100) -CurrentOperation $topicName -Status 'About Topics'
            $html = $aboutTopic | Convert-AboutTopicToHtml -ModuleName $ModuleName -Script $Script
            [pscustomobject]@{
                                Name = $topicName;
                                Type = 'AboutTopic';
                                Html = $html
                             }
        }
    
        foreach( $dscResource in $dscResources )
        {
            $dscResourceName = $dscResource.BaseName
            Write-Progress -Activity $activity -PercentComplete ($count++ / $numPages * 100) -CurrentOperation $dscResourceName -Status 'DSC Resources'
            Import-Module -Name $dscResource.FullName
            $html = Convert-HelpToHtml -Name 'Set-TargetResource' -DisplayName $dscResourceName -Syntax (Get-DscResource -Name $dscResourceName -Syntax) -ModuleName $ModuleName -Script $Script
            [pscustomobject]@{
                                Name = $dscResourceName;
                                Type = 'DscResource';
                                Html = $html;
                             }
        }
    }
  • Silk\Functions\Convert-RelatedLinkToHtml.ps1 Show
    function Convert-RelatedLinkToHtml
    {
        <#
        .SYNOPSIS
        Converts a command's related link to HTML.
    
        .DESCRIPTION
        `Convert-RelatedLinkToHtml` converts a command's related links to HTML. If the related link is not a URL, the command name is converted to a link that poitns to a `CommandName.html` file.
    
    
        #>
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            # The help object returned by `Get-Help`.
            $CommandHelp,
    
            [string]
            # The name of the module the command is in.
            $ModuleName,
    
            [string[]]
            # The names of any scripts in the module.
            $Script
        )
    
        begin
        {
            Set-StrictMode -Version 'Latest'
    
        }
    
        process
        {
            if( -not $ModuleName -and ($CommandHelp | Get-Member -Name 'ModuleName') -and $CommandHelp.ModuleName )
            {
                $ModuleName = $CommandHelp.ModuleName
            }
    
            $aboutTopics = @()
            if( $ModuleName )
            {
                $moduleBase = Get-Module -Name $ModuleName |  Select-Object -ExpandProperty 'ModuleBase'
                if( $moduleBase -and (Test-Path -Path (Join-Path -Path $moduleBase -ChildPath 'en-US') -PathType Container) )
                {
                    $aboutTopics = $moduleBase | 
                                        Get-ChildItem -Filter 'en-US\about_*' | 
                                        Select-Object -ExpandProperty 'BaseName' | 
                                        ForEach-Object { $_ -replace '\.help$','' }
                }
                else
                {
                    $aboutTopics = @()
                }
            }
    
            Invoke-Command -ScriptBlock {
                    if( $CommandHelp | Get-Member -Name 'RelatedLinks' )
                    {
                         return $CommandHelp.RelatedLinks |
                                    Out-String -Width ([Int32]::MaxValue) |
                                    ForEach-Object { $_ -split "`n" } |
                                    ForEach-Object { $_.Trim() } |
                                    Where-Object { $_ }
                    }
    
                    if( $CommandHelp -is [string] )
                    {
                        return $CommandHelp
                    }
                } |
                ForEach-Object {
                    if( $_ -match '^https?\:\/\/' )
                    {
                        return '<a href="{0}">{0}</a>' -f $_
                    }
    
                    if( $ModuleName -and (Get-Command -Name $_ -Module $ModuleName -ErrorAction Ignore) )
                    {
                        $cmdName = $_
                        $alias = Get-Alias -Name $_ -ErrorAction Ignore | Where-Object { $_.ModuleName -eq $ModuleName }
                        if( $alias )
                        {
                            $cmdName = $alias.ReferencedCommand
                        }
                        return '<a href="{0}.html">{1}</a>' -f $cmdName,$_
                    }
    
                    $cmd = Get-Command -Name $_ -ErrorAction Ignore
                    if( $cmd -and $cmd.HelpUri )
                    {
                        return '<a href="{0}.html">{1}</a>' -f $cmd.HelpUri,$_
                    }
    
                    if( $aboutTopics -contains $_ -or $Script -contains $_ )
                    {
                        return '<a href="{0}.html">{0}</a>' -f $_
                    }
    
                    return $_
                }
        }
    
        end
        {
        }
    }
  • Silk\Functions\Edit-HelpText.ps1 Show
    function Edit-HelpText
    {
        <#
        .SYNOPSIS
        Converts the command names in a block of text to links.
    
        .DESCRIPTION
        The `Edit-HelpText` function converts all a module's command names or help topic names into Markdown links. The command names or help topic names should be surrounded by backticks, e.g. `Invoke-Function`, `about_Module`.
        #>
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true,VAlueFromPipeline=$true)]
            # The text to convert.
            $InputObject,
    
            [string]
            # The name of the module whose command names to convert.
            $ModuleName
        )
    
        begin
        {
            Set-StrictMode -Version 'Latest'
    
            $commands = Invoke-Command -ScriptBlock {
                                                        Get-Command -Module $ModuleName -CommandType Cmdlet
                                                        Get-Command -Module $ModuleName -CommandType Function
                                                        Get-Command -Module $ModuleName -CommandType Filter
                                                    }
            $aliases = Get-Command -Module $ModuleName -CommandType Alias | Get-Alias
            $aboutTopicNames = Get-ChildItem -Path (Get-Module -Name $ModuleName).ModuleBase -Filter 'en-US\about_*' |
                                    Select-Object -ExpandProperty 'BaseName' |
                                    ForEach-Object { $_ -replace '\.help$','' }
        }
    
        process
        {
            $regex = $commands | Select-Object -ExpandProperty 'Name' | ForEach-Object { [regex]::Escape( $_ ) }
            $regex = $regex -join '|'
            $regex = '`({0})`' -f $regex
            $replacement = '[$1]($1.html)'
    
           $InputObject | 
                ForEach-Object { $_ -replace $regex,$replacement } |
                ForEach-Object {
                    $text = $_
                    foreach( $alias in $aliases )
                    {
                        $text = $text -replace ('`({0})`' -f $alias.Name),('[$1]({0}.html)' -f $alias.Definition)
                    }
    
                    foreach( $aboutTopicName in $aboutTopicNames )
                    {
                        $text = $text -replace ('`({0})`' -f $aboutTopicName),('[{0}]($1.html)' -f ($aboutTopicName -replace '_','\_'))
                    }
                    return $text
                }
        }
    
        end
        {
        }
    }
  • Silk\Functions\Format-ForHtml.ps1 Show
    filter Format-ForHtml 
    {
        <#
        .SYNOPSIS
        Encodes text for HTML.
        #>
        if( $_ )
        {
            [Web.HttpUtility]::HtmlEncode($_)
        }
    }
    
  • Silk\Functions\Get-Function.ps1 Show
    filter Get-Function
    {
        <#
        .SYNOPSIS
        Gets all of a module's functions.
        #>
        param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            # The file to parse for functions
            $Path
        )
        
        Write-Verbose "Loading script '$Path'."
        $scriptContent = Get-Content "$Path"
        if( -not $scriptContent )
        {
            return @()
        }
    
        $errors = [Management.Automation.PSParseError[]] @()
        $tokens = [System.Management.Automation.PsParser]::Tokenize( $scriptContent, [ref] $errors )
        if( $errors -ne $null -and $errors.Count -gt 0 )
        {
            Write-Error "Found $($errors.count) error(s) parsing '$Path'."
            return
        }
        
        Write-Verbose "Found $($tokens.Count) tokens in '$Path'."
        
        for( $idx = 0; $idx -lt $tokens.Count; ++$idx )
        {
            $token = $tokens[$idx]
            if( $token.Type -eq 'Keyword'-and ($token.Content -eq 'Function' -or $token.Content -eq 'Filter') )
            {
                $atFunction = $true
            }
            
            if( $atFunction -and $token.Type -eq 'CommandArgument' -and $token.Content -ne '' )
            {
                Write-Verbose "Found function '$($token.Content).'"
                $token.Content
                $atFunction = $false
            }
        }
    }
    
  • Silk\Functions\Get-ModuleReleaseNotes.ps1 Show
    function Get-ModuleReleaseNotes
    {
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # Path to the module's manifest.
            $ManifestPath,
    
            [Parameter(Mandatory=$true)]
            [string]
            # Path to the releaes notes file.
            $ReleaseNotesPath
        )
    
        Set-StrictMode -Version 'Latest'
    
        $Version = Test-ModuleManifest -Path $ManifestPath | Select-Object -ExpandProperty 'Version'
        if( -not $Version )
        {
            Write-Error -Message ('Version not found in module manifest ''{0}''.' -f $ManifestPath)
            return
        }
    
        $foundVersion = $false
        $versionReleaseNotes = Get-Content -Path $ReleaseNotesPath |
                                Where-Object {
                                    $line = $_
                                    if( -not $foundVersion )
                                    {
                                        if( $line -match ('^#\s+{0}' -f [regex]::Escape($version)) )
                                        {
                                            $foundVersion = $true
                                            return
                                        }
                                    }
                                    else
                                    {
                                        if( $line -match ('^#\s+(?!{0})' -f [regex]::Escape($version)) )
                                        {
                                            $foundVersion = $false
                                        }
                                    }
                                    return( $foundVersion )
                                }
        if( -not $versionReleaseNotes )
        {
            Write-Error -Message ('There are no release notes for version {0} in ''{1}''.' -f $Version,$ReleaseNotesPath)
            return
        }
    
        $versionReleaseNotes -join [Environment]::NewLine
    
    }
  • Silk\Functions\Get-ModuleVersion.ps1 Show
    function Get-ModuleVersion
    {
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the module's manifest.
            $ManifestPath
        )
    
        Set-StrictMode -Version 'Latest'
    
    }
  • Silk\Functions\Get-TypeDocumentationLink.ps1 Show
  • Silk\Functions\New-ChocolateyPackage.ps1 Show
    # Copyright 2012 Aaron Jensen
    # 
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    function New-ChocolateyPackage
    {
        <#
        .SYNOPSIS
        Creates a NuGet package.
        #>
        [CmdletBinding(SupportsShouldProcess=$true)]
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the module manifest of the module you want to publish.
            $ManifestPath,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the nuspec file for the NuGet package to publish.
            $NuspecPath,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The directory where the .nupkg file should be saved.
            $OutputDirectory
        )
    
        Set-StrictMode -Version 'Latest'
        Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
        if( -not (Get-Command -Name 'choco.exe' -ErrorAction Ignore) )
        {
            Write-Error -Message ('choco.exe not found. Please install Chocoatey from chocolatey.org')
            return
        }
    
        if( -not (Test-Path -Path $OutputDirectory -PathType Container) )
        {
            New-Item -Path $OutputDirectory -ItemType 'directory' -Force
        }
    
        $manifest = Test-ModuleManifest -Path $ManifestPath
        if( -not $manifest )
        {
            return
        }
    
        Push-Location -Path $OutputDirectory
        try
        {
            Get-ChildItem -Path '*.nupkg' | Remove-Item
    
            $verbosity = ''
            if( $VerbosePreference -eq 'Continue' )
            {
                $verbosity = '-v'
            }
    
            choco.exe pack $NuspecPath --version=$($manifest.Version) $verbosity
            if( -not (Test-Path -Path '*.nupkg' -PathType Leaf) )
            {
                Write-Error -Message 'Chocolatey package not created.'
            }
        }
        finally
        {
            Pop-Location
        }
    }
  • Silk\Functions\New-ModuleHelpIndex.ps1 Show
    function New-ModuleHelpIndex
    {
        <#
        .SYNOPSIS
        Creates an index page for a module's help.
        #>
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # The name of the module whose index page to create.
            $ModuleName,
    
            [string[]]
            # The names of any scripts that should be included.
            $Script,
    
            [string]
            # The path to the tags file. If not provided, no tag tab is generated.
            $TagsJsonPath
        )
    
        Set-StrictMode -Version 'Latest'
    
        if( $TagsJsonPath )
        {
            $tagsJson = Get-Content -Path $TagsJsonPath | ConvertFrom-Json
    
            $tags = @{ }
    
            foreach( $item in $tagsJson )
            {
                foreach( $tagName in $item.Tags )
                {
                    if( -not $tags.ContainsKey( $tagName ) )
                    {
                        $tags[$tagName] = New-Object 'Collections.Generic.List[string]'
                    }
    
                    $tags[$tagName].Add( $item.Name )
                }
            }
    
            $tagCloud = $tags.Keys | Sort-Object | ForEach-Object { 
    
            $commands = $tags[$_] | ForEach-Object { '<li><a href="{0}.html">{0}</a></li>' -f $_ }
            @'
        <h3>{0}</h3>
    
        <ul>
            {1}
        </ul>
    '@ -f $_,($commands -join ([Environment]::NewLine))
            }
    
        }
        else
        {
            $tagCloud = ''
        }
    
        $verbs = @{ }
    
        $commands = Get-Command -Module $ModuleName -CommandType Cmdlet,Function,Filter 
        foreach( $command in $commands )
        {
            if( -not $verbs.ContainsKey( $command.Verb ) )
            {
                $verbs[$command.Verb] = New-Object 'Collections.Generic.List[string]'
            }
            $verbs[$command.Verb].Add( $command.Name )
        }
    
        $commandList = Invoke-Command {
                                            $commands |  Select-Object -ExpandProperty 'Name'
                                            $moduleBase = Get-Module -Name $ModuleName | Select-Object -ExpandProperty 'ModuleBase'
                                            $dscResourceBase = Join-Path -Path $moduleBase -ChildPath 'DscResources'
                                            if( (Test-Path -Path $dscResourceBase -PathType Container) )
                                            {
                                                Get-ChildItem -Directory -Path $dscResourceBase
                                            }
                                        } |
                            Sort-Object | 
                            ForEach-Object { '<li><a href="{0}.html">{0}</a></li>' -f $_ }
        $commandList = @'
    <ul>
        {0}
    </ul>
    '@ -f ($commandList -join ([Environment]::NewLine))
    
        $verbList = $verbs.Keys | Sort-Object | ForEach-Object {
            $verb = $_
            $verbCommands = $verbs[$verb] | ForEach-Object { '<li><a href="{0}.html">{0}</a></li>' -f $_ }
            @'
        <h3>{0}</h3>
    
        <ul>
            {1}
        </ul>
    '@ -f $verb,($verbCommands -join ([Environment]::NewLine))
        }
    
        $scriptContent = ''
        if( $Script )
        {
            $scriptContent = @"
    <h2>Scripts</h2>
    
    <ul>
        $($Script | ForEach-Object { '<li><a href="{0}.html">{0}</a></li>' -f $_ })
    </ul>
    "@
        }
    
        $topicList = New-Object 'Collections.Generic.List[string]'
    
        $moduleBase = Get-Module -Name $ModuleName |  Select-Object -ExpandProperty 'ModuleBase'
        $aboutTopics = @()
        if( (Test-Path -Path (Join-Path -Path $moduleBase -ChildPath 'en-US') -PathType Container) )
        {
            $aboutTopics = Get-ChildItem -Path $moduleBase -Filter 'en-US\about_*.help.txt'
        }
    
        foreach( $aboutTopic in $aboutTopics )
        {
            $topicName = $aboutTopic.BaseName -replace '\.help$',''
            $virtualPath = '{0}.html' -f $topicName
            $topicList.Add( ('<li><a href="{0}">{1}</a></li>' -f $virtualPath,$topicName) )
        }
    
        function New-CommandsMenuItem
        {
            param(
                $ID,
                $Name
            )
    
            Set-StrictMode -Version 'Latest'
    
            if( -not $tagCloud -and $ID -eq 'ByTag' )
            {
                return
            }
    
            $selectedAttr = ''
            if( ($tagCloud -and $ID -eq 'ByTag') -or ($ID -eq 'ByName' -and -not $tagCloud) )
            {
                $selectedAttr = 'class="selected"'
            }
    
            '<li id="{0}MenuItem" {1}><a href="#{0}">{2}</a></li>' -f $ID,$selectedAttr,$Name
        }
    
        function New-CommandContentDiv
        {
            param(
                $ID,
                $Line
            )
    
            Set-StrictMode -Version 'Latest'
    
            if( -not $Line )
            {
                return
            }
    
            $styleAttr = 'display:none;'
            if( ($ID -eq 'Tag' -and $tagCloud) -or ($ID -eq 'Name' -and -not $tagCloud) )
            {
                $styleAttr = ''
            }
    
            @'
    <div id="By{0}Content" style="{2}">
        <a id="By{0}"></a>
    
        {1}
    
    </div>
    '@ -f $ID,($Line -join ([Environment]::NewLine)),$styleAttr
        }
    
        @"
    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script>
    jQuery( document ).ready(function() {
        jQuery("#CommandsMenu > li").click( function() {
            var selectedLi = jQuery("#CommandsMenu li.selected")
            selectedLi.removeClass("selected");
            
            var selectedCmdID = selectedLi.attr("id").replace("MenuItem","");
            jQuery("#" + selectedCmdID + 'Content').hide();
            
            var li = jQuery(this);
            li.addClass("selected");
            
            var id = li.attr( 'id' )
            id = id.replace('MenuItem','');
            
            jQuery('#' + id + 'Content').show();
            
            return false;
        });
    });
    </script>
    
    <h2>About Help Topics</h2>
    
    <ul>
        $($topicList.ToArray() -join ([Environment]::NewLine))
    </ul>
    
    $($scriptContent)
    
    <h2>Commands</h1>
    
    <ul id="CommandsMenu">
        $( New-CommandsMenuItem 'ByTag' 'By Tag' )
        $( New-CommandsMenuItem 'ByName' 'By Name' )
        $( New-CommandsMenuItem 'ByVerb' 'By Verb' )
    </ul>
    
    <div id="CommandsContent">
    
        $( New-CommandContentDiv 'Tag' $tagCloud )
        $( New-CommandContentDiv 'Name' $commandList )
        $( New-CommandContentDiv 'Verb' $verbList )
    
    </div>
    "@
    
    }
  • Silk\Functions\New-NuGetPackage.ps1 Show
    # Copyright 2012 Aaron Jensen
    # 
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    function New-NuGetPackage
    {
        <#
        .SYNOPSIS
        Creates a NuGet package.
        #>
        [CmdletBinding(SupportsShouldProcess=$true)]
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the module manifest of the module you want to publish.
            $ManifestPath,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the nuspec file for the NuGet package to publish.
            $NuspecPath,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The base directory for the files defined in the `NuspecPath` file.
            $NuspecBasePath,
    
            [string]
            # The name of the NuGet package, if it is different than the module name.
            $PackageName,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The directory where the .nupkg file should be saved.
            $OutputDirectory
        )
    
        Set-StrictMode -Version 'Latest'
        Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
        $nugetPath = Join-Path -Path $PSScriptRoot -ChildPath '..\bin\NuGet.exe' -Resolve
        if( -not $nugetPath )
        {
            return
        }
    
        if( -not (Test-Path -Path $OutputDirectory -PathType Container) )
        {
            New-Item -Path $OutputDirectory -ItemType 'directory' -Force
        }
    
        $manifest = Test-ModuleManifest -Path $ManifestPath
        if( -not $manifest )
        {
            return
        }
    
        if( -not $PackageName )
        {
            $PackageName = $manifest.Name
        }
    
        Push-Location -Path $NuSpecBasePath
        try
        {
            $nupkgPath = Join-Path -Path $OutputDirectory -ChildPath ('{0}.{1}.nupkg' -f $PackageName,$manifest.Version)
            if( (Test-Path -Path $nupkgPath -PathType Leaf) )
            {
                Remove-Item -Path $nupkgPath
            }
    
            $verbosity = 'normal'
            if( $VerbosePreference -eq 'Continue' )
            {
                $verbosity = 'detailed'
            }
            & $nugetPath pack $NuspecPath -BasePath '.' -NoPackageAnalysis -Verbosity $verbosity -OutputDirectory $OutputDirectory
            if( -not (Test-Path -Path $nupkgPath -PathType Leaf) )
            {
                Write-Error ('NuGet package ''{0}'' not found.' -f $nupkgPath)
                return
            }
        }
        finally
        {
            Pop-Location
        }
    }
  • Silk\Functions\Out-HtmlString.ps1 Show
    filter Out-HtmlString
    {
        <#
        .SYNOPSIS
        Writes a string out to the pipeline, trimming whitespace.
        #>
        $_ | 
            Out-String -Width 9999 | 
            ForEach-Object { $_.Trim() } |
            Where-Object { $_ }
    }
    
    
  • Silk\Functions\Publish-BitbucketDownload.ps1 Show
    # Copyright 2012 Aaron Jensen
    # 
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    function Publish-BitbucketDownload
    {
        <#
        .SYNOPSIS
        Creates and publishes a ZIP file to Bitbucket so it is available on a project's download page.
    
        .DESCRIPTION
        The `Publish-BitbucketDownload` function creates a ZIP file and publishes it to a repository so it is availabe on a project's download page. If the file already exists on Bitbucket, nothing is uploaded.
    
        .LINK
        https://bitbucket.org/Swyter/bitbucket-curl-upload-to-repo-downloads
        #>
        [CmdletBinding()]
        param(
            [pscredential]
            # The Bitbucket credentials to use.
            $Credential,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The account of the project you're uploading a file to.
            $Username,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The name of the project you're uploading a file to.
            $ProjectName,
    
            [Parameter(Mandatory=$true)]
            [string[]]
            # The paths to the files and directories to include in the ZIP file. All files and sub-directories under directory are added.
            $Path,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the manifest of the module being published.
            $ManifestPath
        )
    
        Set-StrictMode -Version 'Latest'
    
        function Assert-Response
        {
            param(
                [Microsoft.PowerShell.Commands.HtmlWebResponseObject]
                $Response,
    
                [Uri]
                $ExpectedUri
            )
    
            if( -not $Response )
            {
                Write-Error ('No response.')
                return $false
            }
    
            if( $Response.BaseResponse.StatusCode -ne [Net.HttpStatusCode]::OK )
            {
                Write-Error ('Response failed.')
                return $false
            }
    
            if( $Response.BaseResponse.ResponseUri -ne $ExpectedUri )
            {
                Write-Error ('Response didn''t finish on URI {0} ({1}).' -f $ExpectedUri,$Response.BaseResponse.ResponseUri)
                return $false
            }
    
            $errorElement = $Response.ParsedHtml.getElementById('error')
            if( $errorElement -and ($errorElement | Get-Member 'innerHtml') -and $erroElement.innerHtml )
            {
                Write-Error $errorElement.innerHtml
                return $false
            }
    
            return $true
    
        }
    
        $manifest = Test-ModuleManifest -Path $ManifestPath
        if( -not $manifest )
        {
            return
        }
    
        $baseProjectUri = 'https://bitbucket.org/{0}/{1}' -f $Username,$ProjectName
    
        $zipFileName = "{0}-{1}.zip" -f $manifest.Name,$manifest.Version
        $zipDownloadUrl = '{0}/downloads/{1}' -f $baseProjectUri,$zipFileName
    
        try
        {
            $resp = Invoke-WebRequest -Uri $zipDownloadUrl -ErrorAction Ignore
            $publish = ($resp.StatusCode -ne 200)
        }
        catch
        {
            $publish = $true
        }
    
        if( -not $publish )
        {
            Write-Warning -Message ('{0} file already published.' -f $zipFileName)
            return
        }
    
        $zipFilePath = Join-Path -Path $env:TEMP -ChildPath $zipFileName
    
        $outFile = '{0}+{1}' -f $manifest.Name,[IO.Path]::GetRandomFileName()
        $outFile = Join-Path -Path $env:TEMP -ChildPath $outFile
    
        try
        {
            if( Test-Path $zipFilePath -PathType Leaf )
            {
                Remove-Item $zipFilePath
            }
    
            Write-Verbose -Message ('Creating {0} ZIP file.' -f $zipFileName)
            Compress-Item -Path $Path -OutFile $zipFilePath
    
            $PSDefaultParameterValues.Clear()
            $PSDefaultParameterValues['Invoke-WebRequest:PassThru'] = $true
            $PSDefaultParameterValues['Invoke-WebRequest:OutFile'] = $outFile
    
            if( -not $Credential )
            {
                $Credential = Get-Credential -Message ('Enter credentials for {0}' -f $baseProjectUri)
            }
    
            $session = $null
            $loginUri = 'https://bitbucket.org/account/signin/'
            $resp = Invoke-WebRequest -Uri $loginUri -SessionVariable 'session' -Method Get 
            if( -not (Assert-Response -Response $resp -ExpectedUri $loginUri) )
            {
                return
            }
    
            $PSDefaultParameterValues['Invoke-WebRequest:WebSession'] = $session
    
            $form = $resp.Forms | 
                        Where-Object { $_.Action -eq '/account/signin/' }
            $formFields = $form.Fields
            $formFields.id_username = $Credential.UserName
            $formFields.id_password = $Credential.GetNetworkCredential().Password
    
            $loginUri = 'https://bitbucket.org{0}' -f $form.Action
            $body = @{
                            'username' = $Credential.UserName;
                            'password' = $Credential.GetNetworkCredential().Password;
                            'csrfmiddlewaretoken' = $formFields.csrfmiddlewaretoken;
                            'submit' = '';
                            'next' = '';
                            }
            $resp = Invoke-WebRequest -Uri $loginUri -Method $form.Method -Body $body -Headers @{ Referer = $loginUri }
            if( -not (Assert-Response -Response $resp -ExpectedUri 'https://bitbucket.org/') )
            {
                exit 1
            }
    
            $downloadUri = '{0}/downloads' -f $baseProjectUri
            $resp = Invoke-WebRequest -Uri $downloadUri -Method Get 
            if( -not (Assert-Response -Response $resp -ExpectedUri $downloadUri) )
            {
                exit 1
            }
    
            $csrfToken = $resp.Forms |
                            Where-Object { $_.Fields.ContainsKey( 'csrfmiddlewaretoken' ) } |
                            ForEach-Object { $_.Fields.csrfmiddlewaretoken }
            Write-Debug $csrfToken
    
            $boundary = [Guid]::NewGuid().ToString()
    
            $bodyStart = @"
    --$boundary
    Content-Disposition: form-data; name="csrfmiddlewaretoken"
    
    $csrfToken
    --$boundary
    Content-Disposition: form-data; name="token"
    
    --$boundary
    Content-Disposition: form-data; name="files"; filename="$(Split-Path -Leaf -Path $zipFilePath)"
    Content-Type: application/octet-stream
    
    
    "@
    
            $bodyEnd = @"
    
    --$boundary--
    "@
    
            $requestInFile = Join-Path -Path $env:TEMP -ChildPath ([IO.Path]::GetRandomFileName())
    
            try
            {
                $fileStream = New-Object 'System.IO.FileStream' ($requestInFile, [System.IO.FileMode]'Create', [System.IO.FileAccess]'Write')
        
                try
                {
                    $bytes = [Text.Encoding]::UTF8.GetBytes($bodyStart)
                    $fileStream.Write( $bytes, 0, $bytes.Length )
    
                    $bytes = [IO.File]::ReadAllBytes($zipFilePath)
                    $fileStream.Write( $bytes, 0, $bytes.Length )
    
                    $bytes = [Text.Encoding]::UTF8.GetBytes($bodyEnd)
                    $fileStream.Write( $bytes, 0, $bytes.Length )
                }
                finally
                { 
                    $fileStream.Close()
                }
    
                $contentType = 'multipart/form-data; boundary={0}' -f $boundary
    
                $resp = Invoke-WebRequest -Uri $downloadUri `
                                          -Method Post `
                                          -InFile $requestInFile `
                                          -ContentType $contentType `
                                          -Headers @{ Referer = $downloadUri }
                if( -not (Assert-Response -Response $resp -ExpectedUri $downloadUri) )
                {
                    return
                }
    
            }
            finally
            {
                Remove-Item -Path $requestInFile
            }
    
            $numTries = 10
            $tryNum = 0
            while( $tryNum++ -lt $numTries )
            {
                try
                {
                    $resp = Invoke-WebRequest -Uri $zipDownloadUrl
                    $resp | Select-Object -Property 'StatusCode','StatusDescription',@{ Name = 'Uri'; Expression = { $zipDownloadUrl }}
                    break
                }
                catch
                {
                    Start-Sleep -Seconds 1
                }
            }
    
        }
        finally
        {
            if( (Test-Path -Path $outFile -PathType Leaf) )
            {
                Remove-Item -Path $outFile
            }
    
            if( (Test-Path -Path $zipFilePath -PathType Leaf) )
            {
                Remove-Item -Path $zipFilePath
            }
        }
    }
  • Silk\Functions\Publish-ChocolateyPackage.ps1 Show
    # Copyright 2012 Aaron Jensen
    # 
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    function Publish-ChocolateyPackage
    {
        <#
        .SYNOPSIS
        Creates and publishes a NuGet package to nuget.org.
        #>
        [CmdletBinding(SupportsShouldProcess=$true)]
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the module manifest of the module you want to publish.
            $NupkgPath,
    
            [string]
            # The API key(s) to use. To supply multiple API keys, use a hashtable where each key is a repository server name and the value is the API key for that repository. For example,
            #
            # @{ 'nuget.org' = '395edfa5-652f-4598-868e-c0a73be02c84' }
            #
            # If not specified, you'll be prompted for it. 
            $ApiKey
        )
    
        Set-StrictMode -Version 'Latest'
        Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
        if( -not (Get-Command -Name 'choco.exe' -ErrorAction Ignore) )
        {
            Write-Error -Message ('Chocolatey is not installed. Go to http://chocolatey.org for installation instructions.')
            return
        }
    
        if( -not (Test-Path -Path $NupkgPath -PathType Leaf) )
        {
            Write-Error -Message ('Chocolatey package ''{0}'' does not exist.' -f $NupkgPath)
            return
        }
    
        $nupkgName = [IO.Path]::GetFileNameWithoutExtension($NupkgPath)
        if( $nupkgName -notmatch '^(.+)\.(\d+\.\d+\.\d)+$' )
        {
            Write-Error -Message ('Chocolatey package ''{0}'' does not have the version to publish in its name.' -f $nupkgName)
            return
        }
    
        $packageName = $Matches[1]
        $version = $Matches[2]
        try
        {
            $packageUrl = 'https://chocolatey.org/api/v2/package/{0}/{1}' -f $packageName,$version
            try
            {
                $resp = Invoke-WebRequest -Uri $packageUrl -ErrorAction Ignore
                $publish = ($resp.StatusCode -ne 200)
            }
            catch
            {
                $publish = $true
            }
    
            if( -not $publish )
            {
                Write-Warning ('Chocolatey package {0} {1} already published to chocolatey.org.' -f $packageName,$version)
                return
            }
    
            if( $PSCmdlet.ShouldProcess(('publish package to chocolatey.org'),'','') )
            {
                if( -not $ApiKey )
                {
                    $ApiKey = Read-Host -Prompt ('Please enter your chocolatey.org API key')
                    if( -not $ApiKey )
                    {
                        Write-Error -Message ('The chocolatey.org API key is required. Package not published to chocolatey.org')
                        continue
                    }
                }
    
                $verbosity = ''
                if( $VerbosePreference -eq 'Continue' )
                {
                    $verbosity = '-v'
                }
    
                choco.exe push --source 'https://chocolatey.org' --key $ApiKey $verbosity $nupkgPath
    
                $resp = Invoke-WebRequest -Uri $packageUrl
                $resp | Select-Object -Property 'StatusCode','StatusDescription',@{ Name = 'Uri'; Expression = { $packageUrl }}
            }
        }
        finally
        {
            Pop-Location
        }
    }
  • Silk\Functions\Publish-NuGetPackage.ps1 Show
    # Copyright 2012 Aaron Jensen
    # 
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    function Publish-NuGetPackage
    {
        <#
        .SYNOPSIS
        Creates and publishes a NuGet package to nuget.org.
        #>
        [CmdletBinding(SupportsShouldProcess=$true)]
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the module manifest of the module you want to publish.
            $NupkgPath,
    
            [object]
            # The API key(s) to use. To supply multiple API keys, use a hashtable where each key is a repository server name and the value is the API key for that repository. For example,
            #
            # @{ 'nuget.org' = '395edfa5-652f-4598-868e-c0a73be02c84' }
            #
            # If not specified, you'll be prompted for it. 
            $ApiKey
        )
    
        Set-StrictMode -Version 'Latest'
        Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
        $nugetPath = Join-Path -Path $PSScriptRoot -ChildPath '..\bin\NuGet.exe' -Resolve
        if( -not $nugetPath )
        {
            return
        }
    
        if( -not (Test-Path -Path $NupkgPath -PathType Leaf) )
        {
            Write-Error -Message ('NuGet package ''{0}'' does not exist.' -f $NupkgPath)
            return
        }
    
        $nupkgName = [IO.Path]::GetFileNameWithoutExtension($NupkgPath)
        if( $nupkgName -notmatch '^(.+)\.(\d+\.\d+\.\d)+$' )
        {
            Write-Error -Message ('NuGet package ''{0}'' does not have the version to publish in its name.' -f $nupkgName)
            return
        }
    
        $packageName = $Matches[1]
        $version = $Matches[2]
        try
        {
            $packageUrl = 'https://nuget.org/api/v2/package/{0}/{1}' -f $packageName,$version
            try
            {
                $resp = Invoke-WebRequest -Uri $packageUrl -ErrorAction Ignore
                $publish = ($resp.StatusCode -ne 200)
            }
            catch
            {
                $publish = $true
            }
    
            if( -not $publish )
            {
                Write-Warning ('NuGet package {0} {1} already published to nuget.org.' -f $packageName,$version)
                return
            }
    
            if( $PSCmdlet.ShouldProcess(('publish package to nuget.org'),'','') )
            {
                if( -not $ApiKey )
                {
                    $ApiKey = Read-Host -Prompt ('Please enter your nuget.org API key')
                    if( -not $ApiKey )
                    {
                        Write-Error -Message ('The nuget.org API key is required. Package not published to nuget.org.')
                        continue
                    }
                }
    
                $verbosity = 'normal'
                if( $VerbosePreference -eq 'Continue' )
                {
                    $verbosity = 'detailed'
                }
    
                & $nugetPath push $nupkgPath -ApiKey $ApiKey -Source 'https://nuget.org/api/v2/package' -Verbosity $verbosity
    
                $resp = Invoke-WebRequest -Uri $packageUrl
                $resp | Select-Object -Property 'StatusCode','StatusDescription',@{ Name = 'Uri'; Expression = { $packageUrl }}
            }
        }
        finally
        {
            Pop-Location
        }
    }
  • Silk\Functions\Publish-PowerShellGalleryPackage.ps1 Show
    #>
    # Copyright 2012 Aaron Jensen
    # 
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    function Publish-PowerShellGalleryModule
    {
        <#
        .SYNOPSIS
        Publishes a module to the PowerShell gallery.
    
        .DESCRIPTION
        The `Publish-PowerShellGalleryModule` functin publishes a module to the PowerShell Gallery. If the given version of the module already exists in the Gallery, a warning is written and no other work is done.
    
        If you don't supply a PowerShell Gallery API key via the `ApiKey` parameter, you'll be prompted for it.
    
        Returns a `PSGetItemInfo` object if the module gets published (the object returned by the `Find-Module` cmdlet). If the version of the module already exists in the Gallery, you'll get a warning that the module has already been published.
    
        This function requires the `PowerShellGet` module. If it isn't available, you'll get an error.
    
        .OUTPUTS
        PSGetItemInfo
    
        .EXAMPLE
        Publish-PowerShellGalleryModule -Name 'Carbon' -Version '2.0.0' -LicenseUri ''http://www.apache.org/licenses/LICENSE-2.0'
        #>
        [CmdletBinding(SupportsShouldProcess=$true)]
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # Path to the module's manifest.
            $ManifestPath,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the module.
            $ModulePath,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The release notes.
            $ReleaseNotesPath,
    
            [string]
            # The name of the module being published. Defaults to the name in the module manifest.
            $Name,
    
            [string]
            # The API key for the PowerShell Gallery.
            $ApiKey,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The URL to the module's license.
            $LicenseUri,
    
            [string[]]
            # Any tags for the module.
            $Tags,
    
            [string]
            # The URL to the project's home page.
            $ProjectUri
        )
    
        Set-StrictMode -Version 'Latest'
        Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState
    
        $manifest = Test-ModuleManifest -Path $ManifestPath
        if( -not $manifest )
        {
            return
        }
    
        if( -not $Name )
        {
            $Name = $manifest.Name
        }
    
        if( Get-Module -ListAvailable -Name 'PowerShellGet' )
        {
            if( -not (Find-Module -Name $Name -RequiredVersion $manifest.Version -Repository 'PSGallery' -ErrorAction Ignore) )
            {
                $releaseNotes = Get-ModuleReleaseNotes -ManifestPath $ManifestPath -ReleaseNotesPath $ReleaseNotesPath
                Write-Verbose -Message ('Publishing to PowerShell Gallery.')
                
                if( $PSCmdlet.ShouldProcess('publish module to PowerShell Gallery','','') )
                {
                    if( -not $ApiKey )
                    {
                        $ApiKey = Read-Host -Prompt ('Please enter PowerShell Gallery API key')
                    }
    
                    Publish-Module -Path $ModulePath `
                                   -Repository 'PSGallery' `
                                   -NuGetApiKey $ApiKey `
                                   -LicenseUri $LicenseUri `
                                   -ReleaseNotes $releaseNotes `
                                   -Tags $Tags `
                                   -ProjectUri $ProjectUri
    
                    Find-Module -Name $Name -RequiredVersion $manifest.Version -Repository 'PSGallery'
                }
            }
            else
            {
                Write-Warning -Message ('{0} {1} already exists in the PowerShell Gallery.' -f $Name,$manifest.Version)
            }
        }
        else
        {
            Write-Error -Message ('Unable to publish to PowerShell Gallery: PowerShellGet module not found.')
        }
    
    }
  • Silk\Functions\Set-ModuleManifestMetadata.ps1 Show
    function Set-ModuleManifestMetadata
    {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true)]
            # The path to the module.
            $ManifestPath,
    
            [string[]]
            # Tags for the module.
            $Tag,
    
            [string]
            # The path to the module's release notes.
            $ReleaseNotesPath
        )
    
        Set-StrictMode -Version 'Latest'
    
        $releaseNotes = Get-ModuleReleaseNotes -ManifestPath $ManifestPath -ReleaseNotesPath $ReleaseNotesPath
    
        $manifest = Test-ModuleManifest -Path $ManifestPath
        if( -not $manifest )
        {
            return
        }
    
        $module = Import-Module -Force -Name $manifestPath -PassThru
    
        $foundTags = $false
        $foundReleaseNotes = $false
        $inReleaseNotes = $false
        $releaseNotesWhitespacePrefix = ''
        $moduleManifestLines = Get-Content -Path $manifestPath |
                                    ForEach-Object {
                                        $line = $_
    
                                        if( $inReleaseNotes )
                                        {
                                            if( $line -match '^(''|")@$' )
                                            {
                                                $inReleaseNotes = $false
                                                $foundReleaseNotes = $true
                                                return '{0}ReleaseNotes = @{1}{2}{3}{2}{1}@' -f $releaseNotesWhitespacePrefix,$Matches[1],[Environment]::NewLine,$releaseNotes.Trim()
                                            }
                                            return
                                        }
    
                                        if( $line -match '^(\s+)ReleaseNotes\ =\ @(''|")$' )
                                        {
                                            $inReleaseNotes = $true
                                            $releaseNotesWhitespacePrefix = $Matches[1]
                                            return
                                        }
    
                                        if( $line -match '^(\s+)Tags\ =\ @\(' )
                                        {
                                            $foundTags = $true
                                            return '{0}Tags = @(''{1}'')' -f $Matches[1],($Tag -join ''',''')
                                        }
    
                                        return $_
                                    }
        if( -not $foundTags )
        {
            Write-Error -Message ('PrivateData PSData hashtable missing Tags metadata. Please add `Tags = @()` to the PSData section of {0} and re-run.' -f $ManifestPath)
            return
        }
    
        if( -not $foundReleaseNotes )
        {
            Write-Error -Message (@"
    PrivateData PSData hasthable missing ReleaseNotes metadata. Please add a `ReleaseNotes` key to the PSData hashtable whose value is an empty here string, e.g. 
        
        PrivateData = @{
    
            PSData = @{
    
                ReleaseNotes = @'
    '@
            }
        }
    "@)
            return
        }
    
        $moduleManifestLines | Set-Content -Path $ManifestPath
    }
  • Silk\Functions\Set-ModuleNuspec.ps1 Show
    function Set-ModuleNuspec
    {
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # Path to the module's manifest.
            $ManifestPath,
    
            [Parameter(Mandatory=$true)]
            [string]
            # Path to the module's Nuspec file.
            $NuspecPath,
    
            [Parameter(Mandatory=$true)]
            [string]
            # Path to the releaes notes file.
            $ReleaseNotesPath,
    
            [string]
            # The ID of the package. If not provided, the existing ID in the .nuspec file is left in place.
            $PackageID,
    
            [string]
            # The title of the package. If not provided, the existing title in the .nuspec file is left in place.
            $PackageTitle,
    
            [string[]]
            # Tags to add to the manifest. Tags are space-delimited, so tags shouldn't have spaces.
            $Tags
        )
    
        Set-StrictMode -Version 'Latest'
    
        $NuspecPath = Resolve-Path -Path $NuspecPath
        if( -not $NuspecPath )
        {
            return
        }
    
        $nuspec = [xml](Get-Content -Path $NuspecPath -Raw)
        if( -not $nuspec )
        {
            return
        }
    
        $manifest = Test-ModuleManifest -Path $ManifestPath
        if( -not $manifest )
        {
            return
        }
    
        $releaseNotes = Get-ModuleReleaseNotes -ManifestPath $ManifestPath -ReleaseNotesPath $ReleaseNotesPath
        if( -not $releaseNotes )
        {
            return
        }
    
        $nuspecMetadata = $nuspec.package.metadata
    
        if( $PackageID )
        {
            $nuspecMetadata.id = $PackageID
        }
    
        if( $PackageTitle )
        {
            $nuspecMetadata.title = $PackageTitle
        }
    
        $nuspecMetadata.description = $manifest.Description
        $nuspecMetadata.version = $manifest.Version.ToString()
        $nuspecMetadata.copyright = $manifest.Copyright
        $nuspecMetadata.releaseNotes = $releaseNotes
        if( $Tags )
        {
            $nuspecMetadata.tags = $Tags -join ' '
        }
    
        $nuspec.Save( $NuspecPath )
    }
  • Silk\Functions\Set-ModuleVersion.ps1 Show
    function Set-ModuleVersion
    {
        <#
        .SYNOPSIS
        Updates a module's version.
        #>
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the module's manifest.
            $ManifestPath,
    
            [string]
            # The path to the module's manifest.
            $SolutionPath,
    
            [string]
            # Path to an C# file to update with the assembly version.
            $AssemblyInfoPath,
    
            [string]
            # Path to a release notes file.
            $ReleaseNotesPath,
    
            [string]
            # Path to the module's Nuspec file.
            $NuspecPath,
    
            [Version]
            # The version to build. If not provided, pulled from the module's manifest.
            $Version,
    
            [string]
            # The pre-release version, e.g. alpha.39, rc.1, etc.
            $PreReleaseVersion,
    
            [string]
            # Build metadata.
            $BuildMetadata
        )
    
        Set-StrictMode -Version 'Latest'
    
        if( -not $Version )
        {
            $Version = Test-ModuleManifest -Path $ManifestPath | Select-Object -ExpandProperty 'Version'
            if( -not $Version )
            {
                return
            }
        }
    
        if( $Version.Build -lt 0 )
        {
            Write-Error ('Version number must have a build number, i.e. it must have three parts.' -f $Version)
            return
        }
    
        if( $Version.Revision -ge 0 )
        {
            Write-Error ('Version number must not have a revision number, i.e. it must only have three parts.' -f $Version)
            return
        }
    
        $manifest = Test-ModuleManifest -Path $ManifestPath
        if( -not $manifest )
        {
            return
        }
    
        $moduleVersionRegex = 'ModuleVersion\s*=\s*(''|")([^''"])+(''|")' 
        $rawManifest = Get-Content -Raw -Path $manifestPath
        if( $rawManifest -notmatch ('ModuleVersion\s*=\s*(''|"){0}(''|")' -f [regex]::Escape($version.ToString())) )
        {
            $rawManifest = $rawManifest -replace $moduleVersionRegex,('ModuleVersion = ''{0}''' -f $version)
            $rawManifest | Set-Content -Path $manifestPath -NoNewline
        }
    
        if( $AssemblyInfoPath )
        {
            $assemblyVersionRegex = 'Assembly(File|Informational)?Version\("[^"]*"\)'
            $assemblyVersion = Get-Content -Path $AssemblyInfoPath |
                                    ForEach-Object {
                                        if( $_ -match $assemblyVersionRegex )
                                        {
                                            $infoVersion = ''
                                            if( $Matches[1] -eq 'Informational' )
                                            {
                                                if( $PreReleaseVersion )
                                                {
                                                    $infoVersion = '-{0}' -f $PreReleaseVersion
                                                }
                                                if( $BuildMetadata )
                                                {
                                                    $infoVersion = '{0}+{1}' -f $infoVersion,$BuildMetadata
                                                }
                                            }
                                            return $_ -replace $assemblyVersionRegex,('Assembly$1Version("{0}{1}")' -f $Version,$infoVersion)
                                        }
                                        elseif( $_ -match 'AssemblyCopyright' )
                                        {
                                            return $_ -replace '\("[^"]*"\)',('("{0}")' -f $manifest.Copyright)
                                        }
                                        $_
                                    }
            $assemblyVersion | Set-Content -Path $AssemblyInfoPath
        }
    
        if( $ReleaseNotesPath )
        {
            $newVersionHeader = "# {0}" -f $Version
            $updatedVersion = $false
            $releaseNotes = Get-Content -Path $releaseNotesPath |
                                ForEach-Object {
                                    if( -not $updatedVersion -and $_ -match '^#\s+' )
                                    {
                                        $updatedVersion = $true
                                        return $newVersionHeader
                                    }
    
                                    return $_
                                }
            $releaseNotes | Set-Content -Path $releaseNotesPath
        }
    
        if( $SolutionPath )
        {
            $msbuildRoot = Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\MSBuild\ToolsVersions\12.0 -Name 'MSBuildToolsPath' | Select-Object -ExpandProperty 'MSBuildToolsPath'
            $msbuildExe = Join-Path -Path $msbuildRoot -ChildPath 'MSBuild.exe' -Resolve
            if( -not $msbuildExe )
            {
                return
            }
    
            & $msbuildExe /target:"clean;build" $SolutionPath /v:m /nologo
        }
    
        if( $NuspecPath )
        {
            $nuspec = [xml](Get-Content -Raw -Path $nuspecPath)
            if( $nuspec.package.metadata.version -ne $version.ToString() )
            {
                $nuGetVersion = $version -replace '-([A-Z0-9]+)[^A-Z0-9]*(\d+)$','-$1$2'
                $nuspec.package.metadata.version = $nugetVersion
                $nuspec.Save( $nuspecPath )
            }
        }
    }
  • Silk\Functions\Set-ReleaseNotesReleaseDate.ps1 Show
    function Set-ReleaseNotesReleaseDate
    {
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the module manifest whose release notes to update.
            $ManifestPath,
    
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the release notes file.
            $ReleaseNotesPath
        )
    
        Set-StrictMode -Version 'Latest'
    
        $manifest = Test-ModuleManifest -Path $ManifestPath
        if( -not $manifest )
        {
            return
        }
    
        $setHeader = $false
        $releaseNotes = Get-Content -Path $ReleaseNotesPath |
                            ForEach-Object {
                                if( $_ -match '^# {0}\s*$' -f [regex]::Escape($manifest.Version.ToString()) )
                                {
                                    $setHeader = $true
                                    return "# {0} ({1})" -f $manifest.Version,((Get-Date).ToString("d MMMM yyyy"))
                                }
                                return $_
                            }
        if( $setHeader )
        {
            $releaseNotes | Set-Content -Path $releaseNotesPath
        }
    }
    
  • Silk\Functions\Split-MarkdownTopic.ps1 Show
    function Split-MarkdownTopic
    {
        <#
        .SYNOPSIS
        Parses a Markdown-formatted module help topic, e.g. about_Module.
    
        .DESCRIPTION
        A Markdown-formatted help topic should contain four sections, `Topic`, `Short Description`, `Long Description`, and `See Also`.  These should all be formatted as level-1 headings.  For example:
    
            # Topic
    
            about_Silk
    
            # Short Description
    
            Silk is a PowerShell module used to convert another module's help system into an HTML website.
    
            # Long Description
    
            MOre details here.  Yadda, yadda, yadda.
    
            # See Also
    
            about_Silk_AdditionalTopic
        #>
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true)]
            # The root where the config file was found.
            $ConfigFileRoot,
    
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            # An object containing information about the topic to parse.
            $TopicInfo
        )
        process
        {
            Set-StrictMode -Version Latest
    
            $path = $TopicInfo.Path
            if( -not (Test-Path -Path $path -PathType Leaf) )
            {
                Write-Error ('Markdown help topic <{0}> not found.' -f $path)
                return
            }
    
            $content = New-Object Collections.ArrayList
            $sectionName = $null
            $eof = [Guid]::NewGuid().ToString()
            $topic = New-Object PsObject -Property @{ Name = ''; Synopsis = ''; Description = ''; RelatedLinks = ''; FileName = $TopicInfo.FileName }
            $lineNum = 0
            Invoke-Command { Get-Content -Path $path ; $eof } | ForEach-Object {
                if( $_ -match '^# (.*)$' -or $_ -eq $eof )
                {
                    if( $sectionName -or $_ -eq $eof )
                    {
                        $topic.$sectionName = $content -join "`n"
                        $topic.$sectionName = $topic.$sectionName.Trim()
                        if( $_ -eq $eof )
                        {
                            return
                        }
                        $content.Clear()
                    }
    
    
                    $sectionName = $matches[1]
                    switch -Regex ($sectionName)
                    {
                        'Topic|Name' 
                        {
                            $sectionName = 'Name'
                        }
                        'Short Description|Synopsis'
                        {
                            $sectionName = 'Synopsis'
                        }
                        'Long Description|Description'
                        {
                            $sectionName = 'Description'
                        }
                        'See Also|(Related )?Links?'
                        {
                            $sectionName = 'RelatedLinks'
                        }
                        default
                        {
                            Write-Error ('{0}: line {1}: Unknown top-level heading <{2}>.  Expected <Name>, <Synopsis>, <Description>, or <Link>. <Link> may be used multiple times.' -f $path,$lineNum,$_)
                        }
                    }
                }
                else
                {
                    if( -not $sectionName )
                    {
                        Write-Error ('{0}: line {1}: Invalid Markdown help topic: the first line must be `# Name`.' -f $path,$lineNum)
                        return
                    }
                    [void] $content.Add( $_ )
                }
                ++$lineNum
            }
    
            if( $TopicInfo | Get-Member Title )
            {
                $topic.Name = $TopicInfo.Title
            }
            return $topic
        }
    }
  • Silk\Functions\Test-ModuleVersion.ps1 Show
    function Assert-ModuleVersion
    {
        param(
            [Parameter(Mandatory=$true)]
            [string]
            # The path to the module's manifest.
            $ManifestPath,
    
            [string[]]
            # Path to any additional assemblies whose versions should get checked.
            $AssemblyPath,
    
            [string]
            # Path to a release notes file.
            $ReleaseNotesPath,
    
            [string]
            # The path to the module's nuspec file.
            $NuspecPath,
    
            [string[]]
            # A list of assembly file names that should be excluded from the version check. Wildcards allowed. Only assembly names are matched
            $ExcludeAssembly
        )
    
        Set-StrictMode -Version 'Latest'
    
        $errorsAtStart = $Error.Count
    
        $manifest = Test-ModuleManifest -Path $ManifestPath
        if( -not $manifest )
        {
            return
        }
    
        $version = $manifest.Version
    
        Write-Verbose -Message ('Checking that {0} module is at version {1}.' -f $manifest.Name,$version)
    
        $badAssemblies = Invoke-Command {
                                $manifest.RequiredAssemblies | 
                                    ForEach-Object { 
                                        if( -not [IO.Path]::IsPathRooted($_) )
                                        {
                                            Join-Path -Path (Split-Path -Parent -Path $manifest.Path) -ChildPath $_
                                        }
                                        else
                                        {
                                            $_
                                        }
                                    }
                                if( $AssemblyPath )
                                {
                                    $AssemblyPath
                                }
                            } |
                            Where-Object { 
                                foreach( $exclusion in $ExcludeAssembly )
                                {
                                    if( (Split-Path -Leaf -Path $_) -like $exclusion )
                                    {
                                        return $false
                                    }
                                }
                                return $true
                            } |
                            Get-Item | 
                            Where-Object { 
                                -not ($_.VersionInfo.FileVersion.ToString().StartsWith($version.ToString())) -or -not ($_.VersionInfo.ProductVersion.ToString().StartsWith($version.ToString()))
                            } |
                            ForEach-Object {
                                ' * {0} (FileVersion: {1}; ProductVersion: {2})' -f $_.Name,$_.VersionInfo.FileVersion,$_.VersionInfo.ProductVersion
                            }
        if( $badAssemblies )
        {
            Write-Error -Message ('The following assemblies are not at version {0}.{1}{2}' -f $version,([Environment]::NewLine),($badAssemblies -join ([Environment]::NewLine)))
        }
    
        if( $ReleaseNotesPath )
        {
            $foundFirstVersion = $false
            $releaseNotesVersion = Get-Content -Path $ReleaseNotesPath |
                                        ForEach-Object {
                                            if( -not $foundFirstVersion -and $_ -match '^#\s+(\d+\.\d+\.\d+)' )
                                            {
                                                $foundFirstVersion = $true
                                                return [Version]$Matches[1]
                                            }
                                        }
            if( -not $releaseNotesVersion )
            {
                Write-Error -Message ('Version {0} not found in release notes ({1}).' -f $version,$ReleaseNotesPath)
            }
        }
    
        if( $NuspecPath )
        {
            $nuspec = [xml](Get-Content -Raw -Path $NuspecPath)
            if( $nuspec )
            {
                $nuspecVersion = [Version]($nuspec.package.metadata.version)
                if( $nuspecVersion )
                {
                    if( $version -ne $nuspecVersion )
                    {
                        Write-Error -Message ('Nuspec file ''{0}'' is at version {1}, but should be at version {2}..' -f $NuspecPath,$nuspecVersion,$version)
                    }
                }
                else
                {
                    Write-Error -Message ('Nuspec file ''{0}'' contains an invalid version.' -f $NuspecPath)
                }
            }
            else
            {
                Write-Error -Message ('Nuspec file ''{0}'' does not contain valid XML.' -f $NuspecPath)
            }
        }
    
        return (($Error.Count - $errorsAtStart) -eq 0)
    }
  • Silk\Functions\Use-CallerPreference.ps1 Show
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    function Use-CallerPreference
    {
        <#
        .SYNOPSIS
        Sets the PowerShell preference variables in a module's function based on the callers preferences.
    
        .DESCRIPTION
        Script module functions do not automatically inherit their caller's variables, including preferences set by common parameters. This means if you call a script with switches like `-Verbose` or `-WhatIf`, those that parameter don't get passed into any function that belongs to a module. 
    
        When used in a module function, `Use-CallerPreference` will grab the value of these common parameters used by the function's caller:
    
         * ErrorAction
         * Debug
         * Confirm
         * InformationAction
         * Verbose
         * WarningAction
         * WhatIf
        
        This function should be used in a module's function to grab the caller's preference variables so the caller doesn't have to explicitly pass common parameters to the module function.
    
        This function is adapted from the [`Get-CallerPreference` function written by David Wyatt](https://gallery.technet.microsoft.com/scriptcenter/Inherit-Preference-82343b9d).
    
        There is currently a [bug in PowerShell](https://connect.microsoft.com/PowerShell/Feedback/Details/763621) that causes an error when `ErrorAction` is implicitly set to `Ignore`. If you use this function, you'll need to add explicit `-ErrorAction $ErrorActionPreference` to every function/cmdlet call in your function. Please vote up this issue so it can get fixed.
    
        .LINK
        about_Preference_Variables
    
        .LINK
        about_CommonParameters
    
        .LINK
        https://gallery.technet.microsoft.com/scriptcenter/Inherit-Preference-82343b9d
    
        .LINK
        http://powershell.org/wp/2014/01/13/getting-your-script-module-functions-to-inherit-preference-variables-from-the-caller/
    
        .EXAMPLE
        Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
    
        Demonstrates how to set the caller's common parameter preference variables in a module function.
        #>
        [CmdletBinding()]
        param (
            [Parameter(Mandatory = $true)]
            #[Management.Automation.PSScriptCmdlet]
            # The module function's `$PSCmdlet` object. Requires the function be decorated with the `[CmdletBinding()]` attribute.
            $Cmdlet,
    
            [Parameter(Mandatory = $true)]
            [Management.Automation.SessionState]
            # The module function's `$ExecutionContext.SessionState` object.  Requires the function be decorated with the `[CmdletBinding()]` attribute. 
            #
            # Used to set variables in its callers' scope, even if that caller is in a different script module.
            $SessionState
        )
    
        Set-StrictMode -Version 'Latest'
    
        # List of preference variables taken from the about_Preference_Variables and their common parameter name (taken from about_CommonParameters).
        $commonPreferences = @{
                                  'ErrorActionPreference' = 'ErrorAction';
                                  'DebugPreference' = 'Debug';
                                  'ConfirmPreference' = 'Confirm';
                                  'InformationPreference' = 'InformationAction';
                                  'VerbosePreference' = 'Verbose';
                                  'WarningPreference' = 'WarningAction';
                                  'WhatIfPreference' = 'WhatIf';
                              }
    
        foreach( $prefName in $commonPreferences.Keys )
        {
            $parameterName = $commonPreferences[$prefName]
    
            # Don't do anything if the parameter was passed in.
            if( $Cmdlet.MyInvocation.BoundParameters.ContainsKey($parameterName) )
            {
                continue
            }
    
            $variable = $Cmdlet.SessionState.PSVariable.Get($prefName)
            # Don't do anything if caller didn't use a common parameter.
            if( -not $variable )
            {
                continue
            }
    
            if( $SessionState -eq $ExecutionContext.SessionState )
            {
                Set-Variable -Scope 1 -Name $variable.Name -Value $variable.Value -Force -Confirm:$false -WhatIf:$false
            }
            else
            {
                $SessionState.PSVariable.Set($variable.Name, $variable.Value)
            }
        }
    
    }
    
  • Silk\Import-Silk.ps1 Show
    <#
    .SYNOPSIS
    Imports the Silk module.
    
    .DESCRIPTION
    Imports the Silk module.  If the Silk module is already loaded, it will remove it and then reloaded.
    
    .EXAMPLE
    Import-Silk.ps1
    
    Imports the Silk module, re-loading it if its already loaded.
    
    #>
    
    # Copyright 2012 Aaron Jensen
    # 
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    [CmdletBinding()]
    param(
    )
    
    Set-StrictMode -Version Latest
    $PSScriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
    
    if( (Get-Module Silk) )
    {
        Remove-Module Silk -WhatIf:$false
    }
    
    Import-Module (Join-Path $PSScriptRoot Silk.psd1 -Resolve) -ErrorAction Stop
    
  • Silk\LICENSE
  • Silk\NOTICE
  • Silk\RELEASE_NOTES.md Show
    # 0.2.0 (21 November 2016)
    
     * Improved `about_Silk` help topic.
     * Added example scripts `Invoke-Build.ps1`, `Publish-Module.ps1`, and `New-Website.ps1` to show how to use Silk.
    
  • Silk\Resources\silk.css
  • Silk\Silk.psd1 Show
    # Copyright 2012 Aaron Jensen
    # 
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    #
    # Module manifest for module 'Silk'
    #
    # Generated by: Aaron Jensen
    #
    # Generated on: 7/4/2013
    #
    
    @{
    
    # Script module or binary module file associated with this manifest
    RootModule = 'Silk.psm1'
    
    # Version number of this module.
    ModuleVersion = '0.2.0'
    
    # ID used to uniquely identify this module
    GUID = 'b4d24de5-aa00-4a18-bbde-ac8bb641751f'
    
    # Author of this module
    Author = 'Aaron Jensen'
    
    # Company or vendor of this module
    CompanyName = ''
    
    # Copyright statement for this module
    Copyright = '(c) 2013 Aaron Jensen. All rights reserved.'
    
    # Description of the functionality provided by this module
    Description = 'PowerShell module for publishing another module''s help system as a website.'
    
    # Minimum version of the Windows PowerShell engine required by this module
    PowerShellVersion = ''
    
    # Name of the Windows PowerShell host required by this module
    PowerShellHostName = ''
    
    # Minimum version of the Windows PowerShell host required by this module
    PowerShellHostVersion = ''
    
    # Minimum version of the .NET Framework required by this module
    DotNetFrameworkVersion = ''
    
    # Minimum version of the common language runtime (CLR) required by this module
    CLRVersion = ''
    
    # Processor architecture (None, X86, Amd64, IA64) required by this module
    ProcessorArchitecture = ''
    
    # Modules that must be imported into the global environment prior to importing this module
    RequiredModules = @()
    
    # Assemblies that must be loaded prior to importing this module
    RequiredAssemblies = @()
    
    # Script files (.ps1) that are run in the caller's environment prior to importing this module
    ScriptsToProcess = @()
    
    # Type files (.ps1xml) to be loaded when importing this module
    TypesToProcess = @()
    
    # Format files (.ps1xml) to be loaded when importing this module
    FormatsToProcess = @( )
    
    # Modules to import as nested modules of the module specified in ModuleToProcess
    NestedModules = @()
    
    # Functions to export from this module
    FunctionsToExport = '*'
    
    # Cmdlets to export from this module
    CmdletsToExport = '*'
    
    # Variables to export from this module
    VariablesToExport = '*'
    
    # Aliases to export from this module
    AliasesToExport = '*'
    
    # List of all modules packaged with this module
    ModuleList = @()
    
    # List of all files packaged with this module
    FileList = @()
    
    # Private data to pass to the module specified in ModuleToProcess
    PrivateData = @{
    
        PSData = @{
    
            # Tags applied to this module. These help with module discovery in online galleries.
            Tags = @('powershell','module','help','tools')
    
            # A URL to the license for this module.
            LicenseUri = 'http://www.apache.org/licenses/LICENSE-2.0'
    
            # A URL to the main website for this project.
            ProjectUri = 'http://get-silk.org'
    
            # A URL to an icon representing this module.
            # IconUri = ''
    
            # ReleaseNotes of this module
            ReleaseNotes = @'
    * Improved `about_Silk` help topic.
     * Added example scripts `Invoke-Build.ps1`, `Publish-Module.ps1`, and `New-Website.ps1` to show how to use Silk.
    '@
    
        } # End of PSData hashtable
    
    } # End of PrivateData hashtable
    
    }
    
    
  • Silk\Silk.psm1 Show
    # Copyright 2013 Aaron Jensen
    # 
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    Add-Type -Path (Join-Path $PSSCriptRoot bin\MarkdownSharp.dll)
    $markdown = New-Object MarkdownSharp.Markdown
    $markdown.AutoHyperlink = $true
    
    $loadedTypes = @{ }
    [AppDomain]::CurrentDomain.GetAssemblies() | 
        ForEach-Object { $_.GetTypes() } | 
        Where-Object { $_.IsPublic } |
        Sort-Object -Property 'Name' |
        ForEach-Object { 
            if( $loadedTypes.ContainsKey( $_.Name ) )
            {
                Write-Verbose ("Found multiple <{0}> types <{1}> <{2}>." -f $_.Name,$_.FullName,$loadedTypes[$_.Name])
            }
            else
            {
                $loadedTypes[$_.Name] = $_.FullName
            }
        }
    
    $filesToSkip = @{
                        'Import-Silk' = $true;
                    }
    
    Get-Item (Join-Path -Path $PSScriptRoot -ChildPath 'Functions\*.ps1') | 
        ForEach-Object {
            Write-Debug ("Importing function {0}." -f $_.FullName)
            . $_.FullName
        }
    
  • Tools\chocolateyInstall.ps1 Show
    <#
    .SYNOPSIS
    Chocolately install script for Silk.
    #>
    
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.[CmdletBinding()]
    
    param(
    )
    
    #Requires -Version 4
    Set-StrictMode -Version 'Latest'
    $ErrorActionPreference = 'Stop'
    
    function Get-PowerShellModuleInstallPath
    {
        <#
        .SYNOPSIS
        Returns the path to the directory where you can install custom modules.
    
        .DESCRIPTION
        Custom modules should be installed under the `Program Files` directory. This function looks at the `PSModulePath` environment variable to find the install location under `Program Files`. If that path isn't part of the `PSModulePath` environment variable, returns the module path under `$PSHOME`. If that isn't part of the `PSModulePath` environment variable, an error is written and nothing is returned.
    
        `Get-PowerShellModuleInstallPath` is new in Carbon 2.0.
    
        .EXAMPLE
        Get-PowerShellModuleInstallPath
    
        Demonstrates how to get the path where modules should be installed.
        #>
        [CmdletBinding()]
        [OutputType([string])]
        param(
        )
    
        Set-StrictMode -Version 'Latest'
    
        $modulePaths = $env:PSModulePath -split ';'
    
        $programFileModulePath = Join-Path -Path $env:ProgramFiles -ChildPath 'WindowsPowerShell\Modules'
        $installRoot = $modulePaths | 
                            Where-Object { $_.TrimEnd('\') -eq $programFileModulePath } |
                            Select-Object -First 1
        if( $installRoot )
        {
            return $programFileModulePath
        }
    
        $psHomeModulePath = Join-Path -Path $PSHOME -ChildPath 'Modules'
    
        $installRoot = $modulePaths | 
                            Where-Object { $_.TrimEnd('\') -eq $psHomeModulePath } |
                            Select-Object -First 1
        if( $installRoot )
        {
            return $psHomeModulePath
        }
    
        Write-Error -Message ('PSModulePaths ''{0}'' and ''{1}'' not found in the PSModulePath environment variable.' -f $programFileModulePath,$psHomeModulePath)
    }
    
    $installPath = Get-PowerShellModuleInstallPath
    $installPath = Join-Path -Path $installPath -ChildPath 'Silk'
    
    $source = Join-Path -Path $PSScriptRoot -ChildPath '..\Silk' -Resolve
    if( -not $source )
    {
        return
    }
    
    if( (Test-Path -Path $installPath -PathType Container) )
    {
        $newName = 'Silk{0}' -f [IO.Path]::GetRandomFileName()
        Write-Verbose ('Renaming existing Silk module: {0} -> {1}' -f $installPath,$newName)
        Rename-Item -Path $installPath $newName
        $oldModulePath = Join-Path -Path (Get-PowerShellModuleInstallPath) -ChildPath $newName
        if( Test-Path -Path $oldModulePath -PathType Container )
        {
            Write-Verbose ('Removing old Silk module: {0}' -f $oldModulePath)
            Remove-Item -Path $oldModulePath -Force -Recurse
        }
        else
        {
            return
        }
    
        if( Test-Path -Path $oldModulePath -PathType Container )
        {
            return
        }
    }
    
    Write-Verbose -Message ('Installing Silk: {0} -> {1}' -f $source,$installPath)
    Copy-Item -Path $source -Destination $installPath -Recurse
    
  • Tools\chocolateyUninstall.ps1 Show
    <#
    .SYNOPSIS
    Chocolately install script for Silk.
    #>
    
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # 
    #     http://www.apache.org/licenses/LICENSE-2.0
    # 
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.[CmdletBinding()]
    
    param(
    )
    
    #Requires -Version 4
    Set-StrictMode -Version 'Latest'
    $ErrorActionPreference = 'Stop'
    
    $errorCount = $Global:Error.Count
    try
    {
        $env:PSModulePath -split ';' |
            Where-Object { $_ } | 
            Join-Path -ChildPath 'Silk' |
            Where-Object { Test-Path -Path $_ -PathType Container } |
            Rename-Item -NewName { 'Silk{0}' -f [IO.Path]::GetRandomFileName() } -PassThru |
            Remove-Item -Recurse -Force
    }
    finally
    {
        for( $idx = $errorCount; $idx -lt $Global:Error.Count; ++$idx )
        {
            $Global:Error[$idx]
            $Global:Error[$idx] | Format-List -Property '*' -Force | Out-String | Write-Verbose
        }
    }

Virus Scan Results

In cases where actual malware is found, the packages are subject to removal. Software sometimes has false positives. Moderators do not necessarily validate the safety of the underlying software, only that a package retrieves software from the official distribution point and/or validate embedded software against official distribution point (where distribution rights allow redistribution).

Chocolatey Pro provides runtime protection from possible malware.

Dependencies

This package has no dependencies.

Package Maintainer(s)

Software Author(s)

  • Aaron Jensen

Copyright

(c) 2013 Aaron Jensen. All rights reserved.

Tags

Release Notes

  • Improved about_Silk help topic.

    • Added example scripts Invoke-Build.ps1, Publish-Module.ps1, and New-Website.ps1 to show how to use Silk.

Version History

Version Downloads Last updated Status

Discussion for the Silk Package

Ground rules:

  • This discussion is only about Silk and the Silk package. If you have feedback for Chocolatey, please contact the google group.
  • This discussion will carry over multiple versions. If you have a comment about a particular version, please note that in your comments.
  • The maintainers of this Chocolatey Package will be notified about new comments that are posted to this Disqus thread, however, it is NOT a guarantee that you will get a response. If you do not hear back from the maintainers after posting a message below, please follow up by using the link on the left side of this page or follow this link to contact maintainers. If you still hear nothing back, please follow the package triage process.
  • Tell us what you love about the package or Silk, or tell us what needs improvement.
  • Share your experiences with the package, or extra configuration or gotchas that you've found.
  • If you use a url, the comment will be flagged for moderation until you've been whitelisted. Disqus moderated comments are approved on a weekly schedule if not sooner. It could take between 1-5 days for your comment to show up.

comments powered by Disqus
Chocolatey.org uses cookies to enhance the user experience of the site.
Ok