plex-tui 0.4.2__tar.gz → 0.4.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plex_tui-0.4.2 → plex_tui-0.4.3}/.github/workflows/post-release-homebrew.yml +120 -3
- {plex_tui-0.4.2 → plex_tui-0.4.3}/AGENTS.md +9 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/CHANGELOG.md +12 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/PACKAGING.md +16 -6
- {plex_tui-0.4.2 → plex_tui-0.4.3}/PKG-INFO +11 -5
- {plex_tui-0.4.2 → plex_tui-0.4.3}/README.md +10 -4
- {plex_tui-0.4.2 → plex_tui-0.4.3}/RELEASE.md +11 -4
- {plex_tui-0.4.2 → plex_tui-0.4.3}/ROADMAP.md +4 -2
- {plex_tui-0.4.2 → plex_tui-0.4.3}/config.example.toml +5 -1
- plex_tui-0.4.3/docs/homebrew-install-time.md +171 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/packaging/aur/.SRCINFO +3 -3
- {plex_tui-0.4.2 → plex_tui-0.4.3}/packaging/aur/PKGBUILD +2 -2
- {plex_tui-0.4.2 → plex_tui-0.4.3}/packaging/homebrew/README.md +12 -3
- {plex_tui-0.4.2 → plex_tui-0.4.3}/pyproject.toml +1 -1
- {plex_tui-0.4.2 → plex_tui-0.4.3}/scripts/check_release.py +38 -0
- plex_tui-0.4.3/scripts/measure_homebrew_install.py +154 -0
- plex_tui-0.4.3/scripts/prepare_homebrew_bottle_assets.py +70 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/src/plextui/__init__.py +1 -1
- {plex_tui-0.4.2 → plex_tui-0.4.3}/src/plextui/app.py +33 -12
- {plex_tui-0.4.2 → plex_tui-0.4.3}/src/plextui/config.py +1 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/tests/test_app_helpers.py +8 -5
- {plex_tui-0.4.2 → plex_tui-0.4.3}/tests/test_app_navigation.py +26 -12
- plex_tui-0.4.3/tests/test_homebrew_bottle_assets.py +72 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/tests/test_release_checks.py +27 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/.github/workflows/aur.yml +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/.github/workflows/bump.yml +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/.github/workflows/ci.yml +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/.github/workflows/post-release-aur.yml +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/.github/workflows/publish-aur.yml +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/.github/workflows/publish-pypi.yml +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/.github/workflows/publish-testpypi.yml +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/.gitignore +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/LICENSE +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/Makefile +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/docs/assets/grid-view.png +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/docs/assets/list-view.png +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/docs/plex-integration-research.md +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/packaging/aur/README.md +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/scripts/stage_release.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/scripts/update_aur_package.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/scripts/update_homebrew_formula.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/src/plextui/__main__.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/src/plextui/artwork.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/src/plextui/auth.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/src/plextui/models.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/src/plextui/player.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/src/plextui/plex_service.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/src/plextui/smoke.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/tests/test_artwork.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/tests/test_auth.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/tests/test_cli.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/tests/test_config.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/tests/test_player.py +0 -0
- {plex_tui-0.4.2 → plex_tui-0.4.3}/tests/test_plex_service.py +0 -0
|
@@ -13,6 +13,7 @@ on:
|
|
|
13
13
|
|
|
14
14
|
env:
|
|
15
15
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
16
|
+
HOMEBREW_NO_REQUIRE_TAP_TRUST: "1"
|
|
16
17
|
|
|
17
18
|
jobs:
|
|
18
19
|
publish-tap:
|
|
@@ -133,14 +134,127 @@ jobs:
|
|
|
133
134
|
"${{ steps.tap.outputs.path }}/Formula/plex-tui.rb" \
|
|
134
135
|
"${{ steps.release.outputs.version }}"
|
|
135
136
|
|
|
136
|
-
- name:
|
|
137
|
+
- name: Check tap update need
|
|
137
138
|
if: steps.release.outputs.publish == 'true'
|
|
139
|
+
id: tap-update
|
|
140
|
+
working-directory: ${{ steps.tap.outputs.path }}
|
|
141
|
+
env:
|
|
142
|
+
VERSION: ${{ steps.release.outputs.version }}
|
|
143
|
+
run: |
|
|
144
|
+
set -euo pipefail
|
|
145
|
+
|
|
146
|
+
bottle_release="plex-tui-${VERSION}"
|
|
147
|
+
bottle_root_url="https://github.com/so1omon563/homebrew-plex-tui/releases/download/${bottle_release}"
|
|
148
|
+
needed=false
|
|
149
|
+
|
|
150
|
+
if ! git diff --quiet -- Formula/plex-tui.rb; then
|
|
151
|
+
needed=true
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
if ! grep -Fq "root_url \"${bottle_root_url}\"" Formula/plex-tui.rb; then
|
|
155
|
+
needed=true
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
{
|
|
159
|
+
echo "needed=${needed}"
|
|
160
|
+
echo "bottle_release=${bottle_release}"
|
|
161
|
+
echo "bottle_root_url=${bottle_root_url}"
|
|
162
|
+
} >> "$GITHUB_OUTPUT"
|
|
163
|
+
|
|
164
|
+
if [ "$needed" = "false" ]; then
|
|
165
|
+
echo "Homebrew tap is already up to date with bottle metadata."
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
- name: Build Homebrew bottle
|
|
169
|
+
if: steps.release.outputs.publish == 'true' && steps.tap-update.outputs.needed == 'true'
|
|
170
|
+
id: bottle
|
|
171
|
+
timeout-minutes: 60
|
|
172
|
+
working-directory: ${{ steps.tap.outputs.path }}
|
|
173
|
+
env:
|
|
174
|
+
BOTTLE_ROOT_URL: ${{ steps.tap-update.outputs.bottle_root_url }}
|
|
175
|
+
VERSION: ${{ steps.release.outputs.version }}
|
|
176
|
+
run: |
|
|
177
|
+
set -euo pipefail
|
|
178
|
+
|
|
179
|
+
brew --version
|
|
180
|
+
brew config
|
|
181
|
+
brew info so1omon563/plex-tui/plex-tui
|
|
182
|
+
|
|
183
|
+
(
|
|
184
|
+
while true; do
|
|
185
|
+
sleep 60
|
|
186
|
+
echo "Still building Homebrew bottle for plex-tui ${VERSION} at $(date -u +%Y-%m-%dT%H:%M:%SZ)."
|
|
187
|
+
done
|
|
188
|
+
) &
|
|
189
|
+
heartbeat_pid=$!
|
|
190
|
+
trap 'kill "$heartbeat_pid" 2>/dev/null || true' EXIT
|
|
191
|
+
|
|
192
|
+
brew uninstall --ignore-dependencies so1omon563/plex-tui/plex-tui >/dev/null 2>&1 || true
|
|
193
|
+
brew install --verbose --build-bottle so1omon563/plex-tui/plex-tui
|
|
194
|
+
kill "$heartbeat_pid" 2>/dev/null || true
|
|
195
|
+
trap - EXIT
|
|
196
|
+
|
|
197
|
+
rm -f plex-tui--*.bottle.json plex-tui--*.bottle.tar.gz
|
|
198
|
+
brew bottle \
|
|
199
|
+
--json \
|
|
200
|
+
--no-rebuild \
|
|
201
|
+
--root-url "$BOTTLE_ROOT_URL" \
|
|
202
|
+
so1omon563/plex-tui/plex-tui
|
|
203
|
+
|
|
204
|
+
bottle_json="$(find "$PWD" -maxdepth 1 -name 'plex-tui--*.bottle.json' -print -quit)"
|
|
205
|
+
if [ -z "$bottle_json" ]; then
|
|
206
|
+
echo "brew bottle did not produce bottle JSON" >&2
|
|
207
|
+
exit 1
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
bottle_dir="${RUNNER_TEMP}/homebrew-bottles"
|
|
211
|
+
rm -rf "$bottle_dir"
|
|
212
|
+
mkdir -p "$bottle_dir"
|
|
213
|
+
python "${GITHUB_WORKSPACE}/scripts/prepare_homebrew_bottle_assets.py" \
|
|
214
|
+
"$bottle_json" \
|
|
215
|
+
--output-dir "$bottle_dir"
|
|
216
|
+
|
|
217
|
+
brew bottle --merge --write --no-commit "$bottle_json"
|
|
218
|
+
|
|
219
|
+
{
|
|
220
|
+
echo "json_path=${bottle_json}"
|
|
221
|
+
echo "upload_dir=${bottle_dir}"
|
|
222
|
+
} >> "$GITHUB_OUTPUT"
|
|
223
|
+
|
|
224
|
+
- name: Publish Homebrew bottle assets
|
|
225
|
+
if: steps.release.outputs.publish == 'true' && steps.tap-update.outputs.needed == 'true'
|
|
226
|
+
working-directory: ${{ steps.bottle.outputs.upload_dir }}
|
|
227
|
+
env:
|
|
228
|
+
GH_TOKEN: ${{ secrets.PACKAGING_PR_TOKEN }}
|
|
229
|
+
VERSION: ${{ steps.release.outputs.version }}
|
|
230
|
+
BOTTLE_RELEASE: ${{ steps.tap-update.outputs.bottle_release }}
|
|
231
|
+
run: |
|
|
232
|
+
set -euo pipefail
|
|
233
|
+
|
|
234
|
+
if gh release view "$BOTTLE_RELEASE" --repo so1omon563/homebrew-plex-tui >/dev/null 2>&1; then
|
|
235
|
+
gh release edit "$BOTTLE_RELEASE" \
|
|
236
|
+
--repo so1omon563/homebrew-plex-tui \
|
|
237
|
+
--title "plex-tui ${VERSION} Homebrew bottle"
|
|
238
|
+
else
|
|
239
|
+
gh release create "$BOTTLE_RELEASE" \
|
|
240
|
+
--repo so1omon563/homebrew-plex-tui \
|
|
241
|
+
--target main \
|
|
242
|
+
--title "plex-tui ${VERSION} Homebrew bottle" \
|
|
243
|
+
--notes "Homebrew bottle assets for plex-tui ${VERSION}."
|
|
244
|
+
fi
|
|
245
|
+
|
|
246
|
+
gh release upload "$BOTTLE_RELEASE" ./* \
|
|
247
|
+
--repo so1omon563/homebrew-plex-tui \
|
|
248
|
+
--clobber
|
|
249
|
+
|
|
250
|
+
- name: Audit formula
|
|
251
|
+
if: steps.release.outputs.publish == 'true' && steps.tap-update.outputs.needed == 'true'
|
|
138
252
|
working-directory: ${{ steps.tap.outputs.path }}
|
|
139
253
|
run: |
|
|
140
254
|
brew audit --strict --online so1omon563/plex-tui/plex-tui
|
|
141
255
|
|
|
142
256
|
- name: Commit tap update
|
|
143
|
-
if: steps.release.outputs.publish == 'true'
|
|
257
|
+
if: steps.release.outputs.publish == 'true' && steps.tap-update.outputs.needed == 'true'
|
|
144
258
|
id: commit
|
|
145
259
|
working-directory: ${{ steps.tap.outputs.path }}
|
|
146
260
|
env:
|
|
@@ -172,15 +286,18 @@ jobs:
|
|
|
172
286
|
GH_TOKEN: ${{ secrets.PACKAGING_PR_TOKEN }}
|
|
173
287
|
VERSION: ${{ steps.release.outputs.version }}
|
|
174
288
|
BRANCH: ${{ steps.commit.outputs.branch }}
|
|
289
|
+
BOTTLE_RELEASE: ${{ steps.tap-update.outputs.bottle_release }}
|
|
175
290
|
run: |
|
|
176
291
|
set -euo pipefail
|
|
177
292
|
|
|
293
|
+
pr_body="$(printf 'Automated Homebrew tap update for plex-tui %s.\n\nIncludes the generated bottle metadata for %s.\n' "$VERSION" "$BOTTLE_RELEASE")"
|
|
294
|
+
|
|
178
295
|
pr_url="$(gh pr create \
|
|
179
296
|
--repo so1omon563/homebrew-plex-tui \
|
|
180
297
|
--base main \
|
|
181
298
|
--head "$BRANCH" \
|
|
182
299
|
--title "Update plex-tui to ${VERSION}" \
|
|
183
|
-
--body "
|
|
300
|
+
--body "$pr_body")"
|
|
184
301
|
|
|
185
302
|
gh pr merge "$pr_url" \
|
|
186
303
|
--repo so1omon563/homebrew-plex-tui \
|
|
@@ -184,6 +184,11 @@ Pull requests should include:
|
|
|
184
184
|
Use PRs for repository changes. When publishing local commits, branch from
|
|
185
185
|
`main` with a scoped name such as `codex/release-prep`, push that branch, and
|
|
186
186
|
open a draft PR instead of pushing directly to `main`.
|
|
187
|
+
Create or switch to a scoped branch before doing repo work; do not keep feature
|
|
188
|
+
work in the local `main` working tree.
|
|
189
|
+
Repo work is not complete when a branch is merely pushed. Treat the workflow as
|
|
190
|
+
open until there is a draft PR for the branch or the work is explicitly
|
|
191
|
+
canceled.
|
|
187
192
|
|
|
188
193
|
`main` is protected by repository rulesets. Changes must flow through PRs; force
|
|
189
194
|
pushes and branch deletion are blocked. `plex-tui` requires the Python 3.11 and
|
|
@@ -198,6 +203,10 @@ merge should create the GitHub Release and publish package channels. Exceptions
|
|
|
198
203
|
are allowed for packaging-only follow-ups, automation repair, docs-only
|
|
199
204
|
maintenance, or other changes that should not create a new version tag; call out
|
|
200
205
|
the reason in the PR body when omitting a bump marker.
|
|
206
|
+
When a change is judged release-worthy, do not only add `#release`: run the
|
|
207
|
+
scripted release prep in the same branch and keep the release marker in the PR
|
|
208
|
+
title. A release decision means both staged release files and a publishing
|
|
209
|
+
marker are required unless the release is explicitly canceled.
|
|
201
210
|
|
|
202
211
|
When preparing or estimating a release version, fetch remote tags first with
|
|
203
212
|
`git fetch --tags origin` and base the decision on the latest origin tag, not
|
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.4.3 - 2026-06-18
|
|
6
|
+
|
|
7
|
+
- Made the default `mpv` window open with `--autofit=80%`, keeping custom
|
|
8
|
+
Settings overrides for exact pixel sizes or other percentage presets, and
|
|
9
|
+
made the old `1280x720` preset cycle back to Default.
|
|
10
|
+
- Added Homebrew bottle publishing to the post-release tap automation so macOS
|
|
11
|
+
installs can pour a prebuilt `plex-tui` virtualenv instead of rebuilding
|
|
12
|
+
Python resources from source, with bounded verbose CI diagnostics for bottle
|
|
13
|
+
builds.
|
|
14
|
+
- Documented that Homebrew bottles are published for Apple Silicon macOS, while
|
|
15
|
+
Intel macOS remains supported through Homebrew's source-build path.
|
|
16
|
+
|
|
5
17
|
## 0.4.2 - 2026-06-18
|
|
6
18
|
|
|
7
19
|
- Prefer episode stills and season posters for TV artwork while keeping show art
|
|
@@ -51,8 +51,12 @@ brew install plex-tui
|
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
The formula depends on `mpv` and `python@3.13`, then installs the Python app in
|
|
54
|
-
a Homebrew-managed virtualenv.
|
|
55
|
-
|
|
54
|
+
a Homebrew-managed virtualenv. Post-release automation publishes Homebrew
|
|
55
|
+
bottles for Apple Silicon macOS so supported installs can pour the prebuilt app
|
|
56
|
+
virtualenv instead of rebuilding Python resources such as `pillow` from source.
|
|
57
|
+
Intel macOS remains supported through Homebrew's source install path while that
|
|
58
|
+
platform continues to be supported. If no matching bottle is available,
|
|
59
|
+
Homebrew falls back to the source install path.
|
|
56
60
|
Homebrew 6 requires non-official taps to be trusted before Homebrew loads
|
|
57
61
|
formulae from them. The `plex-tui` formula only uses Homebrew/core formula
|
|
58
62
|
dependencies, so users do not need to trust any additional taps for `mpv`,
|
|
@@ -65,6 +69,10 @@ brew test so1omon563/plex-tui/plex-tui
|
|
|
65
69
|
brew audit --strict --online so1omon563/plex-tui/plex-tui
|
|
66
70
|
```
|
|
67
71
|
|
|
72
|
+
Install-time investigation lives in `docs/homebrew-install-time.md`. Use
|
|
73
|
+
`scripts/measure_homebrew_install.py` to capture no-op upgrade, reinstall,
|
|
74
|
+
fresh-install, and bottle-pour timings before changing the tap formula.
|
|
75
|
+
|
|
68
76
|
### Arch AUR
|
|
69
77
|
|
|
70
78
|
AUR package:
|
|
@@ -95,8 +103,8 @@ Validation is handled by `.github/workflows/aur.yml`, which runs inside
|
|
|
95
103
|
For each new app release:
|
|
96
104
|
|
|
97
105
|
1. Publish and validate PyPI.
|
|
98
|
-
2. Let the `Post-release Homebrew Publish` workflow update, validate,
|
|
99
|
-
the Homebrew tap formula.
|
|
106
|
+
2. Let the `Post-release Homebrew Publish` workflow update, bottle, validate,
|
|
107
|
+
and merge the Homebrew tap formula.
|
|
100
108
|
3. Let the `Post-release AUR Update` workflow update AUR metadata, open the
|
|
101
109
|
packaging PR, approve it, and enable auto-merge.
|
|
102
110
|
4. After the packaging PR merges and the `AUR Package` workflow passes on
|
|
@@ -111,9 +119,11 @@ The AUR automation requires:
|
|
|
111
119
|
`ssh://aur@aur.archlinux.org/plex-tui.git`.
|
|
112
120
|
|
|
113
121
|
The Homebrew automation uses `PACKAGING_PR_TOKEN`; that token must also be able
|
|
114
|
-
to
|
|
122
|
+
to create or update GitHub Releases, upload bottle assets, push branches, and
|
|
123
|
+
merge pull requests in `so1omon563/homebrew-plex-tui`.
|
|
115
124
|
|
|
116
125
|
## Known Follow-Up
|
|
117
126
|
|
|
118
|
-
-
|
|
127
|
+
- Continue validating Homebrew bottle publishing on release dry-runs and
|
|
128
|
+
follow-up packaging PRs.
|
|
119
129
|
- Consider standalone artifacts only after the app behavior stabilizes.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plex-tui
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.3
|
|
4
4
|
Summary: A small standalone Plex terminal UI.
|
|
5
5
|
Project-URL: Homepage, https://github.com/so1omon563/plex-tui
|
|
6
6
|
Project-URL: Issues, https://github.com/so1omon563/plex-tui/issues
|
|
@@ -108,9 +108,11 @@ brew install plex-tui
|
|
|
108
108
|
plex-tui --smoke
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
The Homebrew formula installs `mpv` automatically.
|
|
112
|
-
|
|
113
|
-
from source.
|
|
111
|
+
The Homebrew formula installs `mpv` automatically. Apple Silicon macOS installs
|
|
112
|
+
use prebuilt bottles when available so Homebrew can pour the app virtualenv
|
|
113
|
+
instead of rebuilding native Python dependencies such as `pillow` from source.
|
|
114
|
+
Intel macOS installs still use Homebrew's source-build path while that platform
|
|
115
|
+
continues to be supported.
|
|
114
116
|
Homebrew 6 requires non-official taps to be trusted before Homebrew loads
|
|
115
117
|
formulae from them. `plex-tui` only depends on formulae from Homebrew/core, so no
|
|
116
118
|
additional tap trust is required for its dependencies.
|
|
@@ -204,7 +206,11 @@ preferences are applied when matching streams are available, and the details
|
|
|
204
206
|
pane shows the effective playback choices. Playback mode defaults to
|
|
205
207
|
direct/default behavior and can be changed in Settings to force Plex
|
|
206
208
|
transcoding with Original, 1080p 8 Mbps, 720p 4 Mbps, or 480p 2 Mbps quality
|
|
207
|
-
presets.
|
|
209
|
+
presets. The default `mpv` launch uses `--autofit=80%` so videos open at a
|
|
210
|
+
comfortable size on modern displays; Settings can override this with values
|
|
211
|
+
such as `90%`, `1280x720`, or `80%x80%`. If an older config has an exact
|
|
212
|
+
`mpv_window_size = "1280x720"` override, cycle the mpv window-size setting once
|
|
213
|
+
to return to the Default preset.
|
|
208
214
|
|
|
209
215
|
## Key Bindings
|
|
210
216
|
|
|
@@ -71,9 +71,11 @@ brew install plex-tui
|
|
|
71
71
|
plex-tui --smoke
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
The Homebrew formula installs `mpv` automatically.
|
|
75
|
-
|
|
76
|
-
from source.
|
|
74
|
+
The Homebrew formula installs `mpv` automatically. Apple Silicon macOS installs
|
|
75
|
+
use prebuilt bottles when available so Homebrew can pour the app virtualenv
|
|
76
|
+
instead of rebuilding native Python dependencies such as `pillow` from source.
|
|
77
|
+
Intel macOS installs still use Homebrew's source-build path while that platform
|
|
78
|
+
continues to be supported.
|
|
77
79
|
Homebrew 6 requires non-official taps to be trusted before Homebrew loads
|
|
78
80
|
formulae from them. `plex-tui` only depends on formulae from Homebrew/core, so no
|
|
79
81
|
additional tap trust is required for its dependencies.
|
|
@@ -167,7 +169,11 @@ preferences are applied when matching streams are available, and the details
|
|
|
167
169
|
pane shows the effective playback choices. Playback mode defaults to
|
|
168
170
|
direct/default behavior and can be changed in Settings to force Plex
|
|
169
171
|
transcoding with Original, 1080p 8 Mbps, 720p 4 Mbps, or 480p 2 Mbps quality
|
|
170
|
-
presets.
|
|
172
|
+
presets. The default `mpv` launch uses `--autofit=80%` so videos open at a
|
|
173
|
+
comfortable size on modern displays; Settings can override this with values
|
|
174
|
+
such as `90%`, `1280x720`, or `80%x80%`. If an older config has an exact
|
|
175
|
+
`mpv_window_size = "1280x720"` override, cycle the mpv window-size setting once
|
|
176
|
+
to return to the Default preset.
|
|
171
177
|
|
|
172
178
|
## Key Bindings
|
|
173
179
|
|
|
@@ -124,9 +124,15 @@ be run manually with a release tag. It updates:
|
|
|
124
124
|
- Formula URL and sha256.
|
|
125
125
|
- Python resource blocks if dependencies changed.
|
|
126
126
|
- Formula test expectations if version output changed.
|
|
127
|
+
- Homebrew bottle assets and the generated formula `bottle do` block.
|
|
127
128
|
|
|
128
|
-
It
|
|
129
|
-
|
|
129
|
+
It builds the formula with `brew install --build-bottle`, generates bottle
|
|
130
|
+
metadata with `brew bottle --json`, uploads the bottle tarball to a
|
|
131
|
+
`plex-tui-X.Y.Z` GitHub Release in the tap repository, merges the generated
|
|
132
|
+
`bottle do` block into the formula, runs `brew audit --strict --online`, opens a
|
|
133
|
+
tap PR, and merges it. This uses `PACKAGING_PR_TOKEN`, which must have access to
|
|
134
|
+
create releases, upload assets, push branches, and merge pull requests in the
|
|
135
|
+
tap repository.
|
|
130
136
|
|
|
131
137
|
If the automated workflow cannot run, update and validate manually:
|
|
132
138
|
|
|
@@ -186,8 +192,9 @@ To verify post-release packaging without publishing a new app release, manually
|
|
|
186
192
|
dispatch the post-release workflows with the latest real release tag, for
|
|
187
193
|
example `v0.3.6`. A healthy idempotent run should:
|
|
188
194
|
|
|
189
|
-
- update and audit the Homebrew formula
|
|
190
|
-
|
|
195
|
+
- update, bottle, and audit the Homebrew formula when bottle metadata is
|
|
196
|
+
missing; then skip tap PR creation on later reruns when the formula and bottle
|
|
197
|
+
block are already current;
|
|
191
198
|
- regenerate and validate AUR metadata, then skip packaging PR auto-merge when
|
|
192
199
|
there is no diff.
|
|
193
200
|
|
|
@@ -32,8 +32,10 @@
|
|
|
32
32
|
requires the Python 3.11 and 3.13 checks before merge. Rulesets require PRs
|
|
33
33
|
with zero approving reviews so automation branches can merge after checks
|
|
34
34
|
without self-approval.
|
|
35
|
-
- Improve Homebrew install time; the current
|
|
36
|
-
|
|
35
|
+
- Improve Homebrew install time; baseline the current install/update paths with
|
|
36
|
+
`scripts/measure_homebrew_install.py`, then prioritize tap bottle automation.
|
|
37
|
+
The current formula works but builds Python resources from source, with
|
|
38
|
+
native compilation concentrated in `pillow`.
|
|
37
39
|
- Keep post-release package publishing fully automated across PyPI, Homebrew,
|
|
38
40
|
and AUR. Periodically dry-run existing release tags through the post-release
|
|
39
41
|
workflows to confirm Homebrew and AUR no-op cleanly when already current.
|
|
@@ -14,7 +14,11 @@ client_identifier = "plex-tui-your-stable-client-id"
|
|
|
14
14
|
# preferred_subtitle_language = "eng"
|
|
15
15
|
# subtitle_mode can be "auto", "none", or "preferred".
|
|
16
16
|
# subtitle_mode = "preferred"
|
|
17
|
-
# Optional mpv window size passed as --autofit.
|
|
17
|
+
# Optional mpv window size passed as --autofit. Empty uses the app default
|
|
18
|
+
# "80%" for a more comfortable window on modern displays.
|
|
19
|
+
# Examples: "90%", "1280x720", "80%x80%".
|
|
20
|
+
# Existing exact-size overrides such as "1280x720" stay exact until reset or
|
|
21
|
+
# changed in Settings.
|
|
18
22
|
# mpv_window_size = "1280x720"
|
|
19
23
|
# playback_mode can be "auto" for direct/default playback or "transcode" to
|
|
20
24
|
# force Plex transcoding.
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Homebrew Install-Time Investigation
|
|
2
|
+
|
|
3
|
+
The current Homebrew formula is correct for a Python application: it uses
|
|
4
|
+
`Language::Python::Virtualenv`, declares `python@3.13`, and installs explicit
|
|
5
|
+
Python `resource` blocks into a Homebrew-managed virtualenv. The slow path is
|
|
6
|
+
therefore expected formula work, not a known correctness bug.
|
|
7
|
+
|
|
8
|
+
## Current Hypothesis
|
|
9
|
+
|
|
10
|
+
Fresh installs are slow because Homebrew installs the app from source resources.
|
|
11
|
+
Most dependencies are pure Python, but `pillow` is a native dependency and is
|
|
12
|
+
the most likely expensive build. Even no-op updates can feel slow because
|
|
13
|
+
Homebrew still evaluates the tap, dependency state, Python resources, and the
|
|
14
|
+
installed virtualenv before deciding there is little to do.
|
|
15
|
+
|
|
16
|
+
Baseline measurements on Apple silicon with `plex-tui 0.4.2`:
|
|
17
|
+
|
|
18
|
+
| Scenario | Auto-update | Result |
|
|
19
|
+
| --- | --- | ---: |
|
|
20
|
+
| `brew upgrade plex-tui` no-op | disabled | 0.5s |
|
|
21
|
+
| `brew upgrade plex-tui` no-op | enabled | 4.7s |
|
|
22
|
+
| `brew reinstall plex-tui` from source | disabled | 49.6s |
|
|
23
|
+
| `brew install plex-tui` after uninstall | disabled | 49.6s |
|
|
24
|
+
| `brew install --force-bottle plex-tui` from local bottle | disabled | 3.3s |
|
|
25
|
+
| `brew test plex-tui` | n/a | 3.0s |
|
|
26
|
+
|
|
27
|
+
The source install output reported `/opt/homebrew/Cellar/plex-tui/0.4.2` was
|
|
28
|
+
"built in 47 seconds". The local bottle prototype avoided that build and poured
|
|
29
|
+
successfully in 3.3 seconds, then passed `brew test`.
|
|
30
|
+
|
|
31
|
+
Separate these timing buckets before changing packaging:
|
|
32
|
+
|
|
33
|
+
- Homebrew overhead: auto-update, tap loading, dependency resolution, and audit
|
|
34
|
+
checks.
|
|
35
|
+
- System dependencies: `mpv` and `python@3.13` installation or upgrades.
|
|
36
|
+
- App resources: Python source resources installed into `libexec`.
|
|
37
|
+
- Native compilation: currently expected to be dominated by `pillow`.
|
|
38
|
+
- Post-install checks: `brew test` and smoke execution.
|
|
39
|
+
|
|
40
|
+
## Dependency Layers
|
|
41
|
+
|
|
42
|
+
A truly first-time Homebrew install has two dependency layers:
|
|
43
|
+
|
|
44
|
+
- Formula dependencies: `mpv` and `python@3.13`, plus their recursive Homebrew
|
|
45
|
+
dependencies. On the measured machine these were already installed, but
|
|
46
|
+
`brew deps --installed so1omon563/plex-tui/plex-tui` listed the full runtime
|
|
47
|
+
stack, including `ffmpeg`, `vapoursynth`, `yt-dlp`, and many media libraries
|
|
48
|
+
below `mpv`.
|
|
49
|
+
- Python resources: the formula vendors every Python dependency into
|
|
50
|
+
`plex-tui`'s Homebrew-managed virtualenv. These resources are absent from a
|
|
51
|
+
fresh `plex-tui` install even if the user has similar packages elsewhere.
|
|
52
|
+
|
|
53
|
+
The Python resources currently installed by the formula are:
|
|
54
|
+
|
|
55
|
+
- `certifi`
|
|
56
|
+
- `charset-normalizer`
|
|
57
|
+
- `idna`
|
|
58
|
+
- `linkify-it-py`
|
|
59
|
+
- `markdown-it-py`
|
|
60
|
+
- `mdit-py-plugins`
|
|
61
|
+
- `mdurl`
|
|
62
|
+
- `pillow`
|
|
63
|
+
- `platformdirs`
|
|
64
|
+
- `PlexAPI`
|
|
65
|
+
- `Pygments`
|
|
66
|
+
- `requests`
|
|
67
|
+
- `rich`
|
|
68
|
+
- `textual`
|
|
69
|
+
- `typing-extensions`
|
|
70
|
+
- `uc-micro-py`
|
|
71
|
+
- `urllib3`
|
|
72
|
+
|
|
73
|
+
Homebrew logs from a `--build-bottle` install showed each Python resource being
|
|
74
|
+
built as a wheel from its source resource. Only `pillow` produced native
|
|
75
|
+
extensions and a compiler log. The installed virtualenv contains Pillow
|
|
76
|
+
extension modules such as `PIL/_imaging*.so`, and `brew linkage plex-tui` shows
|
|
77
|
+
links to `freetype`, `jpeg-turbo`, `libtiff`, and `little-cms2`.
|
|
78
|
+
|
|
79
|
+
## Measurement Script
|
|
80
|
+
|
|
81
|
+
Use the local measurement helper from the repository root:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
python3 scripts/measure_homebrew_install.py --help
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Measure a no-op update path without changing the installed formula:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
python3 scripts/measure_homebrew_install.py --upgrade --test --output /tmp/plex-tui-brew-noop.json
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Measure a reinstall of the current formula:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
python3 scripts/measure_homebrew_install.py --reinstall --test --output /tmp/plex-tui-brew-reinstall.json
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Measure a fresh formula install after uninstalling only `plex-tui`:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
python3 scripts/measure_homebrew_install.py --fresh-install --test --output /tmp/plex-tui-brew-fresh.json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Measure a bottle-pour path after adding a valid `bottle do` block to the tap
|
|
106
|
+
formula:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
python3 scripts/measure_homebrew_install.py --fresh-install --force-bottle --test --output /tmp/plex-tui-brew-bottle.json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
By default, the script sets `HOMEBREW_NO_AUTO_UPDATE=1` so measurements focus on
|
|
113
|
+
the formula and dependency work. Add `--allow-auto-update` when measuring the
|
|
114
|
+
full user-facing command cost.
|
|
115
|
+
|
|
116
|
+
## Candidate Improvements
|
|
117
|
+
|
|
118
|
+
### Bottle The Tap
|
|
119
|
+
|
|
120
|
+
Build and publish Homebrew bottles for `so1omon563/homebrew-plex-tui`, then add
|
|
121
|
+
a `bottle do` block to the formula. Homebrew automatically downloads a matching
|
|
122
|
+
bottle when one exists, which should avoid rebuilding the virtualenv and native
|
|
123
|
+
resources during ordinary installs.
|
|
124
|
+
|
|
125
|
+
This is the highest-impact path for first-install time in the current
|
|
126
|
+
measurement. A local `arm64_tahoe` bottle for `0.4.2` was 3.1MB, relocatable
|
|
127
|
+
with `cellar: :any`, and poured in 3.3 seconds. It requires a tap-side bottle
|
|
128
|
+
workflow, storage for bottle artifacts, formula `bottle do` updates, and
|
|
129
|
+
verification on the supported macOS runners.
|
|
130
|
+
|
|
131
|
+
### Reduce Runtime Dependencies
|
|
132
|
+
|
|
133
|
+
Review whether any dependency can move from required runtime to an optional
|
|
134
|
+
feature. `pillow` is the main candidate because it enables rich artwork paths
|
|
135
|
+
but also brings native build cost. Removing or optionalizing it would require a
|
|
136
|
+
deliberate app fallback so Homebrew users do not lose expected artwork behavior
|
|
137
|
+
silently.
|
|
138
|
+
|
|
139
|
+
This path can improve both Homebrew and PyPI installs, but it changes app
|
|
140
|
+
capability and needs product judgment.
|
|
141
|
+
|
|
142
|
+
### Keep The Formula Source-Based
|
|
143
|
+
|
|
144
|
+
Keep `virtualenv_install_with_resources` unchanged and improve docs only. This
|
|
145
|
+
preserves the simplest, most standard formula and avoids bottle automation, but
|
|
146
|
+
it does not solve the initial-install pain.
|
|
147
|
+
|
|
148
|
+
### Standalone Artifacts
|
|
149
|
+
|
|
150
|
+
Standalone app artifacts could bypass Python resource installation entirely, but
|
|
151
|
+
they are a larger distribution project. Keep this behind bottle exploration
|
|
152
|
+
unless app packaging requirements change.
|
|
153
|
+
|
|
154
|
+
## Next Slice
|
|
155
|
+
|
|
156
|
+
1. Capture baseline timings for no-op upgrade, reinstall, and fresh install on
|
|
157
|
+
Apple silicon. Done for `0.4.2`.
|
|
158
|
+
2. Prototype bottle creation in the tap repo and compare bottle-pour timing
|
|
159
|
+
against the baseline. Done locally for `arm64_tahoe`.
|
|
160
|
+
3. Add tap automation that builds bottles, uploads them to a release asset, and
|
|
161
|
+
merges the generated `bottle do` block. Implemented in the post-release
|
|
162
|
+
Homebrew workflow.
|
|
163
|
+
4. Keep optional `pillow` dependency reduction as a secondary path if bottle
|
|
164
|
+
automation proves too brittle.
|
|
165
|
+
5. Update `PACKAGING.md` and the tap README once bottle automation is proven.
|
|
166
|
+
|
|
167
|
+
## References
|
|
168
|
+
|
|
169
|
+
- Homebrew Bottles: https://docs.brew.sh/Bottles
|
|
170
|
+
- Homebrew Python formula guidance:
|
|
171
|
+
https://docs.brew.sh/Python-for-Formula-Authors
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
pkgbase = plex-tui
|
|
2
2
|
pkgdesc = Standalone Plex terminal UI with mpv playback
|
|
3
|
-
pkgver = 0.4.
|
|
3
|
+
pkgver = 0.4.2
|
|
4
4
|
pkgrel = 1
|
|
5
5
|
url = https://github.com/so1omon563/plex-tui
|
|
6
6
|
arch = any
|
|
@@ -16,7 +16,7 @@ pkgbase = plex-tui
|
|
|
16
16
|
depends = python-plexapi
|
|
17
17
|
depends = python-rich
|
|
18
18
|
depends = python-textual
|
|
19
|
-
source = plex-tui-0.4.
|
|
20
|
-
sha256sums =
|
|
19
|
+
source = plex-tui-0.4.2.tar.gz::https://github.com/so1omon563/plex-tui/archive/refs/tags/v0.4.2.tar.gz
|
|
20
|
+
sha256sums = 0d7832319a5468a89ed4eeb2dd0bad543663922f215765f40490d9e67723dac7
|
|
21
21
|
|
|
22
22
|
pkgname = plex-tui
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Maintainer: so1omon
|
|
2
2
|
pkgname=plex-tui
|
|
3
|
-
pkgver=0.4.
|
|
3
|
+
pkgver=0.4.2
|
|
4
4
|
pkgrel=1
|
|
5
5
|
pkgdesc="Standalone Plex terminal UI with mpv playback"
|
|
6
6
|
arch=("any")
|
|
@@ -22,7 +22,7 @@ makedepends=(
|
|
|
22
22
|
"python-wheel"
|
|
23
23
|
)
|
|
24
24
|
source=("$pkgname-$pkgver.tar.gz::$url/archive/refs/tags/v$pkgver.tar.gz")
|
|
25
|
-
sha256sums=("
|
|
25
|
+
sha256sums=("0d7832319a5468a89ed4eeb2dd0bad543663922f215765f40490d9e67723dac7")
|
|
26
26
|
|
|
27
27
|
build() {
|
|
28
28
|
cd "$pkgname-$pkgver"
|
|
@@ -22,12 +22,21 @@ For each `plex-tui` release:
|
|
|
22
22
|
|
|
23
23
|
1. Update the formula URL and sha256 for the new PyPI sdist.
|
|
24
24
|
2. Refresh Python resource blocks if dependencies changed.
|
|
25
|
-
3.
|
|
25
|
+
3. Build and publish a Homebrew bottle, then merge the generated `bottle do`
|
|
26
|
+
block into the formula.
|
|
27
|
+
4. Run:
|
|
26
28
|
|
|
27
29
|
```bash
|
|
28
30
|
brew test so1omon563/plex-tui/plex-tui
|
|
29
31
|
brew audit --strict --online so1omon563/plex-tui/plex-tui
|
|
30
32
|
```
|
|
31
33
|
|
|
32
|
-
The
|
|
33
|
-
resources such as `pillow` are built from source.
|
|
34
|
+
The source formula is correct but slow on first install because native Python
|
|
35
|
+
resources such as `pillow` are built from source. Release automation publishes
|
|
36
|
+
Apple Silicon macOS bottles so supported installs can pour a prebuilt
|
|
37
|
+
virtualenv. Intel macOS continues to use Homebrew's source-build path while that
|
|
38
|
+
platform remains supported.
|
|
39
|
+
|
|
40
|
+
Install-time investigation notes and the baseline measurement helper live in the
|
|
41
|
+
main repo at `docs/homebrew-install-time.md` and
|
|
42
|
+
`scripts/measure_homebrew_install.py`.
|