Unpacking Software Livestream

Join our monthly Unpacking Software livestream to hear about the latest news, chat and opinion on packaging, software deployment and lifecycle management!

Learn More

Chocolatey Product Spotlight

Join the Chocolatey Team on our regular monthly stream where we put a spotlight on the most recent Chocolatey product releases. You'll have a chance to have your questions answered in a live Ask Me Anything format.

Learn More

Chocolatey Coding Livestream

Join us for the Chocolatey Coding Livestream, where members of our team dive into the heart of open source development by coding live on various Chocolatey projects. Tune in to witness real-time coding, ask questions, and gain insights into the world of package management. Don't miss this opportunity to engage with our team and contribute to the future of Chocolatey!

Learn More

Calling All Chocolatiers! Whipping Up Windows Automation with Chocolatey Central Management

Webinar from
Wednesday, 17 January 2024

We are delighted to announce the release of Chocolatey Central Management v0.12.0, featuring seamless Deployment Plan creation, time-saving duplications, insightful Group Details, an upgraded Dashboard, bug fixes, user interface polishing, and refined documentation. As an added bonus we'll have members of our Solutions Engineering team on-hand to dive into some interesting ways you can leverage the new features available!

Watch On-Demand
Chocolatey Community Coffee Break

Join the Chocolatey Team as we discuss all things Community, what we do, how you can get involved and answer your Chocolatey questions.

Watch The Replays
Chocolatey and Intune Overview

Webinar Replay from
Wednesday, 30 March 2022

At Chocolatey Software we strive for simple, and teaching others. Let us teach you just how simple it could be to keep your 3rd party applications updated across your devices, all with Intune!

Watch On-Demand
Chocolatey For Business. In Azure. In One Click.

Livestream from
Thursday, 9 June 2022

Join James and Josh to show you how you can get the Chocolatey For Business recommended infrastructure and workflow, created, in Azure, in around 20 minutes.

Watch On-Demand
The Future of Chocolatey CLI

Livestream from
Thursday, 04 August 2022

Join Paul and Gary to hear more about the plans for the Chocolatey CLI in the not so distant future. We'll talk about some cool new features, long term asks from Customers and Community and how you can get involved!

Watch On-Demand
Hacktoberfest Tuesdays 2022

Livestreams from
October 2022

For Hacktoberfest, Chocolatey ran a livestream every Tuesday! Re-watch Cory, James, Gary, and Rain as they share knowledge on how to contribute to open-source projects such as Chocolatey CLI.

Watch On-Demand

(unofficial) Chocolatey .nuspec Checker (Script)

This is not the latest version of (unofficial) Chocolatey .nuspec Checker (Script) available.

  • 1
  • 2
  • 3

2019.01.29 | Updated: 30 Jan 2019

Downloads:

8,192

Downloads of v 2019.01.29:

254

Software Author(s):

  • Bill Curran

(unofficial) Chocolatey .nuspec Checker (Script) 2019.01.29

This is not the latest version of (unofficial) Chocolatey .nuspec Checker (Script) available.

Legal Disclaimer: Neither this package nor Chocolatey Software, Inc. are affiliated with or endorsed by Bill Curran. The inclusion of Bill Curran trademark(s), if any, upon this webpage is solely to identify Bill Curran goods or services and not for commercial purposes.

  • 1
  • 2
  • 3

All Checks are Passing

3 Passing Tests


Validation Testing Passed


Verification Testing Passed

Details

Scan Testing Successful:

No detections found in any package files

Details
Learn More

Deployment Method: Individual Install, Upgrade, & Uninstall

To install (unofficial) Chocolatey .nuspec Checker (Script), run the following command from the command line or from PowerShell:

>

To upgrade (unofficial) Chocolatey .nuspec Checker (Script), run the following command from the command line or from PowerShell:

>

To uninstall (unofficial) Chocolatey .nuspec Checker (Script), run the following command from the command line or from PowerShell:

>

Deployment Method:

NOTE

This applies to both open source and commercial editions of Chocolatey.

1. Enter Your Internal Repository Url

