[gnome-builder/wip/gtk4-port] plugins/meson-templates: start porting to C



commit 8bd692e7b132a07151f3fbde4251f3fec0c0f6db
Author: Christian Hergert <chergert redhat com>
Date:   Tue Jun 7 16:17:35 2022 -0700

    plugins/meson-templates: start porting to C
    
    This is a partial port of the meson-templates plugin to C. So far it only
    includes the GNOME application template, but it gets things going for how
    we'll go about porting the rest of them.
    
    There is a bunch still to do here, but the C one works. I'd also like to
    be able to automate testing of all of these at some point, or at least
    that they expand.
    
    But that will also come with cleaning up what they generate as I'm not
    happy with how haphazard things have become.
    
    The python plugin still is around, until we finish porting, then we can
    remove it too.
    
    As we don't need pattern icons anymore, those are removed.

 meson_options.txt                                  |   1 +
 .../meson-templates/gbp-meson-template-provider.c  | 238 ++++++++++++++++
 .../meson-templates/gbp-meson-template-provider.h  |  31 +++
 src/plugins/meson-templates/gbp-meson-template.c   | 302 +++++++++++++++++++++
 src/plugins/meson-templates/gbp-meson-template.h   |  54 ++++
 .../icons/scalable/actions/pattern-browse.svg      | 284 -------------------
 .../icons/scalable/actions/pattern-cli.svg         | 178 ------------
 .../icons/scalable/actions/pattern-gnome.svg       | 150 ----------
 .../icons/scalable/actions/pattern-grid.svg        | 270 ------------------
 .../icons/scalable/actions/pattern-gtk.svg         |  34 ---
 .../icons/scalable/actions/pattern-legacy.svg      | 243 -----------------
 .../icons/scalable/actions/pattern-library.svg     | 141 ----------
 .../meson-templates/meson-templates-plugin.c       |  35 +++
 .../meson-templates/meson-templates.gresource.xml  |  14 +-
 src/plugins/meson-templates/meson-templates.plugin |  15 +-
 src/plugins/meson-templates/meson.build            |  28 +-
 src/plugins/meson-templates/meson_templates.py     |  12 -
 .../meson-templates/resources/flatpak.json.in      |   2 +-
 .../resources/src/meson-c-vala.build               |  16 +-
 src/plugins/meson.build                            |   1 +
 20 files changed, 694 insertions(+), 1355 deletions(-)
---
diff --git a/meson_options.txt b/meson_options.txt
index 682e5c8fd..2abd6a9e0 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -62,6 +62,7 @@ option('plugin_make_templates', type: 'boolean')
 option('plugin_markdown_preview', type: 'boolean')
 option('plugin_maven', type: 'boolean')
 option('plugin_meson', type: 'boolean')
+option('plugin_meson_templates', type: 'boolean')
 option('plugin_modelines', type: 'boolean')
 option('plugin_mono', type: 'boolean')
 option('plugin_newcomers', type: 'boolean')
