Last active
October 11, 2023 02:14
-
-
Save erodozer/ca172bb3b8dbbea1abf5cb047062abca to your computer and use it in GitHub Desktop.
Godot github package dependency helper script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# godot-package helper | |
# @author Erodozer <[email protected]> | |
# | |
# Simple Bach Script that fetches and merges standard godot addon repositories from github | |
# to your project. You can use this instead of Godot's Asset Library if you wish to | |
# include dependencies in your projects while developing, but not include them in your git. | |
# | |
# Run this from the root directory of your project | |
# | |
# It parses a json file called godot_packages.json with the following schema | |
# | |
# [ | |
# { | |
# # one of | |
# "github": "<user>/<repo>", | |
# "git": "<giturl>", | |
# | |
# # one of (branch with name main is used by default if none are set) | |
# "commit" ?: string, # pull by a specific commit hash, regardless of branch | |
# "branch" ?: string, # select the latest commit by branch name | |
# "tag" ?: string, # pull a specific tagged commit | |
# | |
# # specify specific folders to copy instead of dumping the whole repository | |
# "include" ?: [ | |
# "<path>(?:<rename>)" | |
# ] | |
# }, | |
# ... | |
# ] | |
# | |
# You may declare the same repository multiple times, as each pull is versioned by its point. | |
# | |
# | |
# Downloaded addons are merged into your project's addon's folder. | |
# If the addon as a LICENSE file in the root of the repo, it is copied to the addon's nested folder | |
# .gitignore files are also added to the nested folder. | |
# | |
# | |
# Requires: | |
# unzip | |
# jq | |
# wget (optional, only if using github references) | |
# git (optional, only if using git urls) | |
TMP_DIR=".godot-addon-tmp" | |
# create the dir tree for our work | |
mkdir -p $TMP_DIR | |
mkdir -p "$TMP_DIR/archives" | |
mkdir -p "$TMP_DIR/content" | |
echo "*" > "$TMP_DIR/.gitignore" | |
fetch_archive () { | |
row="$1" | |
# parse record | |
_jq() { | |
echo "${row}" | jq -r "${1}" | |
} | |
branch=$(_jq ".branch // \"main\"" ) | |
tag=$(_jq '.tag // empty') | |
commit=$(_jq '.commit // empty') | |
if [ ! -z "$commit" ]; then | |
treeish=$commit | |
elif [ ! -z "$tag" ]; then | |
treeish=$tag | |
else | |
treeish=$branch | |
fi | |
# pull archive using git | |
if [ ! -z $(_jq '.git // empty') ]; then | |
git_remote=$(_jq '.git') | |
echo "fetching from git $git_remote" | |
repo=${git_remote##*/} | |
repo=${repo%.git} | |
echo $repo | |
outfile="$TMP_DIR/archives/$repo-$treeish.zip" | |
# pull archive if it does not exist in the cache | |
if [ ! -f "$outfile" ]; then | |
git archive --remote=$git_remote -o $outfile $treeish | |
fi | |
# fetch archive from github (wget) | |
elif [ ! -z $(_jq '.github // empty') ]; then | |
github=$(_jq '.github') | |
user=$(echo "$github" | cut -d "/" -f 1) | |
repo=$(echo "$github" | cut -d "/" -f 2) | |
outfile="$(echo "$github" | tr "/" _)-$treeish" | |
if [ ! -z "$tag" ]; then | |
remote_url="https://github.com/$user/$repo/archive/refs/tags/$tag.zip" | |
elif [ ! -z "$commit" ]; then | |
remote_url="https://github.com/$user/$repo/archive/$commit.zip" | |
else | |
remote_url="https://github.com/$user/$repo/archive/refs/heads/$branch.zip" | |
fi | |
outfile="$TMP_DIR/archives/$outfile.zip" | |
if [ ! -f "$outfile" ]; then | |
wget -O $outfile $remote_url | |
fi | |
else | |
exit 1 "git or github must be declared" | |
fi | |
# extract the archive to a random folder to avoid collisions | |
dst_folder="$TMP_DIR/content/$RANDOM" | |
unzip $outfile -d $dst_folder | |
# overlap archive contents on addons folder | |
include=$(_jq '.include // empty') | |
mv_archive "$dst_folder/$repo-$treeish" "$include" | |
} | |
mv_archive() { | |
package_folder="$1" | |
include="$2" | |
echo "Including: $include" | |
# extract only the included directories | |
# useful for monorepos of multiple addons | |
if [ ! -z "$include" ]; then | |
echo "$include" | jq -cr ".[]" | while read d; do | |
src_folder=$(echo "$d" | cut -d ">" -f 1) | |
dst_folder=$(echo "$d" | cut -d ">" -f 2) | |
echo "copying $package_folder/addons/$src_folder to ./addons/$dst_folder" | |
rm -r "./addons/$dst_folder" | |
mv "$package_folder/addons/$src_folder" "./addons/$dst_folder" | |
echo "*" > "./addons/$dst_folder/.gitignore" | |
done; | |
else | |
addons_folder="$package_folder/addons" | |
for dir in $(ls -d $addons_folder/*); do | |
echo "*" > "$dir/.gitignore" | |
if [ ! -f "$dir/LICENSE" ]; then | |
cp "$package_folder/LICENSE" "$dir/LICENSE" | |
fi | |
if [ ! -f "$dir/README.md" ]; then | |
cp "$package_folder/README.md" "$dir/README.md" | |
fi | |
done | |
cp -r "$addons_folder" "." | |
fi | |
} | |
# fetch archives in parallel | |
for row in $(jq -c '.[]' godot_packages.json); do | |
fetch_archive $row & | |
done | |
wait | |
# remove expanded archive folders, keeping the cache | |
rm -r $TMP_DIR/content |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment