Add scripts that help managing plugins and their repos

This commit is contained in:
Odd Stråbø 2021-03-28 23:45:22 +02:00
parent 7d880d7128
commit 13fdb390c1
8 changed files with 301 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
artifacts/
test_repo/

28
README.md Normal file
View File

@ -0,0 +1,28 @@
Plugin tools
============
Dependencies
------------
- [hub](https://hub.github.com/)
- [jprm](https://pypi.org/project/jprm/) (building)
- dotnet (building)
- git
- bash
- python3
Tools
-----
- `build_all.sh`
Builds (and publishes) all plugins.
- `build_plugin.sh`
Builds (and publishes) a single plugin.
- `show_drafts.sh`
Lists draft releases prepared by release-drafter.
- `show_issues.sh`
Lists all open issues on the plugin repositories.
- `show_pullrequests.sh`
Lists all open pull-requests on the plugin repositories.
- `update_submodules.py`
Updates sub-modules, adds new plugins from the org, and removes archived/moved ones.

40
build_all.sh Executable file
View File

@ -0,0 +1,40 @@
#!/bin/bash
#set -x
MY=$(dirname $(realpath -s "${0}"))
export ARTIFACT_DIR="${MY}/artifacts"
mkdir -p "${ARTIFACT_DIR}"
DEFAULT_REPO_DIR="${MY}/test_repo"
DEFAULT_REPO_URL="http://localhost:8080"
export JELLYFIN_REPO=${JELLYFIN_REPO:-$DEFAULT_REPO_DIR}
export JELLYFIN_REPO_URL=${JELLYFIN_REPO_URL:-$DEFAULT_REPO_URL}
export VERSION_SUFFIX=$(date -u +%y%m.%d%H.%M%S)
FAILED=()
for plugin in $(find . -maxdepth 1 -mindepth 1 -type d -name 'jellyfin-plugin-*' | sort); do
name=$(basename $plugin)
if [ "$name" = "jellyfin-plugin-meta" ]; then
continue
fi
pushd $plugin > /dev/null
echo -e "\n##### ${name} #####"
bash $MY/build_plugin.sh || {
FAILED+=("$name")
}
popd > /dev/null
done
if [ ! ${#FAILED[@]} -eq 0 ]; then
echo -e "\n\nThe following plugins failed to compile:" > /dev/stderr
for plugin in "${FAILED[@]}"; do
echo " - $plugin" > /dev/stderr
done
exit 1
fi

64
build_plugin.sh Executable file
View File

@ -0,0 +1,64 @@
#!/bin/bash
#
# Copyright (c) 2020 - Odd Strabo <oddstr13@openshell.no>
#
#
# The Unlicense
# =============
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to <http://unlicense.org/>
#
MY=$(dirname $(realpath -s "${0}"))
JPRM="jprm"
DEFAULT_REPO_DIR="${MY}/test_repo"
DEFAULT_REPO_URL="http://localhost:8080"
PLUGIN=${1:-${PLUGIN:-.}}
ARTIFACT_DIR=${ARTIFACT_DIR:-"${MY}/artifacts"}
mkdir -p "${ARTIFACT_DIR}"
JELLYFIN_REPO=${JELLYFIN_REPO:-${DEFAULT_REPO_DIR}}
JELLYFIN_REPO_URL=${JELLYFIN_REPO_URL:-${DEFAULT_REPO_URL}}
# Each segment of the version is a 16bit number.
# Max number is 65535.
VERSION_SUFFIX=${VERSION_SUFFIX:-$(date -u +%y%m.%d%H.%M%S)}
meta_version=$(grep -Po '^ *version: * "*\K[^"$]+' "${PLUGIN}/build.yaml")
VERSION=${VERSION:-$(echo $meta_version | sed 's/\.[0-9]*\.[0-9]*\.[0-9]*$/.'"$VERSION_SUFFIX"'/')}
# !!! VERSION IS OVERWRITTEN HERE
#VERSION="${meta_version}"
find "${PLUGIN}" -name project.assets.json -exec rm -v '{}' ';'
zipfile=$($JPRM --verbosity=debug plugin build "${PLUGIN}" --output="${ARTIFACT_DIR}" --version="${VERSION}") && {
$JPRM --verbosity=debug repo add --url=${JELLYFIN_REPO_URL} "${JELLYFIN_REPO}" "${zipfile}"
}
exit $?

52
show_drafts.sh Executable file
View File

@ -0,0 +1,52 @@
#!/bin/bash
rstrip_ver() {
if [ -z "$1" ]; then
grep -Po "^.*?(?=(\.0\.0\.0|\.0\.0|\.0)?$)"
else
echo $1 | grep -Po "^.*?(?=(\.0\.0\.0|\.0\.0|\.0)?$)"
fi
}
esc=$(printf '\033')
colorize_changelog() {
#1 pr number
#2 list char
#3 pr submitter
sed -r -e "s/\\((#[0-9]+)\)/(${esc}[32m\1${esc}[0m)/g" \
-e "s/^\s*[*+-]\s*/ ${esc}[1;30m-${esc}[0m /g" \
-e "s/@([^ ]+)$/${esc}[1;30m@${esc}[0;36m\1${esc}[0m/gi"
}
echo "Fetching git release info..."
DRAFTS=$(
git submodule foreach \
'hub release --include-drafts -f "$(basename $PWD)|%T|%t|%S%n"' \
| grep draft
)
IFS=$'\n'
for draft in $DRAFTS; do
IFS='|' parts=(${draft})
name=${parts[0]}
tag=${parts[1]}
title=${parts[2]}
echo
echo -e "\e[1m$name\e[0m: $title"
pushd $name > /dev/null
description=$(hub release show $tag)
changes=$(echo $description | grep -Po '^\s*\K\*.*$' )
meta_version=$(grep -Po "version: ?[\"']?\K.*(?=[\"']$)" build.yaml | rstrip_ver)
draft_version=$(echo $tag | grep -Po 'v\K.*' | rstrip_ver)
if [ "$meta_version" != "$draft_version" ]; then
echo -e " \e[1;31mVersion bump needed!"
echo -e " \e[0;31mDraft is for v\e[0m\e[1m$draft_version\e[0;31m, but build.yaml specifies v\e[0m\e[1m$meta_version\e[0m"
fi
echo $changes | colorize_changelog
popd > /dev/null
done

4
show_issues.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
git submodule foreach \
hub issue --format='%sC%>(8)%i%Creset %t% l%n%Cblue% U%Creset%n' --color=always

4
show_pullrequests.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
git submodule foreach \
hub pr list --format='%pC%>(8)%i%Creset %t% l%n%Cblue% U%Creset%n' --color=always

107
update_submodules.py Executable file
View File

@ -0,0 +1,107 @@
#!/usr/bin/env python3
import os
import subprocess
import requests
import time
try:
subprocess.run(["git", "diff", "--staged", "--quiet", "--exit-code"], check=True)
except subprocess.SubprocessError:
print("Error: You have staged changes!")
exit(1)
available = []
fetched = []
failed = []
removed = []
added = []
def update(_name, url=None):
if not os.path.exists(_name):
print("Adding {} @ {}".format(_name, url))
subprocess.run(["git", "submodule", "add", "--force", "-b", "master", url, _name], check=True)
added.append(_name)
subprocess.run(["git", "submodule", "update", "--init", "--remote", "--checkout", "--force", _name], check=True)
subprocess.run(["git", "fetch", "--all", "--tags"], cwd=_name, check=True)
subprocess.run(["git", "checkout", "-f", "-B", "master", "origin/master"], cwd=_name, check=True)
fetched.append(_name)
def remove(_name):
if os.path.exists(_name):
print("Removing {}".format(_name))
subprocess.run(["git", "rm", _name], check=True)
removed.append(_name)
page_num = 1
per_page = 100
PAGINATION_URL = "https://api.github.com/orgs/jellyfin/repos?sort=created&per_page={per}&page={page}"
next = PAGINATION_URL.format(per=per_page, page=page_num)
while next:
resp = requests.get(next)
repos = resp.json()
page_num += 1
next = PAGINATION_URL.format(per=per_page, page=page_num)
if len(repos) < per_page:
next = None
for repo in repos:
_name = repo.get("name")
url = repo.get("clone_url")
if _name.startswith("jellyfin-plugin-"):
available.append(_name)
try:
update(_name, url)
pass
except Exception as e:
failed.append((_name, e))
for repo in os.listdir("."):
if repo in fetched:
continue
if not os.path.isdir(repo):
continue
if not repo.startswith("jellyfin-plugin-"):
continue
try:
if not repo in available:
remove(repo)
except Exception as e:
failed.append((repo, e))
if failed:
print("The following repositories failed to update:")
for repo, e in failed:
print(repo, e)
commit_message = ["Updated plugin submodules"]
if added:
commit_message.append("")
commit_message.append("Added")
commit_message.append("-----")
commit_message.append("")
for plugin in added:
commit_message.append("- {}".format(plugin))
if removed:
commit_message.append("")
commit_message.append("Removed")
commit_message.append("-------")
commit_message.append("")
for plugin in removed:
commit_message.append("- {}".format(plugin))
subprocess.run(["git", "commit", "-m", "\n".join(commit_message)])