[gnome-builder] libide-foundry: modernize build pipeline around run contexts
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] libide-foundry: modernize build pipeline around run contexts
- Date: Tue, 12 Jul 2022 06:39:11 +0000 (UTC)
commit 54f1b8b2b9c6cbc8fc592427cdc9748596260cd9
Author: Christian Hergert <chergert redhat com>
Date: Mon Jul 11 21:12:07 2022 -0700
libide-foundry: modernize build pipeline around run contexts
This also cleans up how we process devices and deploy strategies, moves
away from libdazzle, simplifies PTY usage, among more.
src/libide/foundry/ide-build-manager.c | 480 ++++++++++++++++++++-----
src/libide/foundry/ide-build-manager.h | 9 +
src/libide/foundry/ide-deploy-strategy.c | 145 +++-----
src/libide/foundry/ide-deploy-strategy.h | 116 +++---
src/libide/foundry/ide-device-manager.c | 407 ++-------------------
src/libide/foundry/ide-device-manager.h | 56 ++-
src/libide/foundry/ide-device-provider.c | 14 -
src/libide/foundry/ide-pipeline-stage-mkdirs.c | 8 +-
src/libide/foundry/ide-pipeline-stage.c | 8 +-
src/libide/foundry/ide-pipeline-stage.h | 2 +-
src/libide/foundry/ide-pipeline.c | 464 +++++++++++++-----------
src/libide/foundry/ide-pipeline.h | 8 +
src/libide/foundry/meson.build | 1 -
13 files changed, 836 insertions(+), 882 deletions(-)
---
diff --git a/src/libide/foundry/ide-build-manager.c b/src/libide/foundry/ide-build-manager.c
index 132a39a54..2c9a5b478 100644
--- a/src/libide/foundry/ide-build-manager.c
+++ b/src/libide/foundry/ide-build-manager.c
@@ -22,14 +22,19 @@
#include "config.h"
-#include <dazzle.h>
#include <glib/gi18n.h>
+#include <libpeas/peas.h>
+
+#include <libide-core.h>
#include <libide-code.h>
+#include <libide-plugins.h>
#include <libide-threading.h>
#include <libide-vcs.h>
#include "ide-build-manager.h"
#include "ide-build-private.h"
+#include "ide-build-target.h"
+#include "ide-build-target-provider.h"
#include "ide-config-manager.h"
#include "ide-config.h"
#include "ide-device-info.h"
@@ -37,12 +42,12 @@
#include "ide-device.h"
#include "ide-foundry-compat.h"
#include "ide-pipeline.h"
-#include "ide-run-manager.h"
#include "ide-runtime-manager.h"
#include "ide-runtime-private.h"
#include "ide-runtime.h"
#include "ide-toolchain-manager.h"
#include "ide-toolchain-private.h"
+#include "ide-triplet.h"
/**
* SECTION:ide-build-manager
@@ -70,9 +75,20 @@ struct _IdeBuildManager
IdePipeline *pipeline;
GDateTime *last_build_time;
- DzlSignalGroup *pipeline_signals;
+ IdeSignalGroup *pipeline_signals;
+
+ IdeExtensionSetAdapter
+ *build_target_providers;
+
+ char *branch_name;
- gchar *branch_name;
+ /* The name of the default build target to build if no targets
+ * are specified. Setting to NULL (or empty string) implies that
+ * no target should be specified and therefore the build system
+ * should attempt a "full build" such as you would get by running
+ * `make` or `ninja`.
+ */
+ char *default_build_target;
GTimer *running_time;
@@ -90,29 +106,40 @@ struct _IdeBuildManager
guint has_configured : 1;
};
-static void initable_iface_init (GInitableIface *iface);
-static void ide_build_manager_set_can_build (IdeBuildManager *self,
- gboolean can_build);
-static void ide_build_manager_action_build (IdeBuildManager *self,
- GVariant *param);
-static void ide_build_manager_action_rebuild (IdeBuildManager *self,
- GVariant *param);
-static void ide_build_manager_action_cancel (IdeBuildManager *self,
- GVariant *param);
-static void ide_build_manager_action_clean (IdeBuildManager *self,
- GVariant *param);
-static void ide_build_manager_action_export (IdeBuildManager *self,
- GVariant *param);
-static void ide_build_manager_action_install (IdeBuildManager *self,
- GVariant *param);
-
-DZL_DEFINE_ACTION_GROUP (IdeBuildManager, ide_build_manager, {
+typedef struct
+{
+ IdePipeline *pipeline;
+ GPtrArray *targets;
+ char *default_target;
+ IdePipelinePhase phase;
+} BuildState;
+
+static void initable_iface_init (GInitableIface *iface);
+static void ide_build_manager_set_can_build (IdeBuildManager *self,
+ gboolean can_build);
+static void ide_build_manager_action_build (IdeBuildManager *self,
+ GVariant *param);
+static void ide_build_manager_action_rebuild (IdeBuildManager *self,
+ GVariant *param);
+static void ide_build_manager_action_cancel (IdeBuildManager *self,
+ GVariant *param);
+static void ide_build_manager_action_clean (IdeBuildManager *self,
+ GVariant *param);
+static void ide_build_manager_action_export (IdeBuildManager *self,
+ GVariant *param);
+static void ide_build_manager_action_install (IdeBuildManager *self,
+ GVariant *param);
+static void ide_build_manager_action_default_build_target (IdeBuildManager *self,
+ GVariant *param);
+
+IDE_DEFINE_ACTION_GROUP (IdeBuildManager, ide_build_manager, {
{ "build", ide_build_manager_action_build },
{ "cancel", ide_build_manager_action_cancel },
{ "clean", ide_build_manager_action_clean },
{ "export", ide_build_manager_action_export },
{ "install", ide_build_manager_action_install },
{ "rebuild", ide_build_manager_action_rebuild },
+ { "default-build-target", ide_build_manager_action_default_build_target, "s", "''" },
})
G_DEFINE_TYPE_EXTENDED (IdeBuildManager, ide_build_manager, IDE_TYPE_OBJECT, G_TYPE_FLAG_FINAL,
@@ -144,6 +171,39 @@ enum {
static GParamSpec *properties [N_PROPS];
static guint signals [N_SIGNALS];
+static void
+build_state_free (BuildState *state)
+{
+ g_clear_pointer (&state->default_target, g_free);
+ g_clear_pointer (&state->targets, g_ptr_array_unref);
+ g_clear_object (&state->pipeline);
+ g_slice_free (BuildState, state);
+}
+
+static void
+ide_build_manager_action_default_build_target (IdeBuildManager *self,
+ GVariant *param)
+{
+ const char *str;
+
+ g_assert (IDE_IS_BUILD_MANAGER (self));
+ g_assert (param != NULL);
+ g_assert (g_variant_is_of_type (param, G_VARIANT_TYPE_STRING));
+
+ str = g_variant_get_string (param, NULL);
+ if (ide_str_empty0 (str))
+ str = NULL;
+
+ if (g_strcmp0 (str, self->default_build_target) != 0)
+ {
+ g_free (self->default_build_target);
+ self->default_build_target = g_strdup (str);
+ ide_build_manager_set_action_state (self,
+ "default-build-target",
+ g_variant_new_string (str ? str : ""));
+ }
+}
+
static void
ide_build_manager_rediagnose (IdeBuildManager *self)
{
@@ -192,14 +252,7 @@ ide_build_manager_start_timer (IdeBuildManager *self)
else
self->running_time = g_timer_new ();
- /*
- * We use the DzlFrameSource for our timer callback because we only want to
- * update at a rate somewhat close to a typical monitor refresh rate.
- * Additionally, we want to handle drift (which that source does) so that we
- * don't constantly fall behind.
- */
self->timer_source = g_timeout_add_seconds (1, timer_callback, self);
-
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_RUNNING_TIME]);
IDE_EXIT;
@@ -212,7 +265,7 @@ ide_build_manager_stop_timer (IdeBuildManager *self)
g_assert (IDE_IS_BUILD_MANAGER (self));
- dzl_clear_source (&self->timer_source);
+ g_clear_handle_id (&self->timer_source, g_source_remove);
if (self->running_time != NULL)
{
@@ -582,7 +635,6 @@ ide_build_manager_invalidate_pipeline (IdeBuildManager *self)
g_autoptr(IdeTask) task = NULL;
IdeConfigManager *config_manager;
IdeDeviceManager *device_manager;
- IdeRunManager *run_manager;
IdeConfig *config;
IdeContext *context;
IdeDevice *device;
@@ -604,16 +656,10 @@ ide_build_manager_invalidate_pipeline (IdeBuildManager *self)
g_assert (self->pipeline != NULL);
self->building = FALSE;
- dzl_clear_source (&self->timer_source);
+ g_clear_handle_id (&self->timer_source, g_source_remove);
g_signal_emit (self, signals [BUILD_FAILED], 0, self->pipeline);
}
- /*
- * Clear any cached build targets from the run manager.
- */
- run_manager = ide_run_manager_from_context (context);
- ide_run_manager_set_build_target (run_manager, NULL);
-
/*
* Cancel and clear our previous pipeline and associated components
* as they are not invalide.
@@ -654,7 +700,7 @@ ide_build_manager_invalidate_pipeline (IdeBuildManager *self)
"device", device,
NULL);
ide_object_append (IDE_OBJECT (self), IDE_OBJECT (self->pipeline));
- dzl_signal_group_set_target (self->pipeline_signals, self->pipeline);
+ ide_signal_group_set_target (self->pipeline_signals, self->pipeline);
/*
* Create a task to manage our async pipeline initialization state.
@@ -819,14 +865,15 @@ ide_build_manager_finalize (GObject *object)
{
IdeBuildManager *self = (IdeBuildManager *)object;
+ ide_clear_and_destroy_object (&self->build_target_providers);
ide_clear_and_destroy_object (&self->pipeline);
g_clear_object (&self->pipeline_signals);
g_clear_object (&self->cancellable);
g_clear_pointer (&self->last_build_time, g_date_time_unref);
g_clear_pointer (&self->running_time, g_timer_destroy);
g_clear_pointer (&self->branch_name, g_free);
-
- dzl_clear_source (&self->timer_source);
+ g_clear_pointer (&self->default_build_target, g_free);
+ g_clear_handle_id (&self->timer_source, g_source_remove);
G_OBJECT_CLASS (ide_build_manager_parent_class)->finalize (object);
}
@@ -1166,33 +1213,33 @@ ide_build_manager_init (IdeBuildManager *self)
self->cancellable = g_cancellable_new ();
self->needs_rediagnose = TRUE;
- self->pipeline_signals = dzl_signal_group_new (IDE_TYPE_PIPELINE);
+ self->pipeline_signals = ide_signal_group_new (IDE_TYPE_PIPELINE);
- dzl_signal_group_connect_object (self->pipeline_signals,
+ ide_signal_group_connect_object (self->pipeline_signals,
"diagnostic",
G_CALLBACK (ide_build_manager_handle_diagnostic),
self,
G_CONNECT_SWAPPED);
- dzl_signal_group_connect_object (self->pipeline_signals,
+ ide_signal_group_connect_object (self->pipeline_signals,
"notify::busy",
G_CALLBACK (ide_build_manager_notify_busy),
self,
G_CONNECT_SWAPPED);
- dzl_signal_group_connect_object (self->pipeline_signals,
+ ide_signal_group_connect_object (self->pipeline_signals,
"notify::message",
G_CALLBACK (ide_build_manager_notify_message),
self,
G_CONNECT_SWAPPED);
- dzl_signal_group_connect_object (self->pipeline_signals,
+ ide_signal_group_connect_object (self->pipeline_signals,
"started",
G_CALLBACK (ide_build_manager_pipeline_started),
self,
G_CONNECT_SWAPPED);
- dzl_signal_group_connect_object (self->pipeline_signals,
+ ide_signal_group_connect_object (self->pipeline_signals,
"finished",
G_CALLBACK (ide_build_manager_pipeline_finished),
self,
@@ -1381,49 +1428,127 @@ failure:
}
static void
-ide_build_manager_save_all_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
+ide_build_manager_build_list_targets_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- IdeBufferManager *buffer_manager = (IdeBufferManager *)object;
+ IdeBuildManager *self = (IdeBuildManager *)object;
+ g_autoptr(GListModel) targets = NULL;
g_autoptr(IdeTask) task = user_data;
g_autoptr(GError) error = NULL;
- IdeBuildManager *self;
- GCancellable *cancellable;
- GPtrArray *targets;
- IdePipelinePhase phase;
+ BuildState *state;
IDE_ENTRY;
- g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
+ g_assert (IDE_IS_BUILD_MANAGER (self));
+ g_assert (G_IS_ASYNC_RESULT (result));
g_assert (IDE_IS_TASK (task));
- self = ide_task_get_source_object (task);
- cancellable = ide_task_get_cancellable (task);
- targets = ide_task_get_task_data (task);
+ state = ide_task_get_task_data (task);
- g_assert (IDE_IS_BUILD_MANAGER (self));
- g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+ g_assert (state != NULL);
+ g_assert (state->targets == NULL);
+ g_assert (state->default_target != NULL);
+ g_assert (IDE_IS_PIPELINE (state->pipeline));
- if (!ide_buffer_manager_save_all_finish (buffer_manager, result, &error))
+ if ((targets = ide_build_manager_list_targets_finish (self, result, &error)))
{
- ide_task_return_error (task, g_steal_pointer (&error));
- IDE_EXIT;
+ guint n_items = g_list_model_get_n_items (targets);
+
+ for (guint i = 0; i < n_items; i++)
+ {
+ g_autoptr(IdeBuildTarget) target = g_list_model_get_item (targets, i);
+ const char *name = ide_build_target_get_name (target);
+
+ if (g_strcmp0 (name, state->default_target) == 0)
+ {
+ state->targets = g_ptr_array_new_with_free_func (g_object_unref);
+ g_ptr_array_add (state->targets, g_steal_pointer (&target));
+ break;
+ }
+ }
}
- phase = ide_pipeline_get_requested_phase (self->pipeline);
+ if (error != NULL && !ide_error_ignore (error))
+ g_warning ("Failed to list build targets: %s", error->message);
- ide_pipeline_build_targets_async (self->pipeline,
- phase,
- targets,
- cancellable,
+ ide_pipeline_build_targets_async (state->pipeline,
+ state->phase,
+ state->targets,
+ ide_task_get_cancellable (task),
ide_build_manager_build_targets_cb,
- g_steal_pointer (&task));
+ g_object_ref (task));
+
+ IDE_EXIT;
+}
+
+static void
+ide_build_manager_build_after_save (IdeTask *task)
+{
+ IdeBuildManager *self;
+ BuildState *state;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_TASK (task));
+
+ self = ide_task_get_source_object (task);
+ state = ide_task_get_task_data (task);
+
+ g_assert (IDE_IS_BUILD_MANAGER (self));
+ g_assert (state != NULL);
+ g_assert (IDE_IS_PIPELINE (state->pipeline));
+
+ /* If a default build target was preferred instead of the build system
+ * default then we need to go fetch that from the build target providers.
+ * However, we can only do this if we are just building. Anything requiring
+ * us to install means that we have to do regular builds as that will happen
+ * anyway as part of the install process.
+ */
+ if (state->targets == NULL &&
+ state->default_target != NULL &&
+ state->phase < IDE_PIPELINE_PHASE_INSTALL)
+ ide_build_manager_list_targets_async (self,
+ ide_task_get_cancellable (task),
+ ide_build_manager_build_list_targets_cb,
+ g_object_ref (task));
+ else
+ ide_pipeline_build_targets_async (state->pipeline,
+ state->phase,
+ state->targets,
+ ide_task_get_cancellable (task),
+ ide_build_manager_build_targets_cb,
+ g_object_ref (task));
+
+ IDE_EXIT;
+}
+
+static void
+ide_build_manager_save_all_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeBufferManager *buffer_manager = (IdeBufferManager *)object;
+ g_autoptr(IdeTask) task = user_data;
+ g_autoptr(GError) error = NULL;
+ IdeBuildManager *self;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
+ g_assert (IDE_IS_TASK (task));
+
+ self = ide_task_get_source_object (task);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_HAS_DIAGNOSTICS]);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_LAST_BUILD_TIME]);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_RUNNING_TIME]);
+ if (!ide_buffer_manager_save_all_finish (buffer_manager, result, &error))
+ ide_task_return_error (task, g_steal_pointer (&error));
+ else
+ ide_build_manager_build_after_save (task);
+
IDE_EXIT;
}
@@ -1451,8 +1576,7 @@ ide_build_manager_build_async (IdeBuildManager *self,
gpointer user_data)
{
g_autoptr(IdeTask) task = NULL;
- IdeBufferManager *buffer_manager;
- IdeContext *context;
+ BuildState *state;
IDE_ENTRY;
@@ -1460,16 +1584,13 @@ ide_build_manager_build_async (IdeBuildManager *self,
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
g_return_if_fail (!g_cancellable_is_cancelled (self->cancellable));
- cancellable = dzl_cancellable_chain (cancellable, self->cancellable);
+ cancellable = ide_cancellable_chain (cancellable, self->cancellable);
task = ide_task_new (self, cancellable, callback, user_data);
ide_task_set_source_tag (task, ide_build_manager_build_async);
ide_task_set_priority (task, G_PRIORITY_LOW);
ide_task_set_return_on_cancel (task, TRUE);
- if (targets != NULL)
- ide_task_set_task_data (task, _g_ptr_array_copy_objects (targets), g_ptr_array_unref);
-
if (self->pipeline == NULL ||
self->can_build == FALSE ||
!ide_pipeline_is_ready (self->pipeline))
@@ -1487,6 +1608,17 @@ ide_build_manager_build_async (IdeBuildManager *self,
IDE_EXIT;
}
+ /* Setup our state for the build process. We try to cache everything
+ * we need up front so that we don't need to deal with races between
+ * asynchronous operations.
+ */
+ state = g_slice_new0 (BuildState);
+ state->phase = phase;
+ state->default_target = g_strdup (self->default_build_target);
+ state->targets = targets ? _g_ptr_array_copy_objects (targets) : NULL;
+ state->pipeline = g_object_ref (self->pipeline);
+ ide_task_set_task_data (task, state, build_state_free);
+
/*
* Only update our "build time" if we are advancing to IDE_PIPELINE_PHASE_BUILD,
* we don't really care about "builds" for configure stages and less.
@@ -1510,8 +1642,9 @@ ide_build_manager_build_async (IdeBuildManager *self,
*/
if ((phase & IDE_PIPELINE_PHASE_MASK) >= IDE_PIPELINE_PHASE_BUILD)
{
- context = ide_object_get_context (IDE_OBJECT (self));
- buffer_manager = ide_buffer_manager_from_context (context);
+ IdeContext *context = ide_object_get_context (IDE_OBJECT (self));
+ IdeBufferManager *buffer_manager = ide_buffer_manager_from_context (context);
+
ide_buffer_manager_save_all_async (buffer_manager,
NULL,
ide_build_manager_save_all_cb,
@@ -1519,12 +1652,7 @@ ide_build_manager_build_async (IdeBuildManager *self,
IDE_EXIT;
}
- ide_pipeline_build_targets_async (self->pipeline,
- phase,
- targets,
- cancellable,
- ide_build_manager_build_targets_cb,
- g_steal_pointer (&task));
+ ide_build_manager_build_after_save (task);
IDE_EXIT;
}
@@ -1606,7 +1734,7 @@ ide_build_manager_clean_async (IdeBuildManager *self,
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
g_return_if_fail (!g_cancellable_is_cancelled (self->cancellable));
- cancellable = dzl_cancellable_chain (cancellable, self->cancellable);
+ cancellable = ide_cancellable_chain (cancellable, self->cancellable);
task = ide_task_new (self, cancellable, callback, user_data);
ide_task_set_source_tag (task, ide_build_manager_clean_async);
@@ -1715,7 +1843,7 @@ ide_build_manager_rebuild_async (IdeBuildManager *self,
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
g_return_if_fail (!g_cancellable_is_cancelled (self->cancellable));
- cancellable = dzl_cancellable_chain (cancellable, self->cancellable);
+ cancellable = ide_cancellable_chain (cancellable, self->cancellable);
task = ide_task_new (self, cancellable, callback, user_data);
ide_task_set_source_tag (task, ide_build_manager_rebuild_async);
@@ -1844,3 +1972,185 @@ _ide_build_manager_start (IdeBuildManager *self)
ide_build_manager_invalidate (self);
}
+
+static void
+ensure_build_target_providers (IdeBuildManager *self)
+{
+ g_assert (IDE_IS_BUILD_MANAGER (self));
+
+ if (self->build_target_providers != NULL)
+ return;
+
+ self->build_target_providers =
+ ide_extension_set_adapter_new (IDE_OBJECT (self),
+ peas_engine_get_default (),
+ IDE_TYPE_BUILD_TARGET_PROVIDER,
+ NULL, NULL);
+}
+
+typedef struct
+{
+ GListStore *store;
+ guint n_active;
+} ListTargets;
+
+static void
+list_targets_free (ListTargets *state)
+{
+ g_clear_object (&state->store);
+ g_slice_free (ListTargets, state);
+}
+
+static void
+ide_build_manager_list_targets_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeBuildTargetProvider *provider = (IdeBuildTargetProvider *)object;
+ g_autoptr(GPtrArray) targets = NULL;
+ g_autoptr(IdeTask) task = user_data;
+ g_autoptr(GError) error = NULL;
+ ListTargets *state;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_MAIN_THREAD ());
+ g_assert (IDE_IS_BUILD_TARGET_PROVIDER (provider));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (IDE_IS_TASK (task));
+
+ state = ide_task_get_task_data (task);
+
+ g_assert (state != NULL);
+ g_assert (G_IS_LIST_STORE (state->store));
+
+ targets = ide_build_target_provider_get_targets_finish (provider, result, &error);
+ IDE_PTR_ARRAY_SET_FREE_FUNC (targets, g_object_unref);
+
+ if (targets != NULL)
+ {
+ for (guint i = 0; i < targets->len; i++)
+ {
+ IdeBuildTarget *target = g_ptr_array_index (targets, i);
+
+ g_list_store_append (state->store, target);
+ }
+ }
+
+ state->n_active--;
+
+ if (state->n_active == 0)
+ {
+ if (g_list_model_get_n_items (G_LIST_MODEL (state->store)) > 0)
+ ide_task_return_object (task, g_steal_pointer (&state->store));
+ else
+ ide_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ "No build targets could be located, perhaps project needs to be
configured");
+ }
+
+ IDE_EXIT;
+}
+
+static void
+ide_build_manager_list_targets_foreach_cb (IdeExtensionSetAdapter *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ IdeBuildTargetProvider *provider = (IdeBuildTargetProvider *)exten;
+ IdeTask *task = user_data;
+ ListTargets *state;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_MAIN_THREAD ());
+ g_assert (IDE_IS_EXTENSION_SET_ADAPTER (set));
+ g_assert (IDE_IS_BUILD_TARGET_PROVIDER (provider));
+ g_assert (IDE_IS_TASK (task));
+
+ state = ide_task_get_task_data (task);
+
+ g_assert (state != NULL);
+ g_assert (G_IS_LIST_STORE (state->store));
+
+ state->n_active++;
+
+ ide_build_target_provider_get_targets_async (provider,
+ ide_task_get_cancellable (task),
+ ide_build_manager_list_targets_cb,
+ g_object_ref (task));
+
+ IDE_EXIT;
+}
+
+void
+ide_build_manager_list_targets_async (IdeBuildManager *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(IdeTask) task = NULL;
+ ListTargets *state;
+
+ IDE_ENTRY;
+
+ g_return_if_fail (IDE_IS_BUILD_MANAGER (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ state = g_slice_new0 (ListTargets);
+ state->store = g_list_store_new (IDE_TYPE_BUILD_TARGET);
+
+ task = ide_task_new (self, cancellable, callback, user_data);
+ ide_task_set_source_tag (task, ide_build_manager_list_targets_async);
+ ide_task_set_task_data (task, state, list_targets_free);
+
+ ensure_build_target_providers (self);
+
+ ide_extension_set_adapter_foreach (self->build_target_providers,
+ ide_build_manager_list_targets_foreach_cb,
+ task);
+
+ if (state->n_active == 0)
+ ide_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ "No build target providers found");
+
+ IDE_EXIT;
+}
+
+/**
+ * ide_build_manager_list_targets_finish:
+ * @self: a #IdeBuildManager
+ * @error: a location for a #GError
+ *
+ * Lists available build targets.
+ *
+ * Completes a request to list available build targets that was started with
+ * ide_build_manager_list_targets_async(). If no build targetproviders were
+ * discovered or no build targets were found, this will return %NULL and @error
+ * will be set to %G_IO_ERROR_NOT_SUPPORTED.
+ *
+ * Otherwise, a non-empty #GListModel of #IdeBuildTarget will be returned.
+ *
+ * Returns: (transfer full): a #GListModel of #IdeBuildTarget if successful;
+ * otherwise %NULL and @error is set.
+ */
+GListModel *
+ide_build_manager_list_targets_finish (IdeBuildManager *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GListModel *ret;
+
+ IDE_ENTRY;
+
+ g_return_val_if_fail (IDE_IS_BUILD_MANAGER (self), NULL);
+ g_return_val_if_fail (IDE_IS_TASK (result), NULL);
+
+ ret = ide_task_propagate_object (IDE_TASK (result), error);
+
+ IDE_RETURN (ret);
+}
diff --git a/src/libide/foundry/ide-build-manager.h b/src/libide/foundry/ide-build-manager.h
index a6812c7f2..f0774962c 100644
--- a/src/libide/foundry/ide-build-manager.h
+++ b/src/libide/foundry/ide-build-manager.h
@@ -93,5 +93,14 @@ IDE_AVAILABLE_IN_ALL
gboolean ide_build_manager_clean_finish (IdeBuildManager *self,
GAsyncResult *result,
GError **error);
+IDE_AVAILABLE_IN_ALL
+void ide_build_manager_list_targets_async (IdeBuildManager *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+IDE_AVAILABLE_IN_ALL
+GListModel *ide_build_manager_list_targets_finish (IdeBuildManager *self,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
diff --git a/src/libide/foundry/ide-deploy-strategy.c b/src/libide/foundry/ide-deploy-strategy.c
index bc0a976c8..84a2d4e18 100644
--- a/src/libide/foundry/ide-deploy-strategy.c
+++ b/src/libide/foundry/ide-deploy-strategy.c
@@ -22,14 +22,16 @@
#include "config.h"
-#include "ide-pipeline.h"
#include "ide-deploy-strategy.h"
+#include "ide-pipeline.h"
+#include "ide-run-context.h"
+#include "ide-runtime.h"
G_DEFINE_ABSTRACT_TYPE (IdeDeployStrategy, ide_deploy_strategy, IDE_TYPE_OBJECT)
static void
ide_deploy_strategy_real_load_async (IdeDeployStrategy *self,
- IdePipeline *pipeline,
+ IdePipeline *pipeline,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -45,18 +47,21 @@ ide_deploy_strategy_real_load_async (IdeDeployStrategy *self,
static gboolean
ide_deploy_strategy_real_load_finish (IdeDeployStrategy *self,
GAsyncResult *result,
+ int *priority,
GError **error)
{
g_assert (IDE_IS_DEPLOY_STRATEGY (self));
g_assert (G_IS_TASK (result));
g_assert (g_task_is_valid (G_TASK (result), self));
+ *priority = G_MAXINT;
+
return g_task_propagate_boolean (G_TASK (result), error);
}
static void
ide_deploy_strategy_real_deploy_async (IdeDeployStrategy *self,
- IdePipeline *pipeline,
+ IdePipeline *pipeline,
GFileProgressCallback progress,
gpointer progress_data,
GDestroyNotify progress_data_destroy,
@@ -85,36 +90,27 @@ ide_deploy_strategy_real_deploy_finish (IdeDeployStrategy *self,
}
static void
-ide_deploy_strategy_real_create_runner_async (IdeDeployStrategy *self,
- IdePipeline *pipeline,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ide_deploy_strategy_real_prepare_run_context (IdeDeployStrategy *self,
+ IdePipeline *pipeline,
+ IdeRunContext *run_context)
{
- g_autoptr(IdeTask) task = NULL;
-
- g_return_if_fail (IDE_IS_DEPLOY_STRATEGY (self));
- g_return_if_fail (IDE_IS_PIPELINE (pipeline));
- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
-
- task = ide_task_new (self, cancellable, callback, user_data);
- ide_task_return_new_error (task,
- G_IO_ERROR,
- G_IO_ERROR_NOT_SUPPORTED,
- "Not supported");
+ IdeRuntime *runtime;
-}
+ IDE_ENTRY;
-static IdeRunner *
-ide_deploy_strategy_real_create_runner_finish (IdeDeployStrategy *self,
- GAsyncResult *result,
- GError **error)
-{
g_assert (IDE_IS_DEPLOY_STRATEGY (self));
- g_assert (IDE_IS_TASK (result));
- g_assert (ide_task_is_valid (G_TASK (result), self));
+ g_assert (IDE_IS_PIPELINE (pipeline));
+ g_assert (IDE_IS_RUN_CONTEXT (run_context));
+
+ /* In the default implementation, for running locally, we just defer to
+ * the pipeline's runtime for how to create a run context.
+ */
+ if ((runtime = ide_pipeline_get_runtime (pipeline)))
+ ide_runtime_prepare_to_run (runtime, pipeline, run_context);
+ else
+ g_return_if_reached ();
- return g_task_propagate_pointer (G_TASK (result), error);
+ IDE_EXIT;
}
static void
@@ -124,8 +120,7 @@ ide_deploy_strategy_class_init (IdeDeployStrategyClass *klass)
klass->load_finish = ide_deploy_strategy_real_load_finish;
klass->deploy_async = ide_deploy_strategy_real_deploy_async;
klass->deploy_finish = ide_deploy_strategy_real_deploy_finish;
- klass->create_runner_async = ide_deploy_strategy_real_create_runner_async;
- klass->create_runner_finish = ide_deploy_strategy_real_create_runner_finish;
+ klass->prepare_run_context = ide_deploy_strategy_real_prepare_run_context;
}
static void
@@ -151,12 +146,10 @@ ide_deploy_strategy_init (IdeDeployStrategy *self)
* get the install data out of the pipeline. Given so many moving parts
* in build systems, how to determine that is an implementation detail of
* the specific #IdeDeployStrategy.
- *
- * Since: 3.32
*/
void
ide_deploy_strategy_load_async (IdeDeployStrategy *self,
- IdePipeline *pipeline,
+ IdePipeline *pipeline,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -182,12 +175,11 @@ ide_deploy_strategy_load_async (IdeDeployStrategy *self,
*
* Returns: %TRUE if successful and the pipeline was supported; otherwise
* %FALSE and @error is set.
- *
- * Since: 3.32
*/
gboolean
ide_deploy_strategy_load_finish (IdeDeployStrategy *self,
GAsyncResult *result,
+ int *priority,
GError **error)
{
gboolean ret;
@@ -196,8 +188,9 @@ ide_deploy_strategy_load_finish (IdeDeployStrategy *self,
g_assert (IDE_IS_DEPLOY_STRATEGY (self));
g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (priority != NULL);
- ret = IDE_DEPLOY_STRATEGY_GET_CLASS (self)->load_finish (self, result, error);
+ ret = IDE_DEPLOY_STRATEGY_GET_CLASS (self)->load_finish (self, result, priority, error);
IDE_RETURN (ret);
}
@@ -219,12 +212,10 @@ ide_deploy_strategy_load_finish (IdeDeployStrategy *self,
*
* If supported, the strategy will call @progress with periodic updates as
* the application is deployed.
- *
- * Since: 3.32
*/
void
ide_deploy_strategy_deploy_async (IdeDeployStrategy *self,
- IdePipeline *pipeline,
+ IdePipeline *pipeline,
GFileProgressCallback progress,
gpointer progress_data,
GDestroyNotify progress_data_destroy,
@@ -260,8 +251,6 @@ ide_deploy_strategy_deploy_async (IdeDeployStrategy *self,
* build pipeline's device.
*
* Returns: %TRUE if successful; otherwise %FALSE and @error is set
- *
- * Since: 3.32
*/
gboolean
ide_deploy_strategy_deploy_finish (IdeDeployStrategy *self,
@@ -272,8 +261,8 @@ ide_deploy_strategy_deploy_finish (IdeDeployStrategy *self,
IDE_ENTRY;
- g_assert (IDE_IS_DEPLOY_STRATEGY (self));
- g_assert (G_IS_ASYNC_RESULT (result));
+ g_return_val_if_fail (IDE_IS_DEPLOY_STRATEGY (self), FALSE);
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
ret = IDE_DEPLOY_STRATEGY_GET_CLASS (self)->deploy_finish (self, result, error);
@@ -281,66 +270,28 @@ ide_deploy_strategy_deploy_finish (IdeDeployStrategy *self,
}
/**
- * ide_deploy_strategy_create_runner_async:
+ * ide_deploy_strategy_prepare_run_context:
* @self: a #IdeDeployStrategy
* @pipeline: an #IdePipeline
- * @cancellable: (nullable): a #GCancellable or %NULL
- * @callback: (closure user_data): a callback to execute upon completion
- * @user_data: closure data for @callback
+ * @run_context: an #IdeRunContext
*
- * Gets an #IdeRunner that runs apps deployed to the device, if a
- * runner other than the default is needed.
+ * Prepare an #IdeRunContext to run on a device.
*
- * Since: 41
- */
-void
-ide_deploy_strategy_create_runner_async (IdeDeployStrategy *self,
- IdePipeline *pipeline,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- IDE_ENTRY;
-
- g_assert (IDE_IS_DEPLOY_STRATEGY (self));
- g_assert (IDE_IS_PIPELINE (pipeline));
- g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
-
- IDE_DEPLOY_STRATEGY_GET_CLASS (self)->create_runner_async (self,
- pipeline,
- cancellable,
- callback,
- user_data);
-
- IDE_EXIT;
-}
-
-/**
- * ide_deploy_strategy_create_runner_finish:
- * @self: an #IdeDeployStrategy
- * @result: a #GAsyncResult provided to callback
- * @error: a location for a #GError, or %NULL
+ * This virtual function should be implemented by device strategies to prepare
+ * a run context for running on a device or deployment situation.
*
- * Completes an asynchronous request to get an #IdeRunner for the current
- * device.
- *
- * Returns: (transfer full): An #IdeRunner or %NULL
- *
- * Since: 41
+ * Typically this is either nothing (in the case of running locally) or pushing
+ * a layer into the run context which is a command to deliver the command to
+ * another device/container/simulator/etc.
*/
-IdeRunner *
-ide_deploy_strategy_create_runner_finish (IdeDeployStrategy *self,
- GAsyncResult *result,
- GError **error)
+void
+ide_deploy_strategy_prepare_run_context (IdeDeployStrategy *self,
+ IdePipeline *pipeline,
+ IdeRunContext *run_context)
{
- IdeRunner *ret;
-
- IDE_ENTRY;
-
- g_assert (IDE_IS_DEPLOY_STRATEGY (self));
- g_assert (G_IS_ASYNC_RESULT (result));
-
- ret = IDE_DEPLOY_STRATEGY_GET_CLASS (self)->create_runner_finish (self, result, error);
+ g_return_if_fail (IDE_IS_DEPLOY_STRATEGY (self));
+ g_return_if_fail (IDE_IS_PIPELINE (pipeline));
+ g_return_if_fail (IDE_IS_RUN_CONTEXT (run_context));
- IDE_RETURN (ret);
+ IDE_DEPLOY_STRATEGY_GET_CLASS (self)->prepare_run_context (self, pipeline, run_context);
}
diff --git a/src/libide/foundry/ide-deploy-strategy.h b/src/libide/foundry/ide-deploy-strategy.h
index ccede7f87..546260da3 100644
--- a/src/libide/foundry/ide-deploy-strategy.h
+++ b/src/libide/foundry/ide-deploy-strategy.h
@@ -25,82 +25,72 @@
#endif
#include <libide-core.h>
+
#include "ide-foundry-types.h"
G_BEGIN_DECLS
#define IDE_TYPE_DEPLOY_STRATEGY (ide_deploy_strategy_get_type())
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
G_DECLARE_DERIVABLE_TYPE (IdeDeployStrategy, ide_deploy_strategy, IDE, DEPLOY_STRATEGY, IdeObject)
struct _IdeDeployStrategyClass
{
IdeObjectClass parent;
- void (*load_async) (IdeDeployStrategy *self,
- IdePipeline *pipeline,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
- gboolean (*load_finish) (IdeDeployStrategy *self,
- GAsyncResult *result,
- GError **error);
- void (*deploy_async) (IdeDeployStrategy *self,
- IdePipeline *pipeline,
- GFileProgressCallback progress,
- gpointer progress_data,
- GDestroyNotify progress_data_destroy,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
- gboolean (*deploy_finish) (IdeDeployStrategy *self,
- GAsyncResult *result,
- GError **error);
- void (*create_runner_async) (IdeDeployStrategy *self,
- IdePipeline *pipeline,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
- IdeRunner *(*create_runner_finish) (IdeDeployStrategy *self,
- GAsyncResult *result,
- GError **error);
-
- gpointer _reserved[16];
+ void (*load_async) (IdeDeployStrategy *self,
+ IdePipeline *pipeline,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*load_finish) (IdeDeployStrategy *self,
+ GAsyncResult *result,
+ int *priority,
+ GError **error);
+ void (*deploy_async) (IdeDeployStrategy *self,
+ IdePipeline *pipeline,
+ GFileProgressCallback progress,
+ gpointer progress_data,
+ GDestroyNotify progress_data_destroy,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*deploy_finish) (IdeDeployStrategy *self,
+ GAsyncResult *result,
+ GError **error);
+ void (*prepare_run_context) (IdeDeployStrategy *self,
+ IdePipeline *pipeline,
+ IdeRunContext *run_context);
};
-IDE_AVAILABLE_IN_3_32
-void ide_deploy_strategy_load_async (IdeDeployStrategy *self,
- IdePipeline *pipeline,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-IDE_AVAILABLE_IN_3_32
-gboolean ide_deploy_strategy_load_finish (IdeDeployStrategy *self,
- GAsyncResult *result,
- GError **error);
-IDE_AVAILABLE_IN_3_32
-void ide_deploy_strategy_deploy_async (IdeDeployStrategy *self,
- IdePipeline *pipeline,
- GFileProgressCallback progress,
- gpointer progress_data,
- GDestroyNotify progress_data_destroy,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-IDE_AVAILABLE_IN_3_32
-gboolean ide_deploy_strategy_deploy_finish (IdeDeployStrategy *self,
- GAsyncResult *result,
- GError **error);
-IDE_AVAILABLE_IN_41
-void ide_deploy_strategy_create_runner_async (IdeDeployStrategy *self,
- IdePipeline *pipeline,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-IDE_AVAILABLE_IN_41
-IdeRunner *ide_deploy_strategy_create_runner_finish (IdeDeployStrategy *self,
- GAsyncResult *result,
- GError **error);
+IDE_AVAILABLE_IN_ALL
+void ide_deploy_strategy_load_async (IdeDeployStrategy *self,
+ IdePipeline *pipeline,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+IDE_AVAILABLE_IN_ALL
+gboolean ide_deploy_strategy_load_finish (IdeDeployStrategy *self,
+ GAsyncResult *result,
+ int *priority,
+ GError **error);
+IDE_AVAILABLE_IN_ALL
+void ide_deploy_strategy_deploy_async (IdeDeployStrategy *self,
+ IdePipeline *pipeline,
+ GFileProgressCallback progress,
+ gpointer progress_data,
+ GDestroyNotify progress_data_destroy,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+IDE_AVAILABLE_IN_ALL
+gboolean ide_deploy_strategy_deploy_finish (IdeDeployStrategy *self,
+ GAsyncResult *result,
+ GError **error);
+IDE_AVAILABLE_IN_ALL
+void ide_deploy_strategy_prepare_run_context (IdeDeployStrategy *self,
+ IdePipeline *pipeline,
+ IdeRunContext *run_context);
G_END_DECLS
diff --git a/src/libide/foundry/ide-device-manager.c b/src/libide/foundry/ide-device-manager.c
index 2f920bdc7..e6a2100b5 100644
--- a/src/libide/foundry/ide-device-manager.c
+++ b/src/libide/foundry/ide-device-manager.c
@@ -23,9 +23,10 @@
#include "config.h"
#include <glib/gi18n.h>
+#include <libpeas/peas.h>
+
#include <libide-plugins.h>
#include <libide-threading.h>
-#include <libpeas/peas.h>
#include "ide-build-manager.h"
#include "ide-pipeline.h"
@@ -36,6 +37,7 @@
#include "ide-device.h"
#include "ide-foundry-compat.h"
#include "ide-local-device.h"
+#include "ide-triplet.h"
struct _IdeDeviceManager
{
@@ -75,12 +77,6 @@ struct _IdeDeviceManager
guint loading : 1;
};
-typedef struct
-{
- IdeObjectArray *strategies;
- IdePipeline *pipeline;
-} DeployState;
-
typedef struct
{
gint n_active;
@@ -92,18 +88,17 @@ static void ide_device_manager_action_device (IdeDeviceManager *self,
GVariant *param);
static void ide_device_manager_action_deploy (IdeDeviceManager *self,
GVariant *param);
-static void ide_device_manager_deploy_tick (IdeTask *task);
-DZL_DEFINE_ACTION_GROUP (IdeDeviceManager, ide_device_manager, {
+IDE_DEFINE_ACTION_GROUP (IdeDeviceManager, ide_device_manager, {
{ "device", ide_device_manager_action_device, "s", "'local'" },
{ "deploy", ide_device_manager_action_deploy },
})
G_DEFINE_FINAL_TYPE_WITH_CODE (IdeDeviceManager, ide_device_manager, IDE_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP,
- ide_device_manager_init_action_group)
- G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_init_iface)
- G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_init_interface))
+ G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP,
+ ide_device_manager_init_action_group)
+ G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_init_iface)
+ G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_init_interface))
enum {
PROP_0,
@@ -121,14 +116,6 @@ enum {
static GParamSpec *properties [N_PROPS];
static guint signals [N_SIGNALS];
-static void
-deploy_state_free (DeployState *state)
-{
- g_clear_object (&state->pipeline);
- g_clear_pointer (&state->strategies, ide_object_array_unref);
- g_slice_free (DeployState, state);
-}
-
static void
ide_device_manager_provider_device_added_cb (IdeDeviceManager *self,
IdeDevice *device,
@@ -495,8 +482,6 @@ ide_device_manager_class_init (IdeDeviceManagerClass *klass)
* The "device" property indicates the currently selected device by the
* user. This is the device we will try to deploy to when running, and
* execute the application on.
- *
- * Since: 3.32
*/
properties [PROP_DEVICE] =
g_param_spec_object ("device",
@@ -510,8 +495,6 @@ ide_device_manager_class_init (IdeDeviceManagerClass *klass)
*
* The "progress" property is updated with a value between 0.0 and 1.0 while
* the deployment is in progress.
- *
- * Since: 3.32
*/
properties [PROP_PROGRESS] =
g_param_spec_double ("progress",
@@ -561,8 +544,6 @@ ide_device_manager_init (IdeDeviceManager *self)
* Fetches the first device that matches the device identifier @device_id.
*
* Returns: (transfer none): An #IdeDevice or %NULL.
- *
- * Since: 3.32
*/
IdeDevice *
ide_device_manager_get_device_by_id (IdeDeviceManager *self,
@@ -593,8 +574,6 @@ ide_device_manager_get_device_by_id (IdeDeviceManager *self,
* Usually, this is an #IdeLocalDevice.
*
* Returns: (transfer none) (not nullable): an #IdeDevice
- *
- * Since: 3.32
*/
IdeDevice *
ide_device_manager_get_device (IdeDeviceManager *self)
@@ -628,8 +607,6 @@ ide_device_manager_get_device (IdeDeviceManager *self)
* the devices architecture and operating system.
*
* If @device is %NULL, the local device will be used.
- *
- * Since: 3.32
*/
void
ide_device_manager_set_device (IdeDeviceManager *self,
@@ -752,31 +729,14 @@ deploy_progress_cb (goffset current_num_bytes,
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PROGRESS]);
}
-static void
-collect_strategies (PeasExtensionSet *set,
- PeasPluginInfo *plugin_info,
- PeasExtension *exten,
- gpointer user_data)
-{
- IdeObjectArray *strategies = user_data;
- IdeDeployStrategy *strategy = (IdeDeployStrategy *)exten;
-
- g_assert (PEAS_IS_EXTENSION_SET (set));
- g_assert (plugin_info != NULL);
- g_assert (IDE_IS_DEPLOY_STRATEGY (strategy));
- g_assert (strategies != NULL);
-
- ide_object_array_add (strategies, strategy);
-}
-
static void
ide_device_manager_deploy_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
IdeDeployStrategy *strategy = (IdeDeployStrategy *)object;
- g_autoptr(GError) error = NULL;
g_autoptr(IdeTask) task = user_data;
+ g_autoptr(GError) error = NULL;
IDE_ENTRY;
@@ -792,94 +752,13 @@ ide_device_manager_deploy_cb (GObject *object,
IDE_EXIT;
}
-static void
-ide_device_manager_deploy_load_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- IdeDeployStrategy *strategy = (IdeDeployStrategy *)object;
- g_autoptr(GError) error = NULL;
- g_autoptr(IdeTask) task = user_data;
- IdeDeviceManager *self;
- DeployState *state;
-
- IDE_ENTRY;
-
- g_assert (IDE_IS_DEPLOY_STRATEGY (strategy));
- g_assert (G_IS_ASYNC_RESULT (result));
- g_assert (IDE_IS_TASK (task));
-
- if (!ide_deploy_strategy_load_finish (strategy, result, &error))
- {
- g_debug ("Deploy strategy failed to load: %s", error->message);
- ide_object_destroy (IDE_OBJECT (strategy));
- ide_device_manager_deploy_tick (task);
- IDE_EXIT;
- }
-
- /* Okay, we found a match. Now deploy to the device. */
-
- self = ide_task_get_source_object (task);
- state = ide_task_get_task_data (task);
-
- g_assert (IDE_IS_DEVICE_MANAGER (self));
- g_assert (state != NULL);
- g_assert (state->strategies != NULL);
- g_assert (IDE_IS_PIPELINE (state->pipeline));
-
- ide_deploy_strategy_deploy_async (strategy,
- state->pipeline,
- deploy_progress_cb,
- g_object_ref (self),
- g_object_unref,
- ide_task_get_cancellable (task),
- ide_device_manager_deploy_cb,
- g_object_ref (task));
-
- IDE_EXIT;
-}
-
-static void
-ide_device_manager_deploy_tick (IdeTask *task)
-{
- g_autoptr(IdeDeployStrategy) strategy = NULL;
- DeployState *state;
-
- IDE_ENTRY;
-
- g_assert (IDE_IS_TASK (task));
-
- state = ide_task_get_task_data (task);
-
- g_assert (state != NULL);
- g_assert (state->strategies != NULL);
- g_assert (IDE_IS_PIPELINE (state->pipeline));
-
- if (state->strategies->len == 0)
- {
- ide_task_return_new_error (task,
- G_IO_ERROR,
- G_IO_ERROR_NOT_SUPPORTED,
- "Failed to locate deployment strategy for device");
- IDE_EXIT;
- }
-
- strategy = ide_object_array_steal_index (state->strategies, 0);
-
- ide_deploy_strategy_load_async (strategy,
- state->pipeline,
- ide_task_get_cancellable (task),
- ide_device_manager_deploy_load_cb,
- g_object_ref (task));
-
- IDE_EXIT;
-}
-
static void
ide_device_manager_deploy_completed (IdeDeviceManager *self,
GParamSpec *pspec,
IdeTask *task)
{
+ IDE_ENTRY;
+
g_assert (IDE_IS_DEVICE_MANAGER (self));
g_assert (IDE_IS_TASK (task));
@@ -890,6 +769,8 @@ ide_device_manager_deploy_completed (IdeDeviceManager *self,
}
g_signal_emit (self, signals [DEPLOY_FINISHED], 0);
+
+ IDE_EXIT;
}
/**
@@ -903,20 +784,16 @@ ide_device_manager_deploy_completed (IdeDeviceManager *self,
* Requests that the application be deployed to the device. This may need to
* be done before running the application so that the device has the most
* up to date build.
- *
- * Since: 3.32
*/
void
ide_device_manager_deploy_async (IdeDeviceManager *self,
- IdePipeline *pipeline,
+ IdePipeline *pipeline,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- g_autoptr(PeasExtensionSet) set = NULL;
g_autoptr(IdeTask) task = NULL;
- DeployState *state;
- IdeDevice *device;
+ IdeDeployStrategy *strategy;
IDE_ENTRY;
@@ -938,37 +815,20 @@ ide_device_manager_deploy_async (IdeDeviceManager *self,
self,
G_CONNECT_SWAPPED);
- if (!(device = ide_pipeline_get_device (pipeline)))
- {
- ide_task_return_new_error (task,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Missing device in pipeline");
- IDE_EXIT;
- }
-
- if (IDE_IS_LOCAL_DEVICE (device))
- {
- ide_task_return_boolean (task, TRUE);
- IDE_EXIT;
- }
-
- state = g_slice_new0 (DeployState);
- state->pipeline = g_object_ref (pipeline);
- state->strategies = ide_object_array_new ();
- ide_task_set_task_data (task, state, deploy_state_free);
-
- set = peas_extension_set_new (peas_engine_get_default (),
- IDE_TYPE_DEPLOY_STRATEGY,
- NULL);
- peas_extension_set_foreach (set, collect_strategies, state->strategies);
-
- /* Root the addins as children of us so that they get context access */
- for (guint i = 0; i < state->strategies->len; i++)
- ide_object_append (IDE_OBJECT (self),
- ide_object_array_index (state->strategies, i));
-
- ide_device_manager_deploy_tick (task);
+ if (!(strategy = ide_pipeline_get_deploy_strategy (pipeline)))
+ ide_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Missing device in pipeline, cannot deploy");
+ else
+ ide_deploy_strategy_deploy_async (strategy,
+ pipeline,
+ deploy_progress_cb,
+ g_object_ref (self),
+ g_object_unref,
+ cancellable,
+ ide_device_manager_deploy_cb,
+ g_steal_pointer (&task));
IDE_EXIT;
}
@@ -982,8 +842,6 @@ ide_device_manager_deploy_async (IdeDeviceManager *self,
* Completes a request to deploy the application to the device.
*
* Returns: %TRUE if successful; otherwise %FALSE and @error is set
- *
- * Since: 3.32
*/
gboolean
ide_device_manager_deploy_finish (IdeDeviceManager *self,
@@ -1003,213 +861,6 @@ ide_device_manager_deploy_finish (IdeDeviceManager *self,
IDE_RETURN (ret);
}
-static void
-ide_device_manager_create_runner_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- IdeDeployStrategy *strategy = (IdeDeployStrategy *)object;
- g_autoptr(GError) error = NULL;
- g_autoptr(IdeTask) task = user_data;
- IdeRunner *runner;
-
- IDE_ENTRY;
-
- g_assert (IDE_IS_DEPLOY_STRATEGY (strategy));
- g_assert (G_IS_ASYNC_RESULT (result));
- g_assert (IDE_IS_TASK (task));
-
- runner = ide_deploy_strategy_create_runner_finish (strategy, result, &error);
-
- if (error)
- ide_task_return_error (task, g_steal_pointer (&error));
- else
- ide_task_return_pointer (task, runner, g_object_unref);
-
- ide_object_destroy (IDE_OBJECT (strategy));
-
- IDE_EXIT;
-}
-
-static void
-ide_device_manager_create_runner_load_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- IdeDeployStrategy *strategy = (IdeDeployStrategy *)object;
- g_autoptr(GError) error = NULL;
- g_autoptr(IdeTask) task = user_data;
- IdeDeviceManager *self;
- DeployState *state;
-
- IDE_ENTRY;
-
- g_assert (IDE_IS_DEPLOY_STRATEGY (strategy));
- g_assert (G_IS_ASYNC_RESULT (result));
- g_assert (IDE_IS_TASK (task));
-
- if (!ide_deploy_strategy_load_finish (strategy, result, &error))
- {
- g_debug ("Deploy strategy failed to load: %s", error->message);
- ide_object_destroy (IDE_OBJECT (strategy));
- ide_device_manager_deploy_tick (task);
- IDE_EXIT;
- }
-
- /* Okay, we found a match. Now run on the device. */
-
- self = ide_task_get_source_object (task);
- state = ide_task_get_task_data (task);
-
- g_assert (IDE_IS_DEVICE_MANAGER (self));
- g_assert (state != NULL);
- g_assert (state->strategies != NULL);
- g_assert (IDE_IS_PIPELINE (state->pipeline));
-
- ide_deploy_strategy_create_runner_async (strategy,
- state->pipeline,
- ide_task_get_cancellable (task),
- ide_device_manager_create_runner_cb,
- g_object_ref (task));
-
- IDE_EXIT;
-}
-
-static void
-ide_device_manager_create_runner_tick (IdeTask *task)
-{
- g_autoptr(IdeDeployStrategy) strategy = NULL;
- DeployState *state;
-
- IDE_ENTRY;
-
- g_assert (IDE_IS_TASK (task));
-
- state = ide_task_get_task_data (task);
-
- g_assert (state != NULL);
- g_assert (state->strategies != NULL);
- g_assert (IDE_IS_PIPELINE (state->pipeline));
-
- if (state->strategies->len == 0)
- {
- ide_task_return_new_error (task,
- G_IO_ERROR,
- G_IO_ERROR_NOT_SUPPORTED,
- "Failed to locate deployment strategy for device");
- IDE_EXIT;
- }
-
- strategy = ide_object_array_steal_index (state->strategies, 0);
-
- ide_deploy_strategy_load_async (strategy,
- state->pipeline,
- ide_task_get_cancellable (task),
- ide_device_manager_create_runner_load_cb,
- g_object_ref (task));
-
- IDE_EXIT;
-}
-
-/**
- * ide_device_manager_create_runner_async:
- * @self: a #IdeDeviceManager
- * @pipeline: an #IdePipeline
- * @cancellable: a #GCancellable, or %NULL
- * @callback: a #GAsyncReadyCallback
- * @user_data: closure data for @callback
- *
- * Requests an #IdeRunner that runs on the current device, if a runner
- * other than the default is required.
- *
- * Since: 41
- */
-void
-ide_device_manager_create_runner_async (IdeDeviceManager *self,
- IdePipeline *pipeline,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_autoptr(PeasExtensionSet) set = NULL;
- g_autoptr(IdeTask) task = NULL;
- DeployState *state;
- IdeDevice *device;
-
- IDE_ENTRY;
-
- g_return_if_fail (IDE_IS_DEVICE_MANAGER (self));
- g_return_if_fail (IDE_IS_PIPELINE (pipeline));
- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
-
- task = ide_task_new (self, cancellable, callback, user_data);
- ide_task_set_source_tag (task, ide_device_manager_create_runner_async);
-
- if (!(device = ide_pipeline_get_device (pipeline)))
- {
- ide_task_return_new_error (task,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Missing device in pipeline");
- IDE_EXIT;
- }
-
- if (IDE_IS_LOCAL_DEVICE (device))
- {
- (ide_task_return_pointer) (task, NULL, NULL);
- IDE_EXIT;
- }
-
- state = g_slice_new0 (DeployState);
- state->pipeline = g_object_ref (pipeline);
- state->strategies = ide_object_array_new ();
- ide_task_set_task_data (task, state, deploy_state_free);
-
- set = peas_extension_set_new (peas_engine_get_default (),
- IDE_TYPE_DEPLOY_STRATEGY,
- NULL);
- peas_extension_set_foreach (set, collect_strategies, state->strategies);
-
- /* Root the addins as children of us so that they get context access */
- for (guint i = 0; i < state->strategies->len; i++)
- ide_object_append (IDE_OBJECT (self),
- ide_object_array_index (state->strategies, i));
-
- ide_device_manager_create_runner_tick (task);
-
- IDE_EXIT;
-}
-
-/**
- * ide_device_manager_create_runner_finish:
- * @self: a #IdeDeviceManager
- * @result: a #GAsyncResult provided to callback
- * @error: a location for a #GError, or %NULL
- *
- * Completes a request to create an #IdeRunner to run on the device.
- *
- * Returns: (transfer full): An #IdeRunner or %NULL.
- *
- * Since: 41
- */
-IdeRunner *
-ide_device_manager_create_runner_finish (IdeDeviceManager *self,
- GAsyncResult *result,
- GError **error)
-{
- IdeRunner *ret;
-
- IDE_ENTRY;
-
- g_return_val_if_fail (IDE_IS_DEVICE_MANAGER (self), FALSE);
- g_return_val_if_fail (IDE_IS_TASK (result), FALSE);
- g_return_val_if_fail (ide_task_is_valid (IDE_TASK (result), self), FALSE);
-
- ret = ide_task_propagate_pointer (IDE_TASK (result), error);
-
- IDE_RETURN (ret);
-}
-
gdouble
ide_device_manager_get_progress (IdeDeviceManager *self)
{
diff --git a/src/libide/foundry/ide-device-manager.h b/src/libide/foundry/ide-device-manager.h
index 1e8f1ee20..e3f680f06 100644
--- a/src/libide/foundry/ide-device-manager.h
+++ b/src/libide/foundry/ide-device-manager.h
@@ -32,40 +32,30 @@ G_BEGIN_DECLS
#define IDE_TYPE_DEVICE_MANAGER (ide_device_manager_get_type())
-IDE_AVAILABLE_IN_3_32
+IDE_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (IdeDeviceManager, ide_device_manager, IDE, DEVICE_MANAGER, IdeObject)
-IDE_AVAILABLE_IN_3_32
-IdeDeviceManager *ide_device_manager_from_context (IdeContext *context);
-IDE_AVAILABLE_IN_3_32
-gdouble ide_device_manager_get_progress (IdeDeviceManager *self);
-IDE_AVAILABLE_IN_3_32
-IdeDevice *ide_device_manager_get_device (IdeDeviceManager *self);
-IDE_AVAILABLE_IN_3_32
-void ide_device_manager_set_device (IdeDeviceManager *self,
- IdeDevice *device);
-IDE_AVAILABLE_IN_3_32
-IdeDevice *ide_device_manager_get_device_by_id (IdeDeviceManager *self,
- const gchar *device_id);
-IDE_AVAILABLE_IN_3_32
-void ide_device_manager_deploy_async (IdeDeviceManager *self,
- IdePipeline *pipeline,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-IDE_AVAILABLE_IN_3_32
-gboolean ide_device_manager_deploy_finish (IdeDeviceManager *self,
- GAsyncResult *result,
- GError **error);
-IDE_AVAILABLE_IN_41
-void ide_device_manager_create_runner_async (IdeDeviceManager *self,
- IdePipeline *pipeline,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-IDE_AVAILABLE_IN_41
-IdeRunner *ide_device_manager_create_runner_finish (IdeDeviceManager *self,
- GAsyncResult *result,
- GError **error);
+IDE_AVAILABLE_IN_ALL
+IdeDeviceManager *ide_device_manager_from_context (IdeContext *context);
+IDE_AVAILABLE_IN_ALL
+gdouble ide_device_manager_get_progress (IdeDeviceManager *self);
+IDE_AVAILABLE_IN_ALL
+IdeDevice *ide_device_manager_get_device (IdeDeviceManager *self);
+IDE_AVAILABLE_IN_ALL
+void ide_device_manager_set_device (IdeDeviceManager *self,
+ IdeDevice *device);
+IDE_AVAILABLE_IN_ALL
+IdeDevice *ide_device_manager_get_device_by_id (IdeDeviceManager *self,
+ const gchar *device_id);
+IDE_AVAILABLE_IN_ALL
+void ide_device_manager_deploy_async (IdeDeviceManager *self,
+ IdePipeline *pipeline,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+IDE_AVAILABLE_IN_ALL
+gboolean ide_device_manager_deploy_finish (IdeDeviceManager *self,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
diff --git a/src/libide/foundry/ide-device-provider.c b/src/libide/foundry/ide-device-provider.c
index e83787a66..cb5440b03 100644
--- a/src/libide/foundry/ide-device-provider.c
+++ b/src/libide/foundry/ide-device-provider.c
@@ -128,8 +128,6 @@ ide_device_provider_class_init (IdeDeviceProviderClass *klass)
*
* Subclasses of #IdeDeviceManager must chain-up if they override the
* #IdeDeviceProviderClass.device_added vfunc.
- *
- * Since: 3.32
*/
signals [DEVICE_ADDED] =
g_signal_new ("device-added",
@@ -153,8 +151,6 @@ ide_device_provider_class_init (IdeDeviceProviderClass *klass)
*
* Subclasses of #IdeDeviceManager must chain-up if they override the
* #IdeDeviceProviderClass.device_removed vfunc.
- *
- * Since: 3.32
*/
signals [DEVICE_REMOVED] =
g_signal_new ("device-removed",
@@ -181,8 +177,6 @@ ide_device_provider_init (IdeDeviceProvider *self)
*
* This should only be called by subclasses of #IdeDeviceProvider when
* a new device has been discovered.
- *
- * Since: 3.32
*/
void
ide_device_provider_emit_device_added (IdeDeviceProvider *provider,
@@ -201,8 +195,6 @@ ide_device_provider_emit_device_added (IdeDeviceProvider *provider,
*
* This should only be called by subclasses of #IdeDeviceProvider when
* a previously added device has been removed.
- *
- * Since: 3.32
*/
void
ide_device_provider_emit_device_removed (IdeDeviceProvider *provider,
@@ -231,8 +223,6 @@ ide_device_provider_emit_device_removed (IdeDeviceProvider *provider,
* That should be done for known devices before returning from the asynchronous
* operation so that the device manager does not need to wait for additional
* devices to enter the "settled" state.
- *
- * Since: 3.32
*/
void
ide_device_provider_load_async (IdeDeviceProvider *self,
@@ -256,8 +246,6 @@ ide_device_provider_load_async (IdeDeviceProvider *self,
* ide_device_provider_load_async().
*
* Returns: %TRUE if successful; otherwise %FALSE and @error is set.
- *
- * Since: 3.32
*/
gboolean
ide_device_provider_load_finish (IdeDeviceProvider *self,
@@ -279,8 +267,6 @@ ide_device_provider_load_finish (IdeDeviceProvider *self,
*
* Returns: (transfer full) (element-type Ide.Device) (not nullable):
* a #GPtrArray of #IdeDevice.
- *
- * Since: 3.32
*/
GPtrArray *
ide_device_provider_get_devices (IdeDeviceProvider *self)
diff --git a/src/libide/foundry/ide-pipeline-stage-mkdirs.c b/src/libide/foundry/ide-pipeline-stage-mkdirs.c
index a3be032ae..0184ece6c 100644
--- a/src/libide/foundry/ide-pipeline-stage-mkdirs.c
+++ b/src/libide/foundry/ide-pipeline-stage-mkdirs.c
@@ -135,14 +135,14 @@ ide_pipeline_stage_mkdirs_build (IdePipelineStage *stage,
}
static void
-ide_pipeline_stage_mkdirs_reap (IdePipelineStage *stage,
- DzlDirectoryReaper *reaper)
+ide_pipeline_stage_mkdirs_reap (IdePipelineStage *stage,
+ IdeDirectoryReaper *reaper)
{
IdePipelineStageMkdirs *self = (IdePipelineStageMkdirs *)stage;
IdePipelineStageMkdirsPrivate *priv = ide_pipeline_stage_mkdirs_get_instance_private (self);
g_assert (IDE_IS_PIPELINE_STAGE_MKDIRS (self));
- g_assert (DZL_IS_DIRECTORY_REAPER (reaper));
+ g_assert (IDE_IS_DIRECTORY_REAPER (reaper));
ide_pipeline_stage_set_active (stage, TRUE);
@@ -153,7 +153,7 @@ ide_pipeline_stage_mkdirs_reap (IdePipelineStage *stage,
if (path->remove_on_rebuild)
{
g_autoptr(GFile) file = g_file_new_for_path (path->path);
- dzl_directory_reaper_add_directory (reaper, file, 0);
+ ide_directory_reaper_add_directory (reaper, file, 0);
}
}
diff --git a/src/libide/foundry/ide-pipeline-stage.c b/src/libide/foundry/ide-pipeline-stage.c
index 8522be277..526913ab4 100644
--- a/src/libide/foundry/ide-pipeline-stage.c
+++ b/src/libide/foundry/ide-pipeline-stage.c
@@ -539,7 +539,7 @@ ide_pipeline_stage_class_init (IdePipelineStageClass *klass)
/**
* IdePipelineStage::reap:
* @self: An #IdePipelineStage
- * @reaper: An #DzlDirectoryReaper
+ * @reaper: An #IdeDirectoryReaper
*
* This signal is emitted when a request to rebuild the project has
* occurred. This allows build stages to ensure that certain files are
@@ -553,7 +553,7 @@ ide_pipeline_stage_class_init (IdePipelineStageClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (IdePipelineStageClass, reap),
NULL, NULL, NULL,
- G_TYPE_NONE, 1, DZL_TYPE_DIRECTORY_REAPER);
+ G_TYPE_NONE, 1, IDE_TYPE_DIRECTORY_REAPER);
}
static void
@@ -1059,12 +1059,12 @@ ide_pipeline_stage_clean_finish (IdePipelineStage *self,
void
ide_pipeline_stage_emit_reap (IdePipelineStage *self,
- DzlDirectoryReaper *reaper)
+ IdeDirectoryReaper *reaper)
{
IDE_ENTRY;
g_return_if_fail (IDE_IS_PIPELINE_STAGE (self));
- g_return_if_fail (DZL_IS_DIRECTORY_REAPER (reaper));
+ g_return_if_fail (IDE_IS_DIRECTORY_REAPER (reaper));
g_signal_emit (self, signals [REAP], 0, reaper);
diff --git a/src/libide/foundry/ide-pipeline-stage.h b/src/libide/foundry/ide-pipeline-stage.h
index da0a1e6fd..a66f39b89 100644
--- a/src/libide/foundry/ide-pipeline-stage.h
+++ b/src/libide/foundry/ide-pipeline-stage.h
@@ -197,6 +197,6 @@ IDE_AVAILABLE_IN_ALL
void ide_pipeline_stage_unpause (IdePipelineStage *self);
IDE_AVAILABLE_IN_ALL
void ide_pipeline_stage_emit_reap (IdePipelineStage *self,
- DzlDirectoryReaper *reaper);
+ IdeDirectoryReaper *reaper);
G_END_DECLS
diff --git a/src/libide/foundry/ide-pipeline.c b/src/libide/foundry/ide-pipeline.c
index f2504f5d3..693b12f3a 100644
--- a/src/libide/foundry/ide-pipeline.c
+++ b/src/libide/foundry/ide-pipeline.c
@@ -23,8 +23,6 @@
#include "config.h"
#include <glib/gi18n.h>
-#include <dazzle.h>
-#include <libide-plugins.h>
#include <libpeas/peas.h>
#include <string.h>
#include <vte/vte.h>
@@ -37,7 +35,8 @@
#include <libide-threading.h>
#include "ide-build-log-private.h"
-#include "ide-build-log.h"
+#include "ide-config.h"
+#include "ide-deploy-strategy.h"
#include "ide-pipeline-addin.h"
#include "ide-pipeline.h"
#include "ide-build-private.h"
@@ -49,17 +48,20 @@
#include "ide-device.h"
#include "ide-foundry-compat.h"
#include "ide-foundry-enums.h"
+#include "ide-local-deploy-strategy.h"
+#include "ide-local-device.h"
+#include "ide-run-command.h"
+#include "ide-run-context.h"
#include "ide-run-manager-private.h"
#include "ide-runtime.h"
#include "ide-toolchain-manager.h"
#include "ide-toolchain.h"
#include "ide-triplet.h"
-DZL_DEFINE_COUNTER (Instances, "Pipeline", "N Pipelines", "Number of Pipeline instances")
G_DEFINE_QUARK (ide_build_error, ide_build_error)
/**
- * SECTION:idebuildpipeline
+ * SECTION:idepipeline
* @title: IdePipeline
* @short_description: Pluggable build pipeline
* @include: ide.h
@@ -96,22 +98,20 @@ G_DEFINE_QUARK (ide_build_error, ide_build_error)
* ide_pipeline_stage_set_transient(). This may be useful to perform operations
* such as an "export tarball" stage which should only run once as determined
* by the user requesting a "make dist" style operation.
- *
- * Since: 3.32
*/
typedef struct
{
- guint id;
+ guint id;
IdePipelinePhase phase;
- gint priority;
+ int priority;
IdePipelineStage *stage;
} PipelineEntry;
typedef struct
{
IdePipeline *self;
- GPtrArray *addins;
+ GPtrArray *addins;
} IdleLoadState;
typedef struct
@@ -138,6 +138,15 @@ struct _IdePipeline
*/
IdeExtensionSetAdapter *addins;
+ /*
+ * Deployment stategies help discover how to make a deployment to
+ * a device which might require sending data to another system such
+ * as a phone or tablet.
+ */
+ IdeExtensionSetAdapter *deploy_strategies;
+ IdeDeployStrategy *best_strategy;
+ int best_strategy_priority;
+
/*
* This is the configuration for the build. It is a snapshot of
* the real configuration so that we do not need to synchronize
@@ -214,18 +223,17 @@ struct _IdePipeline
guint errfmt_seqnum;
/*
- * The VtePty is used to connect to a VteTerminal. It's basically
- * just a wrapper around a PTY master. We then add a IdePtyIntercept
- * to proxy PTY data while allowing us to tap into the content being
- * transmitted. We can use that to run regexes against and perform
- * additional error extraction. Finally, pty_slave is the PTY device
- * we created that will get attached to stdin/stdout/stderr in our
- * spawned subprocesses. It is a slave to the PTY master owned by
- * the IdePtyIntercept.
+ * The VtePty is used to connect to a VteTerminal. It's basically just a
+ * wrapper around a PTY consumer. We then add a IdePtyIntercept to proxy
+ * PTY data while allowing us to tap into the content being transmitted.
+ * We can use that to run regexes against and perform additional error
+ * extraction. Finally, pty_producer is the PTY device we created that
+ * will get attached to stdin/stdout/stderr in our spawned subprocesses.
+ * It is a producer to the PTY consumer owned by the IdePtyIntercept.
*/
VtePty *pty;
IdePtyIntercept intercept;
- IdePtyFd pty_slave;
+ IdePtyFd pty_producer;
/*
* If the terminal interpreting our Pty has received a terminal
@@ -765,11 +773,11 @@ ide_pipeline_log_observer (IdeBuildLogStream stream,
}
static void
-ide_pipeline_intercept_pty_master_cb (const IdePtyIntercept *intercept,
- const IdePtyInterceptSide *side,
- const guint8 *data,
- gsize len,
- gpointer user_data)
+ide_pipeline_intercept_pty_consumer_cb (const IdePtyIntercept *intercept,
+ const IdePtyInterceptSide *side,
+ const guint8 *data,
+ gsize len,
+ gpointer user_data)
{
IdePipeline *self = user_data;
@@ -843,8 +851,6 @@ ide_pipeline_check_ready (IdePipeline *self,
*
* Gets the current phase that is executing. This is only useful during
* execution of the pipeline.
- *
- * Since: 3.32
*/
IdePipelinePhase
ide_pipeline_get_phase (IdePipeline *self)
@@ -867,8 +873,6 @@ ide_pipeline_get_phase (IdePipeline *self)
* Gets the #IdeConfig to use for the pipeline.
*
* Returns: (transfer none): An #IdeConfig
- *
- * Since: 3.32
*/
IdeConfig *
ide_pipeline_get_config (IdePipeline *self)
@@ -1061,6 +1065,7 @@ register_build_commands_stage (IdePipeline *self,
g_autofree gchar *rundir_path = NULL;
GFile *rundir;
+ g_assert (IDE_IS_MAIN_THREAD ());
g_assert (IDE_IS_PIPELINE (self));
g_assert (IDE_IS_CONTEXT (context));
g_assert (IDE_IS_CONFIG (self->config));
@@ -1165,6 +1170,60 @@ collect_pipeline_addins (IdeExtensionSetAdapter *set,
g_ptr_array_add (addins, g_object_ref (exten));
}
+static void
+ide_pipeline_deploy_strategy_load_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeDeployStrategy *strategy = (IdeDeployStrategy *)object;
+ g_autoptr(IdePipeline) self = user_data;
+ g_autoptr(GError) error = NULL;
+ int priority = 0;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_DEPLOY_STRATEGY (strategy));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (IDE_IS_PIPELINE (self));
+
+ if (ide_deploy_strategy_load_finish (strategy, result, &priority, &error))
+ {
+ if (self->best_strategy == NULL || priority < self->best_strategy_priority)
+ {
+ g_set_object (&self->best_strategy, strategy);
+ self->best_strategy_priority = priority;
+ IDE_EXIT;
+ }
+ }
+
+ IDE_EXIT;
+}
+
+static void
+ide_pipeline_deploy_strategy_added_cb (IdeExtensionSetAdapter *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ IdePipeline *self = user_data;
+ IdeDeployStrategy *strategy = (IdeDeployStrategy *)exten;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_EXTENSION_SET_ADAPTER (set));
+ g_assert (plugin_info != NULL);
+ g_assert (IDE_IS_DEPLOY_STRATEGY (strategy));
+ g_assert (IDE_IS_PIPELINE (self));
+
+ ide_deploy_strategy_load_async (strategy,
+ self,
+ self->cancellable,
+ ide_pipeline_deploy_strategy_load_cb,
+ g_object_ref (self));
+
+ IDE_EXIT;
+}
+
static gboolean
ide_pipeline_load_cb (IdleLoadState *state)
{
@@ -1200,6 +1259,15 @@ ide_pipeline_load_cb (IdleLoadState *state)
return G_SOURCE_CONTINUE;
}
+ /* Now setup deployment strategies */
+ g_signal_connect (state->self->deploy_strategies,
+ "extension-added",
+ G_CALLBACK (ide_pipeline_deploy_strategy_added_cb),
+ state->self);
+ ide_extension_set_adapter_foreach (state->self->deploy_strategies,
+ ide_pipeline_deploy_strategy_added_cb,
+ state->self);
+
state->self->loaded = TRUE;
state->self->idle_addins_load_source = 0;
@@ -1218,13 +1286,10 @@ ide_pipeline_load_cb (IdleLoadState *state)
* enable/disable the pipeline as the IdeConfig:ready property changes.
* This could happen when the device or runtime is added/removed while the
* application is running.
- *
- * Since: 3.32
*/
static void
ide_pipeline_load (IdePipeline *self)
{
- g_autoptr(GPtrArray) addins = NULL;
IdleLoadState *state;
IdeContext *context;
@@ -1240,42 +1305,39 @@ ide_pipeline_load (IdePipeline *self)
register_build_commands_stage (self, context);
register_post_install_commands_stage (self, context);
+ /* Setup pipeline addins */
self->addins = ide_extension_set_adapter_new (IDE_OBJECT (self),
peas_engine_get_default (),
IDE_TYPE_PIPELINE_ADDIN,
NULL, NULL);
-
g_signal_connect (self->addins,
"extension-added",
G_CALLBACK (ide_pipeline_extension_prepare),
self);
-
ide_extension_set_adapter_foreach (self->addins,
ide_pipeline_extension_prepare,
self);
-
g_signal_connect_after (self->addins,
"extension-added",
G_CALLBACK (ide_pipeline_extension_added),
self);
-
g_signal_connect (self->addins,
"extension-removed",
G_CALLBACK (ide_pipeline_extension_removed),
self);
- /* Collect our addins so we can incrementally load them in an
- * idle callback to reduce chances of stalling the main loop.
- */
- addins = g_ptr_array_new_with_free_func (g_object_unref);
- ide_extension_set_adapter_foreach (self->addins,
- collect_pipeline_addins,
- addins);
+ /* Create deployment strategies */
+ self->deploy_strategies = ide_extension_set_adapter_new (IDE_OBJECT (self),
+ peas_engine_get_default (),
+ IDE_TYPE_DEPLOY_STRATEGY,
+ NULL, NULL);
state = g_slice_new0 (IdleLoadState);
state->self = g_object_ref (self);
- state->addins = g_steal_pointer (&addins);
-
+ state->addins = g_ptr_array_new_with_free_func (g_object_unref);
+ ide_extension_set_adapter_foreach (self->addins,
+ collect_pipeline_addins,
+ state->addins);
self->idle_addins_load_source =
g_idle_add_full (G_PRIORITY_LOW,
(GSourceFunc) ide_pipeline_load_cb,
@@ -1350,8 +1412,6 @@ ide_pipeline_begin_load (IdePipeline *self)
* This function is safe to run even if load has not been called. We will not
* clean things up if the pipeline is currently executing (we can wait until
* its finished or dispose/finalize to cleanup up further.
- *
- * Since: 3.32
*/
static void
ide_pipeline_unload (IdePipeline *self)
@@ -1360,7 +1420,10 @@ ide_pipeline_unload (IdePipeline *self)
g_assert (IDE_IS_PIPELINE (self));
+ g_clear_object (&self->best_strategy);
+
ide_clear_and_destroy_object (&self->addins);
+ ide_clear_and_destroy_object (&self->deploy_strategies);
IDE_EXIT;
}
@@ -1423,8 +1486,6 @@ ide_pipeline_finalize (GObject *object)
G_OBJECT_CLASS (ide_pipeline_parent_class)->finalize (object);
- DZL_COUNTER_DEC (Instances);
-
IDE_EXIT;
}
@@ -1445,7 +1506,7 @@ ide_pipeline_destroy (IdeObject *object)
g_clear_pointer (&self->message, g_free);
g_clear_object (&self->pty);
- fd = pty_fd_steal (&self->pty_slave);
+ fd = pty_fd_steal (&self->pty_producer);
if (IDE_IS_PTY_INTERCEPT (&self->intercept))
ide_pty_intercept_clear (&self->intercept);
@@ -1461,7 +1522,7 @@ ide_pipeline_initable_init (GInitable *initable,
GError **error)
{
IdePipeline *self = (IdePipeline *)initable;
- IdePtyFd master_fd;
+ IdePtyFd consumer_fd;
IDE_ENTRY;
@@ -1491,9 +1552,9 @@ ide_pipeline_initable_init (GInitable *initable,
vte_pty_set_utf8 (self->pty, TRUE, NULL);
- master_fd = vte_pty_get_fd (self->pty);
+ consumer_fd = vte_pty_get_fd (self->pty);
- if (!ide_pty_intercept_init (&self->intercept, master_fd, NULL))
+ if (!ide_pty_intercept_init (&self->intercept, consumer_fd, NULL))
{
g_set_error_literal (error,
G_IO_ERROR,
@@ -1503,9 +1564,9 @@ ide_pipeline_initable_init (GInitable *initable,
}
ide_pty_intercept_set_callback (&self->intercept,
- &self->intercept.master,
- ide_pipeline_intercept_pty_master_cb,
- self);
+ &self->intercept.consumer,
+ ide_pipeline_intercept_pty_consumer_cb,
+ self);
g_signal_connect_object (self->config,
"notify::ready",
@@ -1630,8 +1691,6 @@ ide_pipeline_class_init (IdePipelineClass *klass)
* IdePipeline:busy:
*
* Gets the "busy" property. If %TRUE, the pipeline is busy executing.
- *
- * Since: 3.32
*/
properties [PROP_BUSY] =
g_param_spec_boolean ("busy",
@@ -1644,8 +1703,6 @@ ide_pipeline_class_init (IdePipelineClass *klass)
* IdePipeline:configuration:
*
* The configuration to use for the build pipeline.
- *
- * Since: 3.32
*/
properties [PROP_CONFIG] =
g_param_spec_object ("config",
@@ -1658,8 +1715,6 @@ ide_pipeline_class_init (IdePipelineClass *klass)
* IdePipeline:device:
*
* The "device" property is the device we are compiling for.
- *
- * Since: 3.32
*/
properties [PROP_DEVICE] =
g_param_spec_object ("device",
@@ -1673,8 +1728,6 @@ ide_pipeline_class_init (IdePipelineClass *klass)
*
* The "message" property is descriptive text about what the the
* pipeline is doing or it's readiness status.
- *
- * Since: 3.32
*/
properties [PROP_MESSAGE] =
g_param_spec_string ("message",
@@ -1687,8 +1740,6 @@ ide_pipeline_class_init (IdePipelineClass *klass)
* IdePipeline:phase:
*
* The current build phase during execution of the pipeline.
- *
- * Since: 3.32
*/
properties [PROP_PHASE] =
g_param_spec_flags ("phase",
@@ -1703,8 +1754,6 @@ ide_pipeline_class_init (IdePipelineClass *klass)
*
* The "pty" property is the #VtePty that is used by build stages that
* build subprocesses with a pseudo terminal.
- *
- * Since: 3.32
*/
properties [PROP_PTY] =
g_param_spec_object ("pty",
@@ -1722,8 +1771,6 @@ ide_pipeline_class_init (IdePipelineClass *klass)
*
* This signal is emitted when a plugin has detected a diagnostic while
* building the pipeline.
- *
- * Since: 3.32
*/
signals [DIAGNOSTIC] =
g_signal_new_class_handler ("diagnostic",
@@ -1739,8 +1786,6 @@ ide_pipeline_class_init (IdePipelineClass *klass)
*
* This signal is emitted when the pipeline has started executing in
* response to ide_pipeline_build_async() being called.
- *
- * Since: 3.32
*/
signals [STARTED] =
g_signal_new_class_handler ("started",
@@ -1758,8 +1803,6 @@ ide_pipeline_class_init (IdePipelineClass *klass)
* This signal is emitted when the build process has finished executing.
* If the build failed to complete all requested stages, then @failed will
* be set to %TRUE, otherwise %FALSE.
- *
- * Since: 3.32
*/
signals [FINISHED] =
g_signal_new_class_handler ("finished",
@@ -1774,8 +1817,6 @@ ide_pipeline_class_init (IdePipelineClass *klass)
*
* The "loaded" signal is emitted after the pipeline has finished
* loading addins.
- *
- * Since: 3.32
*/
signals [LOADED] =
g_signal_new_class_handler ("loaded",
@@ -1793,8 +1834,6 @@ ide_pipeline_class_init (IdePipelineClass *klass)
* #IdeSubprocessLauncher is created by the pipeline. This may be useful
* to plugins that wan to modify the launcher in a consistent way for all
* pipeline consumers.
- *
- * Since: 3.34
*/
signals [LAUNCHER_CREATED] =
g_signal_new_class_handler ("launcher-created",
@@ -1811,12 +1850,13 @@ ide_pipeline_class_init (IdePipelineClass *klass)
static void
ide_pipeline_init (IdePipeline *self)
{
- DZL_COUNTER_INC (Instances);
-
self->cancellable = g_cancellable_new ();
self->position = -1;
- self->pty_slave = -1;
+ self->pty_producer = -1;
+
+ self->best_strategy_priority = G_MAXINT;
+ self->best_strategy = ide_local_deploy_strategy_new ();
self->pipeline = g_array_new (FALSE, FALSE, sizeof (PipelineEntry));
g_array_set_clear_func (self->pipeline, clear_pipeline_entry);
@@ -1831,8 +1871,8 @@ ide_pipeline_init (IdePipeline *self)
static void
ide_pipeline_stage_build_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
+ GAsyncResult *result,
+ gpointer user_data)
{
IdePipelineStage *stage = (IdePipelineStage *)object;
IdePipeline *self;
@@ -2121,8 +2161,6 @@ ide_pipeline_task_notify_completed (IdePipeline *self,
* Upon completion, @callback will be buildd and should call
* ide_pipeline_build_finish() to get the status of the
* operation.
- *
- * Since: 3.32
*/
void
ide_pipeline_build_targets_async (IdePipeline *self,
@@ -2140,7 +2178,7 @@ ide_pipeline_build_targets_async (IdePipeline *self,
g_return_if_fail (IDE_IS_PIPELINE (self));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- cancellable = dzl_cancellable_chain (cancellable, self->cancellable);
+ cancellable = ide_cancellable_chain (cancellable, self->cancellable);
task = ide_task_new (self, cancellable, callback, user_data);
ide_task_set_source_tag (task, ide_pipeline_build_targets_async);
@@ -2204,8 +2242,6 @@ short_circuit:
* Returns: %TRUE if the build stages were buildd successfully
* up to the requested build phase provided to
* ide_pipeline_build_targets_async().
- *
- * Since: 3.32
*/
gboolean
ide_pipeline_build_targets_finish (IdePipeline *self,
@@ -2247,12 +2283,10 @@ ide_pipeline_build_targets_finish (IdePipeline *self,
* Upon completion, @callback will be buildd and should call
* ide_pipeline_build_finish() to get the status of the
* operation.
- *
- * Since: 3.32
*/
void
ide_pipeline_build_async (IdePipeline *self,
- IdePipelinePhase phase,
+ IdePipelinePhase phase,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -2272,8 +2306,6 @@ ide_pipeline_build_async (IdePipeline *self,
* Returns: %TRUE if the build stages were buildd successfully
* up to the requested build phase provided to
* ide_pipeline_build_async().
- *
- * Since: 3.32
*/
gboolean
ide_pipeline_build_finish (IdePipeline *self,
@@ -2466,10 +2498,7 @@ ide_pipeline_queue_flush (IdePipeline *self)
g_assert (IDE_IS_PIPELINE (self));
- gdk_threads_add_idle_full (G_PRIORITY_LOW,
- ide_pipeline_do_flush,
- g_object_ref (self),
- g_object_unref);
+ g_idle_add_full (G_PRIORITY_LOW, ide_pipeline_do_flush, g_object_ref (self), g_object_unref);
IDE_EXIT;
}
@@ -2487,8 +2516,6 @@ ide_pipeline_queue_flush (IdePipeline *self)
* stages that are part of the same phase.
*
* Returns: A stage_id that may be passed to ide_pipeline_detach().
- *
- * Since: 3.32
*/
guint
ide_pipeline_attach (IdePipeline *self,
@@ -2585,8 +2612,6 @@ cleanup:
* function.
*
* Returns: A stage_id that may be passed to ide_pipeline_remove().
- *
- * Since: 3.32
*/
guint
ide_pipeline_attach_launcher (IdePipeline *self,
@@ -2618,8 +2643,6 @@ ide_pipeline_attach_launcher (IdePipeline *self,
* including all stages that were previously invalidated.
*
* Returns: %TRUE if a stage is known to require execution.
- *
- * Since: 3.32
*/
gboolean
ide_pipeline_request_phase (IdePipeline *self,
@@ -2699,8 +2722,6 @@ cleanup:
* the location that build systems will use for out-of-tree builds.
*
* Returns: the path of the build directory
- *
- * Since: 3.32
*/
const gchar *
ide_pipeline_get_builddir (IdePipeline *self)
@@ -2718,8 +2739,6 @@ ide_pipeline_get_builddir (IdePipeline *self)
* IdeVcs:working-directory property as a string.
*
* Returns: the path of the source directory
- *
- * Since: 3.32
*/
const gchar *
ide_pipeline_get_srcdir (IdePipeline *self)
@@ -2759,8 +2778,6 @@ ide_pipeline_build_path_va_list (const gchar *prefix,
* working directory of the source tree.
*
* Returns: (transfer full): A newly allocated string.
- *
- * Since: 3.32
*/
gchar *
ide_pipeline_build_srcdir_path (IdePipeline *self,
@@ -2791,8 +2808,6 @@ ide_pipeline_build_srcdir_path (IdePipeline *self,
* result of ide_pipeline_get_builddir() as the first parameter.
*
* Returns: (transfer full): A newly allocated string.
- *
- * Since: 3.32
*/
gchar *
ide_pipeline_build_builddir_path (IdePipeline *self,
@@ -2824,8 +2839,6 @@ ide_pipeline_build_builddir_path (IdePipeline *self,
*
* Plugins should use this function to remove their stages when the plugin
* is unloading.
- *
- * Since: 3.32
*/
void
ide_pipeline_detach (IdePipeline *self,
@@ -2863,12 +2876,10 @@ ide_pipeline_detach (IdePipeline *self,
* upon discovering its state is no longer valid. Such an example might be
* invalidating the %IDE_PIPELINE_PHASE_AUTOGEN phase when the an autotools
* projects autogen.sh file has been changed.
- *
- * Since: 3.32
*/
void
-ide_pipeline_invalidate_phase (IdePipeline *self,
- IdePipelinePhase phases)
+ide_pipeline_invalidate_phase (IdePipeline *self,
+ IdePipelinePhase phases)
{
g_return_if_fail (IDE_IS_PIPELINE (self));
@@ -2891,8 +2902,6 @@ ide_pipeline_invalidate_phase (IdePipeline *self,
*
* Returns: (transfer none) (nullable): An #IdePipelineStage or %NULL if the
* stage could not be found.
- *
- * Since: 3.32
*/
IdePipelineStage *
ide_pipeline_get_stage_by_id (IdePipeline *self,
@@ -2918,8 +2927,6 @@ ide_pipeline_get_stage_by_id (IdePipeline *self,
* A convenience function to get the runtime for a build pipeline.
*
* Returns: (transfer none) (nullable): An #IdeRuntime or %NULL
- *
- * Since: 3.32
*/
IdeRuntime *
ide_pipeline_get_runtime (IdePipeline *self)
@@ -2936,8 +2943,6 @@ ide_pipeline_get_runtime (IdePipeline *self)
* A convenience function to get the toolchain for a build pipeline.
*
* Returns: (transfer none): An #IdeToolchain
- *
- * Since: 3.32
*/
IdeToolchain *
ide_pipeline_get_toolchain (IdePipeline *self)
@@ -2955,22 +2960,20 @@ ide_pipeline_get_toolchain (IdePipeline *self)
* using the configuration and runtime associated with the pipeline.
*
* Returns: (transfer full): An #IdeSubprocessLauncher.
- *
- * Since: 3.32
*/
IdeSubprocessLauncher *
ide_pipeline_create_launcher (IdePipeline *self,
GError **error)
{
g_autoptr(IdeSubprocessLauncher) ret = NULL;
+ g_autoptr(IdeRunContext) run_context = NULL;
+ g_auto(GStrv) environ = NULL;
IdeRuntime *runtime;
g_return_val_if_fail (IDE_IS_MAIN_THREAD (), NULL);
g_return_val_if_fail (IDE_IS_PIPELINE (self), NULL);
- runtime = ide_config_get_runtime (self->config);
-
- if (runtime == NULL)
+ if (!(runtime = ide_config_get_runtime (self->config)))
{
g_set_error (error,
G_IO_ERROR,
@@ -2980,17 +2983,19 @@ ide_pipeline_create_launcher (IdePipeline *self,
return NULL;
}
- ret = ide_runtime_create_launcher (runtime, error);
+ environ = ide_environment_get_environ (ide_config_get_environment (self->config));
+
+ run_context = ide_run_context_new ();
+ ide_runtime_prepare_to_build (runtime, self, run_context);
+ ide_run_context_set_cwd (run_context, ide_pipeline_get_builddir (self));
+ ide_run_context_add_environ (run_context, (const char * const *)environ);
+ /* Always ignore V=1 from configurations */
+ ide_run_context_setenv (run_context, "V", "0");
+
+ ret = ide_run_context_end (run_context, error);
if (ret != NULL)
{
- IdeEnvironment *env = ide_config_get_environment (self->config);
-
- ide_subprocess_launcher_set_clear_env (ret, TRUE);
- ide_subprocess_launcher_overlay_environment (ret, env);
- /* Always ignore V=1 from configurations */
- ide_subprocess_launcher_setenv (ret, "V", "0", TRUE);
- ide_subprocess_launcher_set_cwd (ret, ide_pipeline_get_builddir (self));
ide_subprocess_launcher_set_flags (ret,
(G_SUBPROCESS_FLAGS_STDERR_PIPE |
G_SUBPROCESS_FLAGS_STDOUT_PIPE));
@@ -3010,25 +3015,23 @@ ide_pipeline_create_launcher (IdePipeline *self,
* Attaches a PTY to stdin/stdout/stderr of the #IdeSubprocessLauncher.
* This is useful if the application can take advantage of a PTY for
* features like colors and other escape sequences.
- *
- * Since: 3.32
*/
void
-ide_pipeline_attach_pty (IdePipeline *self,
- IdeSubprocessLauncher *launcher)
+ide_pipeline_attach_pty (IdePipeline *self,
+ IdeSubprocessLauncher *launcher)
{
GSubprocessFlags flags;
g_return_if_fail (IDE_IS_PIPELINE (self));
g_return_if_fail (IDE_IS_SUBPROCESS_LAUNCHER (launcher));
- if (self->pty_slave == -1)
+ if (self->pty_producer == -1)
{
- IdePtyFd master_fd = ide_pty_intercept_get_fd (&self->intercept);
- self->pty_slave = ide_pty_intercept_create_slave (master_fd, TRUE);
+ IdePtyFd consumer_fd = ide_pty_intercept_get_fd (&self->intercept);
+ self->pty_producer = ide_pty_intercept_create_producer (consumer_fd, TRUE);
}
- if (self->pty_slave == -1)
+ if (self->pty_producer == -1)
{
ide_object_warning (self, _("Pseudo terminal creation failed. Terminal features will be limited."));
return;
@@ -3041,10 +3044,10 @@ ide_pipeline_attach_pty (IdePipeline *self,
G_SUBPROCESS_FLAGS_STDIN_PIPE);
ide_subprocess_launcher_set_flags (launcher, flags);
- /* Assign slave device */
- ide_subprocess_launcher_take_stdin_fd (launcher, dup (self->pty_slave));
- ide_subprocess_launcher_take_stdout_fd (launcher, dup (self->pty_slave));
- ide_subprocess_launcher_take_stderr_fd (launcher, dup (self->pty_slave));
+ /* Assign producer device */
+ ide_subprocess_launcher_take_stdin_fd (launcher, dup (self->pty_producer));
+ ide_subprocess_launcher_take_stdout_fd (launcher, dup (self->pty_producer));
+ ide_subprocess_launcher_take_stderr_fd (launcher, dup (self->pty_producer));
/* Ensure a terminal type is set */
ide_subprocess_launcher_setenv (launcher, "TERM", "xterm-256color", FALSE);
@@ -3060,8 +3063,6 @@ ide_pipeline_attach_pty (IdePipeline *self,
* guaranteed to happen at object creation time.
*
* Returns: (transfer none) (nullable): a #VtePty or %NULL
- *
- * Since: 3.32
*/
VtePty *
ide_pipeline_get_pty (IdePipeline *self)
@@ -3141,8 +3142,6 @@ ide_pipeline_emit_diagnostic (IdePipeline *self,
*
* Returns: an error format id that may be passed to
* ide_pipeline_remove_error_format().
- *
- * Since: 3.32
*/
guint
ide_pipeline_add_error_format (IdePipeline *self,
@@ -3178,8 +3177,6 @@ ide_pipeline_add_error_format (IdePipeline *self,
* ide_pipeline_add_error_format().
*
* Returns: %TRUE if the error format was removed.
- *
- * Since: 3.32
*/
gboolean
ide_pipeline_remove_error_format (IdePipeline *self,
@@ -3220,8 +3217,6 @@ ide_pipeline_get_busy (IdePipeline *self)
*
* Returns: (nullable) (transfer full): A string representing the
* current stage of the build, or %NULL.
- *
- * Since: 3.32
*/
gchar *
ide_pipeline_get_message (IdePipeline *self)
@@ -3325,8 +3320,6 @@ ide_pipeline_get_message (IdePipeline *self)
*
* This function will call @stage_callback for every #IdePipelineStage registered
* in the pipeline.
- *
- * Since: 3.32
*/
void
ide_pipeline_foreach_stage (IdePipeline *self,
@@ -3469,7 +3462,7 @@ ide_pipeline_clean_async (IdePipeline *self,
if (!ide_pipeline_check_ready (self, task))
return;
- dzl_cancellable_chain (cancellable, self->cancellable);
+ ide_cancellable_chain (cancellable, self->cancellable);
td = task_data_new (task, TASK_CLEAN);
td->phase = phase;
@@ -3600,7 +3593,7 @@ ide_pipeline_reaper_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
- DzlDirectoryReaper *reaper = (DzlDirectoryReaper *)object;
+ IdeDirectoryReaper *reaper = (IdeDirectoryReaper *)object;
IdePipeline *self;
g_autoptr(IdeTask) task = user_data;
g_autoptr(GError) error = NULL;
@@ -3608,7 +3601,7 @@ ide_pipeline_reaper_cb (GObject *object,
IDE_ENTRY;
- g_assert (DZL_IS_DIRECTORY_REAPER (reaper));
+ g_assert (IDE_IS_DIRECTORY_REAPER (reaper));
g_assert (G_IS_ASYNC_RESULT (result));
g_assert (IDE_IS_TASK (task));
@@ -3622,7 +3615,7 @@ ide_pipeline_reaper_cb (GObject *object,
g_assert (IDE_IS_PIPELINE (self));
/* Make sure our reaper completed or else we bail */
- if (!dzl_directory_reaper_execute_finish (reaper, result, &error))
+ if (!ide_directory_reaper_execute_finish (reaper, result, &error))
{
ide_task_return_error (task, g_steal_pointer (&error));
IDE_EXIT;
@@ -3642,9 +3635,9 @@ ide_pipeline_reaper_cb (GObject *object,
static void
ide_pipeline_tick_rebuild (IdePipeline *self,
- IdeTask *task)
+ IdeTask *task)
{
- g_autoptr(DzlDirectoryReaper) reaper = NULL;
+ g_autoptr(IdeDirectoryReaper) reaper = NULL;
GCancellable *cancellable;
IDE_ENTRY;
@@ -3662,7 +3655,7 @@ ide_pipeline_tick_rebuild (IdePipeline *self,
}
#endif
- reaper = dzl_directory_reaper_new ();
+ reaper = ide_directory_reaper_new ();
/*
* Check if we can remove the builddir. We don't want to do this if it is the
@@ -3672,7 +3665,7 @@ ide_pipeline_tick_rebuild (IdePipeline *self,
{
g_autoptr(GFile) builddir = g_file_new_for_path (self->builddir);
- dzl_directory_reaper_add_directory (reaper, builddir, 0);
+ ide_directory_reaper_add_directory (reaper, builddir, 0);
}
/*
@@ -3691,7 +3684,7 @@ ide_pipeline_tick_rebuild (IdePipeline *self,
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
/* Now build the reaper to clean up the build files. */
- dzl_directory_reaper_execute_async (reaper,
+ ide_directory_reaper_execute_async (reaper,
cancellable,
ide_pipeline_reaper_cb,
g_object_ref (task));
@@ -3711,8 +3704,6 @@ ide_pipeline_tick_rebuild (IdePipeline *self,
*
* Asynchronously starts the build pipeline after cleaning any
* existing build artifacts.
- *
- * Since: 3.32
*/
void
ide_pipeline_rebuild_async (IdePipeline *self,
@@ -3733,7 +3724,7 @@ ide_pipeline_rebuild_async (IdePipeline *self,
drop_caches (self);
- cancellable = dzl_cancellable_chain (cancellable, self->cancellable);
+ cancellable = ide_cancellable_chain (cancellable, self->cancellable);
task = ide_task_new (self, cancellable, callback, user_data);
ide_task_set_priority (task, G_PRIORITY_LOW);
@@ -3755,9 +3746,9 @@ ide_pipeline_rebuild_async (IdePipeline *self,
}
gboolean
-ide_pipeline_rebuild_finish (IdePipeline *self,
- GAsyncResult *result,
- GError **error)
+ide_pipeline_rebuild_finish (IdePipeline *self,
+ GAsyncResult *result,
+ GError **error)
{
gboolean ret;
@@ -3781,8 +3772,6 @@ ide_pipeline_rebuild_finish (IdePipeline *self,
* sensitivity of a button.
*
* Returns: %TRUE if there are export pipeline stages.
- *
- * Since: 3.32
*/
gboolean
ide_pipeline_get_can_export (IdePipeline *self)
@@ -3805,7 +3794,7 @@ ide_pipeline_get_can_export (IdePipeline *self)
void
_ide_pipeline_set_message (IdePipeline *self,
- const gchar *message)
+ const gchar *message)
{
g_return_if_fail (IDE_IS_PIPELINE (self));
@@ -3851,8 +3840,6 @@ _ide_pipeline_cancel (IdePipeline *self)
* the configure stage has been reached.
*
* Returns: %TRUE if %IDE_PIPELINE_PHASE_CONFIGURE has been reached.
- *
- * Since: 3.32
*/
gboolean
ide_pipeline_has_configured (IdePipeline *self)
@@ -3940,7 +3927,7 @@ ide_pipeline_get_n_items (GListModel *model)
static gpointer
ide_pipeline_get_item (GListModel *model,
- guint position)
+ guint position)
{
IdePipeline *self = (IdePipeline *)model;
const PipelineEntry *entry;
@@ -3970,8 +3957,6 @@ list_model_iface_init (GListModelInterface *iface)
* get an idea of where the build pipeline will attempt to advance.
*
* Returns: an #IdePipelinePhase
- *
- * Since: 3.32
*/
IdePipelinePhase
ide_pipeline_get_requested_phase (IdePipeline *self)
@@ -3999,18 +3984,18 @@ ide_pipeline_get_requested_phase (IdePipeline *self)
void
_ide_pipeline_set_pty_size (IdePipeline *self,
- guint rows,
- guint columns)
+ guint rows,
+ guint columns)
{
g_return_if_fail (IDE_IS_PIPELINE (self));
- if (self->pty_slave != IDE_PTY_FD_INVALID)
+ if (self->pty_producer != IDE_PTY_FD_INVALID)
ide_pty_intercept_set_size (&self->intercept, rows, columns);
}
void
_ide_pipeline_set_runtime (IdePipeline *self,
- IdeRuntime *runtime)
+ IdeRuntime *runtime)
{
g_return_if_fail (IDE_IS_PIPELINE (self));
g_return_if_fail (!runtime || IDE_IS_RUNTIME (runtime));
@@ -4029,8 +4014,8 @@ _ide_pipeline_set_runtime (IdePipeline *self,
}
void
-_ide_pipeline_set_toolchain (IdePipeline *self,
- IdeToolchain *toolchain)
+_ide_pipeline_set_toolchain (IdePipeline *self,
+ IdeToolchain *toolchain)
{
g_return_if_fail (IDE_IS_PIPELINE (self));
g_return_if_fail (!toolchain || IDE_IS_TOOLCHAIN (toolchain));
@@ -4048,8 +4033,6 @@ _ide_pipeline_set_toolchain (IdePipeline *self,
* Thread-safe variant of ide_pipeline_get_toolchain().
*
* Returns: (transfer full) (nullable): an #IdeToolchain or %NULL
- *
- * Since: 3.32
*/
IdeToolchain *
ide_pipeline_ref_toolchain (IdePipeline *self)
@@ -4130,8 +4113,6 @@ _ide_pipeline_check_toolchain (IdePipeline *self,
* Gets the device that the pipeline is building for.
*
* Returns: (transfer none): an #IdeDevice.
- *
- * Since: 3.32
*/
IdeDevice *
ide_pipeline_get_device (IdePipeline *self)
@@ -4148,8 +4129,6 @@ ide_pipeline_get_device (IdePipeline *self)
* Gets the device info for the current device.
*
* Returns: (nullable) (transfer none): an #IdeDeviceInfo or %NULL
- *
- * Since: 3.32
*/
IdeDeviceInfo *
ide_pipeline_get_device_info (IdePipeline *self)
@@ -4167,8 +4146,6 @@ ide_pipeline_get_device_info (IdePipeline *self)
* due to various initialization routines that need to complete.
*
* Returns: %TRUE if the pipeline has loaded, otherwise %FALSE
- *
- * Since: 3.32
*/
gboolean
ide_pipeline_is_ready (IdePipeline *self)
@@ -4188,8 +4165,6 @@ ide_pipeline_is_ready (IdePipeline *self)
* set for the build pipeline.
*
* Returns: (transfer none): an #IdeTriplet
- *
- * Since: 3.32
*/
IdeTriplet *
ide_pipeline_get_host_triplet (IdePipeline *self)
@@ -4208,8 +4183,6 @@ ide_pipeline_get_host_triplet (IdePipeline *self)
* work by avoiding some cross-compiling work.
*
* Returns: %FALSE if we're possibly cross-compiling, otherwise %TRUE
- *
- * Since: 3.32
*/
gboolean
ide_pipeline_is_native (IdePipeline *self)
@@ -4278,8 +4251,6 @@ contains_in_runtime_with_alt_path (IdeRuntime *runtime,
* @name that may be executed.
*
* Returns: %TRUE if @name was found; otherwise %FALSE
- *
- * Since: 3.34
*/
gboolean
ide_pipeline_contains_program_in_path (IdePipeline *self,
@@ -4333,6 +4304,25 @@ ide_pipeline_contains_program_in_path (IdePipeline *self,
return FALSE;
}
+/**
+ * ide_pipeline_get_deploy_strategy:
+ * @self: a #IdePipeline
+ *
+ * Gets the best discovered deployment strategry.
+ *
+ * Returns: (transfer none) (nullable): the best deployment strategy
+ * if any are supported for the current configuration.
+ */
+IdeDeployStrategy *
+ide_pipeline_get_deploy_strategy (IdePipeline *self)
+{
+ g_return_val_if_fail (IDE_IS_PIPELINE (self), NULL);
+ g_return_val_if_fail (!self->best_strategy ||
+ IDE_IS_DEPLOY_STRATEGY (self->best_strategy), NULL);
+
+ return self->best_strategy;
+}
+
/**
* ide_pipeline_addin_find_by_module_name:
* @pipeline: an #IdePipeline
@@ -4341,8 +4331,6 @@ ide_pipeline_contains_program_in_path (IdePipeline *self,
* Finds the addin (if any) matching the plugin's @module_name.
*
* Returns: (transfer none) (nullable): an #IdePipelineAddin or %NULL
- *
- * Since: 3.40
*/
IdePipelineAddin *
ide_pipeline_addin_find_by_module_name (IdePipeline *pipeline,
@@ -4366,3 +4354,75 @@ ide_pipeline_addin_find_by_module_name (IdePipeline *pipeline,
return IDE_PIPELINE_ADDIN (ret);
}
+
+/**
+ * ide_pipeline_prepare_run_context:
+ * @self: a #IdePipeline
+ * @run_context: an #IdeRunContext
+ *
+ * Prepares #IdeRunContext to build within the pipeline.
+ *
+ * You should use this to prepare a new #IdeRunContext to run within the
+ * build pipeline environment before adding arguments and other settings
+ * to the context.
+ *
+ * The runtime will be consulted to modify any commands necessary.
+ */
+void
+ide_pipeline_prepare_run_context (IdePipeline *self,
+ IdeRunContext *run_context)
+{
+ IdeRuntime *runtime;
+
+ g_return_if_fail (IDE_IS_MAIN_THREAD ());
+ g_return_if_fail (IDE_IS_PIPELINE (self));
+ g_return_if_fail (IDE_IS_RUN_CONTEXT (run_context));
+
+ if (!(runtime = ide_pipeline_get_runtime (self)))
+ {
+ g_critical ("Attempt to prepare a run context before pipeline has a runtime!");
+ return;
+ }
+
+ ide_runtime_prepare_to_build (runtime, self, run_context);
+
+ ide_run_context_setenv (run_context, "BUILDDIR", ide_pipeline_get_builddir (self));
+ ide_run_context_setenv (run_context, "SRCDIR", ide_pipeline_get_srcdir (self));
+ ide_run_context_set_cwd (run_context, ide_pipeline_get_builddir (self));
+}
+
+/**
+ * ide_pipeline_create_run_context:
+ * @self: a #IdePipeline
+ * @run_command: an #IdeRunCommand
+ *
+ * Creates a new #IdeRunContext to run @run_command.
+ *
+ * This helper is generally meant to be used by pipeline stages to create
+ * a run context that will execute within the pipeline to run the command
+ * described in @run_command.
+ *
+ * The run context is first prepared using ide_pipeline_prepare_run_context()
+ * after which the run command's ide_run_command_prepare_to_run() is used.
+ *
+ * Returns: (transfer full): an #IdeRunContext
+ */
+IdeRunContext *
+ide_pipeline_create_run_context (IdePipeline *self,
+ IdeRunCommand *run_command)
+{
+ g_autoptr(IdeRunContext) run_context = NULL;
+ IdeContext *context;
+
+ g_return_val_if_fail (IDE_IS_PIPELINE (self), NULL);
+ g_return_val_if_fail (IDE_IS_RUN_COMMAND (run_command), NULL);
+
+ context = ide_object_get_context (IDE_OBJECT (self));
+ g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
+
+ run_context = ide_run_context_new ();
+ ide_pipeline_prepare_run_context (self, run_context);
+ ide_run_command_prepare_to_run (run_command, run_context, context);
+
+ return g_steal_pointer (&run_context);
+}
diff --git a/src/libide/foundry/ide-pipeline.h b/src/libide/foundry/ide-pipeline.h
index 4de95798c..05a3ead93 100644
--- a/src/libide/foundry/ide-pipeline.h
+++ b/src/libide/foundry/ide-pipeline.h
@@ -92,6 +92,12 @@ IDE_AVAILABLE_IN_ALL
IdeSubprocessLauncher *ide_pipeline_create_launcher (IdePipeline *self,
GError **error);
IDE_AVAILABLE_IN_ALL
+IdeRunContext *ide_pipeline_create_run_context (IdePipeline *self,
+ IdeRunCommand *run_command);
+IDE_AVAILABLE_IN_ALL
+void ide_pipeline_prepare_run_context (IdePipeline *self,
+ IdeRunContext *run_context);
+IDE_AVAILABLE_IN_ALL
gchar *ide_pipeline_build_srcdir_path (IdePipeline *self,
const gchar *first_part,
...) G_GNUC_NULL_TERMINATED;
@@ -196,5 +202,7 @@ IDE_AVAILABLE_IN_ALL
gboolean ide_pipeline_contains_program_in_path (IdePipeline *self,
const gchar *name,
GCancellable *cancellable);
+IDE_AVAILABLE_IN_ALL
+IdeDeployStrategy *ide_pipeline_get_deploy_strategy (IdePipeline *self);
G_END_DECLS
diff --git a/src/libide/foundry/meson.build b/src/libide/foundry/meson.build
index 0595eeb9f..e8155ec93 100644
--- a/src/libide/foundry/meson.build
+++ b/src/libide/foundry/meson.build
@@ -176,7 +176,6 @@ libide_foundry_generated_headers += [libide_foundry_enums[1]]
libide_foundry_deps = [
libgio_dep,
libgtk_dep,
- libdazzle_dep,
libpeas_dep,
libvte_dep,
libjson_glib_dep,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]