[gitg] Added pre-commit and post-commit hook execution



commit c5b60b9e7f3fe3685ff4ae6a11a70cbab634802d
Author: Jesse van den Kieboom <jesse vandenkieboom epfl ch>
Date:   Fri Aug 5 17:33:26 2011 +0200

    Added pre-commit and post-commit hook execution

 gitg/gitg-branch-actions.c |   24 +++---
 gitg/gitg-commit-view.c    |   12 +++-
 gitg/gitg-dnd.c            |   17 ++--
 libgitg/gitg-commit.c      |  154 +++++++++++++++++++++++--------------
 libgitg/gitg-repository.c  |  171 ++++++++++++++++++++++++++++++++++++------
 libgitg/gitg-repository.h  |    5 +
 libgitg/gitg-shell.c       |  180 ++++++++++++++++++++-----------------------
 libgitg/gitg-shell.h       |   48 +++++++-----
 tests/shell.c              |   54 ++++++++-----
 9 files changed, 426 insertions(+), 239 deletions(-)
---
diff --git a/gitg/gitg-branch-actions.c b/gitg/gitg-branch-actions.c
index 2d46d05..4281602 100644
--- a/gitg/gitg-branch-actions.c
+++ b/gitg/gitg-branch-actions.c
@@ -378,22 +378,24 @@ static gchar *
 get_stash_refspec (GitgRepository *repository, GitgRef *stash)
 {
 	gchar **out;
-
-	out = gitg_shell_run_sync_with_output (gitg_command_new (repository,
-	                                                          "log",
-	                                                          "--no-color",
-	                                                          "--pretty=oneline",
-	                                                          "-g",
-	                                                          "refs/stash",
-	                                                          NULL),
-	                                       FALSE,
-	                                       NULL);
+	gboolean retval;
+
+	retval = gitg_shell_run_sync_with_output (gitg_command_new (repository,
+	                                                            "log",
+	                                                            "--no-color",
+	                                                            "--pretty=oneline",
+	                                                            "-g",
+	                                                            "refs/stash",
+	                                                            NULL),
+	                                         FALSE,
+	                                         &out,
+	                                         NULL);
 
 	gchar **ptr = out;
 	gchar *sha1 = gitg_hash_hash_to_sha1_new (gitg_ref_get_hash (stash));
 	gchar *ret = NULL;
 
-	while (ptr && *ptr)
+	while (retval && ptr && *ptr)
 	{
 		if (g_str_has_prefix (*ptr, sha1))
 		{
diff --git a/gitg/gitg-commit-view.c b/gitg/gitg-commit-view.c
index 00f0493..bda199e 100644
--- a/gitg/gitg-commit-view.c
+++ b/gitg/gitg-commit-view.c
@@ -2587,7 +2587,17 @@ on_commit_clicked (GtkButton      *button,
 			show_error (view, _("Your user name or email could not be retrieved for use in the sign off message"));
 		}
 		else
-			show_error (view, _("Something went wrong while trying to commit"));
+		{
+			gchar *msg;
+
+			msg = g_strconcat (_("Something went wrong while trying to commit"),
+			                   ":\n\n",
+			                   error->message,
+			                   NULL);
+
+			show_error (view, msg);
+			g_free (msg);
+		}
 
 		if (error)
 		{
diff --git a/gitg/gitg-dnd.c b/gitg/gitg-dnd.c
index 58b7af7..2b6b91b 100644
--- a/gitg/gitg-dnd.c
+++ b/gitg/gitg-dnd.c
@@ -776,14 +776,15 @@ revision_to_text (GitgRepository *repository,
 	gchar **lines;
 	gchar *sha1 = gitg_revision_get_sha1 (revision);
 
-	lines = gitg_shell_run_sync_with_output (gitg_command_new (repository,
-	                                                           "log",
-	                                                           "-1",
-	                                                           "--pretty=format:%h: %s%n%n%b",
-	                                                           sha1,
-	                                                           NULL),
-	                                         FALSE,
-	                                         NULL);
+	gitg_shell_run_sync_with_output (gitg_command_new (repository,
+	                                                   "log",
+	                                                   "-1",
+	                                                   "--pretty=format:%h: %s%n%n%b",
+	                                                   sha1,
+	                                                   NULL),
+	                                 FALSE,
+	                                 &lines,
+	                                 NULL);
 
 	remove_trailing_newlines (lines);
 	gchar *ret = g_strjoinv ("\n", lines);
diff --git a/libgitg/gitg-commit.c b/libgitg/gitg-commit.c
index 8f0529d..c5b2bdf 100644
--- a/libgitg/gitg-commit.c
+++ b/libgitg/gitg-commit.c
@@ -587,8 +587,10 @@ update_index_staged (GitgCommit      *commit,
 	GFile *f = gitg_changed_file_get_file (file);
 	gchar *path = gitg_repository_relative (commit->priv->repository, f);
 	gchar *head = gitg_repository_parse_head (commit->priv->repository);
+	gboolean retval;
+	gchar **ret;
 
-	gchar **ret = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
+	retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
 	                                                                  "diff-index",
 	                                                                  "--no-ext-diff",
 	                                                                  "--cached",
@@ -597,14 +599,16 @@ update_index_staged (GitgCommit      *commit,
 	                                                                  path,
 	                                                                  NULL),
 	                                               FALSE,
+	                                               &ret,
 	                                               NULL);
 
 	g_free (path);
 	g_free (head);
 	g_object_unref (f);
 
-	if (!ret)
+	if (!retval)
 	{
+		g_strfreev (ret);
 		return;
 	}
 
@@ -641,21 +645,23 @@ update_index_unstaged (GitgCommit      *commit,
 {
 	GFile *f = gitg_changed_file_get_file (file);
 	gchar *path = gitg_repository_relative (commit->priv->repository, f);
+	gboolean retval;
 	gchar **ret;
 
-	ret = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
-	                                                          "diff-files",
-	                                                          "--no-ext-diff",
-	                                                          "--",
-	                                                          path,
-	                                                          NULL),
-	                                       FALSE,
-	                                       NULL);
+	retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
+	                                                            "diff-files",
+	                                                            "--no-ext-diff",
+	                                                            "--",
+	                                                            path,
+	                                                            NULL),
+	                                         FALSE,
+	                                         &ret,
+	                                         NULL);
 
 	g_free (path);
 	g_object_unref (f);
 
-	if (ret && *ret)
+	if (retval && ret && *ret)
 	{
 		gitg_changed_file_set_changes (file,
 		                               gitg_changed_file_get_changes (file) |
@@ -668,10 +674,7 @@ update_index_unstaged (GitgCommit      *commit,
 		                               ~GITG_CHANGED_FILE_CHANGES_UNSTAGED);
 	}
 
-	if (ret)
-	{
-		g_strfreev (ret);
-	}
+	g_strfreev (ret);
 }
 
 static void
@@ -885,13 +888,17 @@ comment_parse_subject (gchar const *comment)
 static gboolean
 write_tree (GitgCommit *commit, gchar **tree, GError **error)
 {
-	gchar **lines = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
-	                                                                    "write-tree",
-	                                                                    NULL),
-	                                                 FALSE,
-	                                                 error);
+	gchar **lines;
+	gboolean retval;
+
+	retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
+	                                                            "write-tree",
+	                                                            NULL),
+	                                          FALSE,
+	                                          &lines,
+	                                          error);
 
