Subject: [WIP/RFC 22/23] submodule: add is_submodule_active

From: Brandon Williams <[email-masked]>
Date: Thu, 18 May 2017 16:21:33 -0700

Add method which checks if a submodule is active given the provided
repository object.

NOTE: this is almost a copy-paste of is_submodule_initialized.  I tried
to convert is_submodule_initialized to take a submodule_cache and
config_set parameters but that turned out to break some other code paths
which I didn't want to change yet.

Signed-off-by: Brandon Williams <[email-masked]>
---
 submodule.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 submodule.h |  2 ++
 2 files changed, 53 insertions(+)

diff --git a/submodule.c b/submodule.c
index 80851d044..9a9c52292 100644
--- a/submodule.c
+++ b/submodule.c
@@ -16,6 +16,7 @@
 #include "quote.h"
 #include "remote.h"
 #include "worktree.h"
+#include "repo.h"
 
 static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND;
 static int config_update_recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
@@ -270,6 +271,56 @@ int is_submodule_initialized(const char *path)
 	return ret;
 }
 
+int is_submodule_active(struct repo *repo, const char *path)
+{
+	int ret = 0;
+	char *key = NULL;
+	char *value = NULL;
+	const struct string_list *sl;
+	const struct submodule *module;
+
+	module = submodule_from_cache(repo->submodule_cache, null_sha1, path);
+
+	/* early return if there isn't a path->module mapping */
+	if (!module)
+		return 0;
+
+	/* submodule.<name>.active is set */
+	key = xstrfmt("submodule.%s.active", module->name);
+	if (!git_configset_get_bool(repo->config, key, &ret)) {
+		free(key);
+		return ret;
+	}
+	free(key);
+
+	/* submodule.active is set */
+	sl = git_configset_get_value_multi(repo->config, "submodule.active");
+	if (sl) {
+		struct pathspec ps;
+		struct argv_array args = ARGV_ARRAY_INIT;
+		const struct string_list_item *item;
+
+		for_each_string_list_item(item, sl) {
+			argv_array_push(&args, item->string);
+		}
+
+		parse_pathspec(&ps, 0, 0, NULL, args.argv);
+		ret = match_pathspec(&ps, path, strlen(path), 0, NULL, 1);
+
+		argv_array_clear(&args);
+		clear_pathspec(&ps);
+		return ret;
+	}
+
+	/* fallback to checking if the URL is set */
+	key = xstrfmt("submodule.%s.url", module->name);
+	ret = !git_configset_get_string(repo->config, key, &value);
+
+	free(value);
+	free(key);
+	return ret;
+}
+
 int is_submodule_populated_gently(const char *path, int *return_error_code)
 {
 	int ret = 0;
diff --git a/submodule.h b/submodule.h
index 266d81f1c..083f16ce5 100644
--- a/submodule.h
+++ b/submodule.h
@@ -5,6 +5,7 @@ struct diff_options;
 struct argv_array;
 struct oid_array;
 struct remote;
+struct repo;
 
 enum {
 	RECURSE_SUBMODULES_ONLY = -5,
@@ -42,6 +43,7 @@ extern int submodule_config(const char *var, const char *value, void *cb);
 extern void gitmodules_config(void);
 extern void gitmodules_config_sha1(const unsigned char *commit_sha1);
 extern int is_submodule_initialized(const char *path);
+extern int is_submodule_active(struct repo *repo, const char *path);
 /*
  * Determine if a submodule has been populated at a given 'path' by checking if
  * the <path>/.git resolves to a valid git repository.
-- 
2.13.0.303.g4ebf302169-goog