mirror of
https://github.com/libgit2/libgit2.git
synced 2026-01-25 02:56:17 +00:00
Merge pull request #6984 from libgit2/ethomson/cli
CLI: introduce `init` command
This commit is contained in:
@@ -32,5 +32,6 @@ extern int cmd_config(int argc, char **argv);
|
||||
extern int cmd_hash_object(int argc, char **argv);
|
||||
extern int cmd_help(int argc, char **argv);
|
||||
extern int cmd_index_pack(int argc, char **argv);
|
||||
extern int cmd_init(int argc, char **argv);
|
||||
|
||||
#endif /* CLI_cmd_h__ */
|
||||
|
||||
102
src/cli/cmd_init.c
Normal file
102
src/cli/cmd_init.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <git2.h>
|
||||
#include "common.h"
|
||||
#include "cmd.h"
|
||||
#include "error.h"
|
||||
#include "sighandler.h"
|
||||
#include "progress.h"
|
||||
|
||||
#include "fs_path.h"
|
||||
#include "futils.h"
|
||||
|
||||
#define COMMAND_NAME "init"
|
||||
|
||||
static char *branch, *git_dir, *template_dir, *path;
|
||||
static int quiet, bare;
|
||||
|
||||
static const cli_opt_spec opts[] = {
|
||||
CLI_COMMON_OPT,
|
||||
|
||||
{ CLI_OPT_TYPE_SWITCH, "quiet", 'q', &quiet, 1,
|
||||
CLI_OPT_USAGE_DEFAULT, NULL, "quiet mode; don't display informational messages" },
|
||||
{ CLI_OPT_TYPE_SWITCH, "bare", 0, &bare, 1,
|
||||
CLI_OPT_USAGE_DEFAULT, NULL, "don't create a working directory" },
|
||||
{ CLI_OPT_TYPE_VALUE, "initial-branch", 'b', &branch, 0,
|
||||
CLI_OPT_USAGE_DEFAULT, "name", "initial branch name" },
|
||||
{ CLI_OPT_TYPE_VALUE, "separate-git-dir", 0, &git_dir, 0,
|
||||
CLI_OPT_USAGE_DEFAULT, "git-dir", "path to separate git directory" },
|
||||
{ CLI_OPT_TYPE_VALUE, "template", 0, &template_dir, 0,
|
||||
CLI_OPT_USAGE_DEFAULT, "template-dir", "path to git directory templates" },
|
||||
{ CLI_OPT_TYPE_LITERAL },
|
||||
{ CLI_OPT_TYPE_ARG, "directory", 0, &path, 0,
|
||||
CLI_OPT_USAGE_DEFAULT, "directory", "directory to create repository in" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void print_help(void)
|
||||
{
|
||||
cli_opt_usage_fprint(stdout, PROGRAM_NAME, COMMAND_NAME, opts, 0);
|
||||
printf("\n");
|
||||
|
||||
printf("Create a new git repository.\n");
|
||||
printf("\n");
|
||||
|
||||
printf("Options:\n");
|
||||
|
||||
cli_opt_help_fprint(stdout, opts);
|
||||
}
|
||||
|
||||
int cmd_init(int argc, char **argv)
|
||||
{
|
||||
git_repository *repo = NULL;
|
||||
git_repository_init_options init_opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
|
||||
cli_opt invalid_opt;
|
||||
const char *repo_path;
|
||||
int ret = 0;
|
||||
|
||||
if (cli_opt_parse(&invalid_opt, opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU))
|
||||
return cli_opt_usage_error(COMMAND_NAME, opts, &invalid_opt);
|
||||
|
||||
if (cli_opt__show_help) {
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
init_opts.flags |= GIT_REPOSITORY_INIT_MKPATH |
|
||||
GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE;
|
||||
|
||||
if (bare && git_dir)
|
||||
return cli_error_usage("the '--bare' and '--separate-git-dir' options cannot be used together");
|
||||
|
||||
if (bare)
|
||||
init_opts.flags |= GIT_REPOSITORY_INIT_BARE;
|
||||
|
||||
init_opts.template_path = template_dir;
|
||||
init_opts.initial_head = branch;
|
||||
|
||||
if (git_dir) {
|
||||
init_opts.flags |= GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;
|
||||
init_opts.workdir_path = path;
|
||||
|
||||
repo_path = git_dir;
|
||||
} else {
|
||||
repo_path = path;
|
||||
}
|
||||
|
||||
if (git_repository_init_ext(&repo, repo_path, &init_opts) < 0) {
|
||||
ret = cli_error_git();
|
||||
} else if (!quiet) {
|
||||
printf("Initialized empty Git repository in %s\n",
|
||||
git_repository_path(repo));
|
||||
}
|
||||
|
||||
git_repository_free(repo);
|
||||
return ret;
|
||||
}
|
||||
@@ -37,6 +37,7 @@ const cli_cmd_spec cli_cmds[] = {
|
||||
{ "hash-object", cmd_hash_object, "Hash a raw object and product its object ID" },
|
||||
{ "help", cmd_help, "Display help information" },
|
||||
{ "index-pack", cmd_index_pack, "Create an index for a packfile" },
|
||||
{ "init", cmd_init, "Create a new git repository" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
@@ -8,32 +8,81 @@
|
||||
#include "common.h"
|
||||
#include "str.h"
|
||||
|
||||
static int print_spec_name(git_str *out, const cli_opt_spec *spec)
|
||||
#define is_switch_or_value(spec) \
|
||||
((spec)->type == CLI_OPT_TYPE_SWITCH || \
|
||||
(spec)->type == CLI_OPT_TYPE_VALUE)
|
||||
|
||||
static int print_spec_args(git_str *out, const cli_opt_spec *spec)
|
||||
{
|
||||
if (spec->type == CLI_OPT_TYPE_VALUE && spec->alias &&
|
||||
!(spec->usage & CLI_OPT_USAGE_VALUE_OPTIONAL) &&
|
||||
!(spec->usage & CLI_OPT_USAGE_SHOW_LONG))
|
||||
return git_str_printf(out, "-%c <%s>", spec->alias, spec->value_name);
|
||||
if (spec->type == CLI_OPT_TYPE_VALUE && spec->alias &&
|
||||
!(spec->usage & CLI_OPT_USAGE_SHOW_LONG))
|
||||
return git_str_printf(out, "-%c [<%s>]", spec->alias, spec->value_name);
|
||||
if (spec->type == CLI_OPT_TYPE_VALUE &&
|
||||
!(spec->usage & CLI_OPT_USAGE_VALUE_OPTIONAL))
|
||||
return git_str_printf(out, "--%s[=<%s>]", spec->name, spec->value_name);
|
||||
if (spec->type == CLI_OPT_TYPE_VALUE)
|
||||
return git_str_printf(out, "--%s=<%s>", spec->name, spec->value_name);
|
||||
GIT_ASSERT(!is_switch_or_value(spec));
|
||||
|
||||
if (spec->type == CLI_OPT_TYPE_ARG)
|
||||
return git_str_printf(out, "<%s>", spec->value_name);
|
||||
if (spec->type == CLI_OPT_TYPE_ARGS)
|
||||
return git_str_printf(out, "<%s>...", spec->value_name);
|
||||
if (spec->type == CLI_OPT_TYPE_LITERAL)
|
||||
return git_str_printf(out, "--");
|
||||
if (spec->alias && !(spec->usage & CLI_OPT_USAGE_SHOW_LONG))
|
||||
return git_str_printf(out, "-%c", spec->alias);
|
||||
if (spec->name)
|
||||
return git_str_printf(out, "--%s", spec->name);
|
||||
|
||||
GIT_ASSERT(0);
|
||||
GIT_ASSERT(!"unknown option spec type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
GIT_INLINE(int) print_spec_alias(git_str *out, const cli_opt_spec *spec)
|
||||
{
|
||||
GIT_ASSERT(is_switch_or_value(spec) && spec->alias);
|
||||
|
||||
if (spec->type == CLI_OPT_TYPE_VALUE &&
|
||||
!(spec->usage & CLI_OPT_USAGE_VALUE_OPTIONAL))
|
||||
return git_str_printf(out, "-%c <%s>", spec->alias, spec->value_name);
|
||||
else if (spec->type == CLI_OPT_TYPE_VALUE)
|
||||
return git_str_printf(out, "-%c [<%s>]", spec->alias, spec->value_name);
|
||||
else
|
||||
return git_str_printf(out, "-%c", spec->alias);
|
||||
}
|
||||
|
||||
GIT_INLINE(int) print_spec_name(git_str *out, const cli_opt_spec *spec)
|
||||
{
|
||||
GIT_ASSERT(is_switch_or_value(spec) && spec->name);
|
||||
|
||||
if (spec->type == CLI_OPT_TYPE_VALUE &&
|
||||
!(spec->usage & CLI_OPT_USAGE_VALUE_OPTIONAL))
|
||||
return git_str_printf(out, "--%s=<%s>", spec->name, spec->value_name);
|
||||
else if (spec->type == CLI_OPT_TYPE_VALUE)
|
||||
return git_str_printf(out, "--%s[=<%s>]", spec->name, spec->value_name);
|
||||
else
|
||||
return git_str_printf(out, "--%s", spec->name);
|
||||
}
|
||||
|
||||
GIT_INLINE(int) print_spec_full(git_str *out, const cli_opt_spec *spec)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if (is_switch_or_value(spec)) {
|
||||
if (spec->alias)
|
||||
error |= print_spec_alias(out, spec);
|
||||
|
||||
if (spec->alias && spec->name)
|
||||
error |= git_str_printf(out, ", ");
|
||||
|
||||
if (spec->name)
|
||||
error |= print_spec_name(out, spec);
|
||||
} else {
|
||||
error |= print_spec_args(out, spec);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
GIT_INLINE(int) print_spec(git_str *out, const cli_opt_spec *spec)
|
||||
{
|
||||
if (is_switch_or_value(spec)) {
|
||||
if (spec->alias && !(spec->usage & CLI_OPT_USAGE_SHOW_LONG))
|
||||
return print_spec_alias(out, spec);
|
||||
else
|
||||
return print_spec_name(out, spec);
|
||||
}
|
||||
|
||||
return print_spec_args(out, spec);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -56,7 +105,7 @@ int cli_opt_usage_fprint(
|
||||
int error;
|
||||
|
||||
/* TODO: query actual console width. */
|
||||
int console_width = 80;
|
||||
int console_width = 78;
|
||||
|
||||
if ((error = git_str_printf(&usage, "usage: %s", command)) < 0)
|
||||
goto done;
|
||||
@@ -88,7 +137,7 @@ int cli_opt_usage_fprint(
|
||||
if (!optional && !choice && next_choice)
|
||||
git_str_putc(&opt, '(');
|
||||
|
||||
if ((error = print_spec_name(&opt, spec)) < 0)
|
||||
if ((error = print_spec(&opt, spec)) < 0)
|
||||
goto done;
|
||||
|
||||
if (!optional && choice && !next_choice)
|
||||
@@ -113,11 +162,11 @@ int cli_opt_usage_fprint(
|
||||
git_str_putc(&usage, ' ');
|
||||
|
||||
linelen = prefixlen;
|
||||
} else {
|
||||
git_str_putc(&usage, ' ');
|
||||
linelen += git_str_len(&opt) + 1;
|
||||
}
|
||||
|
||||
git_str_putc(&usage, ' ');
|
||||
linelen += git_str_len(&opt) + 1;
|
||||
|
||||
git_str_puts(&usage, git_str_cstr(&opt));
|
||||
|
||||
if (git_str_oom(&usage)) {
|
||||
@@ -169,13 +218,13 @@ int cli_opt_help_fprint(
|
||||
|
||||
git_str_printf(&help, " ");
|
||||
|
||||
if ((error = print_spec_name(&help, spec)) < 0)
|
||||
if ((error = print_spec_full(&help, spec)) < 0)
|
||||
goto done;
|
||||
|
||||
if (spec->help)
|
||||
git_str_printf(&help, ": %s", spec->help);
|
||||
|
||||
git_str_printf(&help, "\n");
|
||||
|
||||
if (spec->help)
|
||||
git_str_printf(&help, " %s\n", spec->help);
|
||||
}
|
||||
|
||||
/* Display the remaining arguments */
|
||||
@@ -192,13 +241,13 @@ int cli_opt_help_fprint(
|
||||
|
||||
git_str_printf(&help, " ");
|
||||
|
||||
if ((error = print_spec_name(&help, spec)) < 0)
|
||||
if ((error = print_spec_full(&help, spec)) < 0)
|
||||
goto done;
|
||||
|
||||
if (spec->help)
|
||||
git_str_printf(&help, ": %s", spec->help);
|
||||
|
||||
git_str_printf(&help, "\n");
|
||||
|
||||
if (spec->help)
|
||||
git_str_printf(&help, " %s\n", spec->help);
|
||||
}
|
||||
|
||||
if (git_str_oom(&help) ||
|
||||
|
||||
Reference in New Issue
Block a user