-	if (!lines || strlen (*lines) != GITG_HASH_SHA_SIZE)
+	if (!retval || !lines || strlen (*lines) != GITG_HASH_SHA_SIZE)
 	{
 		g_strfreev (lines);
 		return FALSE;
@@ -906,15 +913,20 @@ write_tree (GitgCommit *commit, gchar **tree, GError **error)
 static gchar *
 get_signed_off_line (GitgCommit *commit)
 {
-	gchar **user = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
-	                                                                   "config",
-	                                                                   "--get",
-	                                                                   "user.name",
-	                                                                   NULL),
-	                                                FALSE,
-	                                                NULL);
-
-	if (!user)
+	gchar **user;
+	gboolean retval;
+	gchar **email;
+
+	retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
+	                                                            "config",
+	                                                            "--get",
+	                                                            "user.name",
+	                                                            NULL),
+	                                           FALSE,
+	                                           &user,
+	                                           NULL);
+
+	if (!retval || !user)
 	{
 		return NULL;
 	}
@@ -925,15 +937,16 @@ get_signed_off_line (GitgCommit *commit)
 		return NULL;
 	}
 
-	gchar **email = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
-	                                                                    "config",
-	                                                                    "--get",
-	                                                                    "user.email",
-	                                                                    NULL),
-	                                                 FALSE,
-	                                                 NULL);
+	retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
+	                                                            "config",
+	                                                            "--get",
+	                                                            "user.email",
+	                                                            NULL),
+	                                          FALSE,
+	                                          &email,
+	                                          NULL);
 
