PSChocolateyGet.psm1
function New-ChocolateyGetPackage { <# .SYNOPSIS Creates a new chocolatey package based on a configuration file #> [CmdletBinding( PositionalBinding )] param ( # Path to a configuration file [Parameter( Mandatory )] [ValidateScript( { if ( -not ( Test-Path $_ )) { throw "Unable to validate path: $_" } return $true })] [string] $ConfigurationFile, # Path to a directory where the package will be built. # By defaul tthi swill be the current working directory # If the directory doesn't exist, it will be created. [string] $OutputDirectory = $PWD ) $ErrorActionPreference = "Stop" if ( -not ( Test-Path $OutputDirectory )) { Write-Debug "Creating local directory at path: $OutputDirectory..." New-Item -Path $OutputDirectory -ItemType Directory -Force | Out-Null } # TODO - validate schema $PackageConfig = [PSCustomObject]( Get-Content $ConfigurationFile | ConvertFrom-Yaml ) $PackageDirName = $PackageConfig.AppMoniker + "." + $PackageConfig.Version $PackageOutputDir = Join-Path $OutputDirectory $PackageDirName $PackageToolsDir = Join-Path $PackageOutputDir "tools" if ( -not ( Test-Path $PackageOutputDir )) { Write-Debug "Creating local directory at path: $PackageOutputDir..." New-Item -Path $PackageOutputDir -ItemType Directory -Force | Out-Null } if ( -not ( Test-Path $PackageToolsDir )) { Write-Debug "Creating local directory at path: $PackageToolsDir..." New-Item -Path $PackageToolsDir -ItemType Directory -Force | Out-Null } $PackageNuspecFileName = $PackageConfig.AppMoniker + ".nuspec" $PackageNuspecPath = Join-Path $PackageOutputDir $PackageNuspecFileName $PackageSummary = $PackageConfig.Description -split "`n" | Select-Object -First 1 $PackageNuspecConfig = @" <?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd"> <metadata> <id>$($PackageConfig.AppMoniker)</id> <version>$($PackageConfig.Version)</version> <owners>$($PackageConfig.Publisher)</owners> <title>$($PackageConfig.Name)(Install)</title> <authors>$($PackageConfig.Author)</authors> <projectUrl>$($PackageConfig.Homepage)</projectUrl> <copyright>$( Get-Date -Format yyyy ) $($PackageConfig.Author)</copyright> <licenseUrl>$($PackageConfig.LicenseUrl)</licenseUrl> <tags>$($PackageConfig.Tags -replace ",")</tags> <summary>$PackageSummary</summary> <description> $(($PackageConfig.Description).Trim()) </description> <dependencies> <dependency id="chocolatey-core.extension" version="1.1.0" /> </dependencies> </metadata> <files> <file src="tools\**" target="tools" /> </files> </package> "@ $NuspecOutdated = $true if ( Test-Path $PackageNuspecPath ) { $PackageNuspecContent = Get-Content $PackageNuspecPath $NuspecOutdated = [bool]( Compare-Object $PackageNuspecContent $PackageNuspecConfig ) } # Update nuspec file if it isn't what it should be if ( $NuspecOutdated ) { ( [xml]$PackageNuspecConfig ).Save( $PackageNuspecPath ) } $ChocolateyInstallScriptPath = Join-Path $PackageOutputDir "tools\chocolateyinstall.ps1" $ChocolateyUninstallScriptPath = Join-Path $PackageOutputDir "tools\chocolateyuninstall.ps1" $ChocolateyBeforeModifyScriptPath = Join-Path $PackageOutputDir "tools\chocolateybeforemodify.ps1" $ChocolateyInstallScriptContent = @() $ChocolateyUninstallScriptContent = @() $ChocolateyBeforeModifyScriptContent = @() # If the installer type is zip, add script to install zip file if ( $PackageConfig.InstallerType -eq 'zip' ) { $InstallDirectory = '$env:ProgramFiles\' + $PackageConfig.Name foreach ( $Installer in $PackageConfig.Installers ) { $Arch = switch ( $Installer.Arch ) { "x64" { @{ Url = "url64"; Checksum = "checksum64"; ChecksumType = "checksumtype64" } } "x86" { @{ Url = "url"; Checksum = "checksum"; ChecksumType = "checksumtype" } } } # Add installation code $ChocoZipInstallCode = @" `$ErrorActionPreference = 'Stop' `$toolsDir = "`$(Split-Path -parent `$MyInvocation.MyCommand.Definition)" `$packageArgs = @{ packageName = `$env:ChocolateyPackageName unzipLocation = "$InstallDirectory" fileType = 'EXE_MSI_OR_MSU' #only one of these: exe, msi, msu $($Arch.Url) = '$($Installer.Url)' $($Arch.Checksum) = '$($Installer.Sha256)' $($Arch.ChecksumType) = 'sha256' } Install-ChocolateyZipPackage @packageArgs # Add bins to path Get-ChildItem "$InstallDirectory\*.exe" | ForEach-Object { Install-BinFile -name `$_.BaseName -path `$_.FullName } "@ $ChocolateyInstallScriptContent += $ChocoZipInstallCode # Add before modify code $ChocoZipBeforeModifyCode = @" Get-ChildItem "$InstallDirectory\*.exe" | ForEach-Object { Uninstall-BinFile -name `$_.BaseName -path `$_.FullName } "@ $ChocolateyBeforeModifyScriptContent += $ChocoZipBeforeModifyCode # Add uninstall code $ZipFileName = Split-Path $Installer.Url -Leaf $ChocoZipUninstallCode = @" Uninstall-ChocolateyZipPackage -packageName `$env:ChocolateyPackageName -zipFileName '$ZipFileName' "@ $ChocolateyUninstallScriptContent += $ChocoZipUninstallCode } } # Write the chocolatey install scripts if ( $ChocolateyInstallScriptContent ) { $NeedsUpdate = $true $ScriptContent = $ChocolateyInstallScriptContent -join "`r`n" if ( Test-Path $ChocolateyInstallScriptPath ) { $ExistingScriptContent = Get-Content $ChocolateyInstallScriptPath $NeedsUpdate = [bool]( Compare-Object $ExistingScriptContent $ScriptContent ) } if ( $NeedsUpdate ) { Set-Content -Path $ChocolateyInstallScriptPath -Value $ScriptContent -Force -Encoding utf8 } } # Write the chocolatey uninstall scripts if ( $ChocolateyUninstallScriptContent ) { $NeedsUpdate = $true $ScriptContent = $ChocolateyUninstallScriptContent -join "`r`n" if ( Test-Path $ChocolateyUninstallScriptPath ) { $ExistingScriptContent = Get-Content $ChocolateyUninstallScriptPath $NeedsUpdate = [bool]( Compare-Object $ExistingScriptContent $ScriptContent ) } if ( $NeedsUpdate ) { Set-Content -Path $ChocolateyUninstallScriptPath -Value $ScriptContent -Force -Encoding utf8 } } # Write the chocolatey before modify script if ( $ChocolateyBeforeModifyScriptContent ) { $NeedsUpdate = $true $ScriptContent = $ChocolateyBeforeModifyScriptContent -join "`r`n" if ( Test-Path $ChocolateyBeforeModifyScriptPath ) { $ExistingScriptContent = Get-Content $ChocolateyBeforeModifyScriptPath $NeedsUpdate = [bool]( Compare-Object $ExistingScriptContent $ScriptContent ) } if ( $NeedsUpdate ) { Set-Content -Path $ChocolateyBeforeModifyScriptPath -Value $ScriptContent -Force -Encoding utf8 } } # Todo - msi installer # Todo - exe installer # Todo - appx installer # Todo - msix installer } function New-ChocolateyGetPackage { <# .SYNOPSIS Creates a new chocolatey package based on a configuration file #> [CmdletBinding( PositionalBinding )] param ( # Path to a configuration file [Parameter( Mandatory )] [ValidateScript( { if ( -not ( Test-Path $_ )) { throw "Unable to validate path: $_" } return $true })] [string] $ConfigurationFile, # Path to a directory where the package will be built. # By defaul tthi swill be the current working directory # If the directory doesn't exist, it will be created. [string] $OutputDirectory = $PWD ) $ErrorActionPreference = "Stop" if ( -not ( Test-Path $OutputDirectory )) { Write-Debug "Creating local directory at path: $OutputDirectory..." New-Item -Path $OutputDirectory -ItemType Directory -Force | Out-Null } # TODO - validate schema $PackageConfig = [PSCustomObject]( Get-Content $ConfigurationFile | ConvertFrom-Yaml ) $PackageDirName = $PackageConfig.AppMoniker + "." + $PackageConfig.Version $PackageOutputDir = Join-Path $OutputDirectory $PackageDirName $PackageToolsDir = Join-Path $PackageOutputDir "tools" if ( -not ( Test-Path $PackageOutputDir )) { Write-Debug "Creating local directory at path: $PackageOutputDir..." New-Item -Path $PackageOutputDir -ItemType Directory -Force | Out-Null } if ( -not ( Test-Path $PackageToolsDir )) { Write-Debug "Creating local directory at path: $PackageToolsDir..." New-Item -Path $PackageToolsDir -ItemType Directory -Force | Out-Null } $PackageNuspecFileName = $PackageConfig.AppMoniker + ".nuspec" $PackageNuspecPath = Join-Path $PackageOutputDir $PackageNuspecFileName $PackageSummary = $PackageConfig.Description -split "`n" | Select-Object -First 1 $PackageNuspecConfig = @" <?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd"> <metadata> <id>$($PackageConfig.AppMoniker)</id> <version>$($PackageConfig.Version)</version> <owners>$($PackageConfig.Publisher)</owners> <title>$($PackageConfig.Name)(Install)</title> <authors>$($PackageConfig.Author)</authors> <projectUrl>$($PackageConfig.Homepage)</projectUrl> <copyright>$( Get-Date -Format yyyy ) $($PackageConfig.Author)</copyright> <licenseUrl>$($PackageConfig.LicenseUrl)</licenseUrl> <tags>$($PackageConfig.Tags -replace ",")</tags> <summary>$PackageSummary</summary> <description> $(($PackageConfig.Description).Trim()) </description> <dependencies> <dependency id="chocolatey-core.extension" version="1.1.0" /> </dependencies> </metadata> <files> <file src="tools\**" target="tools" /> </files> </package> "@ $NuspecOutdated = $true if ( Test-Path $PackageNuspecPath ) { $PackageNuspecContent = Get-Content $PackageNuspecPath $NuspecOutdated = [bool]( Compare-Object $PackageNuspecContent $PackageNuspecConfig ) } # Update nuspec file if it isn't what it should be if ( $NuspecOutdated ) { ( [xml]$PackageNuspecConfig ).Save( $PackageNuspecPath ) } $ChocolateyInstallScriptPath = Join-Path $PackageOutputDir "tools\chocolateyinstall.ps1" $ChocolateyUninstallScriptPath = Join-Path $PackageOutputDir "tools\chocolateyuninstall.ps1" $ChocolateyBeforeModifyScriptPath = Join-Path $PackageOutputDir "tools\chocolateybeforemodify.ps1" $ChocolateyInstallScriptContent = @() $ChocolateyUninstallScriptContent = @() $ChocolateyBeforeModifyScriptContent = @() # If the installer type is zip, add script to install zip file if ( $PackageConfig.InstallerType -eq 'zip' ) { $InstallDirectory = '$env:ProgramFiles\' + $PackageConfig.Name foreach ( $Installer in $PackageConfig.Installers ) { $Arch = switch ( $Installer.Arch ) { "x64" { @{ Url = "url64"; Checksum = "checksum64"; ChecksumType = "checksumtype64" } } "x86" { @{ Url = "url"; Checksum = "checksum"; ChecksumType = "checksumtype" } } } # Add installation code $ChocoZipInstallCode = @" `$ErrorActionPreference = 'Stop' `$toolsDir = "`$(Split-Path -parent `$MyInvocation.MyCommand.Definition)" `$packageArgs = @{ packageName = `$env:ChocolateyPackageName unzipLocation = "$InstallDirectory" fileType = 'EXE_MSI_OR_MSU' #only one of these: exe, msi, msu $($Arch.Url) = '$($Installer.Url)' $($Arch.Checksum) = '$($Installer.Sha256)' $($Arch.ChecksumType) = 'sha256' } Install-ChocolateyZipPackage @packageArgs # Add bins to path Get-ChildItem "$InstallDirectory\*.exe" | ForEach-Object { Install-BinFile -name `$_.BaseName -path `$_.FullName } "@ $ChocolateyInstallScriptContent += $ChocoZipInstallCode # Add before modify code $ChocoZipBeforeModifyCode = @" Get-ChildItem "$InstallDirectory\*.exe" | ForEach-Object { Uninstall-BinFile -name `$_.BaseName -path `$_.FullName } "@ $ChocolateyBeforeModifyScriptContent += $ChocoZipBeforeModifyCode # Add uninstall code $ZipFileName = Split-Path $Installer.Url -Leaf $ChocoZipUninstallCode = @" Uninstall-ChocolateyZipPackage -packageName `$env:ChocolateyPackageName -zipFileName '$ZipFileName' "@ $ChocolateyUninstallScriptContent += $ChocoZipUninstallCode } } # Write the chocolatey install scripts if ( $ChocolateyInstallScriptContent ) { $NeedsUpdate = $true $ScriptContent = $ChocolateyInstallScriptContent -join "`r`n" if ( Test-Path $ChocolateyInstallScriptPath ) { $ExistingScriptContent = Get-Content $ChocolateyInstallScriptPath $NeedsUpdate = [bool]( Compare-Object $ExistingScriptContent $ScriptContent ) } if ( $NeedsUpdate ) { Set-Content -Path $ChocolateyInstallScriptPath -Value $ScriptContent -Force -Encoding utf8 } } # Write the chocolatey uninstall scripts if ( $ChocolateyUninstallScriptContent ) { $NeedsUpdate = $true $ScriptContent = $ChocolateyUninstallScriptContent -join "`r`n" if ( Test-Path $ChocolateyUninstallScriptPath ) { $ExistingScriptContent = Get-Content $ChocolateyUninstallScriptPath $NeedsUpdate = [bool]( Compare-Object $ExistingScriptContent $ScriptContent ) } if ( $NeedsUpdate ) { Set-Content -Path $ChocolateyUninstallScriptPath -Value $ScriptContent -Force -Encoding utf8 } } # Write the chocolatey before modify script if ( $ChocolateyBeforeModifyScriptContent ) { $NeedsUpdate = $true $ScriptContent = $ChocolateyBeforeModifyScriptContent -join "`r`n" if ( Test-Path $ChocolateyBeforeModifyScriptPath ) { $ExistingScriptContent = Get-Content $ChocolateyBeforeModifyScriptPath $NeedsUpdate = [bool]( Compare-Object $ExistingScriptContent $ScriptContent ) } if ( $NeedsUpdate ) { Set-Content -Path $ChocolateyBeforeModifyScriptPath -Value $ScriptContent -Force -Encoding utf8 } } # Todo - msi installer # Todo - exe installer # Todo - appx installer # Todo - msix installer } |