(this should look similar to https://community.chocolatey.org/api/v2/)


2. Setup Your Environment

1. Ensure you are set for organizational deployment

Please see the organizational deployment guide

2. Get the package into your environment

  • Open Source or Commercial:
    • Proxy Repository - Create a proxy nuget repository on Nexus, Artifactory Pro, or a proxy Chocolatey repository on ProGet. Point your upstream to https://community.chocolatey.org/api/v2/. Packages cache on first access automatically. Make sure your choco clients are using your proxy repository as a source and NOT the default community repository. See source command for more information.
    • You can also just download the package and push it to a repository Download

3. Copy Your Script

choco upgrade choco-nuspec-checker -y --source="'INTERNAL REPO URL'" --version="'2019.01.29'" [other options]

See options you can pass to upgrade.

See best practices for scripting.

Add this to a PowerShell script or use a Batch script with tools and in places where you are calling directly to Chocolatey. If you are integrating, keep in mind enhanced exit codes.

If you do use a PowerShell script, use the following to ensure bad exit codes are shown as failures:


choco upgrade choco-nuspec-checker -y --source="'INTERNAL REPO URL'" --version="'2019.01.29'" 
$exitCode = $LASTEXITCODE

Write-Verbose "Exit code was $exitCode"
$validExitCodes = @(0, 1605, 1614, 1641, 3010)
if ($validExitCodes -contains $exitCode) {
  Exit 0
}

Exit $exitCode

- name: Install choco-nuspec-checker
  win_chocolatey:
    name: choco-nuspec-checker
    version: '2019.01.29'
    source: INTERNAL REPO URL
    state: present

See docs at https://docs.ansible.com/ansible/latest/modules/win_chocolatey_module.html.


chocolatey_package 'choco-nuspec-checker' do
  action    :install
  source   'INTERNAL REPO URL'
  version  '2019.01.29'
end

See docs at https://docs.chef.io/resource_chocolatey_package.html.


cChocoPackageInstaller choco-nuspec-checker
{
    Name     = "choco-nuspec-checker"
    Version  = "2019.01.29"
    Source   = "INTERNAL REPO URL"
}

Requires cChoco DSC Resource. See docs at https://github.com/chocolatey/cChoco.


package { 'choco-nuspec-checker':
  ensure   => '2019.01.29',
  provider => 'chocolatey',
  source   => 'INTERNAL REPO URL',
}

Requires Puppet Chocolatey Provider module. See docs at https://forge.puppet.com/puppetlabs/chocolatey.


4. If applicable - Chocolatey configuration/installation

See infrastructure management matrix for Chocolatey configuration elements and examples.

Package Approved

This package was approved by moderator gep13 on 30 Jan 2019.

Description


choco://choco-nuspec-checker
To use choco:// protocol URLs, install (unofficial) choco:// Protocol support


Screenshot of (unofficial) Chocolatey .nuspec Checker (Script)

choco-nuspec-checker (CNC) is a PowerShell script I designed for Chocolatey package maintainers/creators to check Chocolatey .nuspec files for common errors and omissions. Find out what the Chocolatey validator is going to tell you BEFORE you submit your package. Even more useful features have been added outside of it's original scope.

FEATURES:

  • CNC checks for all .nuspec elements and reports any missing
  • CNC checks for all verifier messages (guidelines, suggestions, and notes) and reports them if applicable
  • CNC checks for dead URLs and reports them
  • CNC checks for GitHub direct links, reports them, and can convert them to Staticaly CDN URLs
  • CNC checks for RawGit CDN links, reports them, and can convert them to Staticaly CDN URLs
  • CNC can open all your .nuspec element URLs in your default browser for quick viewing
  • CNC can add a standard template header and/or footer to your .nuspec description and replace tokens
  • CNC checks for UTF-8 encoding and reports the type of encoding if not UTF-8
  • CNC can re-write your nuspec in UTF-8 w/o BOM format
  • CNC checks your chocolateyInstall.ps1 and chocolateyUninstall.ps1 for PowerShell syntax errors
  • CNC checks your chocolateyInstall.ps1 and chocolateyUninstall.ps1 for for UTF-8 w/BOM encoding
  • CNC can optimize PNG files in your nuspec directory if PNGOptimizer.commandline is installed

Helps make packaging Chocolateasy!

INSTRUCTIONS:

  • CNC -help for help with options and switches
  • Run CNC to check the .nuspec in your current directory, run CNC X:\SOMEWHERE to check the .nuspec in that directory. (Do not specify the file, just the directory.)
  • To check all your packages' .nuspec files, change to the root directory of your packages, and via PowerShell run Get-ChildItem | ?{if ($.PSIsContainer){cls;cd $.Name;cnc;cd ..;pause}}
  • To update all your packages' .nuspec files, change to the root directory of your packages, and via PowerShell run Get-ChildItem | ?{if ($.PSIsContainer){cd $.Name;cnc -UpdateAll;cd ..}} (no clear screen or pausing)

PACKAGE NOTES

If you find choco-nuspec-checker useful please consider donating: https://www.paypal.me/bcurran3donations or become a patron at https://www.patreon.com/bcurran3


tools\ChocolateyInstall.ps1
$ErrorActionPreference = 'Stop'
$packageName = 'choco-nuspec-checker'
$toolsDir    = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
$script      = 'CNC.ps1'
$CNCHeader   = 'CNCHeader.txt'
$CNCFooter   = 'CNCFooter.txt'
$CheckExecutionPolicy = Get-ExecutionPolicy

Write-Host "  ** $packageName - FYI: Your PowerShell Execution Policy is curently set to $CheckExecutionPolicy" -ForeGround Yellow

Move-Item "$toolsDir\$script" $env:ChocolateyInstall\bin -Force 

if (!(Test-Path $ENV:ChocolateyInstall\bin\$CNCHeader)) {
    Move-Item "$toolsDir\$CNCHeader" $env:ChocolateyInstall\bin -Force
	$WhoAmI=whoami
    $Acl = Get-Acl "$env:ChocolateyInstall\bin\$CNCHeader"
    $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule($WhoAmI,"FullControl","Allow")
    $Acl.SetAccessRule($Ar)
    Set-Acl "$env:ChocolateyInstall\bin\$CNCHeader" $Acl
   }
if (!(Test-Path $ENV:ChocolateyInstall\bin\$CNCFooter)) {
    Move-Item "$toolsDir\$CNCFooter" $env:ChocolateyInstall\bin -Force
	$WhoAmI=whoami
    $Acl = Get-Acl "$env:ChocolateyInstall\bin\$CNCFooter"
    $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule($WhoAmI,"FullControl","Allow")
    $Acl.SetAccessRule($Ar)
    Set-Acl "$env:ChocolateyInstall\bin\$CNCFooter" $Acl	
   }
tools\ChocolateyUninstall.ps1
$packageName = 'choco-nuspec-checker' 
$script      = 'CNC.ps1'
$CNCHeader   = 'CNCHeader.txt'
$CNCFooter   = 'CNCFooter.txt'

Remove-Item "$ENV:ChocolateyInstall\bin\$script" -Force | Out-Null
Remove-Item "$ENV:ChocolateyInstall\bin\$CNCHeader" -Force -ErrorAction SilentlyContinue | Out-Null
Remove-Item "$ENV:ChocolateyInstall\bin\$CNCFooter" -Force -ErrorAction SilentlyContinue | Out-Null
tools\CNC.ps1
# CNC.ps1 Copyleft 2018-2019 by Bill Curran AKA BCURRAN3
# LICENSE: GNU GPL v3 - https://www.gnu.org/licenses/gpl.html
# Open a GitHub issue at https://github.com/bcurran3/ChocolateyPackages/issues if you have suggestions for improvement.

# REF: https://docs.microsoft.com/en-us/nuget/reference/nuspec
# REF: https://github.com/chocolatey/package-validator/wiki

param (
    [string]$path=(Get-Location)
 )
 
Write-Host "CNC.ps1 v2019.01.29 - (unofficial) Chocolatey .nuspec Checker ""CNC - Run it through the Bill.""" -Foreground White
Write-Host "Copyleft 2018-2019 Bill Curran ([email protected]) - free for personal and commercial use`n" -Foreground White

# parameters and variables -------------------------------------------------------------------------------------

$PSDefaultParameterValues['*:Encoding'] = 'utf8'
$AcceptableIconExts=@("png","svg")
$BinaryExtensions=@("*.exe","*.msi","*.zip","*.rar","*.7z","*.gz","*.tar","*.sfx","*.iso","*.img","*.msu","*.msp","*.appx","*.appxbundle") # miss any?
$CDNlist     = "https://www.staticaly.com, https://raw.githack.com, https://gitcdn.link, or https://www.jsdelivr.com"
$CNCHeader   = "$ENV:ChocolateyInstall\bin\CNCHeader.txt"
$CNCFooter   = "$ENV:ChocolateyInstall\bin\CNCFooter.txt"
$PNGOptimizer = (Test-Path $ENV:ChocolateyInstall\bin\PngOptimizerCL.exe)
$global:UpdateNuspec=$False

if (($args -eq "-help") -or ($args -eq "-?") -or ($args -eq "/?")) {
    Write-Host "OPTIONS AND SWITCHES:" -Foreground Magenta
	Write-Host "-help, -?, or /?"
	Write-Host "   Displays this information."
	Write-Host "-AddFooter"
    Write-Host "   Adds and saves a footer from $CNCFooter to your <description>."	
	Write-Host "-AddHeader"
    Write-Host "   Adds and saves a header from $CNCHeader to your <description>."
	Write-Host "-EditFooter"
    Write-Host "   Edit $CNCFooter with Notepad++ or Notepad."
	Write-Host "-EditHeader"
    Write-Host "   Edit $CNCHeader with Notepad++ or Notepad."
	Write-Host "-OpenURLs"
    Write-Host "   Opens all URLs in your browser for inspection when finished."
	Write-Host "-OpenValidatorInfo"
    Write-Host "   Opens the Chocolatey package-validator info page on GitHub in your default browser."	
	Write-Host "-ShowFooter"
    Write-Host "   Displays $CNCFooter."	
	Write-Host "-ShowHeader"
    Write-Host "   Displays $CNCHeader."
	Write-Host "-OptimizePNGs"
    Write-Host "   Runs PNGOptimizerCL on your PNG files."
	Write-Host "-Update"
    Write-Host "   Will re-write out your nuspec file; e.g. change to UTF-8 w/o BOM."
	Write-Host "-UpdateAll"
    Write-Host "   Rights all wrongs."
	Write-Host "-UpdateImageURLs"
    Write-Host "   Updates image URLs with Staticaly CDN URLs."
	Write-Host "-UpdateXMLComment"
    Write-Host "   Updates the XML comment for UTF-8 checking."
	Write-Host "-UpdateXMLDeclaration"
    Write-Host "   Updates the XML declaration."
	Write-Host "-WhatIf"
    Write-Host "   Don't save changes."
	Write-Host "To check all your packages' .nuspec files: Change to the root directory of your packages and run (via PowerShell):" -Foreground Magenta
	Write-Host 'Get-ChildItem | ?{if ($_.PSIsContainer){cls;cd $_.Name;cnc;cd ..;pause}}' -Foreground Magenta
	return
}

if (Test-Path $ENV:ChocolateyInstall\bin\notepad++.exe){
     $Editor="notepad++.exe"
    } else {
      $Editor="notepad.exe"
    }

if ($args -eq "-EditFooter") {
    Write-Host "  ** Editing contents of $CNCFooter." -Foreground Magenta
	&$Editor $CNCFooter
	return
}

if ($args -eq "-EditHeader") {
    Write-Host "  ** Editing contents of $CNCHeader." -Foreground Magenta
	&$Editor $CNCHeader
	return
}

if ($args -eq "-ShowFooter") {
	Write-Host "  ** Displaying contents of $CNCFooter." -Foreground Magenta
    Write-Host	
    Get-Content $CNCFooter
	return
}

if ($args -eq "-ShowHeader") {
    Write-Host "  ** Displaying contents of $CNCHeader." -Foreground Magenta
    Write-Host	
    Get-Content $CNCHeader
	return
}

if ($args -eq "-OpenValidatorInfo") {
    Write-Host "  ** Opening https://github.com/chocolatey/package-validator/wiki." -Foreground Magenta
    Write-Host	
    &start https://github.com/chocolatey/package-validator/wiki
	return
}

if ($args -eq "-AddHeader") {
     $AddHeader=$True
   } else {
     $AddHeader=$False
}

if ($args -eq "-AddFooter") {
     $AddFooter=$True
   } else {
     $AddFooter=$False
}

if ($args -eq "-Debug") {
     $Debug=$True
   } else {
     $Debug=$False
}

if ($args -eq "-OpenURLs") {
     $OpenURLs=$True
   } else {
     $OpenURLs=$False
}

if ($args -eq "-OptimizePNGs") {
     $OptimizePNGs=$True
   } else {
     $OptimizePNGs=$False
}

if ($args -eq "-UpdateImageURLs") {
     $UpdateImageURLs=$True
   } else {
     $UpdateImageURLs=$False
}

if ($args -eq "-UpdateXMLComment") {
     $UpdateXMLComment=$True
   } else {
     $UpdateXMLComment=$False
}

if ($args -eq "-UpdateXMLDeclaration") {
     $UpdateXMLDeclaration=$True
   } else {
     $UpdateXMLDeclaration=$False
}

if ($args -eq "-Update") {
	 $global:UpdateNuspec=$True
}

if ($args -eq "-UpdateAll") {
     $UpdateAll=$True
	 $UpdateImageURLs=$True
	 $OptimizePNGs=$True
	 $UpdateXMLComment=$True
	 $UpdateXMLDeclaration=$True
	 $global:UpdateNuspec=$True
   } else {
     $UpdateAll=$False
}

if ($args -eq "-UseGitHack") {
     $UseGitHack=$True
   } else {
     $UseGitHack=$False
}

if ($args -eq "-UsegitCDN") {
     $UsegitCDN=$True
   } else {
     $UsegitCDN=$False
}

if ($args -eq "-Usejsdelivr") {
     $Usejsdelivr=$True
   } else {
     $Usejsdelivr=$False
}

if ($args -eq "-WhatIf") {
     $WhatIf=$True
   } else {
     $WhatIf=$False
}

if ($path -eq "\"){
$path=(Get-Location).Drive.Name + ":" + "\"
}

if (!(Test-Path $path)){
    Write-Host "           ** $path is an invalid path." -Foreground Red
	return
   }

# Finds nuspec file for processing. Defaults to current working directory.
# You can specify a directory path, but do NOT specify the file itself, just the directory.
if (!$path) {$LocalnuspecFile = Get-Item -Path $path\*.nuspec}
if ($path) {$LocalnuspecFile = Get-Item $path\*.nuspec}
if (!($LocalnuspecFile)) {
    Write-Host "           ** No .nuspec file found in $path" -Foreground Red
	return
   }
if ($LocalnuspecFile.count -gt 1){
    Write-Host "           ** Multiple .nuspec files found in $path. Please remove or rename the extras." -Foreground Red
	return
   }
if ($LocalnuspecFile.length -lt 168){ # aproximate value of a minimal blank nuspec template
    Write-Host "           ** $LocalnuspecFile file appears to be blank or corrupt." -Foreground Red
	return
   }

# Import package.nuspec file to get values
$nuspecXML = $LocalnuspecFile
[xml]$nuspecFile = Get-Content $nuspecXML
$NuspecAuthors = $nuspecFile.package.metadata.authors
$NuspecBugTrackerURL = $nuspecFile.package.metadata.bugtrackerurl	
$NuspecConflicts = $nuspecFile.package.metadata.conflicts # Built for the future
$NuspecCopyright = $nuspecFile.package.metadata.copyright
$NuspecDependencies = $nuspecFile.package.metadata.dependencies
$NuspecDescription = $nuspecFile.package.metadata.description
$NuspecDocsURL = $nuspecFile.package.metadata.docsurl
$NuspecFiles = $nuspecFile.package.files.file
$NuspecIconURL = $nuspecFile.package.metadata.iconurl
$NuspecID = $nuspecFile.package.metadata.id
$NuspecLicenseURL = $nuspecFile.package.metadata.licenseurl
$NuspecMailingListURL = $nuspecFile.package.metadata.mailinglisturl
$NuspecOwners = $nuspecFile.package.metadata.owners
$NuspecPackageSourceURL = $nuspecFile.package.metadata.packagesourceurl
$NuspecProjectSourceURL = $nuspecFile.package.metadata.projectsourceurl
$NuspecProjectURL = $nuspecFile.package.metadata.projecturl
$NuspecProvides = $nuspecFile.package.metadata.provides # Built for the future
$NuspecReleaseNotes = $nuspecFile.package.metadata.releasenotes
$NuspecReplaces = $nuspecFile.package.metadata.replaces # Built for the future
$NuspecRequireLicenseAcceptance = $nuspecFile.package.metadata.requirelicenseacceptance
$NuspecSummary = $nuspecFile.package.metadata.summary
$NuspecTags = $nuspecFile.package.metadata.tags
$NuspecTitle = $nuspecFile.package.metadata.title
$NuspecVersion = $nuspecFile.package.metadata.version

$NuspecDisplayName=$LocalnuspecFile.Name
$NuspecDisplayName=$NuspecDisplayName.ToUpper()

# functions ------------------------------------------------------------------------------------------------

# Borrowed and slightly modified from
# https://blogs.technet.microsoft.com/samdrey/2014/03/26/determine-the-file-encoding-of-a-file-csv-file-with-french-accents-or-other-exotic-characters-that-youre-trying-to-import-in-powershell/
# UTF-8 w/o BOM reports as ASCII. ASCII is a subset of UTF-8. 

function Get-FileEncoding
{
    [CmdletBinding()] Param (
     [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] [string]$Path
    )
	
    [byte[]]$byte = get-content -Encoding byte -ReadCount 4 -TotalCount 4 -Path $Path

    if ($byte[0] -eq 0xef -and $byte[1] -eq 0xbb -and $byte[2] -eq 0xbf)
    { Write-Output 'UTF-8 w/ BOM' } 
    elseif ($byte[0] -eq 0xfe -and $byte[1] -eq 0xff)
    { Write-Output 'Unicode' }
    elseif ($byte[0] -eq 0 -and $byte[1] -eq 0 -and $byte[2] -eq 0xfe -and $byte[3] -eq 0xff)
    { Write-Output 'UTF-32' }
    elseif ($byte[0] -eq 0x2b -and $byte[1] -eq 0x2f -and $byte[2] -eq 0x76)
    { Write-Output 'UTF-7'}
    else
    { Write-Output 'ASCII or UTF-8 w/o BOM' } 
}

# Get iconUrl dimensions
# Supports BMP, GIF, EXIF, JPG, PNG and TIFF
# Will error on URLs such as
# https://lh3.googleusercontent.com/n6kpA-xZE_0iEy9A8WkJpGT45XB6MEq09t9UdBoIrCfwIoBm3CA9gqI13AqbBN6yx7GwVDjx=s26-h26-e365-rw
function Get-ImageDimensions{
Write-Host "(Downloading icon)" -NoNewLine -Foreground Magenta
(New-Object System.Net.WebClient).DownloadFile($NuspecIconURL, "$pwd\iconURL.image")
Write-Host "`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b                  `b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b" -NoNewLine
if (Test-Path "$pwd\iconURL.image"){
    add-type -AssemblyName System.Drawing
    $image = New-Object System.Drawing.Bitmap "$pwd\iconURL.image"
    $height=$image.height
    $width=$image.width
    $image.dispose()
    if (($height -lt 128) -or ($width -lt 128)){
	if (!$height){$height="?"}
	if (!$width){$width="?"}
        Write-Warning "  ** <iconUrl> - icon dimensions are h$height x w$width."
	    Write-Host "           ** Use package icons with at least 128 pixels in width or height if available." -Foreground Cyan
       }
    Remove-Item "$pwd\iconURL.image" -Force
   }
}

# Borrowed from
# https://web.archive.org/web/20160430132409/http://powershell.org:80/wp/forums/topic/how-to-check-syntax-of-scripts-automatically/
function Test-PowerShellSyntax
{
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string[]]
        $Path
    )

    process
    {
        foreach ($scriptPath in $Path) {
            $contents = Get-Content -Path $scriptPath

            if ($null -eq $contents)
            {
                continue
            }

            $errors = $null
            $null = [System.Management.Automation.PSParser]::Tokenize($contents, [ref]$errors)

            New-Object psobject -Property @{
                Path = $scriptPath
                SyntaxErrorsFound = ($errors.Count -gt 0)
            }
        }
    }
}

# Validate that URL elements are actually URLs and verify the URLs are good
# Thanks https://stackoverflow.com/questions/23760070/the-remote-server-returned-an-error-401-unauthorized
function Validate-URL([string]$element,[string]$url){
if (($url -match "http://") -or ($url -match "https://")){
     Write-Host "(Validating URL)" -NoNewLine -Foreground Magenta
     $HTTP_Response = $null
     $HTTP_Request = [System.Net.WebRequest]::Create($url)
     try{
         $HTTP_Response = $HTTP_Request.GetResponse()
		 Write-Host "`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b                `b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b" -NoNewLine
         $HTTP_Status = [int]$HTTP_Response.StatusCode
         if ($HTTP_Status -eq 200) { 
            $global:ValidURL=$True
         } else {
		   Write-Host "`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b                `b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b" -NoNewLine
           Write-Warning ("  ** $element - the URL:`n              $url`n site might be OK, status code:" + $HTTP_Status)
		   Write-Host "           ** Consider using CNC's -OpenURLs option to open and view all URLs in the .nuspec." -Foreground Cyan
		   $global:ValidURL=$False
         }
         $HTTP_Response.Close()
        } catch {
          $HTTP_Status = [regex]::matches($_.exception.message, "(?<=\()[\d]{3}").Value
		  Write-Host "`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b                `b`b`b`b`b`b`b`b`b`b`b`b`b`b`b`b" -NoNewLine
          Write-Warning ("  ** $element - the URL:`n              $url`n              is probably bad, status code: " + $HTTP_Status)
          Write-Host "           ** Consider using CNC's -OpenURLs option to open and view all URLs in the .nuspec." -Foreground Cyan
		  $global:ValidURL=$False
        }
   }
}

