From: Brandon Williams <bmwill@google.com>
To: Prathamesh Chavan <pc44800@gmail.com>
Cc: git@vger.kernel.org, sbeller@google.com, christian.couder@gmail.com
Subject: Re: [GSoC][PATCH 13/13] submodule: port submodule subcommand 'foreach' from shell to C
Date: Mon, 24 Jul 2017 17:29:24 -0700 [thread overview]
Message-ID: <20170725002924.GI92874@google.com> (raw)
In-Reply-To: <20170724203454.13947-14-pc44800@gmail.com>
On 07/25, Prathamesh Chavan wrote:
> This aims to make git-submodule foreach a builtin. This is the very
> first step taken in this direction. Hence, 'foreach' is ported to
> submodule--helper, and submodule--helper is called from git-submodule.sh.
> The code is split up to have one function to obtain all the list of
> submodules. This function acts as the front-end of git-submodule foreach
> subcommand. It calls the function for_each_submodule_list, which basically
> loops through the list and calls function fn, which in this case is
> runcommand_in_submodule. This third function is a calling function that
> takes care of running the command in that submodule, and recursively
> perform the same when --recursive is flagged.
>
> The first function module_foreach first parses the options present in
> argv, and then with the help of module_list_compute, generates the list of
> submodules present in the current working tree.
>
> The second function for_each_submodule_list traverses through the
> list, and calls function fn (which in case of submodule subcommand
> foreach is runcommand_in_submodule) is called for each entry.
>
> The third function runcommand_in_submodule, generates a submodule struct sub
> for $name, value and then later prepends name=sub->name; and other
> value assignment to the env argv_array structure of a child_process.
> Also the <command> of submodule-foreach is push to args argv_array
> structure and finally, using run_command the commands are executed
> using a shell.
>
> The third function also takes care of the recursive flag, by creating
> a separate child_process structure and prepending "--super-prefix displaypath",
> to the args argv_array structure. Other required arguments and the
> input <command> of submodule-foreach is also appended to this argv_array.
>
> Helped-by: Brandon Williams <bmwill@google.com>
> Mentored-by: Christian Couder <christian.couder@gmail.com>
> Mentored-by: Stefan Beller <sbeller@google.com>
> Signed-off-by: Prathamesh Chavan <pc44800@gmail.com>
> ---
> builtin/submodule--helper.c | 129 ++++++++++++++++++++++++++++++++++++++++++++
> git-submodule.sh | 39 +-------------
> 2 files changed, 130 insertions(+), 38 deletions(-)
>
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index 94d6254f0..be278bf8d 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -765,6 +765,134 @@ static int module_name(int argc, const char **argv, const char *prefix)
> return 0;
> }
>
> +struct cb_foreach {
> + int argc;
> + const char **argv;
> + const char *prefix;
> + unsigned int quiet: 1;
> + unsigned int recursive: 1;
> +};
> +#define CB_FOREACH_INIT { 0, NULL, NULL, 0, 0 }
> +
> +static void runcommand_in_submodule(const struct cache_entry *list_item,
> + void *cb_data)
> +{
> + struct cb_foreach *info = cb_data;
> + const struct submodule *sub;
> + struct child_process cp = CHILD_PROCESS_INIT;
> + char *displaypath;
> +
> + displaypath = get_submodule_displaypath(list_item->name, info->prefix);
> +
> + sub = submodule_from_path(null_sha1, list_item->name);
> +
> + if (!sub)
> + die(_("No url found for submodule path '%s' in .gitmodules"),
> + displaypath);
> +
> + if (!is_submodule_populated_gently(list_item->name, NULL))
> + goto cleanup;
> +
> + prepare_submodule_repo_env(&cp.env_array);
> + /* For the purpose of executing <command> in the submodule,
> + * separate shell is used for the purpose of running the
> + * child process.
> + */
comment style
> + cp.use_shell = 1;
> + cp.dir = list_item->name;
> +
> + if (info->argc == 1) {
Why are you only exposing these variables if argc == 1?
> + char *toplevel = xgetcwd();
> +
> + argv_array_pushf(&cp.env_array, "name=%s", sub->name);
> + argv_array_pushf(&cp.env_array, "sm_path=%s", list_item->name);
> + argv_array_pushf(&cp.env_array, "displaypath=%s", displaypath);
> + argv_array_pushf(&cp.env_array, "sha1=%s",
> + oid_to_hex(&list_item->oid));
> + argv_array_pushf(&cp.env_array, "toplevel=%s", toplevel);
> +
> + /*
> + * Since still the path variable was accessible from the
> + * script before porting, it is also made available.
> + */
> + argv_array_pushf(&cp.args, "path=%s; %s",
> + list_item->name, info->argv[0]);
This bit looks odd. Why are you appending argv[0] after a semicolon?
Oh...its to handle the funny path stuff. I'd add a comment indicating
why you have to expose path via the args argv_array and not the
env_array.
> + free(toplevel);
> + } else {
> + argv_array_pushv(&cp.args, info->argv);
> + }
> +
> + if (!info->quiet)
> + printf(_("Entering '%s'\n"), displaypath);
> +
> + if (info->argv[0] && run_command(&cp))
> + die(_("run_command returned non-zero status for %s\n."),
> + displaypath);
> +
> + if (info->recursive) {
> + struct child_process cpr = CHILD_PROCESS_INIT;
> +
> + cpr.git_cmd = 1;
> + cpr.dir = list_item->name;
> + prepare_submodule_repo_env(&cpr.env_array);
> +
> + argv_array_pushl(&cpr.args, "--super-prefix", displaypath,
Same comment as a few of the other commands about super-prefix.
> + "submodule--helper", "foreach", "--recursive",
> + NULL);
> +
> + if (info->quiet)
> + argv_array_push(&cpr.args, "--quiet");
> +
> + argv_array_pushv(&cpr.args, info->argv);
> +
> + if (run_command(&cpr))
> + die(_("run_command returned non-zero status while"
> + "recursing in the nested submodules of %s\n."),
> + displaypath);
> + }
> +
> +cleanup:
> + free(displaypath);
> +}
> +
> +static int module_foreach(int argc, const char **argv, const char *prefix)
> +{
> + struct cb_foreach info;
> + struct pathspec pathspec;
> + struct module_list list = MODULE_LIST_INIT;
> + int quiet = 0;
> + int recursive = 0;
> +
> + struct option module_foreach_options[] = {
> + OPT__QUIET(&quiet, N_("Suppress output of entering each submodule command")),
> + OPT_BOOL(0, "recursive", &recursive,
> + N_("Recurse into nested submodules")),
> + OPT_END()
> + };
> +
> + const char *const git_submodule_helper_usage[] = {
> + N_("git submodule--helper foreach [--quiet] [--recursive] <command>"),
> + NULL
> + };
> +
> + argc = parse_options(argc, argv, prefix, module_foreach_options,
> + git_submodule_helper_usage, PARSE_OPT_KEEP_UNKNOWN);
> +
> + if (module_list_compute(0, NULL, prefix, &pathspec, &list) < 0)
> + BUG("module_list_compute should not choke on empty pathspec");
> +
> + info.argc = argc;
> + info.argv = argv;
> + info.prefix = prefix;
> + info.quiet = !!quiet;
> + info.recursive = !!recursive;
> +
> + gitmodules_config();
> + for_each_submodule_list(list, runcommand_in_submodule, &info);
> +
> + return 0;
> +}
> +
> struct module_cb {
> unsigned int mod_src;
> unsigned int mod_dst;
> @@ -2203,6 +2331,7 @@ static struct cmd_struct commands[] = {
> {"resolve-relative-url", resolve_relative_url, 0},
> {"resolve-relative-url-test", resolve_relative_url_test, 0},
> {"print-name-rev", print_name_rev, 0},
> + {"foreach", module_foreach, SUPPORT_SUPER_PREFIX},
> {"init", module_init, SUPPORT_SUPER_PREFIX},
> {"status", module_status, SUPPORT_SUPER_PREFIX},
> {"print-default-remote", print_default_remote, 0},
> diff --git a/git-submodule.sh b/git-submodule.sh
> index 493a64372..e25b2c613 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -298,44 +298,7 @@ cmd_foreach()
> shift
> done
>
> - toplevel=$(pwd)
> -
> - # dup stdin so that it can be restored when running the external
> - # command in the subshell (and a recursive call to this function)
> - exec 3<&0
> -
> - {
> - git submodule--helper list --prefix "$wt_prefix" ||
> - echo "#unmatched" $?
> - } |
> - while read -r mode sha1 stage sm_path
> - do
> - die_if_unmatched "$mode" "$sha1"
> - if test -e "$sm_path"/.git
> - then
> - displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
> - say "$(eval_gettext "Entering '\$displaypath'")"
> - name=$(git submodule--helper name "$sm_path")
> - (
> - prefix="$prefix$sm_path/"
> - sanitize_submodule_env
> - cd "$sm_path" &&
> - # we make $path available to scripts ...
> - path=$sm_path &&
> - if test $# -eq 1
> - then
> - eval "$1"
> - else
> - "$@"
> - fi &&
> - if test -n "$recursive"
> - then
> - cmd_foreach "--recursive" "$@"
> - fi
> - ) <&3 3<&- ||
> - die "$(eval_gettext "Stopping at '\$displaypath'; script returned non-zero status.")"
> - fi
> - done
> + git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper foreach ${GIT_QUIET:+--quiet} ${recursive:+--recursive} "$@"
> }
>
> #
> --
> 2.13.0
>
--
Brandon Williams
next prev parent reply other threads:[~2017-07-25 0:29 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-24 20:34 [GSoC][PATCH 00/13] Update: Week 10 Prathamesh Chavan
2017-07-24 20:34 ` [GSoC][PATCH 01/13] submodule--helper: introduce get_submodule_displaypath() Prathamesh Chavan
2017-07-24 20:34 ` [GSoC][PATCH 02/13] submodule--helper: introduce for_each_submodule_list() Prathamesh Chavan
2017-07-24 20:34 ` [GSoC][PATCH 03/13] submodule: port set_name_rev() from shell to C Prathamesh Chavan
2017-07-24 20:54 ` Brandon Williams
2017-07-24 20:34 ` [GSoC][PATCH 04/13] submodule: port submodule subcommand 'status' " Prathamesh Chavan
2017-07-24 21:30 ` Brandon Williams
2017-07-24 20:34 ` [GSoC][PATCH 05/13] submodule: port submodule subcommand 'sync' " Prathamesh Chavan
2017-07-24 21:52 ` Brandon Williams
2017-07-24 20:34 ` [GSoC][PATCH 06/13] submodule: port submodule subcommand 'deinit' " Prathamesh Chavan
2017-07-24 23:03 ` Brandon Williams
2017-07-24 20:34 ` [GSoC][PATCH 07/13] diff: change scope of the function count_lines() Prathamesh Chavan
2017-07-24 20:34 ` [GSoC][PATCH 08/13] submodule: port submodule subcommand 'summary' from shell to C Prathamesh Chavan
2017-07-25 0:09 ` Brandon Williams
2017-07-24 20:34 ` [GSoC][PATCH 09/13] submodule foreach: correct '$path' in nested submodules from a subdirectory Prathamesh Chavan
2017-07-25 0:13 ` Brandon Williams
2017-07-24 20:34 ` [GSoC][PATCH 10/13] submodule foreach: document '$sm_path' instead of '$path' Prathamesh Chavan
2017-07-25 0:15 ` Brandon Williams
2017-07-24 20:34 ` [GSoC][PATCH 11/13] submodule foreach: clarify the '$toplevel' variable documentation Prathamesh Chavan
2017-07-24 20:34 ` [GSoC][PATCH 12/13] submodule foreach: document variable '$displaypath' Prathamesh Chavan
2017-07-25 0:16 ` Brandon Williams
2017-07-24 20:34 ` [GSoC][PATCH 13/13] submodule: port submodule subcommand 'foreach' from shell to C Prathamesh Chavan
2017-07-25 0:29 ` Brandon Williams [this message]
2017-07-29 22:23 ` [GSoC][PATCH v2 00/13] Update: Week 10 Prathamesh Chavan
2017-07-29 22:23 ` [GSoC][PATCH v2 01/13] submodule--helper: introduce get_submodule_displaypath() Prathamesh Chavan
2017-07-29 22:23 ` [GSoC][PATCH v2 02/13] submodule--helper: introduce for_each_submodule_list() Prathamesh Chavan
2017-07-29 22:23 ` [GSoC][PATCH v2 03/13] submodule: port set_name_rev() from shell to C Prathamesh Chavan
2017-07-29 22:23 ` [GSoC][PATCH v2 04/13] submodule: port submodule subcommand 'status' " Prathamesh Chavan
2017-07-30 5:35 ` Christian Couder
2017-07-29 22:23 ` [GSoC][PATCH v2 05/13] submodule: port submodule subcommand 'sync' " Prathamesh Chavan
2017-07-29 22:23 ` [GSoC][PATCH v2 06/13] submodule: port submodule subcommand 'deinit' " Prathamesh Chavan
2017-07-29 22:23 ` [GSoC][PATCH v2 07/13] diff: change scope of the function count_lines() Prathamesh Chavan
2017-07-29 22:23 ` [GSoC][PATCH v2 08/13] submodule: port submodule subcommand 'summary' from shell to C Prathamesh Chavan
2017-07-30 5:28 ` Christian Couder
2017-07-30 6:33 ` Prathamesh Chavan
2017-07-29 22:23 ` [GSoC][PATCH v2 09/13] submodule foreach: correct '$path' in nested submodules from a subdirectory Prathamesh Chavan
2017-07-29 22:23 ` [GSoC][PATCH v2 10/13] submodule foreach: document '$sm_path' instead of '$path' Prathamesh Chavan
2017-07-29 22:23 ` [GSoC][PATCH v2 11/13] submodule foreach: clarify the '$toplevel' variable documentation Prathamesh Chavan
2017-07-29 22:24 ` [GSoC][PATCH v2 12/13] submodule foreach: document variable '$displaypath' Prathamesh Chavan
2017-07-29 22:24 ` [GSoC][PATCH v2 13/13] submodule: port submodule subcommand 'foreach' from shell to C Prathamesh Chavan
2017-07-31 20:28 ` [GSoC][PATCH v2 00/13] Update: Week 10 Brandon Williams
-- strict thread matches above, loose matches on Subject: below --
2017-07-31 20:56 [GSoC][PATCH 00/13] Update: Week-11 Prathamesh Chavan
2017-07-31 20:56 ` [GSoC][PATCH 13/13] submodule: port submodule subcommand 'foreach' from shell to C Prathamesh Chavan
2017-07-31 22:20 ` Stefan Beller
2017-08-07 21:18 [GSoC][PATCH 00/13] Update: Week-12 Prathamesh Chavan
2017-08-07 21:19 ` [GSoC][PATCH 13/13] submodule: port submodule subcommand 'foreach' from shell to C Prathamesh Chavan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170725002924.GI92874@google.com \
--to=bmwill@google.com \
--cc=christian.couder@gmail.com \
--cc=git@vger.kernel.org \
--cc=pc44800@gmail.com \
--cc=sbeller@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.