-	if (!email)
+	if (!retval || !email)
 	{
 		g_strfreev (user);
 		return NULL;
@@ -959,14 +972,22 @@ set_amend_environment (GitgCommit  *commit,
                        GitgCommand *command)
 {
 	gchar **out;
-
-	out = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
-	                                                          "cat-file",
-	                                                          "commit",
-	                                                          "HEAD",
-	                                                          NULL),
-	                                       FALSE,
-	                                       NULL);
+	gboolean retval;
+
+	retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
+	                                                           "cat-file",
+	                                                           "commit",
+	                                                           "HEAD",
+	                                                           NULL),
+	                                          FALSE,
+	                                          &out,
+	                                          NULL);
+
+	if (!retval)
+	{
+		g_strfreev (out);
+		return;
+	}
 
 	// Parse author
 	GRegex *r = g_regex_new ("^author (.*) < ([^>]*)> ([0-9]+.*)$",
@@ -1054,6 +1075,7 @@ commit_tree (GitgCommit   *commit,
              GError      **error)
 {
 	gchar *fullcomment;
+	gboolean retval;
 
 	if (signoff)
 	{
@@ -1109,9 +1131,10 @@ commit_tree (GitgCommit   *commit,
 
 	gchar *converted = convert_commit_encoding (commit, fullcomment);
 
-	buffer = gitg_shell_run_sync_with_input_and_output (command,
+	retval = gitg_shell_run_sync_with_input_and_output (command,
 	                                                    FALSE,
 	                                                    converted,
+	                                                    &buffer,
 	                                                    error);
 
 	g_free (head);
@@ -1119,7 +1142,7 @@ commit_tree (GitgCommit   *commit,
 	g_free (converted);
 	g_object_unref (command);
 
-	if (!buffer || !*buffer || strlen (*buffer) != GITG_HASH_SHA_SIZE)
+	if (!retval || !buffer || !*buffer || strlen (*buffer) != GITG_HASH_SHA_SIZE)
 	{
 		g_strfreev (buffer);
 		return FALSE;
@@ -1163,6 +1186,14 @@ gitg_commit_commit (GitgCommit   *commit,
 
 	gchar *tree;
 
+	if (!gitg_repository_run_hook (commit->priv->repository,
+	                               "pre-commit",
+	                               error,
+	                               NULL))
+	{
+		return FALSE;
+	}
+
 	if (!write_tree (commit, &tree, error))
 	{
 		return FALSE;
@@ -1196,6 +1227,11 @@ gitg_commit_commit (GitgCommit   *commit,
 		return FALSE;
 	}
 
+	gitg_repository_run_hook (commit->priv->repository,
+	                          "post-commit",
+	                          NULL,
+	                          NULL);
+
 	gitg_repository_reload (commit->priv->repository);
 	return TRUE;
 }
@@ -1366,21 +1402,23 @@ gitg_commit_find_changed_file (GitgCommit *commit,
 gchar *
 gitg_commit_amend_message (GitgCommit *commit)
 {
-	g_return_val_if_fail (GITG_IS_COMMIT (commit), NULL);
-
 	gchar **out;
+	gboolean retval;
+
+	g_return_val_if_fail (GITG_IS_COMMIT (commit), NULL);
 
-	out = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
-	                                                          "cat-file",
-	                                                          "commit",
-	                                                          "HEAD",
-	                                                          NULL),
-	                                       FALSE,
-	                                       NULL);
+	retval = gitg_shell_run_sync_with_output (gitg_command_new (commit->priv->repository,
+	                                                            "cat-file",
+	                                                            "commit",
+	                                                            "HEAD",
+	                                                            NULL),
+	                                          FALSE,
+	                                          &out,
+	                                          NULL);
 
 	gchar *ret = NULL;
 
-	if (out)
+	if (retval && out)
 	{
 		gchar **ptr = out;
 
diff --git a/libgitg/gitg-repository.c b/libgitg/gitg-repository.c
index d9af1d3..f0c4f92 100644
--- a/libgitg/gitg-repository.c
+++ b/libgitg/gitg-repository.c
@@ -611,17 +611,22 @@ parse_ref_intern (GitgRepository *repository,
                   gchar const    *ref,
                   gboolean        symbolic)
 {
-	gchar **ret = gitg_shell_run_sync_with_output (gitg_command_new (repository,
-	                                                                  "rev-parse",
-	                                                                  "--verify",
-	                                                                  symbolic ? "--symbolic-full-name" : ref,
-	                                                                  symbolic ? ref : NULL,
-	                                                                  NULL),
-	                                               FALSE,
-	                                               NULL);
-
-	if (!ret)
-	{
+	gchar **ret;
+	gboolean retval;
+
+	retval = gitg_shell_run_sync_with_output (gitg_command_new (repository,
+	                                                            "rev-parse",
+	                                                            "--verify",
+	                                                            symbolic ? "--symbolic-full-name" : ref,
+	                                                            symbolic ? ref : NULL,
+	                                                            NULL),
+	                                          FALSE,
+	                                          &ret,
+	                                          NULL);
+
+	if (!retval || !ret)
+	{
+		g_strfreev (ret);
 		return NULL;
 	}
 
@@ -1407,6 +1412,7 @@ load_current_ref (GitgRepository *self)
 	gchar *ret = NULL;
 	gint i;
 	gint numargs;
+	gboolean retval;
 
 	if (self->priv->last_args == NULL)
 	{
@@ -1426,12 +1432,14 @@ load_current_ref (GitgRepository *self)
 		argv[2 + i] = self->priv->last_args[i];
 	}
 
-	out = gitg_shell_run_sync_with_output (gitg_command_newv (self, argv),
-	                                       FALSE,
-	                                       NULL);
+	retval = gitg_shell_run_sync_with_output (gitg_command_newv (self, argv),
+	                                          FALSE,
+	                                          &out,
+	                                          NULL);
 
-	if (!out)
+	if (!retval || !out)
 	{
+		g_strfreev (out);
 		return NULL;
 	}
 
@@ -1448,17 +1456,20 @@ static void
 load_refs (GitgRepository *self)
 {
 	gchar **refs;
+	gboolean retval;
 
-	refs = gitg_shell_run_sync_with_output (gitg_command_new (self,
-	                                                           "for-each-ref",
-	                                                           "--format=%(refname) %(objectname) %(*objectname)",
-	                                                           "refs",
-	                                                           NULL),
-	                                        FALSE,
-	                                        NULL);
+	retval = gitg_shell_run_sync_with_output (gitg_command_new (self,
+	                                                            "for-each-ref",
+	                                                            "--format=%(refname) %(objectname) %(*objectname)",
+	                                                            "refs",
+	                                                            NULL),
+	                                          FALSE,
+	                                          &refs,
+	                                          NULL);
 
-	if (!refs)
+	if (!retval || !refs)
 	{
+		g_strfreev (refs);
 		return;
 	}
 
@@ -1914,3 +1925,117 @@ gitg_repository_exists (GitgRepository *repository)
 	return g_file_query_exists (repository->priv->git_dir, NULL) &&
 	       g_file_query_exists (repository->priv->work_tree, NULL);
 }
+
+gboolean
+gitg_repository_run_hook (GitgRepository       *repository,
+                          gchar const          *name,
+                          GError              **error,
+                          ...)
+{
+	GFile *hooksdir;
+	GFile *hookfile;
+	GitgCommand *command;
+	gchar *path;
+	GPtrArray *args;
+	gchar **argsv;
+	gchar **ret;
+	va_list ap;
+	gchar const *arg;
+	GFileInfo *info;
+	gboolean canexec;
+	gboolean retval;
+
+	g_return_val_if_fail (GITG_IS_REPOSITORY (repository), FALSE);
+
+	if (repository->priv->git_dir == NULL)
+	{
+		return FALSE;
+	}
+
+	hooksdir = g_file_get_child (repository->priv->git_dir, "hooks");
+	hookfile = g_file_get_child (hooksdir, name);
+	g_object_unref (hooksdir);
+
+	info = g_file_query_info (hookfile,
+	                          G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE,
+	                          G_FILE_QUERY_INFO_NONE,
+	                          NULL,
+	                          NULL);
+
+	canexec = info &&
+	          g_file_info_get_attribute_boolean (info,
+	                                             G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE);
+
+	if (info)
+	{
+		g_object_unref (info);
+	}
+
+	if (!canexec)
+	{
+		/* It's considered a success if the hook cannot be executed */
+		g_object_unref (hookfile);
+		return TRUE;
+	}
+
+	path = g_file_get_path (hookfile);
+	g_object_unref (hookfile);
+
+	args = g_ptr_array_new ();
+	g_ptr_array_add (args, path);
+
+	va_start (ap, error);
+
+	while ((arg = va_arg (ap, gchar const *)) != NULL)
+	{
+		g_ptr_array_add (args, g_strdup (arg));
+	}
+
+	va_end (ap);
+
+	g_ptr_array_add (args, NULL);
+	argsv = (gchar **)g_ptr_array_free (args, FALSE);
+
+	command = gitg_command_newv (NULL,
+	                             (gchar const * const *)argsv);
+
+	g_strfreev (argsv);
+
+	retval = gitg_shell_run_sync_with_output (command,
+	                                          TRUE,
+	                                          &ret,
+	                                          error);
+
+	if (!retval)
+	{
+		if (error)
+		{
+			gchar *joined;
+
+			joined = g_strjoinv ("", ret);
+
+			if (*error)
+			{
+				g_prefix_error (error,
+				                "Hook `%s' failed: %s",
+				                name,
+				                joined);
+			}
+			else
+			{
+				g_set_error (error,
+				             G_IO_ERROR,
+				             G_IO_ERROR_FAILED,
+				             "Hook `%s' failed: %s",
+				             name,
+				             joined);
+			}
+
+			g_free (joined);
+		}
+	}
+
+	g_strfreev (ret);
+
+	return retval;
+}
diff --git a/libgitg/gitg-repository.h b/libgitg/gitg-repository.h
index 158ab23..aebe815 100644
--- a/libgitg/gitg-repository.h
+++ b/libgitg/gitg-repository.h
@@ -103,6 +103,11 @@ gchar **gitg_repository_get_remotes (GitgRepository *repository);
 GSList const *gitg_repository_get_ref_pushes (GitgRepository *repository, GitgRef *ref);
 gchar const **gitg_repository_get_current_selection (GitgRepository *repository);
 
+gboolean gitg_repository_run_hook (GitgRepository       *repository,
+                                   gchar const          *name,
+                                   GError              **error,
+                                   ...) G_GNUC_NULL_TERMINATED;
+
 G_END_DECLS
 
 #endif /* __GITG_REPOSITORY_H__ */
diff --git a/libgitg/gitg-shell.c b/libgitg/gitg-shell.c
index cfbb964..947dc62 100644
--- a/libgitg/gitg-shell.c
+++ b/libgitg/gitg-shell.c
@@ -663,14 +663,16 @@ gitg_shell_get_buffer_size (GitgShell *shell)
 	return shell->priv->buffer_size;
 }
 
-gchar **
-gitg_shell_run_sync_with_output (GitgCommand  *command,
-                                 gboolean      preserve_line_endings,
-                                 GError      **error)
+gboolean
+gitg_shell_run_sync_with_output (GitgCommand   *command,
+                                 gboolean       preserve_line_endings,
+                                 gchar       ***output,
+                                 GError       **error)
 {
-	g_return_val_if_fail (GITG_IS_COMMAND (command), NULL);
+	g_return_val_if_fail (GITG_IS_COMMAND (command), FALSE);
 
 	return gitg_shell_run_sync_with_outputv (preserve_line_endings,
+	                                         output,
 	                                         error,
 	                                         command,
 	                                         NULL);
@@ -687,16 +689,22 @@ collect_update (GitgShell           *shell,
 	}
 }
 
-gchar **
-gitg_shell_run_sync_with_input_and_output_list (GitgCommand **commands,
-                                                gboolean      preserve_line_endings,
-                                                const gchar  *input,
-                                                GError      **error)
+gboolean
+gitg_shell_run_sync_with_input_and_output_list (GitgCommand  **commands,
+                                                gboolean       preserve_line_endings,
+                                                const gchar   *input,
+                                                gchar       ***output,
+                                                GError       **error)
 {
 	GitgShell *shell;
 	GPtrArray *ret;
 	gboolean res;
-	gchar **val;
+	gchar **out;
+
+	if (output)
+	{
+		*output = NULL;
+	}
 
 	shell = gitg_shell_new_synchronized (1000);
 
@@ -722,34 +730,41 @@ gitg_shell_run_sync_with_input_and_output_list (GitgCommand **commands,
 	}
 
 	res = gitg_shell_run_list (shell, commands, error);
-
 	g_ptr_array_add (ret, NULL);
+	out = (gchar **)g_ptr_array_free (ret, FALSE);
+
+	if (output)
+	{
+		*output = out;
+	}
+	else
+	{
+		g_strfreev (out);
+	}
 
 	if (!res || gitg_io_get_exit_status (GITG_IO (shell)) != 0)
 	{
-		g_strfreev ((gchar **)g_ptr_array_free (ret, FALSE));
 		g_object_unref (shell);
 
-		return NULL;
+		return FALSE;
 	}
 
-	val = (gchar **)g_ptr_array_free (ret, FALSE);
 	g_object_unref (shell);
 
-	return val;
-
+	return TRUE;
 }
 
-static gchar **
-gitg_shell_run_sync_with_input_and_outputva (gboolean      preserve_line_endings,
-                                             const gchar  *input,
-                                             va_list       ap,
-                                             GError      **error)
+static gboolean
+gitg_shell_run_sync_with_input_and_outputva (gboolean       preserve_line_endings,
+                                             const gchar   *input,
+                                             gchar       ***output,
+                                             va_list        ap,
+                                             GError       **error)
 {
 	GPtrArray *commands;
 	GitgCommand *cmd;
 	GitgCommand **cmds;
-	gchar **ret;
+	gboolean ret;
 
 	commands = g_ptr_array_new ();
 
@@ -764,44 +779,51 @@ gitg_shell_run_sync_with_input_and_outputva (gboolean      preserve_line_endings
 	ret = gitg_shell_run_sync_with_input_and_output_list (cmds,
 	                                                      preserve_line_endings,
 	                                                      input,
+	                                                      output,
 	                                                      error);
 
 	g_free (cmds);
 	return ret;
 }
 
-static gchar **
-gitg_shell_run_sync_with_outputva (gboolean   preserve_line_endings,
-                                   va_list    ap,
-                                   GError   **error)
+static gboolean
+gitg_shell_run_sync_with_outputva (gboolean    preserve_line_endings,
+                                   gchar    ***output,
+                                   va_list     ap,
+                                   GError    **error)
 {
 	return gitg_shell_run_sync_with_input_and_outputva (preserve_line_endings,
 	                                                    NULL,
+	                                                    output,
 	                                                    ap,
 	                                                    error);
 }
 
-gchar **
-gitg_shell_run_sync_with_output_list (GitgCommand **commands,
-                                      gboolean      preserve_line_endings,
-                                      GError      **error)
+gboolean
+gitg_shell_run_sync_with_output_list (GitgCommand  **commands,
+                                      gboolean       preserve_line_endings,
+                                      gchar       ***output,
+                                      GError       **error)
 {
 	return gitg_shell_run_sync_with_input_and_output_list (commands,
 	                                                       preserve_line_endings,
 	                                                       NULL,
+	                                                       output,
 	                                                       error);
 }
 
-gchar **
-gitg_shell_run_sync_with_outputv (gboolean   preserve_line_endings,
-                                  GError   **error,
+gboolean
+gitg_shell_run_sync_with_outputv (gboolean    preserve_line_endings,
+                                  gchar    ***output,
+                                  GError    **error,
                                   ...)
 {
 	va_list ap;
-	gchar **ret;
+	gboolean ret;
 
 	va_start (ap, error);
 	ret = gitg_shell_run_sync_with_outputva (preserve_line_endings,
+	                                         output,
 	                                         ap,
 	                                         error);
 	va_end (ap);
@@ -822,19 +844,7 @@ gboolean
 gitg_shell_run_sync_list (GitgCommand **commands,
                           GError      **error)
 {
-	gchar **res;
-
-	res = gitg_shell_run_sync_with_output_list (commands, FALSE, error);
-
-	if (res)
-	{
-		g_strfreev (res);
-		return TRUE;
-	}
-	else
-	{
-		return FALSE;
-	}
+	return gitg_shell_run_sync_with_output_list (commands, FALSE, NULL, error);
 }
 
 gboolean
@@ -842,21 +852,13 @@ gitg_shell_run_syncv (GError **error,
                       ...)
 {
 	va_list ap;
-	gchar **res;
+	gboolean res;
 
 	va_start (ap, error);
-	res = gitg_shell_run_sync_with_outputva (FALSE, ap, error);
+	res = gitg_shell_run_sync_with_outputva (FALSE, NULL, ap, error);
 	va_end (ap);
 
-	if (res)
-	{
-		g_strfreev (res);
-		return TRUE;
-	}
-	else
-	{
-		return FALSE;
-	}
+	return res;
 }
 
 gboolean
@@ -874,22 +876,11 @@ gitg_shell_run_sync_with_input_list (GitgCommand  **commands,
                                      const gchar  *input,
                                      GError      **error)
 {
-	gchar **ret;
-
-	ret = gitg_shell_run_sync_with_input_and_output_list (commands,
-	                                                      FALSE,
-	                                                      input,
-	                                                      error);
-
-	if (ret)
-	{
-		g_strfreev (ret);
-		return TRUE;
-	}
-	else
-	{
-		return FALSE;
-	}
+	return gitg_shell_run_sync_with_input_and_output_list (commands,
+	                                                       FALSE,
+	                                                       input,
+	                                                       NULL,
+	                                                       error);
 }
 
 gboolean
@@ -898,53 +889,50 @@ gitg_shell_run_sync_with_inputv (const gchar  *input,
                                  ...)
 {
 	va_list ap;
-	gchar **ret;
+	gboolean ret;
 
 	va_start (ap, error);
 	ret = gitg_shell_run_sync_with_input_and_outputva (FALSE,
 	                                                   input,
+	                                                   NULL,
 	                                                   ap,
 	                                                   error);
 	va_end (ap);
 
-	if (ret)
-	{
-		g_strfreev (ret);
-		return TRUE;
-	}
-	else
-	{
-		return FALSE;
-	}
+	return ret;
 }
 
-gchar **
-gitg_shell_run_sync_with_input_and_output (GitgCommand  *command,
-                                           gboolean      preserve_line_endings,
-                                           const gchar  *input,
-                                           GError      **error)
+gboolean
+gitg_shell_run_sync_with_input_and_output (GitgCommand    *command,
+                                           gboolean        preserve_line_endings,
+                                           const gchar    *input,
+                                           gchar        ***output,
+                                           GError        **error)
 {
-	g_return_val_if_fail (GITG_IS_COMMAND (command), NULL);
+	g_return_val_if_fail (GITG_IS_COMMAND (command), FALSE);
 
 	return gitg_shell_run_sync_with_input_and_outputv (preserve_line_endings,
 	                                                   input,
+	                                                   output,
 	                                                   error,
 	                                                   command,
 	                                                   NULL);
 }
 
-gchar **
-gitg_shell_run_sync_with_input_and_outputv (gboolean      preserve_line_endings,
-                                            const gchar  *input,
-                                            GError      **error,
+gboolean
+gitg_shell_run_sync_with_input_and_outputv (gboolean       preserve_line_endings,
+                                            const gchar   *input,
+                                            gchar       ***output,
+                                            GError       **error,
                                             ...)
 {
 	va_list ap;
-	gchar **ret;
+	gboolean ret;
 
 	va_start (ap, error);
 	ret = gitg_shell_run_sync_with_input_and_outputva (preserve_line_endings,
 	                                                   input,
+	                                                   output,
 	                                                   ap,
 	                                                   error);
 	va_end (ap);
diff --git a/libgitg/gitg-shell.h b/libgitg/gitg-shell.h
index 69b0502..2412ff3 100644
--- a/libgitg/gitg-shell.h
+++ b/libgitg/gitg-shell.h
@@ -100,16 +100,19 @@ gboolean   gitg_shell_runv                      (GitgShell     *shell,
                                                  GError       **error,
                                                 ...) G_GNUC_NULL_TERMINATED;
 
-gchar    **gitg_shell_run_sync_with_output      (GitgCommand  *command,
-                                                 gboolean      preserve_line_endings,
-                                                 GError      **error);
+gboolean   gitg_shell_run_sync_with_output      (GitgCommand   *command,
+                                                 gboolean       preserve_line_endings,
+                                                 gchar       ***output,
+                                                 GError       **error);
 
-gchar    **gitg_shell_run_sync_with_output_list (GitgCommand **commands,
-                                                 gboolean      preserve_line_endings,
-                                                 GError      **error);
+gboolean   gitg_shell_run_sync_with_output_list (GitgCommand  **commands,
+                                                 gboolean       preserve_line_endings,
+                                                 gchar       ***output,
+                                                 GError       **error);
 
-gchar    **gitg_shell_run_sync_with_outputv     (gboolean      preserve_line_endings,
-                                                 GError      **error,
+gboolean   gitg_shell_run_sync_with_outputv     (gboolean       preserve_line_endings,
+                                                 gchar       ***output,
+                                                 GError       **error,
                                                  ...) G_GNUC_NULL_TERMINATED;
 
 gboolean   gitg_shell_run_sync                  (GitgCommand  *command,
@@ -133,19 +136,22 @@ gboolean   gitg_shell_run_sync_with_inputv      (const gchar  *input,
                                                  GError      **error,
                                                  ...) G_GNUC_NULL_TERMINATED;
 
-gchar    **gitg_shell_run_sync_with_input_and_output (GitgCommand  *command,
-                                                      gboolean      preserve_line_endings,
-                                                      const gchar  *input,
-                                                      GError      **error);
-
-gchar    **gitg_shell_run_sync_with_input_and_output_list (GitgCommand **commands,
-                                                           gboolean      preserve_line_endings,
-                                                           const gchar  *input,
-                                                           GError      **error);
-
-gchar    **gitg_shell_run_sync_with_input_and_outputv (gboolean      preserve_line_endings,
-                                                       const gchar  *input,
-                                                       GError      **error,
+gboolean   gitg_shell_run_sync_with_input_and_output (GitgCommand   *command,
+                                                      gboolean       preserve_line_endings,
+                                                      const gchar   *input,
+                                                      gchar       ***output,
+                                                      GError       **error);
+
+gboolean   gitg_shell_run_sync_with_input_and_output_list (GitgCommand  **commands,
+                                                           gboolean       preserve_line_endings,
+                                                           const gchar   *input,
+                                                           gchar       ***output,
+                                                           GError       **error);
+
+gboolean   gitg_shell_run_sync_with_input_and_outputv (gboolean       preserve_line_endings,
+                                                       const gchar   *input,
+                                                       gchar       ***output,
+                                                       GError       **error,
                                                        ...) G_GNUC_NULL_TERMINATED;
 
 G_END_DECLS
diff --git a/tests/shell.c b/tests/shell.c
index b2c1ec2..fbf7915 100644
--- a/tests/shell.c
+++ b/tests/shell.c
@@ -165,17 +165,20 @@ test_output (RepositoryInfo *info,
              gconstpointer   data)
 {
 	gchar **ret;
+	gboolean retval;
 	GError *error = NULL;
 
-	ret = gitg_shell_run_sync_with_output (gitg_command_new (info->repository,
-	                                                          "rev-parse",
-	                                                          "HEAD",
-	                                                          NULL),
-	                                       FALSE,
-	                                       &error);
+	retval = gitg_shell_run_sync_with_output (gitg_command_new (info->repository,
+	                                                            "rev-parse",
+	                                                            "HEAD",
+	                                                            NULL),
+	                                          FALSE,
+	                                          &ret,
+	                                          &error);
 
 	g_assert_no_error (error);
 
+	g_assert (retval);
 	g_assert (ret);
 	g_assert (g_strv_length (ret) == 1);
 
@@ -188,16 +191,19 @@ test_input (void)
 	gchar **ret;
 	gchar const *input = "Hello world";
 	GError *error = NULL;
+	gboolean retval;
 
-	ret = gitg_shell_run_sync_with_input_and_output (gitg_command_new (NULL,
-	                                                                    "cat",
-	                                                                    "-",
-	                                                                    NULL),
-	                                                 FALSE,
-	                                                 input,
-	                                                 &error);
+	retval = gitg_shell_run_sync_with_input_and_output (gitg_command_new (NULL,
+	                                                                      "cat",
+	                                                                      "-",
+	                                                                      NULL),
+	                                                   FALSE,
+	                                                   input,
+	                                                   &ret,
+	                                                   &error);
 
 	g_assert_no_error (error);
+	g_assert (retval);
 	g_assert (ret);
 
 	g_assert (g_strv_length (ret) == 1);
@@ -210,14 +216,17 @@ test_pipe (void)
 	gchar **ret;
 	GError *error = NULL;
 	gchar const *input = "Hello world";
+	gboolean retval;
 
-	ret = gitg_shell_run_sync_with_outputv (FALSE,
-	                                        &error,
-	                                        gitg_command_new (NULL, "echo", input, NULL),
-	                                        gitg_command_new (NULL, "cat", "-", NULL),
-	                                        NULL);
+	retval = gitg_shell_run_sync_with_outputv (FALSE,
+	                                           &ret,
+	                                           &error,
+	                                           gitg_command_new (NULL, "echo", input, NULL),
+	                                           gitg_command_new (NULL, "cat", "-", NULL),
+	                                           NULL);
 
 	g_assert_no_error (error);
+	g_assert (retval);
 	g_assert (ret);
 
 	g_assert (g_strv_length (ret) == 1);
@@ -228,6 +237,7 @@ static void
 test_pipestr (void)
 {
 	gchar **ret;
+	gboolean retval;
 	GError *error = NULL;
 	gchar const *input = "Hello world";
 	gchar *cmdstr;
@@ -240,11 +250,13 @@ test_pipestr (void)
 	g_assert_no_error (error);
 	g_assert (commands);
 
-	ret = gitg_shell_run_sync_with_output_list (commands,
-	                                            FALSE,
-	                                            &error);
+	retval = gitg_shell_run_sync_with_output_list (commands,
+	                                               FALSE,
+	                                               &ret,
+	                                               &error);
 
 	g_assert_no_error (error);
+	g_assert (retval);
 	g_assert (ret);
 
 	g_assert (g_strv_length (ret) == 1);



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