[gnome-builder/wip/project-selector: 4/10] autotools: add basic autotools project miner
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/project-selector: 4/10] autotools: add basic autotools project miner
- Date: Mon, 30 Mar 2015 21:09:59 +0000 (UTC)
commit dd791b5809b4e2963e90805e35497890bbeb470e
Author: Christian Hergert <christian hergert me>
Date: Sun Mar 29 22:33:42 2015 -0700
autotools: add basic autotools project miner
.gitignore | 1 +
libide/Makefile.am | 2 +
libide/autotools/ide-autotools-project-miner.c | 320 ++++++++++++++++++++++++
libide/autotools/ide-autotools-project-miner.h | 37 +++
tools/Makefile.am | 5 +
tools/ide-mine-projects.c | 83 ++++++
6 files changed, 448 insertions(+), 0 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index fdcf05a..bc7a1d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,7 @@ ide-list-devices
ide-list-diagnostics
ide-list-file-settings
ide-list-files
+ide-mine-projects
ide-search
intltool-extract.in
intltool-merge.in
diff --git a/libide/Makefile.am b/libide/Makefile.am
index a239fdb..5129c8e 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -9,6 +9,8 @@ libide_1_0_la_public_sources = \
libide/autotools/ide-autotools-build-task.h \
libide/autotools/ide-autotools-builder.c \
libide/autotools/ide-autotools-builder.h \
+ libide/autotools/ide-autotools-project-miner.c \
+ libide/autotools/ide-autotools-project-miner.h \
libide/c/ide-c-indenter.c \
libide/c/ide-c-indenter.h \
libide/c/ide-c-language.c \
diff --git a/libide/autotools/ide-autotools-project-miner.c b/libide/autotools/ide-autotools-project-miner.c
new file mode 100644
index 0000000..8cfd07b
--- /dev/null
+++ b/libide/autotools/ide-autotools-project-miner.c
@@ -0,0 +1,320 @@
+/* ide-autotools-project-miner.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-autotools-project-miner"
+
+#include <glib/gi18n.h>
+
+#include "ide-autotools-project-miner.h"
+#include "ide-debug.h"
+
+#define MAX_MINE_DEPTH 5
+
+struct _IdeAutotoolsProjectMiner
+{
+ IdeProjectMiner parent_instance;
+ GFile *root_directory;
+};
+
+G_DEFINE_TYPE (IdeAutotoolsProjectMiner, ide_autotools_project_miner, IDE_TYPE_PROJECT_MINER)
+
+enum {
+ PROP_0,
+ PROP_ROOT_DIRECTORY,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+static void
+ide_autotools_project_miner_discovered (IdeAutotoolsProjectMiner *self,
+ GFile *directory,
+ GFileInfo *file_info)
+{
+ g_autofree gchar *uri = NULL;
+ g_autofree gchar *name = NULL;
+ g_autoptr(GFile) file = NULL;
+ g_autoptr(IdeProjectInfo) project_info = NULL;
+ const gchar *filename;
+
+ IDE_ENTRY;
+
+ g_assert (IDE_IS_AUTOTOOLS_PROJECT_MINER (self));
+ g_assert (G_IS_FILE (directory));
+ g_assert (G_IS_FILE_INFO (file_info));
+
+ uri = g_file_get_uri (directory);
+ g_debug ("Discovered autotools project at %s", uri);
+
+ filename = g_file_info_get_attribute_byte_string (file_info, G_FILE_ATTRIBUTE_STANDARD_NAME);
+ file = g_file_get_child (directory, filename);
+ name = g_file_get_basename (directory);
+
+ project_info = g_object_new (IDE_TYPE_PROJECT_INFO,
+ "directory", directory,
+ "file", file,
+ "name", name,
+ NULL);
+
+ ide_project_miner_emit_discovered (IDE_PROJECT_MINER (self), project_info);
+
+ IDE_EXIT;
+}
+
+static void
+ide_autotools_project_miner_mine_directory (IdeAutotoolsProjectMiner *self,
+ GFile *directory,
+ guint depth,
+ GCancellable *cancellable)
+{
+ g_autoptr(GFileEnumerator) file_enum = NULL;
+ GFileInfo *file_info;
+
+ g_assert (IDE_IS_AUTOTOOLS_PROJECT_MINER (self));
+ g_assert (G_IS_FILE (directory));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ if (depth == MAX_MINE_DEPTH)
+ return;
+
+#ifndef IDE_DISABLE_TRACE
+ {
+ g_autofree gchar *uri = NULL;
+
+ uri = g_file_get_uri (directory);
+ IDE_TRACE_MSG ("Mining directory %s", uri);
+ }
+#endif
+
+ file_enum = g_file_enumerate_children (directory,
+ G_FILE_ATTRIBUTE_STANDARD_NAME","
+ G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ G_FILE_QUERY_INFO_NONE,
+ cancellable,
+ NULL);
+
+ if (file_enum == NULL)
+ return;
+
+ while ((file_info = g_file_enumerator_next_file (file_enum, cancellable, NULL)))
+ {
+ const gchar *filename;
+ GFileType file_type;
+ GFile *child;
+
+ file_type = g_file_info_get_attribute_uint32 (file_info, G_FILE_ATTRIBUTE_STANDARD_TYPE);
+ filename = g_file_info_get_attribute_byte_string (file_info, G_FILE_ATTRIBUTE_STANDARD_NAME);
+
+ if (filename && filename [0] == '.')
+ goto cleanup;
+
+ switch (file_type)
+ {
+ case G_FILE_TYPE_DIRECTORY:
+ child = g_file_get_child (directory, filename);
+ ide_autotools_project_miner_mine_directory (self, child, depth + 1, cancellable);
+ g_clear_object (&child);
+ break;
+
+ case G_FILE_TYPE_REGULAR:
+ if ((0 == g_strcmp0 (filename, "configure.ac")) ||
+ (0 == g_strcmp0 (filename, "configure.in")))
+ {
+ ide_autotools_project_miner_discovered (self, directory, file_info);
+ g_clear_object (&file_info);
+ return;
+ }
+ break;
+
+ case G_FILE_TYPE_UNKNOWN:
+ case G_FILE_TYPE_SYMBOLIC_LINK:
+ case G_FILE_TYPE_SPECIAL:
+ case G_FILE_TYPE_SHORTCUT:
+ case G_FILE_TYPE_MOUNTABLE:
+ default:
+ break;
+ }
+
+ cleanup:
+ g_object_unref (file_info);
+ }
+}
+
+static void
+ide_autotools_project_miner_worker (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ IdeAutotoolsProjectMiner *self = source_object;
+ GFile *directory = task_data;
+
+ IDE_ENTRY;
+
+ g_assert (G_IS_TASK (task));
+ g_assert (IDE_IS_AUTOTOOLS_PROJECT_MINER (self));
+ g_assert (G_IS_FILE (directory));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ ide_autotools_project_miner_mine_directory (self, directory, 0, cancellable);
+
+ g_task_return_boolean (task, TRUE);
+
+ IDE_EXIT;
+}
+
+static void
+ide_autotools_project_miner_mine_async (IdeProjectMiner *miner,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ IdeAutotoolsProjectMiner *self = (IdeAutotoolsProjectMiner *)miner;
+ g_autoptr(GTask) task = NULL;
+ g_autoptr(GFile) directory = NULL;
+
+ g_assert (IDE_IS_AUTOTOOLS_PROJECT_MINER (self));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (miner, cancellable, callback, user_data);
+
+ directory = g_file_new_for_path (g_get_home_dir ());
+
+ if (self->root_directory)
+ g_task_set_task_data (task, g_object_ref (self->root_directory), g_object_unref);
+ else
+ g_task_set_task_data (task, g_object_ref (directory), g_object_unref);
+
+ g_task_run_in_thread (task, ide_autotools_project_miner_worker);
+}
+
+static gboolean
+ide_autotools_project_miner_mine_finish (IdeProjectMiner *miner,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = (GTask *)result;
+
+ g_assert (IDE_IS_AUTOTOOLS_PROJECT_MINER (miner));
+ g_assert (G_IS_TASK (task));
+
+ return g_task_propagate_boolean (task, error);
+}
+
+static void
+ide_autotools_project_miner_finalize (GObject *object)
+{
+ IdeAutotoolsProjectMiner *self = (IdeAutotoolsProjectMiner *)object;
+
+ g_clear_object (&self->root_directory);
+
+ G_OBJECT_CLASS (ide_autotools_project_miner_parent_class)->finalize (object);
+}
+
+static void
+ide_autotools_project_miner_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeAutotoolsProjectMiner *self = IDE_AUTOTOOLS_PROJECT_MINER (object);
+
+ switch (prop_id)
+ {
+ case PROP_ROOT_DIRECTORY:
+ g_value_set_object (value, ide_autotools_project_miner_get_root_directory (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_autotools_project_miner_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ IdeAutotoolsProjectMiner *self = IDE_AUTOTOOLS_PROJECT_MINER (object);
+
+ switch (prop_id)
+ {
+ case PROP_ROOT_DIRECTORY:
+ ide_autotools_project_miner_set_root_directory (self, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ide_autotools_project_miner_class_init (IdeAutotoolsProjectMinerClass *klass)
+{
+ IdeProjectMinerClass *miner_class = IDE_PROJECT_MINER_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ide_autotools_project_miner_finalize;
+ object_class->get_property = ide_autotools_project_miner_get_property;
+ object_class->set_property = ide_autotools_project_miner_set_property;
+
+ miner_class->mine_async = ide_autotools_project_miner_mine_async;
+ miner_class->mine_finish = ide_autotools_project_miner_mine_finish;
+
+ gParamSpecs [PROP_ROOT_DIRECTORY] =
+ g_param_spec_object ("root-directory",
+ _("Root Directory"),
+ _("The root directory to scan from."),
+ G_TYPE_FILE,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_ROOT_DIRECTORY,
+ gParamSpecs [PROP_ROOT_DIRECTORY]);
+}
+
+static void
+ide_autotools_project_miner_init (IdeAutotoolsProjectMiner *self)
+{
+}
+
+/**
+ * ide_autotools_project_miner_get_root_directory:
+ *
+ * Gets the IdeAutotoolsProjectMiner:root-directory property.
+ * Scans will start from this directory.
+ *
+ * Returns: (transfer none) (nullable): A #GFile or %NULL.
+ */
+GFile *
+ide_autotools_project_miner_get_root_directory (IdeAutotoolsProjectMiner *self)
+{
+ g_return_val_if_fail (IDE_IS_AUTOTOOLS_PROJECT_MINER (self), NULL);
+
+ return self->root_directory;
+}
+
+void
+ide_autotools_project_miner_set_root_directory (IdeAutotoolsProjectMiner *self,
+ GFile *root_directory)
+{
+ g_return_if_fail (IDE_IS_AUTOTOOLS_PROJECT_MINER (self));
+ g_return_if_fail (!root_directory || G_IS_FILE (root_directory));
+
+ if (g_set_object (&self->root_directory, root_directory))
+ g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_ROOT_DIRECTORY]);
+}
diff --git a/libide/autotools/ide-autotools-project-miner.h b/libide/autotools/ide-autotools-project-miner.h
new file mode 100644
index 0000000..fc98884
--- /dev/null
+++ b/libide/autotools/ide-autotools-project-miner.h
@@ -0,0 +1,37 @@
+/* ide-autotools-project-miner.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IDE_AUTOTOOLS_PROJECT_MINER_H
+#define IDE_AUTOTOOLS_PROJECT_MINER_H
+
+#include "ide-project-miner.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_AUTOTOOLS_PROJECT_MINER (ide_autotools_project_miner_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeAutotoolsProjectMiner, ide_autotools_project_miner,
+ IDE, AUTOTOOLS_PROJECT_MINER, IdeProjectMiner)
+
+GFile *ide_autotools_project_miner_get_root_directory (IdeAutotoolsProjectMiner *self);
+void ide_autotools_project_miner_set_root_directory (IdeAutotoolsProjectMiner *self,
+ GFile *root_directory);
+
+G_END_DECLS
+
+#endif /* IDE_AUTOTOOLS_PROJECT_MINER_H */
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 88641bc..e9abfad 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -33,3 +33,8 @@ noinst_PROGRAMS += ide-search
ide_search_SOURCES = tools/ide-search.c
ide_search_CFLAGS = $(libide_1_0_la_CFLAGS)
ide_search_LDADD = libide-1.0.la $(LIBIDE_LIBS)
+
+noinst_PROGRAMS += ide-mine-projects
+ide_mine_projects_SOURCES = tools/ide-mine-projects.c
+ide_mine_projects_CFLAGS = $(libide_1_0_la_CFLAGS)
+ide_mine_projects_LDADD = libide-1.0.la $(LIBIDE_LIBS)
diff --git a/tools/ide-mine-projects.c b/tools/ide-mine-projects.c
new file mode 100644
index 0000000..4e68eab
--- /dev/null
+++ b/tools/ide-mine-projects.c
@@ -0,0 +1,83 @@
+/* ide-mine-projects.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+#include <ide.h>
+
+#include "ide-project-miner.h"
+#include "autotools/ide-autotools-project-miner.h"
+
+static void
+mine_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeProjectMiner *miner = (IdeProjectMiner *)object;
+ g_autoptr(GError) error = NULL;
+ GMainLoop *main_loop = user_data;
+
+ if (!ide_project_miner_mine_finish (miner, result, &error))
+ g_warning ("%s", error->message);
+
+ g_main_loop_quit (main_loop);
+}
+
+static gboolean
+verbose_cb (void)
+{
+ ide_log_increase_verbosity ();
+ return TRUE;
+}
+
+int
+main (int argc,
+ gchar *argv[])
+{
+ static const GOptionEntry entries[] = {
+ { "verbose", 'v', G_OPTION_FLAG_NO_ARG|G_OPTION_FLAG_IN_MAIN,
+ G_OPTION_ARG_CALLBACK, verbose_cb },
+ { NULL }
+ };
+ IdeProjectMiner *miner;
+ GOptionContext *context;
+ GMainLoop *main_loop;
+ GError *error = NULL;
+
+ ide_log_init (TRUE, NULL);
+
+ context = g_option_context_new (_("- discover projects"));
+ g_option_context_add_main_entries (context, entries, NULL);
+
+ if (!g_option_context_parse (context, &argc, &argv, &error))
+ {
+ g_printerr ("%s\n", error->message);
+ return EXIT_FAILURE;
+ }
+
+ miner = g_object_new (IDE_TYPE_AUTOTOOLS_PROJECT_MINER,
+ "root-directory", NULL,
+ NULL);
+ main_loop = g_main_loop_new (NULL, FALSE);
+ ide_project_miner_mine_async (miner, NULL, mine_cb, main_loop);
+ g_main_loop_run (main_loop);
+ g_main_loop_unref (main_loop);
+
+ ide_log_shutdown ();
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]