From ecbc38f9e9e2c82dbdcf2441a36e10dcf1f632b9 Mon Sep 17 00:00:00 2001 From: Jehan Date: Thu, 8 Oct 2020 13:58:19 +0200 Subject: [PATCH] plug-ins, extension: goat-exercises becomes a GIMP extension. This is an extension containing a few demo plug-ins. This is good to demonstrate the extension format. It will also allow to disable these plug-ins (if at some point, one doesn't want to show these demo plug-ins anymore). And finally it deals with the fact that our plug-in code is stupid, as it just tries to find the first executable with the same name (minus extension) as the plug-in folder. This doesn't go well on Windows, where the permission system is non-existent. So our code just ends up trying to run the first file with a similar name in a plug-in folder. As the C goat-exercise contains both an exe and the C source (and the system probably returns files in alphabetic order), GIMP under Windows tries to run the C source instead of the executable (this obviously doesn't go well). We could try to do more complex logics, like not aborting if the first file run fails and try the next one in the plug-in folder. Or maybe just rename the C file to another name. But any of these is just in the end the proof that our plug-in discovery right now is just bogus. The extension system is explicit, not based on randomly trying out files. Plug-ins entry points are explicitly listed in the metadata manifest. --- Makefile.am | 1 + configure.ac | 23 +++- extensions/.gitignore | 2 + extensions/Makefile.am | 2 + .../goat-exercises/.gitignore | 0 .../goat-exercises/Makefile.am | 27 +++- .../goat-exercises/goat-exercise-c.c | 4 +- .../goat-exercises/goat-exercise-gjs.js | 0 .../goat-exercises/goat-exercise-lua.lua | 0 .../goat-exercises/goat-exercise-py3.py | 0 .../goat-exercises/goat-exercise-vala.vala | 2 +- extensions/goat-exercises/meson.build | 122 ++++++++++++++++++ ...xtension.goat-exercises.metainfo.xml.in.in | 30 +++++ extensions/meson.build | 1 + meson.build | 1 + plug-ins/Makefile.am | 1 - plug-ins/goat-exercises/meson.build | 85 ------------ plug-ins/meson.build | 1 - po-plug-ins/POTFILES.in | 7 +- po-plug-ins/POTFILES.skip | 1 + po-python/POTFILES.in | 2 + po-python/POTFILES.skip | 1 - po-script-fu/POTFILES.skip | 2 +- 23 files changed, 213 insertions(+), 102 deletions(-) create mode 100644 extensions/.gitignore create mode 100644 extensions/Makefile.am rename {plug-ins => extensions}/goat-exercises/.gitignore (100%) rename {plug-ins => extensions}/goat-exercises/Makefile.am (80%) rename {plug-ins => extensions}/goat-exercises/goat-exercise-c.c (98%) rename {plug-ins => extensions}/goat-exercises/goat-exercise-gjs.js (100%) rename {plug-ins => extensions}/goat-exercises/goat-exercise-lua.lua (100%) rename {plug-ins => extensions}/goat-exercises/goat-exercise-py3.py (100%) rename {plug-ins => extensions}/goat-exercises/goat-exercise-vala.vala (98%) create mode 100644 extensions/goat-exercises/meson.build create mode 100644 extensions/goat-exercises/org.gimp.extension.goat-exercises.metainfo.xml.in.in create mode 100644 extensions/meson.build delete mode 100644 plug-ins/goat-exercises/meson.build diff --git a/Makefile.am b/Makefile.am index d485a18b45..3d22f29089 100644 --- a/Makefile.am +++ b/Makefile.am @@ -35,6 +35,7 @@ SUBDIRS = \ app-tools \ $(GIMP_MODULES) \ $(GIMP_PLUGINS) \ + $(GIMP_EXTENSIONS) \ etc \ devel-docs \ docs \ diff --git a/configure.ac b/configure.ac index 3328586ef2..ba3556f3f5 100644 --- a/configure.ac +++ b/configure.ac @@ -2263,6 +2263,8 @@ PKG_CHECK_MODULES(JSON_GLIB, json-glib-1.0 >= json_glib_required_version,, # Check for python runtime dependencies ####################################### +GOAT_EXERCISES="goat-exercise-c$BUILD_EXEEXT" + # By default, we want packagers to install Python plug-ins to get the # optimum experience. --with-python=yes will check for a Python 3 # interpreter and PyGObject, and fails without. @@ -2331,6 +2333,8 @@ if test "x$with_python" = "xyes"; then PYBIN_PATH="$PYTHON" fi AC_SUBST(PYBIN_PATH) + + GOAT_EXERCISES="$GOAT_EXERCISES:goat-exercise-py3.py" fi AM_CONDITIONAL(HAS_PYTHON_INTERP, test "x$PYBIN_PATH" != "x") AM_CONDITIONAL(BUILD_PYTHON, test "x$with_python" != xno) @@ -2378,6 +2382,10 @@ else fi fi +if test "x$with_javascript" = "xyes"; then + GOAT_EXERCISES="$GOAT_EXERCISES:goat-exercise-gjs.js" +fi + AM_CONDITIONAL(HAS_JAVASCRIPT_INTERP, test "x$GJS" != "xno") AM_CONDITIONAL(BUILD_JAVASCRIPT, test "x$with_javascript" != xno) @@ -2424,6 +2432,10 @@ else fi fi +if test "x$with_lua" = "xyes"; then + GOAT_EXERCISES="$GOAT_EXERCISES:goat-exercise-lua.lua" +fi + AM_CONDITIONAL(HAS_LUA_INTERP, test "x$LUA" != "xno") AM_CONDITIONAL(BUILD_LUA, test "x$with_lua" != xno) @@ -2450,7 +2462,12 @@ else fi fi +if test "x$with_vala" = "xyes"; then + GOAT_EXERCISES="$GOAT_EXERCISES:goat-exercise-vala$BUILD_EXEEXT" +fi + AM_CONDITIONAL(BUILD_VALA, test "x$with_vala" != xno) +AC_SUBST(GOAT_EXERCISES) ########################################################### # Some plug-ins don't build on Win32, others are Win32-only @@ -2862,8 +2879,10 @@ fi ################## # easy way to skip the plug-in build +GIMP_EXTENSIONS=extensions GIMP_PLUGINS=plug-ins GIMP_MODULES=modules +AC_SUBST(GIMP_EXTENSIONS) AC_SUBST(GIMP_PLUGINS) AC_SUBST(GIMP_MODULES) @@ -3015,6 +3034,9 @@ build/windows/gimp.rc build/windows/gimp-plug-ins.rc build/windows/installer/Makefile build/windows/installer/lang/Makefile +extensions/Makefile +extensions/goat-exercises/Makefile +extensions/goat-exercises/org.gimp.extension.goat-exercises.metainfo.xml.in plug-ins/Makefile plug-ins/file-bmp/Makefile plug-ins/file-dds/Makefile @@ -3064,7 +3086,6 @@ plug-ins/script-fu/tinyscheme/Makefile plug-ins/selection-to-path/Makefile plug-ins/twain/Makefile plug-ins/common/Makefile -plug-ins/goat-exercises/Makefile modules/Makefile devel-docs/Makefile devel-docs/version diff --git a/extensions/.gitignore b/extensions/.gitignore new file mode 100644 index 0000000000..9ee6454019 --- /dev/null +++ b/extensions/.gitignore @@ -0,0 +1,2 @@ +/Makefile.in +/Makefile diff --git a/extensions/Makefile.am b/extensions/Makefile.am new file mode 100644 index 0000000000..b55e5dba0c --- /dev/null +++ b/extensions/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = \ + goat-exercises diff --git a/plug-ins/goat-exercises/.gitignore b/extensions/goat-exercises/.gitignore similarity index 100% rename from plug-ins/goat-exercises/.gitignore rename to extensions/goat-exercises/.gitignore diff --git a/plug-ins/goat-exercises/Makefile.am b/extensions/goat-exercises/Makefile.am similarity index 80% rename from plug-ins/goat-exercises/Makefile.am rename to extensions/goat-exercises/Makefile.am index a1e62486ab..e9ff6beff6 100644 --- a/plug-ins/goat-exercises/Makefile.am +++ b/extensions/goat-exercises/Makefile.am @@ -36,12 +36,14 @@ AM_CPPFLAGS = \ # C version. -goat_exercise_c_libexecdir = $(gimpplugindir)/plug-ins/goat-exercise-c +goat_exercise_c_libexecdir = $(gimpplugindir)/extensions/org.gimp.extension.goat-exercises goat_exercise_c_datadir = $(goat_exercise_c_libexecdir) goat_exercise_c_libexec_PROGRAMS = goat-exercise-c goat_exercise_c_libexec_DATA = goat-exercise-c.c +PLUG_INS = 'goat-exercise-c$(EXEEXT)' + goat_exercise_c_SOURCES = \ goat-exercise-c.c @@ -64,21 +66,21 @@ goat_exercise_c_LDADD = \ # Javascript (GJS) version. if BUILD_JAVASCRIPT -goat_exercise_gjsdir = $(gimpplugindir)/plug-ins/goat-exercise-gjs +goat_exercise_gjsdir = $(goat_exercise_c_libexecdir) goat_exercise_gjs_SCRIPTS = goat-exercise-gjs.js endif # Lua (lua-jit + LGI) version. if BUILD_LUA -goat_exercise_luadir = $(gimpplugindir)/plug-ins/goat-exercise-lua +goat_exercise_luadir = $(goat_exercise_c_libexecdir) goat_exercise_lua_SCRIPTS = goat-exercise-lua.lua endif # Python 3 (pygobject) version. if BUILD_PYTHON -goat_exercise_py3dir = $(gimpplugindir)/plug-ins/goat-exercise-py3 +goat_exercise_py3dir = $(goat_exercise_c_libexecdir) goat_exercise_py3_SCRIPTS = goat-exercise-py3.py endif @@ -86,7 +88,7 @@ endif if ENABLE_VAPIGEN -goat_exercise_vala_libexecdir = $(gimpplugindir)/plug-ins/goat-exercise-vala +goat_exercise_vala_libexecdir = $(goat_exercise_c_libexecdir) goat_exercise_vala_datadir = $(goat_exercise_vala_libexecdir) goat_exercise_vala_libexec_PROGRAMS = goat-exercise-vala @@ -118,7 +120,20 @@ goat_exercise_vala_VALAFLAGS = \ endif +appstream_in_files = \ + org.gimp.extension.goat-exercises.metainfo.xml.in + +appstream_files = $(appstream_in_files:.xml.in=.xml) + +appdatadir = $(goat_exercise_c_libexecdir) +appdata_DATA = $(appstream_files) + +@INTLTOOL_XML_RULE@ + EXTRA_DIST = \ goat-exercise-gjs.js \ goat-exercise-lua.lua \ - goat-exercise-py3.py + goat-exercise-py3.py \ + $(appstream_in_files) + +DISTCLEANFILES = $(appstream_files) diff --git a/plug-ins/goat-exercises/goat-exercise-c.c b/extensions/goat-exercises/goat-exercise-c.c similarity index 98% rename from plug-ins/goat-exercises/goat-exercise-c.c rename to extensions/goat-exercises/goat-exercise-c.c index d4586c2725..5b8a2498d6 100644 --- a/plug-ins/goat-exercises/goat-exercise-c.c +++ b/extensions/goat-exercises/goat-exercise-c.c @@ -193,8 +193,8 @@ goat_run (GimpProcedure *procedure, gtk_widget_set_vexpand (GTK_WIDGET (scrolled), TRUE); gtk_widget_show (scrolled); - path = g_build_filename (gimp_plug_in_directory (), "plug-ins", - PLUG_IN_BINARY, PLUG_IN_SOURCE, + path = g_build_filename (gimp_plug_in_directory (), "extensions", + "org.gimp.extension.goat-exercises", PLUG_IN_SOURCE, NULL); file = g_file_new_for_path (path); g_free (path); diff --git a/plug-ins/goat-exercises/goat-exercise-gjs.js b/extensions/goat-exercises/goat-exercise-gjs.js similarity index 100% rename from plug-ins/goat-exercises/goat-exercise-gjs.js rename to extensions/goat-exercises/goat-exercise-gjs.js diff --git a/plug-ins/goat-exercises/goat-exercise-lua.lua b/extensions/goat-exercises/goat-exercise-lua.lua similarity index 100% rename from plug-ins/goat-exercises/goat-exercise-lua.lua rename to extensions/goat-exercises/goat-exercise-lua.lua diff --git a/plug-ins/goat-exercises/goat-exercise-py3.py b/extensions/goat-exercises/goat-exercise-py3.py similarity index 100% rename from plug-ins/goat-exercises/goat-exercise-py3.py rename to extensions/goat-exercises/goat-exercise-py3.py diff --git a/plug-ins/goat-exercises/goat-exercise-vala.vala b/extensions/goat-exercises/goat-exercise-vala.vala similarity index 98% rename from plug-ins/goat-exercises/goat-exercise-vala.vala rename to extensions/goat-exercises/goat-exercise-vala.vala index e684f2f63f..4f6c576c1d 100755 --- a/plug-ins/goat-exercises/goat-exercise-vala.vala +++ b/extensions/goat-exercises/goat-exercise-vala.vala @@ -91,7 +91,7 @@ public class Goat : Gimp.PlugIn { label.show(); - string file = Path.build_filename(Gimp.PlugIn.directory(), "plug-ins", PLUG_IN_BINARY, PLUG_IN_SOURCE); + string file = Path.build_filename(Gimp.PlugIn.directory(), "extensions", "org.gimp.extension.goat-exercises", PLUG_IN_SOURCE); string contents; try { FileUtils.get_contents(file, out contents); diff --git a/extensions/goat-exercises/meson.build b/extensions/goat-exercises/meson.build new file mode 100644 index 0000000000..d078690017 --- /dev/null +++ b/extensions/goat-exercises/meson.build @@ -0,0 +1,122 @@ +# C version + +extension_name = 'org.gimp.extension.goat-exercises' +plug_in_name = 'goat-exercise' + +plugin_sources = [ + 'goat-exercise-c.c', +] + +if platform_windows + plugin_sources += windows.compile_resources( + gimp_plugins_rc, + args: [ + '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plug_in_name + '-c.exe'), + '--define', 'INTERNALNAME_STR="@0@"' .format(plug_in_name), + '--define', 'TOP_SRCDIR="@0@"' .format(meson.source_root()), + ], + include_directories: [ + rootInclude, appInclude, + ], + ) +endif + +exe = executable(plug_in_name + '-c', + plugin_sources, + dependencies: [ + libgimpui_dep, + math, + ], + install: true, + install_dir: gimpplugindir / 'extensions' / extension_name, +) + +# XXX This is so ugly! +# From meson 0.54.0, we will be able to use exe.name(). +plug_ins = exe.full_path().split('/')[-1].split('\\')[-1] + +install_data( + 'goat-exercise-c.c', + install_dir: gimpplugindir / 'extensions' / extension_name, +) + +# Vala version + +if have_vala + exe = executable('goat-exercise-vala', + 'goat-exercise-vala.vala', + include_directories: [ rootInclude, ], + dependencies: [ + libgimp_vapi, libgimpui_vapi, gtk3, gegl, math, + ], + c_args: [ + '-DGETTEXT_PACKAGE="@0@"'.format(gettext_package), + ], + install: true, + install_dir: gimpplugindir / 'extensions' / extension_name, + ) + plug_ins = plug_ins + ':' + exe.full_path().split('/')[-1].split('\\')[-1] + + install_data( + 'goat-exercise-vala.vala', + install_dir: gimpplugindir / 'extensions' / extension_name, + ) +endif + +# Python 3 (pygobject) version. + +if have_python + install_data( + 'goat-exercise-py3.py', + install_dir: gimpplugindir / 'extensions' / extension_name, + ) + plug_ins = plug_ins + ':goat-exercise-py3.py' +endif + +# Javascript (GJS) version. + +if have_javascript + install_data( + 'goat-exercise-gjs.js', + install_dir: gimpplugindir / 'extensions' / extension_name, + ) + plug_ins = plug_ins + ':goat-exercise-gjs.js' +endif + +# Lua (lua-jit + LGI) version. + +if have_lua + install_data( + 'goat-exercise-lua.lua', + install_dir: gimpplugindir / 'extensions' / extension_name, + ) + plug_ins = plug_ins + ':goat-exercise-lua.lua' +endif + +# Generate the AppData. + +conf = configuration_data() +conf.set('GOAT_EXERCISES', plug_ins) + +appdatafilename = 'org.gimp.extension.goat-exercises.metainfo.xml' +appdatafilein = configure_file( + input : appdatafilename + '.in.in', + output: appdatafilename + '.in', + configuration: conf, +) + +appdatafile = custom_target(appdatafilename, + input : [ appdatafilein, ], + output: [ appdatafilename, ], + command: [ + intltool_merge, + po_dir, + '@INPUT@', + '@OUTPUT@', + '--xml-style', + '--utf8', + '--cache=' + '@OUTDIR@' / 'intltool-merge-cache', + ], + install: true, + install_dir: gimpplugindir / 'extensions' / extension_name, +) diff --git a/extensions/goat-exercises/org.gimp.extension.goat-exercises.metainfo.xml.in.in b/extensions/goat-exercises/org.gimp.extension.goat-exercises.metainfo.xml.in.in new file mode 100644 index 0000000000..e1eb55b5dc --- /dev/null +++ b/extensions/goat-exercises/org.gimp.extension.goat-exercises.metainfo.xml.in.in @@ -0,0 +1,30 @@ + + + org.gimp.extension.goat-exercises + org.gimp.GIMP + <_name>Goat Exercises + <_summary>Official Demo Plug-ins + + <_p> + This extension provides a set of basic examples to demonstrate + how to create your own plug-ins. + Each plug-in does the same thing, except it is developed in a + different programming language. + They all create a GTK+ dialog with a text view displaying their own code + (hence also demonstrating how to package data) and a button which calls + a GEGL operation on the active layer. + + + https://gimp.org + CC0-1.0 + GPL-3.0+ + + + + + org.gimp.GIMP + + + @GOAT_EXERCISES@ + + diff --git a/extensions/meson.build b/extensions/meson.build new file mode 100644 index 0000000000..4c40775c09 --- /dev/null +++ b/extensions/meson.build @@ -0,0 +1 @@ +subdir('goat-exercises') diff --git a/meson.build b/meson.build index c533a09de8..a12f4a9451 100644 --- a/meson.build +++ b/meson.build @@ -1701,6 +1701,7 @@ subdir('libgimpwidgets') subdir('libgimp') # Executables, plugins +subdir('extensions') subdir('modules') subdir('plug-ins') subdir('app') diff --git a/plug-ins/Makefile.am b/plug-ins/Makefile.am index d19642b04c..6384022430 100644 --- a/plug-ins/Makefile.am +++ b/plug-ins/Makefile.am @@ -44,7 +44,6 @@ SUBDIRS = \ fractal-explorer \ gfig \ gimpressionist \ - goat-exercises \ gradient-flare \ help \ $(help_browser) \ diff --git a/plug-ins/goat-exercises/meson.build b/plug-ins/goat-exercises/meson.build deleted file mode 100644 index 982400778d..0000000000 --- a/plug-ins/goat-exercises/meson.build +++ /dev/null @@ -1,85 +0,0 @@ -# C version - -plugin_name = 'goat-exercise' - -plugin_sources = [ - 'goat-exercise-c.c', -] - -if platform_windows - plugin_sources += windows.compile_resources( - gimp_plugins_rc, - args: [ - '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name + '-c.exe'), - '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name), - '--define', 'TOP_SRCDIR="@0@"' .format(meson.source_root()), - ], - include_directories: [ - rootInclude, appInclude, - ], - ) -endif - -executable(plugin_name + '-c', - plugin_sources, - dependencies: [ - libgimpui_dep, - math, - ], - install: true, - install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-c', -) - -install_data( - 'goat-exercise-c.c', - install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-c', -) - -# Vala version - -if have_vala - goat_exercise_vala = executable('goat-exercise-vala', - 'goat-exercise-vala.vala', - include_directories: [ rootInclude, ], - dependencies: [ - libgimp_vapi, libgimpui_vapi, gtk3, gegl, math, - ], - c_args: [ - '-DGETTEXT_PACKAGE="@0@"'.format(gettext_package), - ], - install: true, - install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-vala', - ) - - install_data( - 'goat-exercise-vala.vala', - install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-vala', - ) -endif - -# Python 3 (pygobject) version. - -if have_python - install_data( - 'goat-exercise-py3.py', - install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-py3', - ) -endif - -# Javascript (GJS) version. - -if have_javascript - install_data( - 'goat-exercise-gjs.js', - install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-gjs', - ) -endif - -# Lua (lua-jit + LGI) version. - -if have_lua - install_data( - 'goat-exercise-lua.lua', - install_dir: gimpplugindir / 'plug-ins' / plugin_name + '-lua', - ) -endif diff --git a/plug-ins/meson.build b/plug-ins/meson.build index 2e60a31550..11c0553541 100644 --- a/plug-ins/meson.build +++ b/plug-ins/meson.build @@ -16,7 +16,6 @@ subdir('flame') subdir('fractal-explorer') subdir('gfig') subdir('gimpressionist') -subdir('goat-exercises') subdir('gradient-flare') subdir('help') subdir('help-browser') diff --git a/po-plug-ins/POTFILES.in b/po-plug-ins/POTFILES.in index dc53845dd2..460dc96cf5 100644 --- a/po-plug-ins/POTFILES.in +++ b/po-plug-ins/POTFILES.in @@ -3,6 +3,10 @@ [encoding: UTF-8] +extensions/goat-exercises/goat-exercise-c.c +extensions/goat-exercises/goat-exercise-vala.vala +extensions/goat-exercises/org.gimp.extension.goat-exercises.metainfo.xml.in.in + plug-ins/common/align-layers.c plug-ins/common/animation-optimize.c #plug-ins/common/animation-play.c @@ -141,9 +145,6 @@ plug-ins/gimpressionist/repaint.c plug-ins/gimpressionist/size.c plug-ins/gimpressionist/sizemap.c plug-ins/gimpressionist/utils.c -plug-ins/goat-exercises/goat-exercise-c.c -plug-ins/goat-exercises/goat-exercise-py3.py -plug-ins/goat-exercises/goat-exercise-vala.vala [type: gettext/glade]plug-ins/ui/plug-in-metadata-editor.ui [type: gettext/glade]plug-ins/ui/plug-in-metadata-viewer.ui plug-ins/gradient-flare/gradient-flare.c diff --git a/po-plug-ins/POTFILES.skip b/po-plug-ins/POTFILES.skip index b3d6107748..beae3fd1e2 100644 --- a/po-plug-ins/POTFILES.skip +++ b/po-plug-ins/POTFILES.skip @@ -5,6 +5,7 @@ data/tags data/tips desktop desktop/gimp.desktop.in +extensions/goat-exercises/org.gimp.extension.goat-exercises.metainfo.xml.in libgimp libgimpbase libgimpcolor diff --git a/po-python/POTFILES.in b/po-python/POTFILES.in index 687b66f00e..7e99b0a635 100644 --- a/po-python/POTFILES.in +++ b/po-python/POTFILES.in @@ -3,6 +3,8 @@ [encoding: UTF-8] +extensions/goat-exercises/goat-exercise-py3.py + plug-ins/python/benchmark-foreground-extract.py plug-ins/python/colorxhtml.py plug-ins/python/foggify.py diff --git a/po-python/POTFILES.skip b/po-python/POTFILES.skip index c16493d8e2..b76260a3d6 100644 --- a/po-python/POTFILES.skip +++ b/po-python/POTFILES.skip @@ -36,7 +36,6 @@ plug-ins/flame plug-ins/fractal-explorer plug-ins/gfig plug-ins/gimpressionist -plug-ins/goat-exercises plug-ins/gradient-flare plug-ins/help plug-ins/help-browser diff --git a/po-script-fu/POTFILES.skip b/po-script-fu/POTFILES.skip index 1cb300c6de..0ea78fed6b 100644 --- a/po-script-fu/POTFILES.skip +++ b/po-script-fu/POTFILES.skip @@ -5,6 +5,7 @@ data/tags data/tips desktop desktop/gimp.desktop.in +extensions/goat-exercises libgimp libgimpbase libgimpcolor @@ -35,7 +36,6 @@ plug-ins/flame plug-ins/fractal-explorer plug-ins/gfig plug-ins/gimpressionist -plug-ins/goat-exercises plug-ins/gradient-flare plug-ins/help plug-ins/help-browser