Skip to content

Commit d917e8b

Browse files
committed
build: add chocolatey scripts
1 parent 8e6684e commit d917e8b

7 files changed

Lines changed: 287 additions & 0 deletions

justfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ build-win-pyinstaller: build-requirements
3737
build-win-package: build-win-pyinstaller
3838
./scripts/windows/build_packages.sh
3939

40+
build-win-chocolatey:
41+
./scripts/chocolatey/build.sh all
42+
4043
build-macos-pyinstaller: build-requirements
4144
BUILD_MACOS_ARCH=x86_64 ./scripts/pyinstaller/build_mac.sh
4245

@@ -49,6 +52,9 @@ build-macos-pyinstaller-arm64: build-requirements
4952
build-macos-package-arm64: build-macos-pyinstaller-arm64
5053
BUILD_MACOS_ARCH=arm64 ./scripts/macos/build_dmg.sh
5154

55+
clean:
56+
rm -rf dist build
57+
5258
clean-pyinstaller-dist:
5359
find dist -maxdepth 1 -mindepth 1 -type d -exec rm -r {} \;
5460

scripts/chocolatey/build.sh

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
#!/bin/bash
2+
3+
# package test (from dist root, after build):
4+
# choco install gridplayer.install -dv -y -s .
5+
# choco install gridplayer.portable -dv -y -s .
6+
# choco install gridplayer -dv -y -s .
7+
#
8+
# push (install/portable first, meta last):
9+
# choco apikey add -s https://push.chocolatey.org/ -k YOUR_API_KEY
10+
# choco push gridplayer.install.*.nupkg --source https://push.chocolatey.org/
11+
# choco push gridplayer.portable.*.nupkg --source https://push.chocolatey.org/
12+
# choco push gridplayer.*.nupkg --source https://push.chocolatey.org/
13+
14+
set -e
15+
16+
SCRIPT_DIR="$( cd "$( dirname $0 )" && pwd )"
17+
18+
. "scripts/init_app_vars.sh"
19+
20+
ensure_prerequisites() {
21+
if ! command -v choco >/dev/null 2>&1; then
22+
die "Chocolatey (choco) is not available on PATH. Install from https://chocolatey.org/install"
23+
fi
24+
25+
if ! command -v jq >/dev/null 2>&1; then
26+
die "jq is required. Install jq and ensure it is on PATH."
27+
fi
28+
29+
if ! command -v curl >/dev/null 2>&1; then
30+
die "curl is required. Install curl and ensure it is on PATH."
31+
fi
32+
33+
local validation_pkg="chocolatey-community-validation.extension"
34+
if ! choco list --exact --limit-output "$validation_pkg" 2>/dev/null \
35+
| grep -qi 'chocolatey-community-validation'; then
36+
die "$validation_pkg" is required.
37+
fi
38+
}
39+
40+
build_one() {
41+
local BUILD_TYPE="$1"
42+
43+
local CHOCO_ID=""
44+
local CHOCO_TITLE=""
45+
local DEPENDENCIES=""
46+
local PACKAGE_PATTERN=""
47+
local INSTALL_SCRIPT=""
48+
local UNINSTALL_SCRIPT=""
49+
local PACKAGE_PARAMETERS=""
50+
local INCLUDE_TOOLS=0
51+
52+
if [ "$BUILD_TYPE" == "meta" ]; then
53+
CHOCO_ID="$APP_MODULE"
54+
CHOCO_TITLE="$APP_NAME"
55+
DEPENDENCIES="<dependencies><dependency id=\"${APP_MODULE}.install\" version=\"[${APP_VERSION}]\" /></dependencies>"
56+
elif [ "$BUILD_TYPE" == "install" ]; then
57+
CHOCO_ID="$APP_MODULE.install"
58+
CHOCO_TITLE="$APP_NAME (Install)"
59+
PACKAGE_PATTERN="GridPlayer-.*-win64-install.exe"
60+
INSTALL_SCRIPT="$SCRIPT_DIR/chocolateyInstall.install.ps1"
61+
# Uninstall via Chocolatey auto-uninstaller (Inno Setup ARP entry + softwareName)
62+
INCLUDE_TOOLS=1
63+
PACKAGE_PARAMETERS="
64+
## Notes
65+
66+
- Windows x64 only
67+
- Installs via Inno Setup to Program Files"
68+
elif [ "$BUILD_TYPE" == "portable" ]; then
69+
CHOCO_ID="$APP_MODULE.portable"
70+
CHOCO_TITLE="$APP_NAME (Portable)"
71+
PACKAGE_PATTERN="GridPlayer-.*-win64-portable.zip"
72+
INSTALL_SCRIPT="$SCRIPT_DIR/chocolateyInstall.portable.ps1"
73+
UNINSTALL_SCRIPT="$SCRIPT_DIR/chocolateyUninstall.portable.ps1"
74+
INCLUDE_TOOLS=1
75+
PACKAGE_PARAMETERS="
76+
## Package Install Parameters
77+
78+
- \`/DesktopIcon\` - Create a Desktop shortcut for the current user.
79+
- \`/NoStart\` - Do not create a Start Menu shortcut.
80+
81+
## Notes
82+
83+
- Windows x64 only
84+
- Extracts to the Chocolatey tools location (app files at package root) and adds a PATH shim"
85+
else
86+
die "Unknown build type '$BUILD_TYPE' (expected: meta, install, portable, or all)"
87+
fi
88+
89+
local BUILD_DIR_CHOCO="$BUILD_DIR/chocolatey/$BUILD_TYPE"
90+
local NUSPEC_PATH="$BUILD_DIR_CHOCO/${CHOCO_ID}.nuspec"
91+
92+
rm -rf "$BUILD_DIR_CHOCO"
93+
mkdir -p "$BUILD_DIR_CHOCO"
94+
95+
if [ "$INCLUDE_TOOLS" -eq 1 ]; then
96+
mkdir -p "$BUILD_DIR_CHOCO/tools"
97+
98+
copy_with_app_vars "$SCRIPT_DIR/chocolateyBeforeModify.ps1" "$BUILD_DIR_CHOCO/tools/chocolateyBeforeModify.ps1"
99+
copy_with_app_vars "$INSTALL_SCRIPT" "$BUILD_DIR_CHOCO/tools/chocolateyInstall.ps1"
100+
101+
if [ -n "$UNINSTALL_SCRIPT" ]; then
102+
copy_with_app_vars "$UNINSTALL_SCRIPT" "$BUILD_DIR_CHOCO/tools/chocolateyUninstall.ps1"
103+
fi
104+
105+
local ASSET_JSON PACKAGE_URL PACKAGE_SHA256
106+
ASSET_JSON=$(curl -sS "$RELEASE_URL" | jq -c ".assets[] | select(.name|test(\"${PACKAGE_PATTERN}\"))")
107+
PACKAGE_URL=$(echo "$ASSET_JSON" | jq -r ".browser_download_url")
108+
# GitHub API provides digest as "sha256:<hex>"; strip the prefix for Chocolatey
109+
PACKAGE_SHA256=$(echo "$ASSET_JSON" | jq -r ".digest | ltrimstr(\"sha256:\")")
110+
111+
if [ -z "$PACKAGE_URL" ] || [ "$PACKAGE_URL" = "null" ]; then
112+
die "No package URL for pattern '$PACKAGE_PATTERN' in release v${APP_VERSION}"
113+
fi
114+
if [ -z "$PACKAGE_SHA256" ] || [ "$PACKAGE_SHA256" = "null" ]; then
115+
die "No checksum (asset digest) for pattern '$PACKAGE_PATTERN' in release v${APP_VERSION}"
116+
fi
117+
118+
sed -i "s#{PACKAGE_URL}#$PACKAGE_URL#g" "$BUILD_DIR_CHOCO/tools/chocolateyInstall.ps1"
119+
sed -i "s#{PACKAGE_SHA256}#$PACKAGE_SHA256#g" "$BUILD_DIR_CHOCO/tools/chocolateyInstall.ps1"
120+
fi
121+
122+
copy_with_app_vars "$SCRIPT_DIR/template.nuspec" "$NUSPEC_PATH"
123+
awk -i inplace -v r="$PACKAGE_PARAMETERS" '{gsub(/{PACKAGE_PARAMETERS}/,r)}1' "$NUSPEC_PATH"
124+
awk -i inplace -v r="$DEPENDENCIES" '{gsub(/{DEPENDENCIES}/,r)}1' "$NUSPEC_PATH"
125+
sed -i "s#{CHOCO_ID}#$CHOCO_ID#g" "$NUSPEC_PATH"
126+
sed -i "s#{CHOCO_TITLE}#$CHOCO_TITLE#g" "$NUSPEC_PATH"
127+
128+
# Meta package is dependency-only; no tools scripts or files section
129+
if [ "$INCLUDE_TOOLS" -eq 0 ]; then
130+
sed -i '/<files>/,/<\/files>/d' "$NUSPEC_PATH"
131+
fi
132+
133+
(cd "$BUILD_DIR_CHOCO" && choco pack)
134+
135+
mkdir -p "$DIST_DIR"
136+
mv "$BUILD_DIR_CHOCO"/*.nupkg "$DIST_DIR"
137+
138+
echo "Built ${CHOCO_ID} ${APP_VERSION} -> $DIST_DIR"
139+
}
140+
141+
ensure_prerequisites
142+
143+
RELEASE_URL="https://api.github.com/repos/${APP_REPO_SLUG}/releases/tags/v${APP_VERSION}"
144+
145+
BUILD_TYPE="${1:-}"
146+
147+
if [ -z "$BUILD_TYPE" ]; then
148+
die "Usage: $0 <meta|install|portable|all>"
149+
fi
150+
151+
if [ "$BUILD_TYPE" == "all" ]; then
152+
build_one install
153+
build_one portable
154+
build_one meta
155+
echo "All Chocolatey packages built in $DIST_DIR"
156+
exit 0
157+
fi
158+
159+
build_one "$BUILD_TYPE"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
$ErrorActionPreference = 'SilentlyContinue'
2+
Get-Process '{APP_NAME}*' -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
$ErrorActionPreference = 'Stop'
2+
3+
$packageArgs = @{
4+
packageName = $env:ChocolateyPackageName
5+
fileType = 'exe'
6+
softwareName = '{APP_NAME}*'
7+
url64bit = '{PACKAGE_URL}'
8+
checksum64 = '{PACKAGE_SHA256}'
9+
checksumType64 = 'sha256'
10+
# Inno Setup
11+
silentArgs = '/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-'
12+
validExitCodes = @(0)
13+
}
14+
15+
Install-ChocolateyPackage @packageArgs
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
$ErrorActionPreference = 'Stop'
2+
3+
$packageName = $env:ChocolateyPackageName
4+
$unzipLocation = Join-Path (Get-ToolsLocation) $packageName
5+
$params = Get-PackageParameters
6+
7+
$packageArgs = @{
8+
packageName = $packageName
9+
unzipLocation = $unzipLocation
10+
url64bit = '{PACKAGE_URL}'
11+
checksum64 = '{PACKAGE_SHA256}'
12+
checksumType64 = 'sha256'
13+
}
14+
15+
Install-ChocolateyZipPackage @packageArgs
16+
17+
# Zip root is GridPlayer/; hoist contents so the package dir is the app root
18+
$nestedDir = Join-Path $unzipLocation '{APP_NAME}'
19+
if (Test-Path -LiteralPath $nestedDir) {
20+
Get-ChildItem -LiteralPath $nestedDir -Force | Move-Item -Destination $unzipLocation -Force
21+
Remove-Item -LiteralPath $nestedDir -Recurse -Force
22+
}
23+
24+
$exePath = Join-Path $unzipLocation '{APP_NAME}.exe'
25+
26+
Install-BinFile -Name '{APP_NAME}' -Path $exePath -UseStart
27+
28+
if ($params.DesktopIcon) {
29+
$desktopIcon = Join-Path ([Environment]::GetFolderPath('Desktop')) '{APP_NAME}.lnk'
30+
Write-Host -ForegroundColor White "Adding $desktopIcon"
31+
Install-ChocolateyShortcut -ShortcutFilePath $desktopIcon -TargetPath $exePath
32+
}
33+
34+
if (-not $params.NoStart) {
35+
$startIcon = Join-Path ([Environment]::GetFolderPath('Programs')) '{APP_NAME}.lnk'
36+
Write-Host -ForegroundColor White "Adding $startIcon"
37+
Install-ChocolateyShortcut -ShortcutFilePath $startIcon -TargetPath $exePath
38+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
$ErrorActionPreference = 'Stop'
2+
3+
$packageName = $env:ChocolateyPackageName
4+
$toolsDir = Join-Path (Get-ToolsLocation) $packageName
5+
$exePath = Join-Path $toolsDir '{APP_NAME}.exe'
6+
7+
$desktopIcon = Join-Path ([Environment]::GetFolderPath('Desktop')) '{APP_NAME}.lnk'
8+
$startIcon = Join-Path ([Environment]::GetFolderPath('Programs')) '{APP_NAME}.lnk'
9+
10+
Remove-Item $desktopIcon -ErrorAction SilentlyContinue
11+
Remove-Item $startIcon -ErrorAction SilentlyContinue
12+
13+
Uninstall-BinFile -Name '{APP_NAME}' -Path $exePath
14+
15+
if (Test-Path -LiteralPath $toolsDir) {
16+
# Keep portable user data across uninstall/reinstall
17+
Get-ChildItem -LiteralPath $toolsDir -Force -Exclude 'portable_data' |
18+
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
19+
}

scripts/chocolatey/template.nuspec

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
3+
<metadata>
4+
<id>{CHOCO_ID}</id>
5+
<version>{APP_VERSION}</version>
6+
<projectUrl>{APP_URL}</projectUrl>
7+
<projectSourceUrl>{APP_URL}</projectSourceUrl>
8+
<packageSourceUrl>{APP_URL}/tree/v{APP_VERSION}/scripts/chocolatey</packageSourceUrl>
9+
<licenseUrl>{APP_URL}/blob/master/LICENSE</licenseUrl>
10+
<bugTrackerUrl>{APP_URL}/issues</bugTrackerUrl>
11+
<releaseNotes>{APP_URL}/blob/master/CHANGELOG.md</releaseNotes>
12+
<iconUrl>{APP_CDN_URL_ROOT}/resources/icons/main/png/128x128.png</iconUrl>
13+
<owners>{APP_AUTHOR}</owners>
14+
<authors>{APP_AUTHOR}</authors>
15+
<title>{CHOCO_TITLE}</title>
16+
<requireLicenseAcceptance>false</requireLicenseAcceptance>
17+
<tags>gridplayer python player youtube streamlink twitch streaming qt video video-player livestream pyqt5 youtube-dl qt5 vlc libvlc pyqt player-video yt-dlp media multi-video</tags>
18+
<summary>Play videos side-by-side</summary>
19+
<description>Simple VLC-based media player that can play multiple videos at the same time. You can
20+
play as many videos as you like, the only limit is your hardware. It supports all video
21+
formats that VLC supports (which is all of them). You can save your playlist retaining
22+
information about the position, sound volume, loops, aspect ratio, etc.
23+
24+
## Features
25+
26+
- Cross-platform (Linux, Mac, and Windows)
27+
- Support for any video and audio format (VLC)
28+
- Support for (almost) any streaming URLs ([streamlink](https://streamlink.github.io/plugins.html) + [yt-dlp](https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md))
29+
- Hardware and software video decoding
30+
- Control video aspect, playback speed, zoom
31+
- Set loop fragments with frame precision
32+
- Configurable grid layout
33+
- Easy swap videos with drag-n-drop
34+
- Playlist retains settings for each video
35+
36+
## Screenshots
37+
38+
[![Screenshot 1]({APP_CDN_URL_ROOT}/resources/public/screenshot-001-thumb.png)]({APP_CDN_URL_ROOT}/resources/public/screenshot-001.png)
39+
[![Screenshot 2]({APP_CDN_URL_ROOT}/resources/public/screenshot-002-thumb.png)]({APP_CDN_URL_ROOT}/resources/public/screenshot-002.png)
40+
[![Screenshot 3]({APP_CDN_URL_ROOT}/resources/public/screenshot-003-thumb.png)]({APP_CDN_URL_ROOT}/resources/public/screenshot-003.png)
41+
[![Screenshot 4]({APP_CDN_URL_ROOT}/resources/public/screenshot-004-thumb.png)]({APP_CDN_URL_ROOT}/resources/public/screenshot-004.png)
42+
{PACKAGE_PARAMETERS}</description>
43+
{DEPENDENCIES}
44+
</metadata>
45+
<files>
46+
<file src="tools\**" target="tools" />
47+
</files>
48+
</package>

0 commit comments

Comments
 (0)