The features reported by the vcs helper are stored in the foreign_data struct which is expanded for this purpose. In the process, we also change the capabilities command slightly to expect one feature per line (instead of all features on a single line). This enables us to add features in the future that take one or more arguments. To terminate the list of features, a blank line is output at the end. Signed-off-by: Johan Herland <johan@xxxxxxxxxxx> --- Documentation/git-vcs.txt | 8 ++-- transport-foreign.c | 83 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 67 insertions(+), 24 deletions(-) diff --git a/Documentation/git-vcs.txt b/Documentation/git-vcs.txt index febe415..85656d4 100644 --- a/Documentation/git-vcs.txt +++ b/Documentation/git-vcs.txt @@ -33,10 +33,10 @@ The output of each command must be produced on the helper's standard output. The helper's standard error stream can be used for status/progress messages. 'capabilities':: - Outputs a single line with a list of feature names separated - by spaces. Each of these indicates a supported feature of the - helper, and the caller will only attempt operations that are - supported. + Outputs a list of feature names, one per line. Each of these + indicates a supported feature of the helper, and the caller + will only attempt operations that are supported. + The output list shall be terminated with a blank line. 'list':: Outputs the names of refs, one per line. These may be diff --git a/transport-foreign.c b/transport-foreign.c index 29aad77..be0a587 100644 --- a/transport-foreign.c +++ b/transport-foreign.c @@ -8,38 +8,81 @@ struct foreign_data { - struct child_process *importer; + struct child_process importer; + + /* capabilities */ + unsigned export:1; + unsigned export_branch:1; + unsigned export_merges:1; }; +static void get_foreign_capabilities(struct foreign_data *fdata) +{ + struct strbuf buf; + FILE *file; + + write(fdata->importer.in, "capabilities\n", 13); + + strbuf_init(&buf, 0); + file = fdopen(fdata->importer.out, "r"); + while (1) { + char *eon; + if (strbuf_getline(&buf, file, '\n') == EOF) + break; + + if (!*buf.buf) + break; + + eon = strchr(buf.buf, ' '); + if (eon) + *eon = '\0'; + + /* parse features */ + if (!strcmp(buf.buf, "export")) + fdata->export = 1; + else if (!strcmp(buf.buf, "export-branch")) + fdata->export_branch = 1; + else if (!strcmp(buf.buf, "export-merges")) + fdata->export_merges = 1; + else + die("Invalid feature '%s'", buf.buf); + + strbuf_reset(&buf); + } + + strbuf_release(&buf); +} + static struct child_process *get_importer(struct transport *transport) { - struct child_process *importer = transport->data; - if (!importer) { + struct foreign_data *fdata = (struct foreign_data *) transport->data; + if (!fdata) { struct strbuf buf; - importer = xcalloc(1, sizeof(*importer)); - importer->in = -1; - importer->out = -1; - importer->err = 0; - importer->argv = xcalloc(3, sizeof(*importer->argv)); + fdata = xcalloc(1, sizeof(*fdata)); + fdata->importer.in = -1; + fdata->importer.out = -1; + fdata->importer.err = 0; + fdata->importer.argv = xcalloc(3, sizeof(*fdata->importer.argv)); strbuf_init(&buf, 80); strbuf_addf(&buf, "vcs-%s", transport->remote->foreign_vcs); - importer->argv[0] = buf.buf; - importer->argv[1] = transport->remote->name; - importer->git_cmd = 1; - start_command(importer); - transport->data = importer; + fdata->importer.argv[0] = buf.buf; + fdata->importer.argv[1] = transport->remote->name; + fdata->importer.git_cmd = 1; + start_command(&fdata->importer); + get_foreign_capabilities(fdata); + transport->data = fdata; } - return importer; + return &fdata->importer; } static int disconnect_foreign(struct transport *transport) { - struct child_process *importer = transport->data; - if (importer) { - write(importer->in, "\n", 1); - close(importer->in); - finish_command(importer); - free(importer); + struct foreign_data *fdata = (struct foreign_data *) transport->data; + if (fdata) { + write(fdata->importer.in, "\n", 1); + close(fdata->importer.in); + finish_command(&fdata->importer); + free(fdata); transport->data = NULL; } return 0; -- 1.6.4.rc3.138.ga6b98.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html