YamlCreate.ps1 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. #Requires -Version 5
  2. <#
  3. .SYNOPSIS
  4. Winget Manifest creation helper script
  5. .DESCRIPTION
  6. The intent of this file is to help you generate a manifest for publishing
  7. to the Windows Package Manager repository.
  8. It'll attempt to download an installer from the user-provided URL to calculate
  9. a checksum. That checksum and the rest of the input data will be compiled in a
  10. .YAML file.
  11. .EXAMPLE
  12. PS C:\Projects\winget-pkgs> Get-Help .\Tools\YamlCreate.ps1 -Full
  13. Show this script's help
  14. .EXAMPLE
  15. PS C:\Projects\winget-pkgs> .\Tools\YamlCreate.ps1
  16. Run the script to create a manifest file
  17. .NOTES
  18. Please file an issue if you run into errors with this script:
  19. https://github.com/microsoft/winget-pkgs/issues/
  20. .LINK
  21. https://github.com/microsoft/winget-pkgs/blob/master/Tools/YamlCreate.ps1
  22. #>
  23. [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
  24. $NewLine = [System.Environment]::NewLine
  25. # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions?view=powershell-7#filters
  26. filter TrimString {
  27. $_.Trim()
  28. }
  29. ##########################################
  30. #region checksum
  31. while ([string]::IsNullOrWhiteSpace($URL)) {
  32. $URL = Read-Host -Prompt 'Enter the URL to the installer' | TrimString
  33. }
  34. Write-Host $NewLine
  35. Write-Host "Downloading URL. This will take awhile..." -ForegroundColor Blue
  36. $WebClient = New-Object System.Net.WebClient
  37. try {
  38. $Stream = $WebClient.OpenRead($URL)
  39. $Hash = (Get-FileHash -InputStream $Stream -Algorithm SHA256).Hash
  40. }
  41. catch {
  42. Write-Host "Error downloading file. Please run the script again." -ForegroundColor Red
  43. exit 1
  44. }
  45. finally {
  46. $Stream.Close()
  47. }
  48. Write-Host "Url: $URL"
  49. Write-Host "Sha256: $Hash"
  50. Write-Host $NewLine
  51. Write-Host "File downloaded. Please Fill out required fields."
  52. #endregion
  53. ##########################################
  54. ##########################################
  55. #region Read in metadata
  56. while ($ID.Length -lt 4 -or $ID.Length -ge 255) {
  57. Write-Host 'Enter the package Id, in the following format <Publisher.Appname>'
  58. $ID = Read-Host -Prompt 'For example: Microsoft.Excel' | TrimString
  59. }
  60. $host.UI.RawUI.ForegroundColor = "White"
  61. while ([string]::IsNullOrWhiteSpace($Publisher) -or $Publisher.Length -ge 128) {
  62. $Publisher = Read-Host -Prompt 'Enter the publisher' | TrimString
  63. }
  64. while ([string]::IsNullOrWhiteSpace($AppName) -or $AppName.Length -ge 128) {
  65. $AppName = Read-Host -Prompt 'Enter the application name' | TrimString
  66. $AppNameFolder = $AppName -replace '\s',''
  67. }
  68. while ([string]::IsNullOrWhiteSpace($version)) {
  69. $version = Read-Host -Prompt 'Enter the version. For example: 1.0.0, 1.0.0.0, 1.0' | TrimString
  70. $ManifestName = $version + ".yaml"
  71. }
  72. while ([string]::IsNullOrWhiteSpace($License) -or $License.Length -ge 40) {
  73. $License = Read-Host -Prompt 'Enter the License, For example: MIT, or Copyright (c) Microsoft Corporation' | TrimString
  74. }
  75. while ($InstallerType -notin @("exe", "msi", "msix", "inno", "nullsoft", "appx", "wix", "zip")) {
  76. $InstallerType = Read-Host -Prompt 'Enter the InstallerType. For example: exe, msi, msix, inno, nullsoft'
  77. }
  78. while ($architecture -notin @("x86", "x64", "arm", "arm64", "neutral")) {
  79. $architecture = Read-Host -Prompt 'Enter the architecture (x86, x64, arm, arm64, Neutral)'
  80. }
  81. do {
  82. $LicenseUrl = Read-Host -Prompt '[OPTIONAL] Enter the license URL' | TrimString
  83. } while (-not [string]::IsNullOrWhiteSpace($LicenseUrl) -and ($LicenseUrl.Length -lt 10 -or $LicenseUrl.Length -gt 2000))
  84. do {
  85. $AppMoniker = Read-Host -Prompt '[OPTIONAL] Enter the AppMoniker (friendly name/alias). For example: vscode' | TrimString
  86. } while ($AppMoniker.Length -gt 40)
  87. do {
  88. $Tags = Read-Host -Prompt '[OPTIONAL] Enter any tags that would be useful to discover this tool. For example: zip, c++' | TrimString
  89. } while ($Tags.Length -gt 40)
  90. do {
  91. $Homepage = Read-Host -Prompt '[OPTIONAL] Enter the Url to the homepage of the application' | TrimString
  92. } while (-not [string]::IsNullOrWhiteSpace($LicenseUrl) -and ($Homepage.Length -lt 10 -or $Homepage.Length -gt 2000))
  93. do {
  94. $Description = Read-Host -Prompt '[OPTIONAL] Enter a description of the application' | TrimString
  95. } while ($Description.Length -gt 500)
  96. # Only prompt for silent switches if $InstallerType is "exe"
  97. if ($InstallerType -ieq "exe") {
  98. $Silent = Read-Host -Prompt '[OPTIONAL] Enter the silent install switch'| TrimString
  99. $SilentWithProgress = Read-Host -Prompt '[OPTIONAL] Enter the silent (with progress) install switch'| TrimString
  100. }
  101. #endregion
  102. ##########################################
  103. ##########################################
  104. #region Write metadata
  105. # YAML files should always start with the document start separator "---"
  106. # https://yaml.org/spec/1.2/spec.html#id2760395
  107. $string = "---$NewLine"
  108. Write-Output $string | Out-File $ManifestName
  109. Write-Host $NewLine
  110. $string = "Id: $ID"
  111. Write-Output $string | Out-File $ManifestName -Append
  112. Write-Host "Id: " -ForegroundColor Blue -NoNewline
  113. Write-Host $ID -ForegroundColor White
  114. $string = "Version: $Version"
  115. Write-Output $string | Out-File $ManifestName -Append
  116. Write-Host "Version: " -ForegroundColor Blue -NoNewline
  117. Write-Host $Version -ForegroundColor White
  118. $string = "Name: $AppName"
  119. Write-Output $string | Out-File $ManifestName -Append
  120. Write-Host "Name: " -ForegroundColor Blue -NoNewline
  121. Write-Host $AppName -ForegroundColor White
  122. $string = "Publisher: $Publisher"
  123. Write-Output $string | Out-File $ManifestName -Append
  124. Write-Host "Publisher: " -ForegroundColor Blue -NoNewline
  125. Write-Host $Publisher -ForegroundColor White
  126. $string = "License: $License"
  127. Write-Output $string | Out-File $ManifestName -Append
  128. Write-Host "License: " -ForegroundColor Blue -NoNewline
  129. Write-Host $License -ForegroundColor White
  130. if (-not [string]::IsNullOrWhiteSpace($LicenseUrl)) {
  131. $string = "LicenseUrl: $LicenseUrl"
  132. Write-Output $string | Out-File $ManifestName -Append
  133. Write-Host "LicenseUrl: " -ForegroundColor Blue -NoNewline
  134. Write-Host $LicenseUrl -ForegroundColor White
  135. }
  136. if (-not [string]::IsNullOrWhiteSpace($AppMoniker)) {
  137. $string = "AppMoniker: $AppMoniker"
  138. Write-Output $string | Out-File $ManifestName -Append
  139. Write-Host "AppMoniker: " -ForegroundColor Blue -NoNewline
  140. Write-Host $AppMoniker -ForegroundColor White
  141. }
  142. if (-not [string]::IsNullOrWhiteSpace($Commands)) {
  143. $string = "Commands: $Commands"
  144. Write-Output $string | Out-File $ManifestName -Append
  145. Write-Host "Commands: " -ForegroundColor Blue -NoNewline
  146. Write-Host $Commands -ForegroundColor White
  147. }
  148. if (-not [string]::IsNullOrWhiteSpace($Tags)) {
  149. $string = "Tags: $Tags"
  150. Write-Output $string | Out-File $ManifestName -Append
  151. Write-Host "Tags: " -ForegroundColor Blue -NoNewline
  152. Write-Host $Tags -ForegroundColor White
  153. }
  154. if (-not [string]::IsNullOrWhiteSpace($Description)) {
  155. $string = "Description: $Description"
  156. Write-Output $string | Out-File $ManifestName -Append
  157. Write-Host "Description: " -ForegroundColor Blue -NoNewline
  158. Write-Host $Description -ForegroundColor White
  159. }
  160. if (-not [string]::IsNullOrWhiteSpace($Homepage)) {
  161. $string = "Homepage: $Homepage"
  162. Write-Output $string | Out-File $ManifestName -Append
  163. Write-Host "Homepage: " -ForegroundColor Blue -NoNewline
  164. Write-Host $Homepage -ForegroundColor White
  165. }
  166. Write-Output "Installers:" | Out-File $ManifestName -Append
  167. $string = " - Arch: $architecture"
  168. Write-Output $string | Out-File $ManifestName -Append
  169. Write-Host "Arch: " -ForegroundColor Blue -NoNewline
  170. Write-Host $architecture -ForegroundColor White
  171. $string = " Url: $URL"
  172. Write-Output $string | Out-File $ManifestName -Append
  173. Write-Host "Url: " -ForegroundColor Blue -NoNewline
  174. Write-Host $URL -ForegroundColor White
  175. $string = " Sha256: $Hash"
  176. Write-Output $string | Out-File $ManifestName -Append
  177. Write-Host "Sha256: " -ForegroundColor Blue -NoNewline
  178. Write-Host $Hash -ForegroundColor White
  179. $string = " InstallerType: $InstallerType"
  180. Write-Output $string | Out-File $ManifestName -Append
  181. Write-Host "InstallerType: " -ForegroundColor Blue -NoNewline
  182. Write-Host $InstallerType -ForegroundColor White
  183. if ((-not [string]::IsNullOrWhiteSpace($Silent)) -or
  184. (-not [string]::IsNullOrWhiteSpace($SilentWithProgress))) {
  185. $string = " Switches:"
  186. Write-Output $string | Out-File $ManifestName -Append
  187. Write-Host "Switches: " -ForegroundColor Blue -NoNewline
  188. }
  189. if (-not [string]::IsNullOrWhiteSpace($Silent)) {
  190. $string = " Silent: $Silent"
  191. Write-Output $string | Out-File $ManifestName -Append
  192. Write-Host "Silent: " -ForegroundColor Blue -NoNewline
  193. Write-Host $Silent -ForegroundColor White
  194. }
  195. if (-not [string]::IsNullOrWhiteSpace($SilentWithProgress)) {
  196. $string = " SilentWithProgress: $SilentWithProgress"
  197. Write-Output $string | Out-File $ManifestName -Append
  198. Write-Host "SilentWithProgress: " -ForegroundColor Blue -NoNewline
  199. Write-Host $SilentWithProgress -ForegroundColor White
  200. }
  201. $ManifestsFolder = (Resolve-Path "$PSScriptRoot\..\manifests").Path
  202. $PublisherFolder = Join-Path $ManifestsFolder $Publisher
  203. $AppFolder = Join-Path $PublisherFolder $AppNameFolder
  204. New-Item -ItemType "Directory" -Force -Path $AppFolder | Out-Null
  205. $FileOldEncoding = Get-Content -Raw $ManifestName
  206. Remove-Item -Path $ManifestName
  207. $ManifestPath = Join-Path $AppFolder $ManifestName
  208. $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
  209. [System.IO.File]::WriteAllLines($ManifestPath, $FileOldEncoding, $Utf8NoBomEncoding)
  210. Write-Host $NewLine
  211. Write-Host "Yaml file created: $ManifestPath"
  212. #endregion
  213. ##########################################