Minimal plugin manager for Godot, inspired by vim-plug
This version is only compatible with Godot 4.x, check out godot3 branch for older version
- Features
- Commands
- Configs
- Installation
- Getting Started
- Post Update Hook
- Version Control
- More Examples
- Known Limitations
- Minimal
- No dependencies other than Godot and git
- Self-contained
- Zero learning curve
- Config file written in GDScript
- Flexible
- Support both commandline and UI(see gd-plug-ui)
- Version freeze
- Freeze plugins by branch, tag or commit
- Reduce remote repository size
- Dependencies can now be installed with just a single-line shell command
- Clean uninstall
- *.import files or import resources located in /.import that generated by plugin will be cleaned as plugin uninstalled
- Multi-threaded
- Parallel download/installation
godot --headless -s plug.gd {action} {options...}
- Actions
init
: Initialize current project by creatingplug.gd
at rootstatus
: Check the status of plugins(installed, added or removed), execute this command whenever in doubtsinstall
, aliasupdate
: Install or update(to latest version if not freezed) "plugged" plugins based onplug.gd
, or uninstall "unplugged" pluginsuninstall
: Uninstall all plugins, regardless ofplug.gd
clean
: Clean unused files/folders from/.plugged
upgrade
: Upgradeaddons/gd-plug/plug.gd
to the latest versionversion
: Print current version of gd-plug
- Options
production
: Install only plugins not marked asdev
, or uninstall already installeddev
pluginstest
: Testing mode, no files will be installed/uninstalled while files to be installed/uninstalled will be printed, mainly used withinstall
oruninstall
force
: Force gd-plug to overwrite destination files when runninginstall
command. By default, gd-plug will terminate installation of plugin when any of the file found to be overwriting user files.keep-import-file
: Keep ".import" files generated by plugin, when rununinstall
commandkeep-import-resource-file
: Keep files located in /.import that generated by plugin, when rununinstall
commanddebug
, aliasd
: Print debug messagedetail
: Print with datetime and log level, "[{time}] [{level}] {msg}"quiet
, aliasq
,silent
: Disable logging
plug(src, args={})
Source:
- Github repo: "username/repo", for example, "imjp94/gd-plug"
or
- Any valid git url
Arguments:
include
: Array of strings that define what files or directory to include. Onlyaddons/
will be included if this option omitted. No expression(like wildcard (*)) supported yet.exclude
: Array of strings that define what files or directory to exclude. No expression(like wildcard (*))supported yet.branch
: Name of branch to freeze totag
: Name of tag to freeze tocommit
: Commit hash string to freeze to, must be full length 40 digits commit-hash ,for example,7a642f90d3fb88976dd913051de994e58e838d1a
.dev
: Boolean to mark the plugin asdev
or not, plugin marked asdev
will not be installed whenproduction
command givenon-updated
: Post update hook, a function name declared inplug.gd
that will be called whenever the plugin installed/updated. See Post Update Hook
-
gd-plug
Install directly from Godot Asset Library
or
Download this repository, move
addons
to your{project_dir}
-
git
Download and install git
git must be set to environment variable
-
gd-plug-ui(optional)
User interface for gd-plug, not required when working with commandline
Create plug.gd
at your project root, as below:
extends "res://addons/gd-plug/plug.gd"
func _plugging():
# Declare your plugins in here with plug(src, args)
pass
Or run
init
command: "godot --headless -s addons/plug.gd init
"
Declare plugins in plug.gd
under _plugging()
, for example:
extends "res://addons/gd-plug/plug.gd"
func _plugging():
# Declare your plugins in here with plug(src, args)
# By default, only "addons/" directory will be installed
# Proudly made by me too!
plug("imjp94/UIDesignTool")
plug("imjp94/gd-YAFSM")
# Tools
plug("fenix-hub/godot-engine.github-integration")
plug("EricEzaM/godot-color-palette")
# Unit test
plug("bitwes/Gut")
# By Zylann
plug("Zylann/godot_scatter_plugin")
plug("Zylann/godot_heightmap_plugin")
Finally, run install
command in shell
# --no-window is optional to disable godot window
godot --no-window -s plug.gd install
Post update hook can be connected in 3 ways:
- Declare in plug() argument
plug(src, {"on_updated": "post_update"})
- Connect to
update
signalconnect("updated", self, "post_update")
- Overwriting
_on_updated
functionfunc _on_update(plugin)
Post update hook always returned with one argument - dictionary that store information about the plugin
func post_update(plugin):
print("%s updated" % plugin.name)
What can be ignored from version control system?
/.plugged
: Plugins' git repo are cloned to this directory/addons
: Based on preference, but now dependencies can be safely ignored since it will be managed by gd-plug
What should be added to version control system?
plug.gd
: Dependency config fileaddons/gd-plug/plug.gd
: gd-plug's core
For most of the case, a plugin can be "plugged" without any extra configuration, as by default gd-plug will extract whatever located in plugin's /addons
directory and install to current project's /addons
directory.
However, some plugin's repository may be structured differently, thus, different configuration needed.
- Addon files are not located in
/addons
directory, for example, Master-J/DecalCo-
Explicitly include the directory to install:
plug("Master-J/DecalCo", {"include": ["decalco/"]})
-
- Repository contains only addons files, for example, HungryProton/scatter
- Change
install_root
to destination directory and include all files:plug("HungryProton/scatter", {"install_root": "addons/scatter", "include": ["."]})
- Change
extends "res://addons/gd-plug/plug.gd"
func _plugging():
# Declare your plugins in here with plug(src, args)
# By default, only "addons/" directory will be installed
# Version freeze
plug("imjp94/UIDesignTool", {"branch": "demo"}) # Always pull update from "demo" branch
plug("imjp94/gd-YAFSM", {"tag": "1.0.0-stable"}) # Freeze to stable version
plug("imjp94/gd-plug", {"commit": "7a642f90d3fb88976dd913051de994e58e838d1a"}) # Must be full length 40 digits commit-hash
# Dev plugins, can be excluded or uninstalled with "production" command
plug("fenix-hub/godot-engine.github-integration", {"dev": true})
plug("EricEzaM/godot-color-palette", {"dev": true})
# Post update hook
plug("bitwes/Gut", {"on_updated": "_on_GUT_updated"})
# It works even if the files are not located in "addons/"
plug("Master-J/DecalCo", {"include": ["decalco/"]})
# Repo that contains only addon files
plug("HungryProton/scatter", {"install_root": "addons/scatter", "include": ["."]})
# Source other than github
plug("https://gitlab.com/Xecestel/sound-manager") # Gitlab
plug("file:///D/Godot/local-project/.git") # Local git repo
connect("updated", "_on_plugin_updated")
func _on_updated(plugin):
# Override to catch all updated plugins
match plugin.name:
"imjp94/gd-plug":
print("Use upgrade command!")
func _on_GUT_updated(plugin):
print("%s updated" % plugin.name)
print("Installed files: " + plugin.dest_files)
func _on_plugin_updated(plugin):
# Catch all updated plugins with signal
print("%s post update hook with signal" % plugin.name)
- Sometimes random .import files will be unable to remove, while the reason behind it still remains unknown.
- Workaround: Read output for those .import files that failed to remove, and manually delete them.
autoload
script references in project setting are not cleared as plugin uninstalled.- Workaround: Manually remove
autoload
scripts from project setting
- Workaround: Manually remove
- Binary files in used by Godot can't be removed by gd-plug, when plugin uninstalled with editor opened. For example, Zylann/godot_heightmap_plugin's GDNative binaries.
- Workaround: Quit editor, then execute
clean
command or manually remove plugin folder from/.plugged
- Workaround: Quit editor, then execute