# Check for license files when binaries are included
function Check-LicenseFile{
$LicenseFile=(Get-ChildItem -Path $path -Include *LICENSE* -Recurse)
if ($LicenseFile){
	 Write-Host '           ** Binary files - '  $LicenseFile.Name ' file(s) found.' -Foreground Green
	} else {
	 Write-Warning "  ** Binary files - LICENSE.txt file NOT found."
   }
}

# Check for verification file when binaries are included
function Check-VerificationFile{
$VerificationFile=(Get-ChildItem -Path $path -Include *VERIFICATION* -Recurse)
if ($VerificationFile){
     Write-Host '           ** Binary files - '  $VerificationFile.Name ' file(s) found.' -Foreground Green
	} else {
	 Write-Warning "  ** Binary files - VERIFICATION.txt file NOT found."
   }
}

# check for binaries
function Check-Binaries{
$IncludedBinaries=(Get-ChildItem -Path $path -Include $BinaryExtensions -Recurse)
if ($IncludedBinaries){
    Write-Warning "  ** Binary files found in package. This will trigger a message from the verifier:"
    Write-Host "           ** Note: Binary files (.exe, .msi, .zip) have been included. The reviewer will ensure the maintainers have`n              distribution rights." -Foreground Cyan
	Check-LicenseFile
	Check-VerificationFile
   }
}

# check for PNG files for possible optimization
function Check-PNGs{
$PNGFiles=(Get-ChildItem -Path $path -Include *.PNG -Recurse)
if ($PNGFiles){
    Write-Warning '  ** PNG file(s) found.'
	if (!$OptimizePNGs){
	Write-Host '           ** Consider running CNC -OptimizePNGs to optimize it/them.' -Foreground Cyan
	}
   }
}

# add header template to <description>
function Add-Header{
if (Test-Path $CNCHeader){
    $Header=[IO.File]::ReadAllText($CNCHeader)
	if ($Header -match '\$NuspecAuthors') {$Header=$Header -replace '\$NuspecAuthors',"$NuspecAuthors"}
	if ($Header -match '\$NuspecID') {$Header=$Header -replace '\$NuspecID',"$NuspecID"}
	if ($Header -match '\$NuspecOwners') {$Header=$Header -replace '\$NuspecOwners',"$NuspecOwners"}
	if ($Header -match '\$NuspecTitle') {$Header=$Header -replace '\$NuspecTitle',"$NuspecTitle"}
    if ($Header -match '\$NuspecVersion') {$Header=$Header -replace '\$NuspecVersion',"$NuspecVersion"}
    $NuspecDescription="`n" + $Header + $NuspecDescription + "`n"
    Write-Host "           ** <description> - header template added." -Foreground Green
	$global:UpdateNuspec=$True
	return $NuspecDescription
   } else {
	Write-Warning "           ** $CNCHeader not found."
   }
}

# add footer template to <description>
function Add-Footer{
if (Test-Path $CNCFooter){
    $Footer=[IO.File]::ReadAllText($CNCFooter)
	if ($Footer -match '\$NuspecAuthors') {$Footer=$Footer -replace '\$NuspecAuthors',"$NuspecAuthors"}
	if ($Footer -match '\$NuspecID') {$Footer=$Footer -replace '\$NuspecID',"$NuspecID"}
	if ($Footer -match '\$NuspecOwners') {$Footer=$Footer -replace '\$NuspecOwners',"$NuspecOwners"}
	if ($Footer -match '\$NuspecTitle') {$Footer=$Footer -replace '\$NuspecTitle',"$NuspecTitle"}
    if ($Footer -match '\$NuspecVersion') {$Footer=$Footer -replace '\$NuspecVersion',"$NuspecVersion"}
    $NuspecDescription=$NuspecDescription + "`n" + $Footer + "`n"
    Write-Host "           ** <description> - footer template added." -Foreground Green
    $global:UpdateNuspec=$True
	return $NuspecDescription
   } else {
	Write-Warning "           ** $CNCFooter NOT found."
   }
}

# check if header template is already in the description
function Check-Header{
$NuspecDescription=$NuspecDescription.Trim()
if ($NuspecDescription.StartsWith("***") -or $NuspecDescription.StartsWith("---") -or $NuspecDescription.StartsWith("___")){ 
    Write-Host "           ** <description> - header template found." -Foreground Green
   }
}

# check if footer template is already in the description
function Check-Footer{
$NuspecDescription=$NuspecDescription.Trim()
if ($NuspecDescription.EndsWith("***") -or $NuspecDescription.EndsWith("---") -or $NuspecDescription.EndsWith("___")){
    Write-Host "           ** <description> - footer template found." -Foreground Green
   }
}

