Делаем пакет для Chocolatey
Совсем недавно я распробовал пакетный менеджер Chocolatey 🔗 для Windows, поддерживаемый сообществом. Я проникся и стал ставить через него почти что весь софт, которым пользуюсь. Можно просто запускать раз в неделю командлет choco update -y all
и получить на выходе весь софт обновлённым, без служб обновлений и тем более без ручных обнов.
Когда я узнал о моде Slayer’s Testament 🔗, в котором на Quake Engine 🔗 пытаются портировать Doom: Eternal, мне стало интересно его пощупать, но оказалось, что ни один из десятков портов этого движка на современные системы не представлен в Chocolatey и, я окунулся в незнакомый для меня мир создания пакетов для него.
Разумеется, я делал пакет по методу культа карго 🔗 и совершил множество ошибок, но прямо сейчас, то, что получилось, работает и выглядит даже не совсем ужасно.
Я собрал 🔗 пакет 🔗 для vkQuake 🔗 - реализацию Quake Engine на Vulkan API 🔗. Во-первых, мне нравится API Vulkan по религиозным соображения, во-вторых, именно этот движок рекомендуют авторы мода Slayer’s Testament, а в-третьих, он выложен на гитхабе и активно обновляется.
Состав
Для минималистичной сборки пакета нужны три файла (все файлы можно посмотреть в репозитории 🔗):
vkQuake.nuspec
XML-файл с описанием пакета, автором приложения, версией, короче, разнообразная мета, которая нужна для построения страницы пакета в официальном 🔗 или личном репозитории.
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>vkQuake</id>
<version>1.05.2</version>
<title>vkQuake (Install)</title>
<authors>Novum</authors>
<owners>nett00n</owners>
<licenseUrl>https://github.com/Novum/vkQuake/blob/master/LICENSE.txt</licenseUrl>
<projectUrl>https://github.com/Novum/vkQuake</projectUrl>
<iconUrl>https://rawcdn.githack.com/nett00n/vkQuake_chocolatey/b5016b97892e64a240198a0bd16690b42ed441a1/quake-vulkan.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Vulkan Quake port based on QuakeSpasm </description>
<summary>vkQuake is a Quake 1 port using Vulkan instead of OpenGL for rendering. It is based on the popular QuakeSpasm port and runs all mods compatible with it like Arcane Dimensions.</summary>
<releaseNotes>https://github.com/Novum/vkQuake/releases</releaseNotes>
<copyright>Novum</copyright>
<tags>quake engine game idtech portable</tags>
<projectSourceUrl>https://github.com/Novum/vkQuake</projectSourceUrl>
<packageSourceUrl>https://github.com/nett00n/vkQuake_chocolatey</packageSourceUrl>
<bugTrackerUrl>https://github.com/Novum/vkQuake/issues</bugTrackerUrl>
</metadata>
<files>
<file src="tools\*.ps1" target="tools"/>
</files>
</package>
Блок files
указывает какие папки и файлы включать в пакет.
⚠ Иконка вашего приложения должна находиться на CDN 🔗, наиболее популярными решениями являются jsDelivr 🔗, Statically 🔗 или Githack 🔗. Я использовал последний.
chocolateyinstall.ps1
Скрипт, устанавливающий нужный вам пакет. Пишется на PowerShell с рядом синтаксического сахара специфичного для Chocolatey.
VkQuake поставляется в виде zip-архива для 32-разрядных и 64-разрядных систем.
Сначала я сделал пакет, который ставит x64, предполагая, что для x32 я сделаю отдельный, но потом я разобрался, посмотрев на примеры кода и понял, что надо делать единый пакет - это будет и проще в поддержании и нагляднее.
На мой взгляд лучше всего держать все переменные в начале файла - их так проще изменять, да и дёргать переменные удобнее, чем хардкодить их в код:
$packageName = 'vkQuake'
$url64 = 'https://github.com/Novum/vkQuake/releases/download/1.05.2/vkquake-1.05.2_win64.zip'
$checksum64 = 'b7e5ed30a6369a3c2c31ce04dd74ebab064a0038db709cfcc661f70e8a1cb7a9'
$url32 = 'https://github.com/Novum/vkQuake/releases/download/1.05.2/vkquake-1.05.2_win32.zip'
$checksum32 = '06920832fcd726e74274bd2c4d48e507879fc1ac7ae23cd4eacbbfcd3f9d9a21'
$toolsPath = Split-Path $MyInvocation.MyCommand.Definition
$vkQuake_folder = "$(Get-ToolsLocation)\vkQuake"
Тут я собрал ссылки на релизы, и их sha256. Можно использовать другие хэшсуммы (md5 не рекомендуется), или не использовать их вовсе, но, на мой взгляд, отсутствие хэшсуммы - это плохая практика. Если бы я выбрал какое-нибудь менее экстравагантное приложение, то переменная $vkQuake_folder
мне бы не понадобилась, но мсье знает толк в извращениях, позже расскажу, зачем нужен этот путь.
$toolsPath
же тут - это получение сервисной директории chocolatey. По-дефолту этоC:\ProgramData\chocolatey\lib
, туда помещаются все устанавливаемые пакеты, чтоб в дальнейшем их можно было переустановить или удалить.
Насколько я понимаю конструкция try-catch это вообще хорошая практика в современном кодстайле для обработки исключений. Что это и зачем - я пока не понимаю, но скопируем, оставшуюся кодовую базу будем писать внутри.
⚠ На самом деле, не нужно, потому что все ошибки chocolatey проверяет самостоятельно
try {
...
Write-ChocolateySuccess $packageName
} catch {
Write-ChocolateyFailure $packageName "$($_.Exception.Message)"
throw
}
Определим архитектуру установленной системы
$processor = Get-WmiObject Win32_Processor
$is64bit = $processor.AddressWidth -eq 64
$is32bit = $processor.AddressWidth -eq 32
И в зависимости от архитектуры ставим нужный нам пакет
⚠ На самом деле тоже не нужно, так как
Install-ChocolateyZipPackage
прекрасно себе с этим справляется самостоятельно, нужно просто передатьurl
иurl64
иchecksum
сchecksum64
:
$packageArgs = @{
packageName = $packageName
url = "https://github.com/Novum/vkQuake/releases/download/1.05.2/vkquake-1.05.2_win64.zip"
checksum = "b7e5ed30a6369a3c2c31ce04dd74ebab064a0038db709cfcc661f70e8a1cb7a9"
url64 = "https://github.com/Novum/vkQuake/releases/download/1.05.2/vkquake-1.05.2_win32.zip"
checksum64 = "06920832fcd726e74274bd2c4d48e507879fc1ac7ae23cd4eacbbfcd3f9d9a21"
checksumType = 'sha256'
unzipLocation = $toolsPath
}
Install-ChocolateyZipPackage @packageArgs
Почему дальше у меня начинаются костыли?
Потому что одного только Quake Engine недостаточно для того, чтоб играть в Quake, нужны ещё ресурсы. Id в лице Джона Кармака нужно высказать отдельные благодарности за то, что он выкладывает в открытый доступ исходный код своих движков, однако уровни, текстуры и звуки всё ещё собственность компании. Изначально Quake поставлялся по лицензии shareware, в которой доступна только часть контента, а остальные уровни нужно было покупать. Сейчас Shareware-версию ресурсов нельзя скачать на официальном сайте id, но легко можно нагуглить. Если у вас есть дисковая, или например steam-копия игры, то можно взять ресурсы из них. Кроме оригинально игры, можно скачать свободные ресурсы LibreQuake 🔗, а также любой пакет уровней, да хоть тот же Slayer’s Testament, с которого у меня и начался этот движ.
Канонично, файлы ресурсов должны лежать в папке id1
внутри папки с игрой. Но есть нюанс - при установке другой версии пакета, всё содержимое $toolsPath
будет затёрто. А значит и ресурсы тоже.
Я посмотрел на реализацию пакета 🔗 с эмулятором Cemu 🔗 У Chocolatey есть внешняя папка tools, адрес которой находится в переменной $(Get-ToolsLocation)
. Отсюда берётся наша переменная $vkQuake_folder
.
Находим новую версия в C:\ProgramData\chocolatey\lib\vkQuake\
, Переносим всё содержимое с перезаписью в c:\tools\vkQuake\
и убираем за собой
$vkQuake_latest = (Get-ChildItem $toolsPath -Recurse -ErrorAction SilentlyContinue | Where-Object {$_.Name -like 'vkquake-*'} | sort-Object {$_.CreationTime} | select-Object -First 1).FullName
Robocopy "$vkQuake_latest" "$vkQuake_folder" /R:0 /W:0 /E /XO
Remove-Item "$vkQuake_latest" -Recurse -Force -ErrorAction SilentlyContinue
И создаём ярлык для запуска в “Пуске”
Install-ChocolateyShortcut -shortcutFilePath "$env:ALLUSERSPROFILE\Microsoft\Windows\Start Menu\Programs\vkQuake.lnk" "$vkQuake_folder\vkQuake.exe" -WorkingDirectory "$vkQuake_folder"
chocolateyuninstall.ps1
Скрипт, удаляющий пакет. Тут всё просто: задаём путь до ярлыка в пуске, до папки с установленной игрой и удаляем их:
$icon_name = (Get-ChildItem "$env:ALLUSERSPROFILE\Microsoft\Windows\Start Menu\Programs" -Filter "vkQuake.lnk" -ErrorAction SilentlyContinue).FullName
$vkQuake_folder = "$(Get-ToolsLocation)\vkQuake"
Remove-Item $icon_name -ErrorAction SilentlyContinue
Remove-Item -Recurse -Force $vkQuake_folder
Сборка, проверка, доставка
Сборка
choco pack
Устанвавливаем его локально и проверяем, что всё встало
chocolatey install vkQuake -s . -y
Удаляем и проверяем, что мы за собой всё прибрали
chocolatey uninstall vkQuake -s . -y
Настраиваем пуш
choco apikey --key XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX --source "https://push.chocolatey.org/"
Сам ключ смотрим в профиле 🔗
Пушим в репо
choco push ".\vkQuake.1.05.2.nupkg" --source "https://push.chocolatey.org/"
После этого на сайте проходит верификация пакета, а также ручная модерация. Если всё в порядке, пакет появляется в общем доступе.