main.c 2.98 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/*
 * 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 "cli.h"
11
#include "cmd.h"
12

13
static int show_help = 0;
14
static int show_version = 0;
15 16
static char *command = NULL;
static char **args = NULL;
17

18 19 20 21 22 23 24 25 26
const cli_opt_spec cli_common_opts[] = {
	{ CLI_OPT_TYPE_SWITCH,    "help",      0, &show_help,    1,
	  CLI_OPT_USAGE_DEFAULT,   NULL,      "display help information" },
	{ CLI_OPT_TYPE_SWITCH,    "version",   0, &show_version, 1,
	  CLI_OPT_USAGE_DEFAULT,   NULL,      "display the version" },
	{ CLI_OPT_TYPE_ARG,       "command",   0, &command,      0,
	  CLI_OPT_USAGE_REQUIRED, "command", "the command to run" },
	{ CLI_OPT_TYPE_ARGS,      "args",      0, &args,         0,
	  CLI_OPT_USAGE_DEFAULT,  "args",    "arguments for the command" },
27 28 29
	{ 0 }
};

30
const cli_cmd_spec cli_cmds[] = {
31
	{ "cat-file",    cmd_cat_file,    "Display an object in the repository" },
32
	{ "clone",       cmd_clone,       "Clone a repository into a new directory" },
33 34
	{ "hash-object", cmd_hash_object, "Hash a raw object and product its object ID" },
	{ "help",        cmd_help,        "Display help information" },
35 36 37
	{ NULL }
};

38 39
int main(int argc, char **argv)
{
40
	const cli_cmd_spec *cmd;
41 42
	cli_opt_parser optparser;
	cli_opt opt;
43 44
	char *help_args[3] = { NULL };
	int help_args_len;
45
	int args_len = 0;
46 47 48 49 50 51 52
	int ret = 0;

	if (git_libgit2_init() < 0) {
		cli_error("failed to initialize libgit2");
		exit(CLI_EXIT_GIT);
	}

53
	cli_opt_parser_init(&optparser, cli_common_opts, argv + 1, argc - 1, CLI_OPT_PARSE_GNU);
54 55 56 57 58

	/* Parse the top-level (common) options and command information */
	while (cli_opt_parser_next(&opt, &optparser)) {
		if (!opt.spec) {
			cli_opt_status_fprint(stderr, PROGRAM_NAME, &opt);
59
			cli_opt_usage_fprint(stderr, PROGRAM_NAME, NULL, cli_common_opts);
60 61 62
			ret = CLI_EXIT_USAGE;
			goto done;
		}
63 64 65 66 67 68 69 70 71 72

		/*
		 * When we see a command, stop parsing and capture the
		 * remaining arguments as args for the command itself.
		 */
		if (command) {
			args = &argv[optparser.idx];
			args_len = (int)(argc - optparser.idx);
			break;
		}
73 74 75 76 77 78 79
	}

	if (show_version) {
		printf("%s version %s\n", PROGRAM_NAME, LIBGIT2_VERSION);
		goto done;
	}

80 81 82 83 84
	/*
	 * If `--help <command>` is specified, delegate to that command's
	 * `--help` option.  If no command is specified, run the `help`
	 * command.  Do this by updating the args to emulate that behavior.
	 */
85
	if (!command || show_help) {
86 87 88 89 90 91 92
		help_args[0] = command ? (char *)command : "help";
		help_args[1] = command ? "--help" : NULL;
		help_args_len = command ? 2 : 1;

		command = help_args[0];
		args = help_args;
		args_len = help_args_len;
93 94 95 96 97 98 99 100 101 102
	}

	if ((cmd = cli_cmd_spec_byname(command)) == NULL) {
		ret = cli_error("'%s' is not a %s command. See '%s help'.",
		                command, PROGRAM_NAME, PROGRAM_NAME);
		goto done;
	}

	ret = cmd->fn(args_len, args);

103 104 105 106
done:
	git_libgit2_shutdown();
	return ret;
}