diff --git a/src/plugins/meson-templates/gbp-meson-template-provider.c 
b/src/plugins/meson-templates/gbp-meson-template-provider.c
new file mode 100644
index 000000000..0d6e9151a
--- /dev/null
+++ b/src/plugins/meson-templates/gbp-meson-template-provider.c
@@ -0,0 +1,238 @@
+/* gbp-meson-template-provider.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gbp-meson-template-provider"
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include <libide-projects.h>
+
+#include "gbp-meson-template.h"
+#include "gbp-meson-template-provider.h"
+
+struct _GbpMesonTemplateProvider
+{
+  GObject parent_instance;
+};
+
+typedef struct _GbpMesonTemplateInfo
+{
+  int                                  priority;
+  const char                          *id;
+  const char                          *name;
+  const char                          *description;
+  const char * const                  *languages;
+  const GbpMesonTemplateExpansion     *expansions;
+  guint                                n_expansions;
+  const GbpMesonTemplateLanguageScope *language_scope;
+  guint                                n_language_scope;
+  const char * const                  *extra_scope;
+} GbpMesonTemplateInfo;
+
+static GbpMesonTemplateExpansion adwaita_expansions[] = {
+  { "meson.build",                                         "meson.build" },
+  { "flatpak.json",                                        "{{appid}}.json" },
+  { "data/hello.desktop.in",                               "data/{{appid}}.desktop.in" },
+  { "data/hello.appdata.xml.in",                           "data/{{appid}}.appdata.xml.in" },
+  { "data/hello.gschema.xml",                              "data/{{appid}}.gschema.xml" },
+  { "data/meson.build",                                    "data/meson.build" },
+  { "data/icons/meson.build",                              "data/icons/meson.build" },
+  { "data/icons/hicolor/scalable/apps/hello.svg",          "data/icons/hicolor/scalable/apps/{{appid}}.svg" 
},
+  { "data/icons/hicolor/symbolic/apps/hello-symbolic.svg", 
"data/icons/hicolor/symbolic/apps/{{appid}}-symbolic.svg" },
+  { "po/LINGUAS",                                          "po/LINGUAS" },
+  { "po/meson.build",                                      "po/meson.build" },
+  { "po/POTFILES",                                         "po/POTFILES" },
+  { "src/help-overlay.ui",                                 "src/gtk/help-overlay.ui" },
+
+  /* C */
+  { "src/application.c", "src/{{prefix}}-application.c", IDE_STRV_INIT ("C") },
+  { "src/application.h", "src/{{prefix}}-application.h", IDE_STRV_INIT ("C") },
+  { "src/hello.gresource.xml", "src/{{prefix}}.gresource.xml", IDE_STRV_INIT ("C") },
+  { "src/main-gtk4.c", "src/main.c", IDE_STRV_INIT ("C") },
+  { "src/meson-c-vala.build", "src/meson.build", IDE_STRV_INIT ("C") },
+  { "src/window-gtk4.ui", "src/{{prefix}}-window.ui", IDE_STRV_INIT ("C") },
+  { "src/window.c", "src/{{prefix}}-window.c", IDE_STRV_INIT ("C") },
+  { "src/window.h", "src/{{prefix}}-window.h", IDE_STRV_INIT ("C") },
+
+  /* JavaScript */
+  { "src/hello.gresource.xml", "src/{{appid}}.data.gresource.xml", IDE_STRV_INIT ("JavaScript") },
+  { "src/hello.gresource.xml", "src/{{prefix}}.data.gresource.xml", IDE_STRV_INIT ("JavaScript") },
+  { "src/hello.js.in", "src/{{appid}}.in", IDE_STRV_INIT ("JavaScript"), TRUE },
+  { "src/hello.src.gresource.xml", "src/{{appid}}.src.gresource.xml", IDE_STRV_INIT ("JavaScript") },
+  { "src/main-gtk4.js.tmpl", "src/main.js", IDE_STRV_INIT ("JavaScript") },
+  { "src/meson-js.build", "src/meson.build", IDE_STRV_INIT ("JavaScript") },
+  { "src/window.js.tmpl", "src/window.js", IDE_STRV_INIT ("JavaScript") },
+
+  /* Python */
+  { "src/__init__.py", "src/__init__.py", IDE_STRV_INIT ("Python") },
+  { "src/hello.gresource.xml", "src/{{prefix}}.gresource.xml", IDE_STRV_INIT ("Python") },
+  { "src/hello.py.in", "src/{{name}}.in", IDE_STRV_INIT ("Python"), TRUE },
+  { "src/main-gtk4.py", "src/main.py", IDE_STRV_INIT ("Python") },
+  { "src/meson-py-gtk4.build", "src/meson.build", IDE_STRV_INIT ("Python") },
+  { "src/window-gtk4.py", "src/window.py", IDE_STRV_INIT ("Python") },
+
+  /* Rust */
+  { "build-aux/cargo.sh", "build-aux/cargo.sh", IDE_STRV_INIT ("Rust") },
+  { "src/Cargo-gtk4.toml", "Cargo.toml", IDE_STRV_INIT ("Rust") },
+  { "src/Cargo.lock", "Cargo.lock", IDE_STRV_INIT ("Rust") },
+  { "src/application.rs", "src/application.rs", IDE_STRV_INIT ("Rust") },
+  { "src/config-gtk4.rs.in", "src/config.rs.in", IDE_STRV_INIT ("Rust") },
+  { "src/hello.gresource.xml", "src/{{prefix}}.gresource.xml", IDE_STRV_INIT ("Rust") },
+  { "src/main-gtk4.rs", "src/main.rs", IDE_STRV_INIT ("Rust") },
+  { "src/meson-rs-gtk4.build", "src/meson.build", IDE_STRV_INIT ("Rust") },
+  { "src/window-gtk4.rs", "src/window.rs", IDE_STRV_INIT ("Rust") },
+
+  /* Vala */
+  { "src/application-gtk4.vala", "src/application.vala", IDE_STRV_INIT ("Vala") },
+  { "src/hello.gresource.xml", "src/{{prefix}}.gresource.xml", IDE_STRV_INIT ("Vala") },
+  { "src/main-gtk4.vala", "src/main.vala", IDE_STRV_INIT ("Vala") },
+  { "src/meson-c-vala.build", "src/meson.build", IDE_STRV_INIT ("Vala") },
+  { "src/window-gtk4.vala", "src/window.vala", IDE_STRV_INIT ("Vala") },
+};
+
+static const GbpMesonTemplateLanguageScope adwaita_language_scope[] = {
+  { "C",          IDE_STRV_INIT ("ui_file={{prefix}}-window.ui") },
+  { "C++",        IDE_STRV_INIT ("ui_file={{prefix}}-window.ui") },
+  { "C♯",         IDE_STRV_INIT ("ui_file=") },
+  { "JavaScript", IDE_STRV_INIT ("exec_name={{appid}}") },
+};
+
+static const GbpMesonTemplateInfo templates[] = {
+  {
+    -1000,
+    N_("adwaita"),
+    N_("GNOME Application"),
+    N_("A Meson-based project for GNOME using libadwaita"),
+    IDE_STRV_INIT ("C", "JavaScript", "Python", "Rust", "Vala"),
+    adwaita_expansions, G_N_ELEMENTS (adwaita_expansions),
+    adwaita_language_scope, G_N_ELEMENTS (adwaita_language_scope),
+    IDE_STRV_INIT ("is_adwaita=true",
+                   "is_gtk4=true",
+                   "enable_i18n=true",
+                   "enable_gnome=true",
+                   "ui_file=window.ui",
+                   "exec_name={{name}}"),
+  },
+};
+
+static GList *
+gbp_meson_template_provider_get_project_templates (IdeTemplateProvider *provider)
+{
+  GList *list = NULL;
+
+  g_assert (GBP_IS_MESON_TEMPLATE_PROVIDER (provider));
+
+  for (guint i = 0; i < G_N_ELEMENTS (templates); i++)
+    {
+      g_autofree char *id = NULL;
+      g_autoptr(GbpMesonTemplate) template = NULL;
+
+      id = g_strdup_printf ("meson-templates:%s", templates[i].id);
+      template = g_object_new (GBP_TYPE_MESON_TEMPLATE,
+                               "description", g_dgettext (GETTEXT_PACKAGE, templates[i].description),
+                               "id", id,
+                               "languages", templates[i].languages,
+                               "name", g_dgettext (GETTEXT_PACKAGE, templates[i].name),
+                               "priority", templates[i].priority,
+                               NULL);
+      gbp_meson_template_set_expansions (template,
+                                         templates[i].expansions,
+                                         templates[i].n_expansions);
+      gbp_meson_template_set_extra_scope (template, templates[i].extra_scope);
+      gbp_meson_template_set_language_scope (template,
+                                             templates[i].language_scope,
+                                             templates[i].n_language_scope);
+      list = g_list_prepend (list, g_steal_pointer (&template));
+    }
+
+#if 0
+  list = g_list_prepend (list,
+                         g_object_new (GBP_TYPE_MESON_TEMPLATE,
+                                       "id", "meson-templates:adwaita",
+                                       "name", _("GNOME Application"),
+                                       "description",
+                                       "languages", IDE_STRV_INIT ("C", "JavaScript", "Python", "Rust", 
"Vala"),
+                                       "priority", -1000,
+                                       NULL));
+  list = g_list_prepend (list,
+                         g_object_new (GBP_TYPE_MESON_TEMPLATE,
+                                       "id", "meson-templates:gtk4",
+                                       "name", _("GTK Application"),
+                                       "description", _("A Meson-based project using GTK 4"),
+                                       "languages", IDE_STRV_INIT ("C", "JavaScript", "Python", "Rust", 
"Vala"),
+                                       "priority", -900,
+                                       NULL));
+  list = g_list_prepend (list,
+                         g_object_new (GBP_TYPE_MESON_TEMPLATE,
+                                       "id", "meson-templates:shared-library",
+                                       "name", _("Shared Library"),
+                                       "description", _("A Meson-based project for a shared-library"),
+                                       "languages", IDE_STRV_INIT ("C"),
+                                       "priority", -800,
+                                       NULL));
+  list = g_list_prepend (list,
+                         g_object_new (GBP_TYPE_MESON_TEMPLATE,
+                                       "id", "meson-templates:cli",
+                                       "name", _("Command Line Tool"),
+                                       "description", _("A Meson-based project creating a command-line 
program"),
+                                       "languages", IDE_STRV_INIT ("C", "C++", "Python", "Rust", "Vala"),
+                                       "priority", -700,
+                                       NULL));
+  list = g_list_prepend (list,
+                         g_object_new (GBP_TYPE_MESON_TEMPLATE,
+                                       "id", "meson-templates:gtk3",
+                                       "name", _("GTK Application (Legacy)"),
+                                       "description", _("A Meson-based project using GTK 3"),
+                                       "languages", IDE_STRV_INIT ("C", "C++", "C♯", "JavaScript", "Python", 
"Rust", "Vala"),
+                                       "priority", -600,
+                                       NULL));
+  list = g_list_prepend (list,
+                         g_object_new (GBP_TYPE_MESON_TEMPLATE,
+                                       "id", "meson-templates:empty",
+                                       "name", _("Empty Meson Project"),
+                                       "description", _("A empty Meson-based project"),
+                                       "languages", IDE_STRV_INIT ("C", "C++", "C♯", "JavaScript", "Python", 
"Rust", "Vala"),
+                                       "priority", -500,
+                                       NULL));
+#endif
+
+  return list;
+}
+
+static void
+template_provider_iface_init (IdeTemplateProviderInterface *iface)
+{
+  iface->get_project_templates = gbp_meson_template_provider_get_project_templates;
+}
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (GbpMesonTemplateProvider, gbp_meson_template_provider, G_TYPE_OBJECT,
+                               G_IMPLEMENT_INTERFACE (IDE_TYPE_TEMPLATE_PROVIDER, 
template_provider_iface_init))
+
+static void
+gbp_meson_template_provider_class_init (GbpMesonTemplateProviderClass *klass)
+{
+}
+
+static void
+gbp_meson_template_provider_init (GbpMesonTemplateProvider *self)
+{
+}
diff --git a/src/plugins/meson-templates/gbp-meson-template-provider.h 
b/src/plugins/meson-templates/gbp-meson-template-provider.h
new file mode 100644
index 000000000..aea19ad19
--- /dev/null
+++ b/src/plugins/meson-templates/gbp-meson-template-provider.h
@@ -0,0 +1,31 @@
+/* gbp-meson-template-provider.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_MESON_TEMPLATE_PROVIDER (gbp_meson_template_provider_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpMesonTemplateProvider, gbp_meson_template_provider, GBP, MESON_TEMPLATE_PROVIDER, 
GObject)
+
+G_END_DECLS
diff --git a/src/plugins/meson-templates/gbp-meson-template.c 
b/src/plugins/meson-templates/gbp-meson-template.c
new file mode 100644
index 000000000..656904aac
--- /dev/null
+++ b/src/plugins/meson-templates/gbp-meson-template.c
@@ -0,0 +1,302 @@
+/* gbp-meson-template.c
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define G_LOG_DOMAIN "gbp-meson-template"
+
+#include "config.h"
+
+#include <string.h>
+
+#include <libide-threading.h>
+
+#include "gbp-meson-template.h"
+
+struct _GbpMesonTemplate
+{
+  IdeProjectTemplate parent_instance;
+  const char * const *extra_scope;
+  const GbpMesonTemplateExpansion *expansions;
+  guint n_expansions;
+  const GbpMesonTemplateLanguageScope *language_scope;
+  guint n_language_scope;
+};
+
+G_DEFINE_FINAL_TYPE (GbpMesonTemplate, gbp_meson_template, IDE_TYPE_PROJECT_TEMPLATE)
+
+static void
+add_to_scope (TmplScope  *scope,
+              const char *pattern)
+{
+  g_autofree char *key = NULL;
+  const char *val;
+
+  g_assert (scope != NULL);
+  g_assert (pattern != NULL);
+
+  val = strchr (pattern, '=');
+
+  /* If it is just "FOO" then set "FOO" to True */
+  if (val == NULL)
+    {
+      tmpl_scope_set_boolean (scope, pattern, TRUE);
+      return;
+    }
+
+  key = g_strndup (pattern, val - pattern);
+  val++;
+
+  /* If simple key=value, set the bool/string */
+  if (strstr (val, "{{") == NULL)
+    {
+      if (ide_str_equal0 (val, "false"))
+        tmpl_scope_set_boolean (scope, key, FALSE);
+      else if (ide_str_equal0 (val, "true"))
+        tmpl_scope_set_boolean (scope, key, TRUE);
+      else
+        tmpl_scope_set_string (scope, key, val);
+
+      return;
+    }
+
+  /* More complex, we have a template to expand from scope */
+  {
+    g_autoptr(TmplTemplate) template = tmpl_template_new (NULL);
+    g_autoptr(GError) error = NULL;
+    g_autofree char *expanded = NULL;
+
+    if (!tmpl_template_parse_string (template, val, &error))
+      {
+        g_warning ("Failed to parse template %s: %s",
+                   val, error->message);
+        return;
+      }
+
+    if (!(expanded = tmpl_template_expand_string (template, scope, &error)))
+      {
+        g_warning ("Failed to expand template %s: %s",
+                   val, error->message);
+        return;
+      }
+
+    tmpl_scope_set_string (scope, key, expanded);
+  }
+}
+
+static void
+gbp_meson_template_expand_cb (GObject      *object,
+                              GAsyncResult *result,
+                              gpointer      user_data)
+{
+  GbpMesonTemplate *self = (GbpMesonTemplate *)object;
+  g_autoptr(IdeTask) task = user_data;
+  g_autoptr(GError) error = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (GBP_IS_MESON_TEMPLATE (self));
+  g_assert (G_IS_ASYNC_RESULT (result));
+  g_assert (IDE_IS_TASK (task));
+
+  if (!ide_template_base_expand_all_finish (IDE_TEMPLATE_BASE (self), result, &error))
+    ide_task_return_error (task, g_steal_pointer (&error));
+  else
+    ide_task_return_boolean (task, TRUE);
+
+  IDE_EXIT;
+}
+
+static void
+gbp_meson_template_expand_async (IdeProjectTemplate  *template,
+                                 IdeTemplateInput    *input,
+                                 TmplScope           *scope,
+                                 GCancellable        *cancellable,
+                                 GAsyncReadyCallback  callback,
+                                 gpointer             user_data)
+{
+  GbpMesonTemplate *self = (GbpMesonTemplate *)template;
+  g_autoptr(IdeTask) task = NULL;
+  g_autoptr(GFile) destdir = NULL;
+  const char *language;
+  const char *name;
+  GFile *directory;
+
+  IDE_ENTRY;
+
+  g_assert (GBP_IS_MESON_TEMPLATE (template));
+  g_assert (IDE_IS_TEMPLATE_INPUT (input));
+  g_assert (scope != NULL);
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = ide_task_new (template, cancellable, callback, user_data);
+  ide_task_set_source_tag (task, gbp_meson_template_expand_async);
+
+  name = ide_template_input_get_name (input);
+  language = ide_template_input_get_language (input);
+  directory = ide_template_input_get_directory (input);
+  destdir = g_file_get_child (directory, name);
+
+  if (self->expansions == NULL || self->n_expansions == 0)
+    {
+      ide_task_return_unsupported_error (task);
+      IDE_EXIT;
+    }
+
+  /* First setup some defaults for our scope */
+  tmpl_scope_set_boolean (scope, "is_adwaita", FALSE);
+  tmpl_scope_set_boolean (scope, "is_gtk4", FALSE);
+  tmpl_scope_set_boolean (scope, "enable_gnome", FALSE);
+  tmpl_scope_set_boolean (scope, "enable_i18n", FALSE);
+
+  /* Add any extra scope to the expander which might be needed */
+  if (self->extra_scope != NULL)
+    {
+      for (guint j = 0; self->extra_scope[j]; j++)
+        add_to_scope (scope, self->extra_scope[j]);
+    }
+
+  /* Now add any per-language scope necessary */
+  if (self->language_scope != NULL)
+    {
+      for (guint j = 0; j < self->n_language_scope; j++)
+        {
+          if (!ide_str_equal0 (language, self->language_scope[j].language) ||
+              self->language_scope[j].extra_scope == NULL)
+            continue;
+
+          for (guint k = 0; self->language_scope[j].extra_scope[k]; k++)
+            add_to_scope (scope, self->language_scope[j].extra_scope[k]);
+        }
+    }
+
+  for (guint i = 0; i < self->n_expansions; i++)
+    {
+      const char *src = self->expansions[i].input;
+      const char *dest = self->expansions[i].output_pattern;
+      g_autofree char *dest_eval = NULL;
+      g_autofree char *resource_path = NULL;
+      g_autoptr(GFile) dest_file = NULL;
+      int mode = 0;
+
+      if (self->expansions[i].languages != NULL &&
+          !g_strv_contains (self->expansions[i].languages, language))
+        continue;
+
+      /* Expand the destination filename if necessary using a template */
+      if (strstr (dest, "{{") != NULL)
+        {
+          g_autoptr(TmplTemplate) expander = tmpl_template_new (NULL);
+          g_autoptr(GError) error = NULL;
+
+          if (!tmpl_template_parse_string (expander, dest, &error))
+            {
+              ide_task_return_error (task, g_steal_pointer (&error));
+              IDE_EXIT;
+            }
+
+          if (!(dest_eval = tmpl_template_expand_string (expander, scope, &error)))
+            {
+              ide_task_return_error (task, g_steal_pointer (&error));
+              IDE_EXIT;
+            }
+
+          dest = dest_eval;
+        }
+
+      resource_path = g_strdup_printf ("/plugins/meson-templates/resources/%s", src);
+      dest_file = g_file_get_child (destdir, dest);
+
+      if (self->expansions[i].executable)
+        mode = 0750;
+
+      ide_template_base_add_resource (IDE_TEMPLATE_BASE (self),
+                                      resource_path, dest_file, scope, mode);
+    }
+
+  ide_template_base_expand_all_async (IDE_TEMPLATE_BASE (self),
+                                      cancellable,
+                                      gbp_meson_template_expand_cb,
+                                      g_steal_pointer (&task));
+
+  IDE_EXIT;
+}
+
+static gboolean
+gbp_meson_template_expand_finish (IdeProjectTemplate  *template,
+                                  GAsyncResult        *result,
+                                  GError             **error)
+{
+  gboolean ret;
+
+  IDE_ENTRY;
+
+  g_assert (GBP_IS_MESON_TEMPLATE (template));
+  g_assert (IDE_IS_TASK (result));
+
+  ret = ide_task_propagate_boolean (IDE_TASK (result), error);
+
+  IDE_RETURN (ret);
+}
+
+static void
+gbp_meson_template_class_init (GbpMesonTemplateClass *klass)
+{
+  IdeProjectTemplateClass *template_class = IDE_PROJECT_TEMPLATE_CLASS (klass);
+
+  template_class->expand_async = gbp_meson_template_expand_async;
+  template_class->expand_finish = gbp_meson_template_expand_finish;
+}
+
+static void
+gbp_meson_template_init (GbpMesonTemplate *self)
+{
+}
+
+void
+gbp_meson_template_set_expansions (GbpMesonTemplate                *self,
+                                   const GbpMesonTemplateExpansion *expansions,
+                                   guint                            n_expansions)
+{
+  g_return_if_fail (GBP_IS_MESON_TEMPLATE (self));
+  g_return_if_fail (n_expansions == 0 || expansions != NULL);
+
+  self->expansions = expansions;
+  self->n_expansions = n_expansions;
+}
+
+void
+gbp_meson_template_set_extra_scope (GbpMesonTemplate   *self,
+                                    const char * const *extra_scope)
+{
+  g_return_if_fail (GBP_IS_MESON_TEMPLATE (self));
+
+  self->extra_scope = extra_scope;
+}
+
+void
+gbp_meson_template_set_language_scope (GbpMesonTemplate                    *self,
+                                       const GbpMesonTemplateLanguageScope *language_scope,
+                                       guint                                n_language_scope)
+{
+  g_return_if_fail (GBP_IS_MESON_TEMPLATE (self));
+  g_return_if_fail (n_language_scope == 0 || language_scope != NULL);
+
+  self->language_scope = language_scope;
+  self->n_language_scope = n_language_scope;
+}
diff --git a/src/plugins/meson-templates/gbp-meson-template.h 
b/src/plugins/meson-templates/gbp-meson-template.h
new file mode 100644
index 000000000..8942eace5
--- /dev/null
+++ b/src/plugins/meson-templates/gbp-meson-template.h
@@ -0,0 +1,54 @@
+/* gbp-meson-template.h
+ *
+ * Copyright 2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#pragma once
+
+#include <libide-projects.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GbpMesonTemplateExpansion
+{
+  const char         *input;
+  const char         *output_pattern;
+  const char * const *languages;
+  gboolean            executable;
+} GbpMesonTemplateExpansion;
+
+typedef struct _GbpMesonTemplateLanguageScope
+{
+  const char *language;
+  const char * const *extra_scope;
+} GbpMesonTemplateLanguageScope;
+
+#define GBP_TYPE_MESON_TEMPLATE (gbp_meson_template_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpMesonTemplate, gbp_meson_template, GBP, MESON_TEMPLATE, IdeProjectTemplate)
+
+void gbp_meson_template_set_expansions     (GbpMesonTemplate                    *self,
+                                            const GbpMesonTemplateExpansion     *expansions,
+                                            guint                                n_expansions);
+void gbp_meson_template_set_extra_scope    (GbpMesonTemplate                    *self,
+                                            const char * const                  *extra_scope);
+void gbp_meson_template_set_language_scope (GbpMesonTemplate                    *self,
+                                            const GbpMesonTemplateLanguageScope *language_scope,
+                                            guint                                n_language_scope);
+
+G_END_DECLS
diff --git a/src/plugins/meson-templates/meson-templates-plugin.c 
b/src/plugins/meson-templates/meson-templates-plugin.c
new file mode 100644
index 000000000..0d432e232
--- /dev/null
+++ b/src/plugins/meson-templates/meson-templates-plugin.c
@@ -0,0 +1,35 @@
+/* meson-templates-plugin.c
+ *
+ * Copyright 2017-2022 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include "config.h"
+
+#include <libpeas/peas.h>
+
+#include <libide-projects.h>
+
+#include "gbp-meson-template-provider.h"
+
+_IDE_EXTERN void
+_gbp_meson_templates_register_types (PeasObjectModule *module)
+{
+  peas_object_module_register_extension_type (module,
+                                              IDE_TYPE_TEMPLATE_PROVIDER,
+                                              GBP_TYPE_MESON_TEMPLATE_PROVIDER);
+}
diff --git a/src/plugins/meson-templates/meson-templates.gresource.xml 
b/src/plugins/meson-templates/meson-templates.gresource.xml
index aac749e2e..e957c6c6b 100644
--- a/src/plugins/meson-templates/meson-templates.gresource.xml
+++ b/src/plugins/meson-templates/meson-templates.gresource.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <gresources>
-  <gresource prefix="/plugins/meson_templates">
+  <gresource prefix="/plugins/meson-templates">
+    <file>meson-templates.plugin</file>
     <file compressed="true">resources/src/window.ui</file>
     <file compressed="true">resources/src/window-gtk4.ui</file>
     <file compressed="true">resources/src/help-overlay.ui</file>
@@ -77,16 +78,7 @@
     <file compressed="true">resources/po/POTFILES</file>
     <file compressed="true">resources/po/LINGUAS</file>
   </gresource>
-  <gresource prefix="/plugins/meson_templates/resources">
+  <gresource prefix="/plugins/meson-templates/resources">
     <file compressed="true">flatpak.json</file>
   </gresource>
-  <gresource prefix="/org/gnome/builder">
-    <file compressed="true">icons/scalable/actions/pattern-legacy.svg</file>
-    <file compressed="true">icons/scalable/actions/pattern-library.svg</file>
-    <file compressed="true">icons/scalable/actions/pattern-grid.svg</file>
-    <file compressed="true">icons/scalable/actions/pattern-browse.svg</file>
-    <file compressed="true">icons/scalable/actions/pattern-cli.svg</file>
-    <file compressed="true">icons/scalable/actions/pattern-gnome.svg</file>
-    <file compressed="true">icons/scalable/actions/pattern-gtk.svg</file>
-  </gresource>
 </gresources>
diff --git a/src/plugins/meson-templates/meson-templates.plugin 
b/src/plugins/meson-templates/meson-templates.plugin
index 92f22f305..dbab4337a 100644
--- a/src/plugins/meson-templates/meson-templates.plugin
+++ b/src/plugins/meson-templates/meson-templates.plugin
@@ -1,11 +1,10 @@
 [Plugin]
-Authors=Patrick Griffis <tingping tingping se>
-Copyright=Copyright © 2016 Patrick Griffis
+Authors=Patrick Griffis <tingping tingping se>, Christian hergert <chergert redhat com>
+Builtin=true
+Copyright=Copyright © 2016 Patrick Griffis, Copyright © 2022 Christian Hergert
 Depends=create-project;
-Description=Provides templates for creating meson projects
-Loader=python3
-Module=meson_templates
-Name=Meson Templates
+Description=Provides templates for creating new meson projects
+Embedded=_gbp_meson_templates_register_types
+Module=meson-templates
+Name=Meson Project Templates
 X-Category=templates
-X-Builder-ABI=@PACKAGE_ABI@
-X-Has-Resources=true
diff --git a/src/plugins/meson-templates/meson.build b/src/plugins/meson-templates/meson.build
index d2ce17c50..ad901b1d4 100644
--- a/src/plugins/meson-templates/meson.build
+++ b/src/plugins/meson-templates/meson.build
@@ -1,3 +1,11 @@
+if get_option('plugin_meson_templates')
+
+plugins_sources += files([
+  'meson-templates-plugin.c',
+  'gbp-meson-template.c',
+  'gbp-meson-template-provider.c',
+])
+
 flatpak_json_data = configuration_data()
 flatpak_json_data.set('gnome_sdk_version', get_option('gnome_sdk_version'))
 flatpak_json = configure_file(
@@ -5,21 +13,13 @@ flatpak_json = configure_file(
   output: 'flatpak.json',
   configuration: flatpak_json_data)
 
-meson_templates_resources = gnome.compile_resources(
-  'meson_templates',
+plugin_meson_templates_resources = gnome.compile_resources(
+  'gbp-meson-templates',
   'meson-templates.gresource.xml',
-  gresource_bundle: true,
-           install: true,
-       install_dir: plugindir,
-      dependencies: [flatpak_json],
+        c_name: 'gbp_meson_templates',
+  dependencies: [flatpak_json],
 )
 
-install_data('meson_templates.py', install_dir: plugindir)
+plugins_sources += plugin_meson_templates_resources
 
-configure_file(
-          input: 'meson-templates.plugin',
-         output: 'meson-templates.plugin',
-  configuration: config_h,
-        install: true,
-    install_dir: plugindir,
-)
+endif
diff --git a/src/plugins/meson-templates/meson_templates.py b/src/plugins/meson-templates/meson_templates.py
index 7c9dc9a2e..b066d680f 100644
--- a/src/plugins/meson-templates/meson_templates.py
+++ b/src/plugins/meson-templates/meson_templates.py
@@ -326,18 +326,6 @@ class GnomeAdwaitaProjectTemplate(MesonTemplate):
             files['resources/src/application.c'] = 'src/%(prefix)s-application.c'
             files['resources/src/application.h'] = 'src/%(prefix)s-application.h'
             window_ui_name = 'src/%(prefix)s-window.ui'
-        elif language == 'c++':
-            files['resources/src/main.cpp'] = 'src/main.cpp'
-            files['resources/src/window.cpp'] = 'src/%(prefix)s-window.cpp'
-            files['resources/src/window.hpp'] = 'src/%(prefix)s-window.h'
-            window_ui_name = 'src/%(prefix)s-window.ui'
-        elif language == 'c♯':
-            files['resources/src/main.cs'] = 'src/main.cs'
-            files['resources/src/application.in'] = 'src/%(exec_name)s.in'
-            files['resources/flatpak-gtksharp.json.tmpl'] = '%(appid)s.json'
-            meson_file = 'resources/src/meson-cs.build'
-            resource_name = None
-            window_ui_name = None
         elif language == 'vala':
             files['resources/src/main-gtk4.vala'] = 'src/main.vala'
             files['resources/src/window-gtk4.vala'] = 'src/window.vala'
diff --git a/src/plugins/meson-templates/resources/flatpak.json.in 
b/src/plugins/meson-templates/resources/flatpak.json.in
index e75204532..2190cd8be 100644
--- a/src/plugins/meson-templates/resources/flatpak.json.in
+++ b/src/plugins/meson-templates/resources/flatpak.json.in
@@ -13,7 +13,7 @@
         "--share=network",
         "--share=ipc",
         "--socket=fallback-x11",
-{{if (template == "gnome-app-gtk4") || (template == "gnome-app-adwaita")}}
+{{if is_gtk4}}
         "--device=dri",
 {{end}}
         "--socket=wayland"
diff --git a/src/plugins/meson-templates/resources/src/meson-c-vala.build 
b/src/plugins/meson-templates/resources/src/meson-c-vala.build
index ab73b14de..63d9d3543 100644
--- a/src/plugins/meson-templates/resources/src/meson-c-vala.build
+++ b/src/plugins/meson-templates/resources/src/meson-c-vala.build
@@ -2,7 +2,7 @@
 {{if language == "c"}}
   'main.c',
   '{{prefix}}-window.c',
-{{if (template == "gnome-app-gtk4") || (template == "gnome-app-adwaita")}}
+{{if is_gtk4}}
   '{{prefix}}-application.c',
 {{end}}
 {{else if language == "c++"}}
@@ -11,27 +11,25 @@
 {{else if language == "vala"}}
   'main.vala',
   'window.vala',
-{{if (template == "gnome-app-gtk4") || (template == "gnome-app-adwaita")}}
+{{if is_gtk4}}
   'application.vala',
 {{end}}
 {{end}}
 ]
 
 {{name_}}_deps = [
-{{if language == "c++"}}
-  dependency('gtkmm-3.0', version: '>= 3.18'),
-{{else if template == "gnome-app-gtk4"}}
+{{if is_adwaita}}
+  dependency('libadwaita-1'),
+{{else if is_gtk4}}
   dependency('gtk4'),
-{{else if template == "gnome-app-adwaita"}}
-  dependency('libadwaita-1', version: '>= 1.0'),
+{{else if language == "c++"}}
+  dependency('gtkmm-3.0', version: '>= 3.18'),
 {{else}}
   dependency('gio-2.0', version: '>= 2.50'),
   dependency('gtk+-3.0', version: '>= 3.22'),
 {{end}}
 ]
 
-gnome = import('gnome')
-
 {{name_}}_sources += gnome.compile_resources('{{prefix}}-resources',
   '{{prefix}}.gresource.xml',
   c_name: '{{prefix_}}'
diff --git a/src/plugins/meson.build b/src/plugins/meson.build
index 0b17fe07a..5cf3819a3 100644
--- a/src/plugins/meson.build
+++ b/src/plugins/meson.build
@@ -184,6 +184,7 @@ status += [
   'Markdown Preview ..................... : @0@'.format(get_option('plugin_markdown_preview')),
   'Maven ................................ : @0@'.format(get_option('plugin_maven')),
   'Meson ................................ : @0@'.format(get_option('plugin_meson')),
+  'Meson Templates ...................... : @0@'.format(get_option('plugin_meson_templates')),
   'Modelines ............................ : @0@'.format(get_option('plugin_modelines')),
   'Mono ................................. : @0@'.format(get_option('plugin_mono')),
   'Newcomers ............................ : @0@'.format(get_option('plugin_newcomers')),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]