[gnome-builder/wip/gtk4-port: 1458/1774] plugins/shellcmd: add basic user editable run command provider




commit 57c5a408f4b6d10d9cc8e5b099cbc72beaed680e
Author: Christian Hergert <chergert redhat com>
Date:   Fri Jun 10 13:51:32 2022 -0700

    plugins/shellcmd: add basic user editable run command provider
    
    The goal here is to have run commands set in gsettings for both the
    application and project settings.

 src/plugins/meson.build                            |   2 +-
 .../shellcmd/gbp-shellcmd-run-command-provider.c   | 153 +++++++++++++++++++++
 .../shellcmd/gbp-shellcmd-run-command-provider.h   |  33 +++++
 src/plugins/shellcmd/gbp-shellcmd-run-command.c    | 147 ++++++++++++++++++++
 src/plugins/shellcmd/gbp-shellcmd-run-command.h    |  33 +++++
 src/plugins/shellcmd/meson.build                   |   5 +
 .../org.gnome.builder.shellcmd.command.gschema.xml |  21 +++
 .../org.gnome.builder.shellcmd.gschema.xml         |  10 ++
 src/plugins/shellcmd/shellcmd-plugin.c             |   8 +-
 src/plugins/shellcmd/shellcmd.plugin               |   4 +-
 10 files changed, 412 insertions(+), 4 deletions(-)
---
diff --git a/src/plugins/meson.build b/src/plugins/meson.build
index 5596c62b1..31ba8a9f3 100644
--- a/src/plugins/meson.build
+++ b/src/plugins/meson.build
@@ -115,7 +115,7 @@ subdir('retab')
 subdir('rstcheck')
 subdir('rubocop')
 subdir('rust-analyzer')
-#subdir('shellcmd')
+subdir('shellcmd')
 subdir('snippets')
 subdir('spellcheck')
 subdir('sphinx-preview')
