Tuesday, July 7, 2020

PowerShell/Nuget: Creating a NuSpec file Containing all Files in a Folder

For a project, I needed a Nuget package that contained all files in a given folder hierarchy. This meant that the Nuget packaged included assemblies (DLLs) and other files that were to be considered content. A luck would have it, my last blog post contained an example of how, given a folder name passed as a parameter, to traverse every file a sub-folder: PowerShell: Traverse all Folders and Files for a given Path.

Files are specified in a Nuspec file using the falling rather mundane XML format where a <files> element contains one ore more <file> elements. Wild cards are supported as are attributes to include and exclude specific files. The release notes found at NuGet 1.5 Release Notes contains the following documentation:

The PowerShell script for traversing a folder hierarchy and creating on <file> element per-detected fie is as follows:

Param (
    [string] $folderName = $PSScriptRoot

class NuSpecFiles {
    [System.Text.StringBuilder] $filesXml = [System.Text.StringBuilder]::new()

    [string] $rootFolder

    [void] Append([string] $parentFolder, [string] $filename) {
        [string] $target = $filename

        if (-not ([string]::IsNullOrEmpty($parentFolder))) {
            $target = Join-Path -Path $parentFolder -ChildPath $filename            

        # <file src="Your_Folder\*.pp" target="content\Your_Folder"/>
        $this.filesXml.AppendLine("  <file src=""$parentFolder"" target=""$target"" />")

    [string] StripParentFolder([string] $folder) {
        return $folder.TrimStart($this.rootFolder)

    [void] Traverse([string] $folderName) {
        [string] $parentFolder = $this.StripParentFolder($folderName)

        $entities = Get-ChildItem `
            -Path $folderName `
            -ErrorAction SilentlyContinue `

        foreach ($entry in $entities) {
            if ($entry -is  [System.IO.DirectoryInfo]) {

            else { # if ($entry -is  [System.IO.FileInfo])
                $this.Append($parentFolder, $entry.Name)                

            <file src="lib\net472\any_assembly.dll" 
                  target="lib\net472" />
            <file src="Any_Folder\*.txt"               
            <file src="Any_Folder\Any_SubFolder\*.*" 
                  target="content" />
            <file src="*.config" target="content" />
    [void] Create([string] $folderName)
        $this.rootFolder = $folderName

    [string] GetFilesXmlElement()
        return $this.filesXml.ToString()

[NuSpecFiles] $nuspecFiles = [NuSpecFiles]::new()


No comments :

Post a Comment