# Open all .nuspec URLs for viewing
function Open-URLs{
if ($NuspecBugTrackerURL){&start $NuspecBugTrackerURL}
if ($NuspecDocsURL){&start $NuspecDocsURL}
if ($NuspecIconURL){&start $NuspecIconURL}
if ($NuspecLicenseURL){&start $NuspecLicenseURL}
if ($NuspecMailingListURL){&start $NuspecMailingListURL}
if ($NuspecPackageSourceURL){&start $NuspecPackageSourceURL}
if ($NuspecProjectSourceURL){&start $NuspecProjectSourceURL}
if ($NuspecProjectURL){&start $NuspecProjectURL}
}

# Run PNGOptimizerCL on PNG files
function Run-PNGOptimizer{
if ($OptimizePNGs){
if (!$PNGOptimizer){
    Write-Warning "  ** -OptimizePNGs parameter given but PNGOptimizerCL.exe not found."
	Write-Host "           ** Run choco install pngoptimizer.commandline first to use this feature." -Foreground Cyan
	return
   }
    $PNGFiles=(Get-ChildItem -Path $path -Include *.PNG -Recurse)
    if ($PNGFiles -and $PNGOptimizer){
        Write-Host "           ** Running PNGOptimzerCL on PNG files." -Foreground Green
	    if ($WhatIf){
            Write-Host "CNC did NOT optimize your PNG files, -WhatIf parameter was used." -Foreground Magenta
	   } else {
		 &PngOptimizerCL.exe -file:"$path\*.png -recurs" #| Out-Null
		 }
   }
}
}

# Convert RawGit and non-CDN URLs to Staticaly (and maybe others in the future)
function Update-CDNURL([string]$oldURL){
if ($oldURL -match 'https://raw.githubusercontent.com'){$StaticalyURL=($oldURL -replace 'https://raw.githubusercontent.com','https://cdn.staticaly.com/gh')}
if ($oldURL -match 'https://cdn.rawgit.com'){$StaticalyURL=($oldURL -replace 'https://cdn.rawgit.com','https://cdn.staticaly.com/gh')}
$global:UpdateNuspec=$True
return $StaticalyURL
}

# Update the nuspec XML comment with encoding test
function Update-XMLComment{
Write-Host "           ** -UpdateXMLComment still under construction." -Foreground Red
#Write-Host "           ** XML UTF-8 encoding test comment added." -Foreground Green
#$nuspecFile.'#comment' = "Do not remove this test for UTF-8: if `“Ω`” doesn`’t appear as greek uppercase omega letter enclosed in quotation marks, you should use an editor that supports UTF-8, not this one."
#$global:UpdateNuspec=$True
}

# Update the nuspec XML declaration with encoding info
function Update-XMLDeclaration{
Write-Host "           ** XML declaration changed to version=""1.0"" encoding=""utf-8""" -Foreground Green
$nuspecFile.xml="version=""1.0"" encoding=""utf-8"""
$global:UpdateNuspec=$True
}

# Update the nuspec with any changes and save as UTF-8 w/o BOM
# Thanks https://stackoverflow.com/questions/8160613/powershell-saving-xml-and-preserving-format
Function Update-nuspec{
if ($global:UpdateNuspec){
   $UpdatednuspecFile = [xml]([System.IO.File]::ReadAllText($LocalnuspecFile))
   $UpdatednuspecFile.PreserveWhitespace = $true
   $settings = New-Object System.Xml.XmlWriterSettings
   $settings.Indent = $true
   $settings.NewLineChars ="`r`n"
   $settings.Encoding = New-Object System.Text.UTF8Encoding($false)   

   # changes
#   if ($nuspecFile.'#comment'){$UpdatednuspecFile.'#comment' = $nuspecFile.'#comment'} # throws error
   if ($nuspecFile.xml){$UpdatednuspecFile.xml = $nuspecFile.xml}
   if ($NuspecDescription){$UpdatednuspecFile.package.metadata.description=[string]$NuspecDescription}
   if ($NuspecIconURL){$UpdatednuspecFile.package.metadata.iconurl=$NuspecIconURL}

   Copy-Item "$LocalnuspecFile" "$LocalnuspecFile.CNC.bak" -Force # make a backup

   $xfile = [System.Xml.XmlWriter]::Create($LocalnuspecFile, $settings)
   try{
     $UpdatednuspecFile.Save($xfile)
    } finally {
     $xfile.Dispose()
    }
   Write-Host "CNC updated $LocalnuspecFile." -Foreground Magenta
  }
}

# Start outputting check results
Write-Host "CNC Summary of $NuspecDisplayName :" -Foreground Magenta

# Open all .nuspec URLs for viewing if -OpenURLs is passed
if ($OpenURLs) {
    Write-Host "           ** Opening all .nuspec URLs in your default browser for viewing." -Foreground Magenta
	Open-URLs
	}
	
# checks ------------------------------------------------------------------------------------------------

# check for UTF8 encoding
# UTF-8 w/BOM is not desired per "You must save your files with UTF–8 character encoding without BOM."
$NuspecEncoding=(Get-FileEncoding -Path $LocalnuspecFile)
if ($NuspecEncoding -ne 'ASCII or UTF-8 w/o BOM'){
    Write-Warning "  ** $NuspecDisplayName is encoded using $NuspecEncoding."
	if ($global:UpdateNuspec) {
	     Write-Host "           ** $NuspecDisplayName will be converted to UTF-8 w/o BOM and saved." -Foreground Green
		 } else {
		   Write-Host "           ** You must save your files with UTF–8 character encoding without BOM." -Foreground Cyan
		   Write-Host "           ** Consider running CNC -Update to re-write`n              $LocalnuspecFile to UTF-8 w/o BOM." -Foreground Cyan
	}
}

# check XML declaration
if ($nuspecFile.xml -eq "version=""1.0"""){
    Write-Warning "  ** XML declaration is version=""1.0"""
	if ($UpdateXMLDeclaration){
	    Update-XMLDeclaration
	} else {
      Write-Host "           ** Consider running CNC -UpdateXMLDeclaration to add a UTF-8 encoding statement." -Foreground Cyan
	}
}

# check XML comment
if (!$nuspecFile.'#comment'){
#$PSDefaultParameterValues['*:Encoding'] = 'utf8'
    Write-Warning "  ** The recommended UTF-8 encoding check comment was not found."
	if ($UpdateXMLComment){
	    Update-XMLComment
	} else {
      Write-Host "           ** Consider running CNC -UpdateXMLComment to add a UTF-8 encoding check comment." -Foreground Cyan
   }
}

# <authors> checks
if (!($NuspecAuthors)) {
    Write-Host "           ** <authors> element is empty, this element is a requirement." -Foreground Red
   } else {
     if ($NuspecAuthors -match "@"){
	     Write-Warning "  ** <authors> - contains an e-mail address. This will trigger a message from the verifier:"
	     Write-Host '           ** Requirements: Email address should not be used in the Author and Copyright fields of the nuspec file. ' -Foreground Cyan
	 }
   }

# <bugTrackerUrl> checks
if (!($NuspecBugTrackerURL)) {
     Write-Warning "  ** <bugTrackerUrl> - element is empty. This will trigger a message from the verifier:"
	Write-Host '           ** Suggestion: bugTrackerUrl - points to the location where issues and tickets can be accessed' -Foreground Cyan
   } else {
     Validate-URL "<bugTrackerUrl>" $NuspecBugTrackerURL
	}

# <conflicts> checks - Built for the future
#if (!($NuspecConflicts)) {Write-Warning "  ** <conflicts> element is empty."}

# <copyright> checks
if (!($NuspecCopyright)) {
    Write-Warning "  ** <copyright> - element is empty."
	} else {
	  if ($NuspecCopyright.Length -lt 5) {
	      Write-Warning "  ** <copyright> - Please update the copyright field so that it is using at least 4 characters."
		  }
	  if ($NuspecAuthors -match "@"){
	      Write-Warning "  ** <copyright> - contains an e-mail address. This will trigger a message from the verifier:"
	      Write-Host '           ** Requirements: Email address should not be used in the Author and Copyright fields of the nuspec file. ' -Foreground Cyan
	 }
	}