diff --git a/src/plugins/shellcmd/gbp-shellcmd-run-command-provider.c 
b/src/plugins/shellcmd/gbp-shellcmd-run-command-provider.c
new file mode 100644
index 000000000..0193b3620
--- /dev/null
+++ b/src/plugins/shellcmd/gbp-shellcmd-run-command-provider.c
@@ -0,0 +1,153 @@
+/* gbp-shellcmd-run-command-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-shellcmd-run-command-provider"
+#define SHELLCMD_SETTINGS_BASE "/org/gnome/builder/shellcmd/"
+
+#include "config.h"
+
+#include <libide-threading.h>
+
+#include "gbp-shellcmd-run-command.h"
+#include "gbp-shellcmd-run-command-provider.h"
+
+struct _GbpShellcmdRunCommandProvider
+{
+  IdeObject parent_instance;
+};
+
+static void
+gbp_shellcmd_run_command_provider_populate (GListStore *store,
+                                            const char *settings_path)
+{
+  g_autoptr(GSettings) settings = NULL;
+  g_auto(GStrv) run_commands = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (G_IS_LIST_STORE (store));
+  g_assert (settings_path != NULL);
+
+  IDE_TRACE_MSG ("Adding commands to GListStore %p from %s", store, settings_path);
+
+  settings = g_settings_new_with_path ("org.gnome.builder.shellcmd", settings_path);
+  run_commands = g_settings_get_strv (settings, "run-commands");
+
+  for (guint i = 0; run_commands[i]; i++)
+    {
+      g_autofree char *run_settings_path = g_strconcat (settings_path, run_commands[i], "/", NULL);
+      g_autoptr(GbpShellcmdRunCommand) run_command = gbp_shellcmd_run_command_new (run_settings_path);
+
+      g_list_store_append (store, run_command);
+    }
+
+  IDE_EXIT;
+}
+
+static void
+gbp_shellcmd_run_command_provider_list_commands_async (IdeRunCommandProvider *provider,
+                                                       GCancellable          *cancellable,
+                                                       GAsyncReadyCallback    callback,
+                                                       gpointer               user_data)
+{
+  g_autoptr(GListStore) store = NULL;
+  g_autoptr(IdeTask) task = NULL;
+  g_autofree char *project_id = NULL;
+  g_autofree char *project_settings_path = NULL;
+  IdeContext *context;
+
+  IDE_ENTRY;
+
+  g_assert (GBP_IS_SHELLCMD_RUN_COMMAND_PROVIDER (provider));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = ide_task_new (provider, cancellable, callback, user_data);
+  ide_task_set_source_tag (task, gbp_shellcmd_run_command_provider_list_commands_async);
+
+  store = g_list_store_new (IDE_TYPE_RUN_COMMAND);
+
+  /* Add project shell commands so they resolve first */
+  context = ide_object_get_context (IDE_OBJECT (provider));
+  project_id = ide_context_dup_project_id (context);
+  project_settings_path = g_strconcat (SHELLCMD_SETTINGS_BASE, "projects/", project_id, "/", NULL);
+  gbp_shellcmd_run_command_provider_populate (store, project_settings_path);
+
+  /* Then application-wide commands for lower priority */
+  gbp_shellcmd_run_command_provider_populate (store, SHELLCMD_SETTINGS_BASE);
+
+  ide_task_return_pointer (task, g_steal_pointer (&store), g_object_unref);
+
+  IDE_EXIT;
+}
+
+static GListModel *
+gbp_shellcmd_run_command_provider_list_commands_finish (IdeRunCommandProvider  *provider,
+                                                        GAsyncResult           *result,
+                                                        GError                **error)
+{
+  GListModel *ret;
+
+  IDE_ENTRY;
+
+  g_assert (GBP_IS_SHELLCMD_RUN_COMMAND_PROVIDER (provider));
+  g_assert (IDE_IS_TASK (result));
+
+  ret = ide_task_propagate_pointer (IDE_TASK (result), error);
+
+  IDE_RETURN (ret);
+}
+
+static void
+run_command_provider_iface_init (IdeRunCommandProviderInterface *iface)
+{
+  iface->list_commands_async = gbp_shellcmd_run_command_provider_list_commands_async;
+  iface->list_commands_finish = gbp_shellcmd_run_command_provider_list_commands_finish;
+}
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (GbpShellcmdRunCommandProvider, gbp_shellcmd_run_command_provider, 
IDE_TYPE_OBJECT,
+                               G_IMPLEMENT_INTERFACE (IDE_TYPE_RUN_COMMAND_PROVIDER, 
run_command_provider_iface_init))
+
+static void
+gbp_shellcmd_run_command_provider_class_init (GbpShellcmdRunCommandProviderClass *klass)
+{
+}
+
+static void
+gbp_shellcmd_run_command_provider_init (GbpShellcmdRunCommandProvider *self)
+{
+}
+
+char *
+gbp_shellcmd_run_command_provider_create_settings_path (IdeContext *context)
+{
+  g_autofree char *uuid = NULL;
+
+  g_assert (!context || IDE_IS_CONTEXT (context));
+
+  uuid = g_uuid_string_random ();
+
+  if (ide_context_has_project (context))
+    {
+      g_autofree char *project_id = ide_context_dup_project_id (context);
+      return g_strconcat (SHELLCMD_SETTINGS_BASE, "projects/", project_id, "/", uuid, "/", NULL);
+    }
+
+  return g_strconcat (SHELLCMD_SETTINGS_BASE, "/", uuid, "/", NULL);
+}
diff --git a/src/plugins/shellcmd/gbp-shellcmd-run-command-provider.h 
b/src/plugins/shellcmd/gbp-shellcmd-run-command-provider.h
new file mode 100644
index 000000000..21f9668a4
--- /dev/null
+++ b/src/plugins/shellcmd/gbp-shellcmd-run-command-provider.h
@@ -0,0 +1,33 @@
+/* gbp-shellcmd-run-command-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 <libide-foundry.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_SHELLCMD_RUN_COMMAND_PROVIDER (gbp_shellcmd_run_command_provider_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpShellcmdRunCommandProvider, gbp_shellcmd_run_command_provider, GBP, 
SHELLCMD_RUN_COMMAND_PROVIDER, IdeObject)
+
+char *gbp_shellcmd_run_command_provider_create_settings_path (IdeContext *context);
+
+G_END_DECLS
diff --git a/src/plugins/shellcmd/gbp-shellcmd-run-command.c b/src/plugins/shellcmd/gbp-shellcmd-run-command.c
new file mode 100644
index 000000000..fe67180d5
--- /dev/null
+++ b/src/plugins/shellcmd/gbp-shellcmd-run-command.c
@@ -0,0 +1,147 @@
+/* gbp-shellcmd-run-command.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-shellcmd-run-command"
+
+#include "config.h"
+
+#include "gbp-shellcmd-run-command.h"
+
+struct _GbpShellcmdRunCommand
+{
+  IdeRunCommand  parent_instance;
+  char          *settings_path;
+  GSettings     *settings;
+};
+
+enum {
+  PROP_0,
+  PROP_SETTINGS_PATH,
+  N_PROPS
+};
+
+G_DEFINE_FINAL_TYPE (GbpShellcmdRunCommand, gbp_shellcmd_run_command, IDE_TYPE_RUN_COMMAND)
+
+static GParamSpec *properties [N_PROPS];
+
+static void
+gbp_shellcmd_run_command_constructed (GObject *object)
+{
+  GbpShellcmdRunCommand *self = (GbpShellcmdRunCommand *)object;
+  g_autofree char *id = NULL;
+  g_auto(GStrv) path_split = NULL;
+  gsize n_parts;
+
+  g_assert (GBP_IS_SHELLCMD_RUN_COMMAND (self));
+  g_assert (self->settings_path != NULL);
+
+  self->settings = g_settings_new_with_path ("org.gnome.builder.shellcmd.command", self->settings_path);
+
+  path_split = g_strsplit (self->settings_path, "/", 0);
+  n_parts = g_strv_length (path_split);
+  id = g_strdup_printf ("shellcmd:%s", path_split[n_parts-1]);
+
+  ide_run_command_set_id (IDE_RUN_COMMAND (self), id);
+  g_settings_bind (self->settings, "display-name", self, "display-name", G_SETTINGS_BIND_DEFAULT);
+  g_settings_bind (self->settings, "env", self, "env", G_SETTINGS_BIND_DEFAULT);
+  g_settings_bind (self->settings, "argv", self, "argv", G_SETTINGS_BIND_DEFAULT);
+  g_settings_bind (self->settings, "cwd", self, "cwd", G_SETTINGS_BIND_DEFAULT);
+}
+
+static void
+gbp_shellcmd_run_command_dispose (GObject *object)
+{
+  GbpShellcmdRunCommand *self = (GbpShellcmdRunCommand *)object;
+
+  g_clear_pointer (&self->settings_path, g_free);
+  g_clear_object (&self->settings);
+
+  G_OBJECT_CLASS (gbp_shellcmd_run_command_parent_class)->dispose (object);
+}
+
+static void
+gbp_shellcmd_run_command_get_property (GObject    *object,
+                                       guint       prop_id,
+                                       GValue     *value,
+                                       GParamSpec *pspec)
+{
+  GbpShellcmdRunCommand *self = GBP_SHELLCMD_RUN_COMMAND (object);
+
+  switch (prop_id)
+    {
+    case PROP_SETTINGS_PATH:
+      g_value_set_string (value, self->settings_path);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gbp_shellcmd_run_command_set_property (GObject      *object,
+                                       guint         prop_id,
+                                       const GValue *value,
+                                       GParamSpec   *pspec)
+{
+  GbpShellcmdRunCommand *self = GBP_SHELLCMD_RUN_COMMAND (object);
+
+  switch (prop_id)
+    {
+    case PROP_SETTINGS_PATH:
+      self->settings_path = g_value_dup_string (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gbp_shellcmd_run_command_class_init (GbpShellcmdRunCommandClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->constructed = gbp_shellcmd_run_command_constructed;
+  object_class->dispose = gbp_shellcmd_run_command_dispose;
+  object_class->get_property = gbp_shellcmd_run_command_get_property;
+  object_class->set_property = gbp_shellcmd_run_command_set_property;
+
+  properties [PROP_SETTINGS_PATH] =
+    g_param_spec_string ("settings-path", NULL, NULL, NULL,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+gbp_shellcmd_run_command_init (GbpShellcmdRunCommand *self)
+{
+}
+
+GbpShellcmdRunCommand *
+gbp_shellcmd_run_command_new (const char *settings_path)
+{
+  return g_object_new (GBP_TYPE_SHELLCMD_RUN_COMMAND,
+                       "settings-path", settings_path,
+                       NULL);
+}
diff --git a/src/plugins/shellcmd/gbp-shellcmd-run-command.h b/src/plugins/shellcmd/gbp-shellcmd-run-command.h
new file mode 100644
index 000000000..f0ecd121e
--- /dev/null
+++ b/src/plugins/shellcmd/gbp-shellcmd-run-command.h
@@ -0,0 +1,33 @@
+/* gbp-shellcmd-run-command.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-foundry.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_SHELLCMD_RUN_COMMAND (gbp_shellcmd_run_command_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpShellcmdRunCommand, gbp_shellcmd_run_command, GBP, SHELLCMD_RUN_COMMAND, 
IdeRunCommand)
+
+GbpShellcmdRunCommand *gbp_shellcmd_run_command_new (const char *settings_path);
+
+G_END_DECLS
diff --git a/src/plugins/shellcmd/meson.build b/src/plugins/shellcmd/meson.build
index 482dbbc7b..581953988 100644
--- a/src/plugins/shellcmd/meson.build
+++ b/src/plugins/shellcmd/meson.build
@@ -2,6 +2,8 @@ if get_option('plugin_shellcmd')
 
 plugins_sources += files([
   'shellcmd-plugin.c',
+  'gbp-shellcmd-run-command.c',
+  'gbp-shellcmd-run-command-provider.c',
 ])
 
 plugin_shellcmd_enum_headers = [
@@ -17,4 +19,7 @@ plugin_shellcmd_resources = gnome.compile_resources(
 plugins_sources += plugin_shellcmd_resources
 plugins_include_directories += [include_directories('.')]
 
+install_data(['org.gnome.builder.shellcmd.gschema.xml'], install_dir: schema_dir)
+install_data(['org.gnome.builder.shellcmd.command.gschema.xml'], install_dir: schema_dir)
+
 endif
diff --git a/src/plugins/shellcmd/org.gnome.builder.shellcmd.command.gschema.xml 
b/src/plugins/shellcmd/org.gnome.builder.shellcmd.command.gschema.xml
new file mode 100644
index 000000000..a6330b19c
--- /dev/null
+++ b/src/plugins/shellcmd/org.gnome.builder.shellcmd.command.gschema.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schemalist>
+  <schema id="org.gnome.builder.shellcmd.command" gettext-domain="gnome-builder">
+    <key name="display-name" type="s">
+      <default>''</default>
+      <summary>Display Name</summary>
+    </key>
+    <key name="cwd" type="s">
+      <default>'$BUILDDIR/'</default>
+      <summary>Current Working Directory</summary>
+    </key>
+    <key name="argv" type="as">
+      <default>[]</default>
+      <summary>Command Arguments</summary>
+    </key>
+    <key name="env" type="as">
+      <default>[]</default>
+      <summary>Command Environment</summary>
+    </key>
+  </schema>
+</schemalist>
diff --git a/src/plugins/shellcmd/org.gnome.builder.shellcmd.gschema.xml 
b/src/plugins/shellcmd/org.gnome.builder.shellcmd.gschema.xml
new file mode 100644
index 000000000..cb6abf007
--- /dev/null
+++ b/src/plugins/shellcmd/org.gnome.builder.shellcmd.gschema.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schemalist>
+  <schema id="org.gnome.builder.shellcmd" gettext-domain="gnome-builder">
+    <key name="run-commands" type="as">
+      <default>[]</default>
+      <summary>Run Commands</summary>
+      <description>A list of run-command ids to load for the application or project.</description>
+    </key>
+  </schema>
+</schemalist>
diff --git a/src/plugins/shellcmd/shellcmd-plugin.c b/src/plugins/shellcmd/shellcmd-plugin.c
index ea215ae6b..9ad48f036 100644
--- a/src/plugins/shellcmd/shellcmd-plugin.c
+++ b/src/plugins/shellcmd/shellcmd-plugin.c
@@ -1,6 +1,6 @@
 /* shellcmd-plugin.c
  *
- * Copyright 2019 Christian Hergert <chergert redhat com>
+ * Copyright 2019-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
@@ -22,8 +22,14 @@
 
 #include <libpeas/peas.h>
 
+#include <libide-foundry.h>
+
+#include "gbp-shellcmd-run-command-provider.h"
 
 _IDE_EXTERN void
 _gbp_shellcmd_register_types (PeasObjectModule *module)
 {
+  peas_object_module_register_extension_type (module,
+                                              IDE_TYPE_RUN_COMMAND_PROVIDER,
+                                              GBP_TYPE_SHELLCMD_RUN_COMMAND_PROVIDER);
 }
diff --git a/src/plugins/shellcmd/shellcmd.plugin b/src/plugins/shellcmd/shellcmd.plugin
index 6e35159c8..8aa4d21fb 100644
--- a/src/plugins/shellcmd/shellcmd.plugin
+++ b/src/plugins/shellcmd/shellcmd.plugin
@@ -1,8 +1,8 @@
 [Plugin]
 Authors=Christian Hergert <christian hergert me>
 Builtin=true
-Copyright=Copyright © 2019 Christian Hergert
-Description=Run shell commands from your project
+Copyright=Copyright © 2019-2022 Christian Hergert
+Description=Use custom commands to run your project
 Embedded=_gbp_shellcmd_register_types
 Hidden=true
 Module=shellcmd


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