# <dependencies> checks
if (!($NuspecDependencies)) {
    Write-Warning "  ** <dependencies> - element is empty."
   } else {
     if ((!$NuspecDependencies) -and ($NuspecTitle -match "deprecated")){Write-Warning "  ** <dependencies> - Deprecated packages must have a dependency."}
	 if ($NuspecDependencies.dependency.id -eq 'chocolatey'){
	     Write-Warning "  ** <dependencies> - ""chocolatey"" is a dependency. This will trigger a message from the verifier:"
	     Write-Host "           ** Note: The package takes a dependency on Chocolatey. The reviewer will ensure the package uses a specific`n              Chocolatey feature that requires a minimum version." -Foreground Cyan
		 }
	 $DependencyName=$NuspecDependencies.dependency.id
	 if ($NuspecDependencies.dependency.id.count -eq 1){
    	 if ($NuspecDependencies.dependency.version -eq $null){
	          Write-Warning "  ** <dependencies> - $DependencyName has no version. This will trigger a message from the verifier:"
      	      Write-Host "           ** Guideline: Package contains dependencies with no specified version. You should at least specify`n              a minimum version of a dependency." -Foreground Cyan
	         }
	 } else {
	   $DependencyNumber=0
	 do{
	    $DependencyName=$NuspecDependencies.dependency.id[$DependencyNumber]
 	    if ($NuspecDependencies.dependency[$DependencyNumber].version -eq $null){
				Write-Warning "  ** <dependencies> - ""$DependencyName"" has no version. This will trigger a message from the verifier:"
			    Write-Host "           ** Guideline: Package contains dependencies with no specified version. You should at least specify`n              a minimum version of a dependency." -Foreground Cyan
			}
	   $DependencyNumber++
       } while ($DependencyNumber -lt $NuspecDependencies.dependency.id.count)
	 }
	 }

# <description> checks
if (!($NuspecDescription)) {
    Write-Host "           ** <description> - element is empty, this element is a requirement." -Foreground Red
   } else {
     Check-Header
     Check-Footer
     if ($NuspecDescription.Length -lt 30) {Write-Warning "  ** <description> - is less than 30 characters."}
     if ($NuspecDescription.Length -gt 4000) {Write-Warning "  ** <description> - is greater than 4,000 characters."}
	 if ($NuspecDescription -match "raw.githubusercontent"){
		 if ($UpdateImageURLs){
             Write-Warning "  ** <description> - includes a GitHub direct link."
			 Write-Host "           ** <description> - URL(s) updated to use Staticly CDN." -Foreground Green
             $NuspecDescription=(Update-CDNURL "$NuspecDescription")
		 } else {
		   Write-Warning "  ** <description> - includes a GitHub direct link. Please change to a CDN such as:"
           Write-Host "           ** $CDNlist" -Foreground Cyan
		   Write-Host "           ** Consider running CNC -UpdateImageURLs to update it." -Foreground Cyan		   
          }
	   }
     if ($NuspecDescription -match "cdn.rawgit.com"){
		 if ($UpdateImageURLs){
             Write-Warning "  ** <description> - includes a RawGit CDN link."
			 Write-Host "           ** <description> - URL(s) updated to use Staticly CDN." -Foreground Green
             $NuspecDescription=(Update-CDNURL "$NuspecDescription")
		 } else {
		   Write-Warning "  ** <description> - RawGit CDN will be going offline October 2019. Please change to a CDN such as:"
           Write-Host "           ** $CDNlist" -Foreground Cyan
		   Write-Host "           ** Consider running CNC -UpdateImageURLs to update it." -Foreground Cyan
		 }
       }
# below checking doesn't work as PowerShell will already give an error readying the nuspec
# Cannot convert value "System.Object[]" to type "System.Xml.XmlDocument". Error: "An error occurred while parsing
# EntityName.
	 if ($NuspecDescription -match ' `& '){
	     Write-Warning "  ** <description> - `& found and needs to be replaced with `&amp;"
		 Write-Host "           ** Packing will error: ""An error occurred while parsing EntityName.""" -Foreground Red
		 if ($UpdateAll){
             $NuspecDescription=$NuspecDescription -replace "`&","`&amp;"
             Write-Host "           ** <description> - `& replaced with `&amp;" -Foreground Green
		    } else {
			  Write-Host "           ** Consider running CNC -UpdateAll to update it." -Foreground Cyan
			 }
       }
	}
	
# add header template to <description> if -AddHeader is passed to script
if ($AddHeader) {
$NuspecDescription=(Add-Header)
}

# add footer template to <description> if -AddFooter is passed to script
if ($AddFooter) {
$NuspecDescription=(Add-Footer)
}
	
# <docsUrl> checks
if (!($NuspecDocsURL)) {
    Write-Warning "  ** <docsUrl> - element is empty. This will trigger a message from the verifier:"
	Write-Host '           ** Suggestion: docsUrl - points to the location of the wiki or docs of the software' -Foreground Cyan
   } else {
     Validate-URL "<docsUrl>" $NuspecDocsURL
	}

# <files> checks
if (!($NuspecFiles)) {
    Write-Warning "  ** <files> - element is empty. All of the following files will be packaged:"
    Get-ChildItem -Path $path -Recurse -Exclude *.nupkg,tools |% $_.file {Write-Host "           ** $_" -Foreground Cyan -ea SilentlyContinue}
	}

# <iconUrl> checks
if (!($NuspecIconURL)) {
    Write-Warning "  ** <iconUrl> - element is empty. This will trigger a message from the verifier:"
	Write-Host '           ** Guideline: The iconUrl should be added if there is one. Please correct this in the nuspec, if applicable.' -Foreground Cyan
   } else {
     Validate-URL "<iconUrl>" $NuspecIconURL
	 if ($global:ValidURL){
	     Get-ImageDimensions
	    }
	 $IconExt=($NuspecIconURL | Select-String -Pattern $AcceptableIconExts)
     if (!($IconExt)){
	     Write-Warning "  ** <iconUrl> - Your package icon is NOT a .PNG or .SVG. This will trigger a message from the verifier:"
	Write-Host '           ** Suggestion: As per the packaging guidelines icons should be either a png or svg file.' -Foreground Cyan
       }
	 if ($NuspecIconURL -match "raw.githubusercontent"){
         if ($UpdateImageURLs) {
		    $NuspecIconURL=(Update-CDNURL "$NuspecIconURL")
			Write-Warning "  ** <iconUrl> - Your package icon links directly to GitHub."
			Write-Host "           ** <iconUrl> - URL updated to: `n              $NuspecIconURL" -Foreground Green
		   } else {
		     Write-Warning "  ** <iconUrl> - Your package icon links directly to GitHub. Please use a CDN such as:"
             Write-Host "           ** $CDNlist" -Foreground Cyan		   
		     Write-Host "           ** Consider running CNC -UpdateImageURLs to update it." -Foreground Cyan
		   }
		}
     if ($NuspecIconURL -match "cdn.rawgit.com"){
         if ($UpdateImageURLs) {
		    $NuspecIconURL=(Update-CDNURL "$NuspecIconURL")
			Write-Warning "  ** <iconUrl> - Your package icon links RawGit which will be going offline October 2019."
			Write-Host "           ** <iconUrl> - URL updated to: `n              $NuspecIconURL" -Foreground Green
		   } else {
		     Write-Warning "  ** <iconUrl> - RawGit CDN will be going offline October 2019. Please change to a CDN such as:"
             Write-Host "           ** $CDNlist" -Foreground Cyan
		     Write-Host "           ** Consider running CNC -UpdateImageURLs to update it." -Foreground Cyan
		   }
       }
   }

# <id> checks
if (!($NuspecID)) {
    Write-Host "           ** <id> - element is empty, this element is a requirement." -Foreground Red
	} else {
     if (($NuspecID.Length -gt 20) -and (!$NuspecID.Contains("-")) -and (!$NuspecID.Contains("."))) {
	     Write-Warning "  ** <id> - is greater than 20 characters. This will trigger a message from the verifier:"
	     Write-Host "           ** Note: If this is a new package that has never been approved, moderators will review and reject the`n              package for one that will be pushed with a new id that meets the package naming guidelines." -Foreground Cyan
	    }
	 if ($NuspecID -cmatch "[A-Z]") {Write-Warning "  ** <id> - includes UPPERcase letters." }
	 if (($NuspecID.Contains(".")) -and (!$NuspecID.Contains(".install")) -and (!$NuspecID.Contains(".portable")) -and (!$NuspecID.Contains(".extension"))) {
	      Write-Warning "  ** <id> - includes a '.'. This will trigger a message from the verifier:"
		  Write-Host "           ** Note: If this is a new package that has never been approved, moderators will review and reject the package`n              for one that will be pushed with a new id that meets the package naming guidelines."  -Foreground Cyan
		 }
	 }

# <licenseUrl> checks
if (!($NuspecLicenseURL)) {
    Write-Warning "  ** <licenseUrl> - element is empty. This will trigger a message from the verifier:"
	Write-Host "           ** Guideline: The licenseUrl should be added if there is one. Please correct this in the nuspec,`n              if applicable." -Foreground Cyan
   } else {
     Validate-URL "<licenseUrl>" $NuspecLicenseURL
	}	

# <mailingListUrl> checks
if (!($NuspecMailingListURL)) {
    Write-Warning "  ** <mailingListUrl> - element is empty. This will trigger a message from the verifier:"
	Write-Host '           ** Suggestion: mailingListUrl - points to the forum or email list group for the software' -Foreground Cyan
   } else {
     Validate-URL "<mailingListUrl>" $NuspecMailingListURL
	}
	
# <owners> checks
if (!($NuspecOwners)) {
    Write-Warning "  ** <owners> element is empty."
   } else {
     if ($NuspecAuthors -eq $NuspecOwners){
        Write-Warning "  ** <owners> and <authors> elements are the same. This will trigger a message from the verifier:"
        Write-Host "           ** Note: The package maintainer field (owners) matches the software author field (authors) in the nuspec.`n              The reviewer will ensure that the package maintainer is also the software author." -Foreground Cyan
		}
   }

# <packageSourceUrl> checks
if (!($NuspecPackageSourceURL)) {
    Write-Warning "  ** <packageSourceUrl> - element is empty. This will trigger a message from the verifier:"
	Write-Host "           ** Guideline: The nuspec has been enhanced to allow packageSourceUrl, pointing to the url where the package`n              source resides. This is a strong guideline because it simplifies collaboration.`n              Please add it to the nuspec." -Foreground Cyan
   } else {
     Validate-URL "<packageSourceUrl>" $NuspecPackageSourceURL
	}		

# <projectSourceUrl> checks
if (!($NuspecProjectSourceURL)) {
    Write-Warning "  ** <projectSourceUrl> - element is empty. This will trigger a message from the verifier:"
	Write-Host '           ** Suggestion: projectSourceUrl - points to the location of the underlying software source' -Foreground Cyan
   } else {
     Validate-URL "<projectSourceUrl>" $NuspecProjectSourceURL
	 if ($NuspecProjectURL -eq $NuspecProjectSourceURL){
         Write-Warning "  ** <projectUrl> and <projectSourceUrl> elements are the same. This will trigger a message from the verifier:"
         Write-Host "           ** Guideline: ProjectUrl and ProjectSourceUrl are typically different, but not always. Please ensure`n              that projectSourceUrl is pointing to software source code or remove the field from the nuspec." -Foreground Cyan
       }
	}
	
# <projectUrl> checks
if (!($NuspecProjectURL)) {
    Write-Warning "  ** <projectUrl> - element is empty."
   } else {
     Validate-URL "<projectUrl>" $NuspecProjectURL
	}	

# <provides> checks - Built for the future
#if (!($NuspecProvides)) {Write-Warning "  ** <provides> element is empty"}

# <releaseNotes> checks
if (!($NuspecReleaseNotes)) {
    Write-Warning "  ** <releaseNotes> - element is empty. This will trigger a message from the verifier:"
	Write-Host "           ** Guideline: Release Notes (releaseNotes) are a short description of changes in each version of a package.`n              Please include releasenotes in the nuspec. NOTE: To prevent the need to continually update this field,`n              providing a URL to an external list of Release Notes is perfectly acceptable." -Foreground Cyan
   }

# <replaces> checks - Built for the future
#if (!($NuspecReplaces)) {Write-Warning "  ** <replaces> element is empty."}

# <requireLicenseAcceptance> checks
if (!($NuspecRequireLicenseAcceptance)) {
    Write-Warning "  ** <requireLicenseAcceptance> - element is empty."
	} else {
	  if (($NuspecRequireLicenseAcceptance -eq "true") -and (!($NuspecLicenseURL))) {
	      Write-Warning "  ** <requireLicenseAcceptance> is set to true but <licenseUrl> is empty."
		  }
	  }

# <summary> checks
if (!($NuspecSummary)) {
    Write-Warning "  ** <summary> - element is empty. This will trigger a message from the verifier:"
    Write-Host '           ** Guideline: Summary (summary) is a short explanation of the software. Please include summary in the nuspec.' -Foreground Cyan
	}

# <tags> checks
if (!($NuspecTags)) {
     Write-Warning "  ** <tags> - element is empty."
	} else {
	  if ($NuspecTags -match ","){
         Write-Warning "  ** <tags> - tags are separated with commas. They should only be separated with spaces."
		}
	  if ($NuspecTags -match "chocolatey"){
         Write-Warning "  ** Note: There is a tag named ""chocolatey"" which will trigger a message from the verifier:"
         Write-Host '           ** Tags (tags) should not contain 'chocolatey' as a tag. Please remove that in the nuspec.' -Foreground Cyan
		}
	  if ($NuspecTags -match "notsilent"){
         Write-Warning "  ** Note: There is a tag named ""notsilent"" which will trigger a message from the verifier:"
         Write-Host '           ** Note: notSilent tag is being used. The reviewer will ensure this is being used appropriately. ' -Foreground Cyan
		}		
    }

# <title> checks
if (!($NuspecTitle)) {Write-Warning "  ** <title> - element is empty."}

# <version> checks
if (!($NuspecVersion)) {Write-Host "           ** <version> - element is empty, this element is a requirement." -Foreground Red}

# cocolateyInstall.ps1 and chocolateyUninstall.ps1 script checks
# out of scope, but nice to have
# will probably convert this to a function
    $ScriptFile="$path\tools\chocolateyInstall.ps1"
    if (Test-Path $ScriptFile) {
	    $CheckEAP=Get-Content $ScriptFile -First 2
		if ($checkEAP -match '\$ErrorActionPreference') {
		    #do nothing
			} else {
			  Write-Warning "  ** CHOCOLATEYINSTALL.PS1 is missing the recommended ErrorActionPreference statement."
			  Write-Host "           ** Consider adding ""`$ErrorActionPreference = 'Stop'"" to it." -Foreground Cyan
			 }
	    $ScriptError=Test-PowerShellSyntax (Get-Item "$path\tools\chocolateyinstall.ps1")
		if ($ScriptError.SyntaxErrorsFound){
		     Write-Warning "  ** PowerShell syntax errors found in $path\tools\chocolateyinstall.ps1"
			 }
	    $PS1Encoding=(Get-FileEncoding -Path $path\tools\chocolateyinstall.ps1)
		if ($PS1Encoding -ne 'UTF-8 w/ BOM'){
            Write-Warning "  ** CHOCOLATEYINSTALL.PS1 is encoded using $PS1Encoding."
			Write-Host '           ** PowerShell scripts need to be saved in UTF–8 with BOM.' -Foreground Cyan
		}
    }
	
    $ScriptError=$False
	$ScriptFile="$path\tools\chocolateyUninstall.ps1"
    if (Test-Path $ScriptFile) {
	    $CheckEAP=Get-Content $ScriptFile -First 2
		if ($checkEAP -match '\$ErrorActionPreference') {
		    #do nothing
			} else {
			  Write-Warning "  ** CHOCOLATEYUNINSTALL.PS1 is missing the recommended ErrorActionPreference statement."
			  Write-Host "           ** Consider adding ""`$ErrorActionPreference = 'Stop'"" to it." -Foreground Cyan
			 }
	    $ScriptError=Test-PowerShellSyntax (Get-Item "$path\tools\chocolateyUninstall.ps1")
        if ($ScriptError.SyntaxErrorsFound){
	        Write-Warning "  ** PowerShell syntax errors found in $path\tools\chocolateyUninstall.ps1"
		    }
		$PS1Encoding=(Get-FileEncoding -Path $path\tools\chocolateyuninstall.ps1)
		if ($PS1Encoding -ne 'UTF-8 w/ BOM'){
            Write-Warning "  ** CHOCOLATEYUNINSTALL.PS1 is encoded using $PS1Encoding."
			Write-Host '           ** PowerShell scripts need to be saved in UTF–8 with BOM.' -Foreground Cyan
		}
		}

# Binaries checks
Check-Binaries

#PNG checks
Check-PNGs

# Git 'er done ------------------------------------------------------------------------------------------------

# Optimize any PNG files
Run-PNGOptimizer

if ($global:UpdateNuspec) {
   if ($WhatIf){
        Write-Host "CNC did NOT update $LocalnuspecFile, -WhatIf parameter was used." -Foreground Magenta
   } else {
	Update-nuspec
	}
}

Write-Host "`nFound CNC.ps1 useful?" -Foreground White
Write-Host "Buy me a beer at https://www.paypal.me/bcurran3donations" -Foreground White
Write-Host "Become a patron at https://www.patreon.com/bcurran3" -Foreground White
return

# TDL
# inject UTF-8 test comment -started (checks done)
# implement multiple CDN choices for iconURL (default Staticly, but -option for others)
# implement syntax and BOM checking on OTHER .ps1 files
# check for &'s in links to change to &amp;
# check for header/footer before adding header/footer
# check for "Nuspec file contains templated values which should be removed."
# option of displaying useful tips and tweaks (AutoHotKey, BeCyIconGrabber, PngOptimizer, Regshot, service viewer program, Sumo, etc)
# MAYBE redo file selection by filename instead of directory and implement a -Recurse option - medium low priority
# MAYBE do full params statement and get rid of args checking - low priority
# MAYBE implement a warning and hard error count to report as well as # of changes- medium low priority
# MAYBE check http links to see if https links are available and report if so - low priority
# MAYBE change install script ACL handling to use icacls
# MAYBE add delete old .nupkg options (all but current) -DeleteOld ? -CleanUp ?
# MAYBE check license/verifiction/readme files for UTF-8 w/o BOM (worthwhile?)
# What else?
tools\CNCFooter.txt
___
___
tools\CNCHeader.txt
___
___

Log in or click on link to see number of positives.

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.

Add to Builder Version Downloads Last Updated Status
(unofficial) Chocolatey .nuspec Checker (CNC) (Script) 2024.1.14-pre 59 Sunday, January 14, 2024 Exempted
(unofficial) Chocolatey .nuspec Checker (Script) 2023.9.10 227 Sunday, September 10, 2023 Exempted
(unofficial) Chocolatey .nuspec Checker (Script) 2023.05.17 180 Wednesday, May 17, 2023 Exempted
(unofficial) Chocolatey .nuspec Checker (Script) 2023.05.15 82 Wednesday, May 17, 2023 Exempted
(unofficial) Chocolatey .nuspec Checker (Script) 2020.09.21 702 Monday, September 21, 2020 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2020.09.20 175 Sunday, September 20, 2020 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2020.09.15 180 Wednesday, September 16, 2020 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2020.04.06.0001 448 Monday, April 6, 2020 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2020.04.06 182 Monday, April 6, 2020 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2020.01.16 319 Thursday, January 16, 2020 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.12.14 223 Saturday, December 14, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.09.01 343 Monday, September 2, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.08.26 272 Tuesday, August 27, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.03.04 342 Monday, March 4, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.02.22 269 Sunday, March 3, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.02.18 269 Tuesday, February 19, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.02.16 238 Sunday, February 17, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.02.04 256 Tuesday, February 5, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.01.29 254 Wednesday, January 30, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.01.26 220 Sunday, January 27, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.01.22 275 Wednesday, January 23, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.01.15 287 Wednesday, January 16, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.01.13 265 Monday, January 14, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.01.12 274 Saturday, January 12, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.01.09 248 Thursday, January 10, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.01.07 244 Tuesday, January 8, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.01.04 228 Saturday, January 5, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2019.01.03 262 Friday, January 4, 2019 Approved
(unofficial) Chocolatey .nuspec Checker (Script) 2018.12.22 279 Friday, December 28, 2018 Approved

CHANGELOG:

  • 2019.01.29 - you can now use the following tokens in your header and footer files: $NuspecAuthors, $NuspecID, $NuspecOwners, $NuspecTitle, and $NuspecVersion - they will be parsed and replaced with the values from your nuspec file, added checking iconUrl image dimensions, new -OptimizePNGs option to run PNGOptimizerCL (if installed via Chocolatey) on PNG files in nuspec dir, added checking for lack of BOM in install/uninstall scripts, added checking for $ErrorActionPreference statement in install/uninstall scripts, now aborts when there are multiple nuspec files found in the same directory, now aborts if nuspec appears corrupt, cosmetic enhancements, now makes a backup file upon updates.
  • 2019.01.26 - CNC is now considered "Ready for Prime Time." (I still have more updates planned.) CNC can now write changes to your nuspec file including the iconUrl, description, and XML declaration (Finally!!!), added ability to update the XML declaration, added -UpdateAll and -Update options, updates are written as UTF-8 w/o BOM, cleaned up UTF-8 reporting, added PowerShell syntax error checking of chocolateyInstall.ps1 and chocolateyUninstall.ps1, new -WhatIf option for testing without saving changes, the normal minor tweaks and cosmetic changes. I will keep making it better though, of course.
  • 2019.01.22 - added XML declaration and UTF-8 comment checking, better dependency version checking, a rare verifier message I missed
  • 2019.01.15 - you can now specify a path to a directory containing a .nuspec file to check, misc minor tweaks
  • 2019.01.13 - finished the dependencies checking, all verifier messages (guidelines, suggestions, and notes) now reporting in CNC
  • 2019.01.12 - minor fixes
  • 2019.01.09 - many more checks and warnings added, almost all known verifier guidelines, suggestions and notes added, some beautifications, added option to view Chocolatey validator info page, added optional image GitHub direct and RawGit URL conversions to Staticaly CDN URLs
  • 2019.01.07 - added help, added option to open and view all URLs in your default browser, added options to view, edit, and add "standard" (template) headers and footers to the description (can't save yet), added reporting of standard header and footer if found, added more verifier messages, added checking for descriptions that are too large (>4,000), now checks for license files other than LICENSE.txt, probably more I don't remember :)
  • 2019.01.04 - implemented included binary files checking and messages, laid out the groundwork for the future enhancements
  • 2019.01.03 - fixed some URL checking handling that could cause PS errors, updated list of CDN recommendations, added checking for RawGit URLs in description, cosmetic updates
  • 2018.12.22-2018-12.28 - initial release

This package has no dependencies.

Discussion for the (unofficial) Chocolatey .nuspec Checker (Script) Package

Ground Rules:

  • This discussion is only about (unofficial) Chocolatey .nuspec Checker (Script) and the (unofficial) Chocolatey .nuspec Checker (Script) 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 (unofficial) Chocolatey .nuspec Checker (Script), 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