mirror of
https://github.com/xHyroM/gimi.git
synced 2024-11-24 00:21:04 +01:00
Compare commits
No commits in common. "e937523a25b69bd390ec01c93c18b175bed753cd" and "60aeeac369b374917c35f15c6384018d25d61138" have entirely different histories.
e937523a25
...
60aeeac369
14 changed files with 37 additions and 331 deletions
|
@ -1,26 +0,0 @@
|
||||||
image: alpine/latest
|
|
||||||
packages:
|
|
||||||
- git
|
|
||||||
sources:
|
|
||||||
- "https://git.sr.ht/~hyro/gimi"
|
|
||||||
secrets:
|
|
||||||
- 55691174-b52f-477c-81ea-dd32deff19b8 # github
|
|
||||||
- 3eaa5e52-e929-4822-842b-e817e0be7e39 # codeberg
|
|
||||||
tasks:
|
|
||||||
- sync: |
|
|
||||||
cd gimi
|
|
||||||
set +x
|
|
||||||
|
|
||||||
git remote add gimi-github git@github.com:xhyrom/gimi.git
|
|
||||||
ssh-keyscan github.com >> ~/.ssh/known_hosts
|
|
||||||
echo -e "Host github.com\nUser git\nIdentityFile ${HOME}/.ssh/55691174-b52f-477c-81ea-dd32deff19b8" >> ~/.ssh/config
|
|
||||||
git push -f --all gimi-github
|
|
||||||
git push -f --tags gimi-github
|
|
||||||
|
|
||||||
git remote add gimi-codeberg git@codeberg.org:xHyroM/gimi.git
|
|
||||||
ssh-keyscan codeberg.org >> ~/.ssh/known_hosts
|
|
||||||
echo -e "Host codeberg.org\nUser git\nIdentityFile ${HOME}/.ssh/3eaa5e52-e929-4822-842b-e817e0be7e39" >> ~/.ssh/config
|
|
||||||
git push -f --all gimi-codeberg
|
|
||||||
git push -f --tags gimi-codeberg
|
|
||||||
|
|
||||||
set -x
|
|
2
.gimi/config.toml
Executable file → Normal file
2
.gimi/config.toml
Executable file → Normal file
|
@ -4,5 +4,3 @@ ssh = "git@git.sr.ht:~hyro/gimi"
|
||||||
primary = true
|
primary = true
|
||||||
[providers.github]
|
[providers.github]
|
||||||
ssh = "git@github.com:xhyrom/gimi.git"
|
ssh = "git@github.com:xhyrom/gimi.git"
|
||||||
[providers.codeberg]
|
|
||||||
ssh = "git@codeberg.org:xHyroM/gimi.git"
|
|
||||||
|
|
1
README
Normal file
1
README
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Gimi is a tool for managing multiple git remotes as mirrors written in C.
|
|
@ -1,4 +0,0 @@
|
||||||
gimi is a tool for managing multiple git remotes as mirrors written in C.
|
|
||||||
|
|
||||||
issue tracker: https://todo.sr.ht/~hyro/gimi \
|
|
||||||
mailing list (PRs): https://lists.sr.ht/~hyro/gimi
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include "../gimi_constants.h"
|
#include "../gimi_constants.h"
|
||||||
#include "command/ci.h"
|
|
||||||
#include "command/config.h"
|
#include "command/config.h"
|
||||||
#include "command/init.h"
|
#include "command/init.h"
|
||||||
#include "command/provider.h"
|
#include "command/provider.h"
|
||||||
|
@ -10,15 +9,7 @@
|
||||||
#define HELP \
|
#define HELP \
|
||||||
"Usage: gimi [-h | --help] [-v | --version]\n\n" \
|
"Usage: gimi [-h | --help] [-v | --version]\n\n" \
|
||||||
"A simple tool for managing multiple git remotes as mirrors\n\n" \
|
"A simple tool for managing multiple git remotes as mirrors\n\n" \
|
||||||
"Useful commands for working with gimi:\n" \
|
"Commands\n"
|
||||||
" ci Generate CI configuration for a specific provider\n" \
|
|
||||||
" config Manage gimi configuration settings\n" \
|
|
||||||
" init Initialize a gimi project in the current workspace\n" \
|
|
||||||
" provider Manage providers (git remotes as mirrors)\n" \
|
|
||||||
" push Push all branches or tags to all providers\n\n" \
|
|
||||||
"Options:\n" \
|
|
||||||
" -h, --help Show this help message and exit\n" \
|
|
||||||
" -v, --version Show the version of gimi\n"
|
|
||||||
|
|
||||||
void cli_print_help() { printf("%s", HELP); }
|
void cli_print_help() { printf("%s", HELP); }
|
||||||
void cli_print_version() {
|
void cli_print_version() {
|
||||||
|
@ -29,18 +20,14 @@ void cli_print_version() {
|
||||||
int cli_handle(int argc, char **argv) {
|
int cli_handle(int argc, char **argv) {
|
||||||
char *sub_command = argv[0];
|
char *sub_command = argv[0];
|
||||||
|
|
||||||
if (strcmp(sub_command, "ci") == 0) {
|
if (strcmp(sub_command, "init") == 0) {
|
||||||
return cli_command_ci(argc, argv);
|
return cli_command_init(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(sub_command, "config") == 0) {
|
if (strcmp(sub_command, "config") == 0) {
|
||||||
return cli_command_config(argc, argv);
|
return cli_command_config(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(sub_command, "init") == 0) {
|
|
||||||
return cli_command_init(argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(sub_command, "provider") == 0) {
|
if (strcmp(sub_command, "provider") == 0) {
|
||||||
return cli_command_provider(argc, argv);
|
return cli_command_provider(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,15 +13,9 @@
|
||||||
argc -= optind; \
|
argc -= optind; \
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
#define OPTION(opt, func, ...) \
|
#define OPTION(opt, func) \
|
||||||
case opt: { \
|
case opt: { \
|
||||||
func(__VA_ARGS__); \
|
func(); \
|
||||||
break; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MASK_OPTION(opt, mask, field) \
|
|
||||||
case opt: { \
|
|
||||||
mask |= field; \
|
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,184 +0,0 @@
|
||||||
#include "../../config.h"
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#define SOURCEHUT \
|
|
||||||
"image: alpine/latest\n" \
|
|
||||||
"packages:\n" \
|
|
||||||
" - git\n" \
|
|
||||||
"sources:\n" \
|
|
||||||
" - \"https://%s/%s/%s\"\n" \
|
|
||||||
"secrets:\n" \
|
|
||||||
" - <secret>\n" \
|
|
||||||
"tasks:\n" \
|
|
||||||
" - sync: |\n" \
|
|
||||||
" cd %s\n" \
|
|
||||||
" set +x" \
|
|
||||||
" %s\n\n" \
|
|
||||||
" set -x\n"
|
|
||||||
|
|
||||||
struct repository {
|
|
||||||
char *domain;
|
|
||||||
char *owner;
|
|
||||||
char *repo;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct repository *translate_ssh_to_repository(char *ssh) {
|
|
||||||
const char *at = strchr(ssh, '@');
|
|
||||||
const char *colon = strchr(ssh, ':');
|
|
||||||
const char *slash = strchr(colon, '/');
|
|
||||||
|
|
||||||
if (!at || !colon || at > colon) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct repository *repo =
|
|
||||||
(struct repository *)malloc(sizeof(struct repository));
|
|
||||||
if (!repo) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int domain_len = colon - at - 1;
|
|
||||||
repo->domain = (char *)malloc(domain_len + 1);
|
|
||||||
snprintf(repo->domain, domain_len + 1, "%.*s", domain_len, at + 1);
|
|
||||||
|
|
||||||
int repo_len = slash - colon - 1;
|
|
||||||
repo->owner = (char *)malloc(repo_len + 1);
|
|
||||||
snprintf(repo->owner, repo_len + 1, "%.*s", repo_len, colon + 1);
|
|
||||||
|
|
||||||
int slash_len = strlen(slash) - 1;
|
|
||||||
repo->repo = (char *)malloc(slash_len + 1);
|
|
||||||
snprintf(repo->repo, slash_len + 1, "%s", slash + 1);
|
|
||||||
|
|
||||||
return repo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void repository_free(struct repository *repo) {
|
|
||||||
free(repo->owner);
|
|
||||||
free(repo->repo);
|
|
||||||
free(repo);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *generate_sourcehut(struct gimi_config *cfg,
|
|
||||||
struct gimi_config_provider *main_provider) {
|
|
||||||
char remotes[1024] = "";
|
|
||||||
|
|
||||||
for (int i = 0; i < cfg->providers_size; i++) {
|
|
||||||
struct gimi_config_provider *provider = cfg->providers[i];
|
|
||||||
if (strcmp(provider->name, main_provider->name) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
struct repository *repo = translate_ssh_to_repository(provider->ssh);
|
|
||||||
|
|
||||||
char buf[1024];
|
|
||||||
snprintf(buf, sizeof(buf),
|
|
||||||
"\n"
|
|
||||||
"\n git remote add gimi-%s %s "
|
|
||||||
"\n ssh-keyscan %s >> ~/.ssh/known_hosts"
|
|
||||||
"\n echo -e \"Host %s\\nUser git\\nIdentityFile "
|
|
||||||
"${HOME}/.ssh/<secret>\" >> ~/.ssh/config"
|
|
||||||
"\n git push -f --all gimi-%s"
|
|
||||||
"\n git push -f --tags gimi-%s",
|
|
||||||
provider->name, provider->ssh, repo->domain, repo->domain,
|
|
||||||
provider->name, provider->name);
|
|
||||||
|
|
||||||
strcat(remotes, buf);
|
|
||||||
|
|
||||||
repository_free(repo);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *buf = (char *)malloc(2048);
|
|
||||||
struct repository *repo = translate_ssh_to_repository(main_provider->ssh);
|
|
||||||
|
|
||||||
snprintf(buf, 2048, SOURCEHUT, repo->domain, repo->owner, repo->repo,
|
|
||||||
repo->repo, remotes);
|
|
||||||
|
|
||||||
repository_free(repo);
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
int generate(int argc, char **argv) {
|
|
||||||
struct gimi_config *cfg = config_read();
|
|
||||||
ASSERT_CONFIG_EXIST(cfg);
|
|
||||||
|
|
||||||
struct gimi_config_provider *provider;
|
|
||||||
|
|
||||||
if (argc == 2) {
|
|
||||||
provider = config_find_provider(cfg, argv[1]);
|
|
||||||
|
|
||||||
if (provider == NULL) {
|
|
||||||
printf("error: no such provider '%s'", argv[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < cfg->providers_size; i++) {
|
|
||||||
if (cfg->providers[i]->primary) {
|
|
||||||
provider = cfg->providers[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (provider == NULL) {
|
|
||||||
printf("error: can't find primary provider");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
char *template;
|
|
||||||
if (strcmp(provider->name, "sourcehut") == 0) {
|
|
||||||
template = generate_sourcehut(cfg, provider);
|
|
||||||
|
|
||||||
int ret = mkdir(".builds", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
|
||||||
if (ret != 0 && errno != EEXIST) {
|
|
||||||
printf("error: failed to create directory .builds with errno %d", errno);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *file_ptr;
|
|
||||||
file_ptr = fopen(".builds/gimi.yml", "w");
|
|
||||||
if (file_ptr == NULL) {
|
|
||||||
printf("error: failed to open file .builds/gimi.yml");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(file_ptr, "%s", template);
|
|
||||||
|
|
||||||
fclose(file_ptr);
|
|
||||||
} else {
|
|
||||||
printf("error: provider '%s' is not supported, create the ci yourself.",
|
|
||||||
provider->name);
|
|
||||||
|
|
||||||
config_free(cfg);
|
|
||||||
free(provider);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
config_free(cfg);
|
|
||||||
free(provider);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cli_command_ci(int argc, char **argv) {
|
|
||||||
if (argc == 1) {
|
|
||||||
printf("usage: gimi ci generate [provider]");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove "ci" from args
|
|
||||||
argc -= 1;
|
|
||||||
argv += 1;
|
|
||||||
|
|
||||||
char *subcommand = argv[0];
|
|
||||||
|
|
||||||
if (strcmp(subcommand, "generate") == 0) {
|
|
||||||
return generate(argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
int cli_command_ci(int argc, char **argv);
|
|
|
@ -6,7 +6,11 @@
|
||||||
|
|
||||||
int cli_command_config(int argc, char **argv) {
|
int cli_command_config(int argc, char **argv) {
|
||||||
struct gimi_config *cfg = config_read();
|
struct gimi_config *cfg = config_read();
|
||||||
ASSERT_CONFIG_EXIST(cfg);
|
if (!cfg) {
|
||||||
|
printf(
|
||||||
|
"error: missing gimi config, initialize it using gimi init command.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < cfg->providers_size; i++) {
|
for (int i = 0; i < cfg->providers_size; i++) {
|
||||||
struct gimi_config_provider *provider = cfg->providers[i];
|
struct gimi_config_provider *provider = cfg->providers[i];
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
int cli_command_init(int argc, char **argv) {
|
int cli_command_init(int argc, char **argv) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
int ret = mkdir(".gimi", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
int ret = mkdir(".gimi", S_IRWXU);
|
||||||
if (ret == -1 && errno != EEXIST) {
|
if (ret == -1 && errno != EEXIST) {
|
||||||
printf("error: failed to initialize gimi.\n");
|
printf("error: failed to initialize gimi.\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -5,17 +5,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define HELP \
|
|
||||||
"Usage: gimi provider [-h | --help]\n\n" \
|
|
||||||
"Commands for working with gimi provider:\n" \
|
|
||||||
" info Print info about the provider\n" \
|
|
||||||
" sync Synchronize gimi provider with git\n\n" \
|
|
||||||
"Options:\n" \
|
|
||||||
" -h, --help Show this help message and exit\n"
|
|
||||||
|
|
||||||
int providers() {
|
int providers() {
|
||||||
struct gimi_config *cfg = config_read();
|
struct gimi_config *cfg = config_read();
|
||||||
ASSERT_CONFIG_EXIST(cfg);
|
if (!cfg)
|
||||||
|
return 1;
|
||||||
|
|
||||||
for (int i = 0; i < cfg->providers_size; i++) {
|
for (int i = 0; i < cfg->providers_size; i++) {
|
||||||
struct gimi_config_provider *provider = cfg->providers[i];
|
struct gimi_config_provider *provider = cfg->providers[i];
|
||||||
|
@ -34,9 +27,11 @@ int provider_info(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gimi_config *cfg = config_read();
|
struct gimi_config *cfg = config_read();
|
||||||
ASSERT_CONFIG_EXIST(cfg);
|
if (!cfg)
|
||||||
|
return 1;
|
||||||
|
|
||||||
struct gimi_config_provider *provider = config_find_provider(cfg, argv[1]);
|
struct gimi_config_provider *provider = config_find_provider(cfg, argv[1]);
|
||||||
|
config_free(cfg);
|
||||||
|
|
||||||
if (!provider) {
|
if (!provider) {
|
||||||
printf("error: no such provider '%s'", argv[1]);
|
printf("error: no such provider '%s'", argv[1]);
|
||||||
|
@ -47,7 +42,6 @@ int provider_info(int argc, char **argv) {
|
||||||
printf("ssh: %s\n", provider->ssh);
|
printf("ssh: %s\n", provider->ssh);
|
||||||
printf("primary: %d\n", provider->primary);
|
printf("primary: %d\n", provider->primary);
|
||||||
|
|
||||||
config_free(cfg);
|
|
||||||
free(provider);
|
free(provider);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -60,9 +54,11 @@ int provider_sync(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gimi_config *cfg = config_read();
|
struct gimi_config *cfg = config_read();
|
||||||
ASSERT_CONFIG_EXIST(cfg);
|
if (!cfg)
|
||||||
|
return 1;
|
||||||
|
|
||||||
struct gimi_config_provider *provider = config_find_provider(cfg, argv[1]);
|
struct gimi_config_provider *provider = config_find_provider(cfg, argv[1]);
|
||||||
|
config_free(cfg);
|
||||||
|
|
||||||
char command[100];
|
char command[100];
|
||||||
snprintf(command, sizeof(command), "git remote add gimi-%s %s",
|
snprintf(command, sizeof(command), "git remote add gimi-%s %s",
|
||||||
|
@ -77,9 +73,6 @@ int provider_sync(int argc, char **argv) {
|
||||||
provider->name);
|
provider->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
config_free(cfg);
|
|
||||||
free(provider);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,11 +87,6 @@ int cli_command_provider(int argc, char **argv) {
|
||||||
|
|
||||||
char *subcommand = argv[0];
|
char *subcommand = argv[0];
|
||||||
|
|
||||||
if (strcmp(argv[0], "--help") == 0 || strcmp(argv[0], "-h") == 0) {
|
|
||||||
printf("%s", HELP);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(subcommand, "info") == 0) {
|
if (strcmp(subcommand, "info") == 0) {
|
||||||
return provider_info(argc, argv);
|
return provider_info(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,68 +1,41 @@
|
||||||
#include "../../config.h"
|
#include "../../config.h"
|
||||||
#include "../cli.h"
|
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#define PUSH_TAGS_OPTION 1 << 0
|
|
||||||
#define VERBOSE_OPTION 1 << 1
|
|
||||||
#define DELETE_BRANCH_OPTION 1 << 2
|
|
||||||
|
|
||||||
char *get_current_branch_name() {
|
char *get_current_branch_name() {
|
||||||
FILE *file_ptr;
|
FILE *file_ptr;
|
||||||
char output[256];
|
static char output[256];
|
||||||
|
|
||||||
file_ptr = popen("git rev-parse --abbrev-ref HEAD", "r");
|
file_ptr = popen("git rev-parse --abbrev-ref HEAD", "r");
|
||||||
if (file_ptr == NULL) {
|
if (file_ptr == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fgets(output, sizeof(output), file_ptr) == NULL) {
|
char *branch = fgets(output, sizeof(output), file_ptr);
|
||||||
pclose(file_ptr);
|
if (branch != NULL) {
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove new line
|
// remove new line
|
||||||
size_t len = strlen(output);
|
size_t len = strlen(branch);
|
||||||
if (len > 0 && output[len - 1] == '\n') {
|
if (len > 0 && branch[len - 1] == '\n') {
|
||||||
output[len - 1] = '\0';
|
branch[len - 1] = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pclose(file_ptr);
|
pclose(file_ptr);
|
||||||
|
|
||||||
return strdup(output);
|
return branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_push(char *provider_name, char *branch_name, int options) {
|
int git_push(char *provider_name, char *branch_name, bool verbose) {
|
||||||
FILE *file_ptr;
|
FILE *file_ptr;
|
||||||
char output[1024];
|
char output[1024];
|
||||||
char command[256];
|
char command[256];
|
||||||
|
|
||||||
char push_options[50] = "";
|
snprintf(command, sizeof(command), "git push gimi-%s %s 2>&1", provider_name,
|
||||||
|
branch_name);
|
||||||
if (options & DELETE_BRANCH_OPTION) {
|
|
||||||
strcat(push_options, " -d");
|
|
||||||
} else {
|
|
||||||
if (strcmp(provider_name, "sourcehut") == 0) {
|
|
||||||
strcat(push_options, " -o skip-ci");
|
|
||||||
} else if (strcmp(provider_name, "gitlab") == 0) {
|
|
||||||
strcat(push_options, " -o ci.skip");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char branch_or_tags[256] = "";
|
|
||||||
if (options & PUSH_TAGS_OPTION) {
|
|
||||||
strcat(branch_or_tags, "--tags");
|
|
||||||
} else {
|
|
||||||
strcat(branch_or_tags, branch_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(command, sizeof(command), "git push%s gimi-%s %s 2>&1", push_options,
|
|
||||||
provider_name, branch_or_tags);
|
|
||||||
|
|
||||||
file_ptr = popen(command, "r");
|
file_ptr = popen(command, "r");
|
||||||
if (file_ptr == NULL) {
|
if (file_ptr == NULL) {
|
||||||
|
@ -71,7 +44,7 @@ int git_push(char *provider_name, char *branch_name, int options) {
|
||||||
|
|
||||||
while (fgets(output, sizeof(output), file_ptr) !=
|
while (fgets(output, sizeof(output), file_ptr) !=
|
||||||
NULL) { // need to process for valid exit code
|
NULL) { // need to process for valid exit code
|
||||||
if (options & VERBOSE_OPTION) {
|
if (verbose) {
|
||||||
printf("%s", output);
|
printf("%s", output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,27 +55,17 @@ int git_push(char *provider_name, char *branch_name, int options) {
|
||||||
|
|
||||||
int cli_command_push(int argc, char **argv) {
|
int cli_command_push(int argc, char **argv) {
|
||||||
struct gimi_config *cfg = config_read();
|
struct gimi_config *cfg = config_read();
|
||||||
ASSERT_CONFIG_EXIST(cfg);
|
if (!cfg)
|
||||||
|
|
||||||
int options = 0;
|
|
||||||
|
|
||||||
HANDLE_OPTIONS(argc, argv, "tvd",
|
|
||||||
MASK_OPTION('t', options, PUSH_TAGS_OPTION)
|
|
||||||
MASK_OPTION('v', options, VERBOSE_OPTION)
|
|
||||||
MASK_OPTION('d', options, DELETE_BRANCH_OPTION));
|
|
||||||
|
|
||||||
if ((options & DELETE_BRANCH_OPTION) && (options & PUSH_TAGS_OPTION)) {
|
|
||||||
printf(
|
|
||||||
"error: options '-d' (delete) and '-t' (tags) cannot be used together");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
bool verbose = argc == 2 && strcmp(argv[1], "--verbose") == 0;
|
||||||
|
|
||||||
char *branch_name = get_current_branch_name();
|
char *branch_name = get_current_branch_name();
|
||||||
|
|
||||||
for (int i = 0; i < cfg->providers_size; i++) {
|
for (int i = 0; i < cfg->providers_size; i++) {
|
||||||
struct gimi_config_provider *provider = cfg->providers[i];
|
struct gimi_config_provider *provider = cfg->providers[i];
|
||||||
|
|
||||||
int ret = git_push(provider->name, branch_name, options);
|
int ret = git_push(provider->name, branch_name, verbose);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printf("error: failed to push into '%s' with git's exit code %d.\n",
|
printf("error: failed to push into '%s' with git's exit code %d.\n",
|
||||||
provider->name, ret);
|
provider->name, ret);
|
||||||
|
@ -112,7 +75,6 @@ int cli_command_push(int argc, char **argv) {
|
||||||
printf("info: successfully pushed into '%s'.\n", provider->name);
|
printf("info: successfully pushed into '%s'.\n", provider->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(branch_name);
|
|
||||||
config_free(cfg);
|
config_free(cfg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -64,11 +64,6 @@ struct gimi_config *config_read() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void config_free(struct gimi_config *cfg) {
|
void config_free(struct gimi_config *cfg) {
|
||||||
for (int i = 0; i < cfg->providers_size; i++) {
|
|
||||||
free(cfg->providers[i]->name);
|
|
||||||
free(cfg->providers[i]->ssh);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(cfg->providers);
|
free(cfg->providers);
|
||||||
free(cfg);
|
free(cfg);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +74,6 @@ struct gimi_config_provider *config_find_provider(struct gimi_config *cfg,
|
||||||
for (int i = 0; i < cfg->providers_size; i++) {
|
for (int i = 0; i < cfg->providers_size; i++) {
|
||||||
if (strcmp(cfg->providers[i]->name, name) == 0) {
|
if (strcmp(cfg->providers[i]->name, name) == 0) {
|
||||||
provider = cfg->providers[i];
|
provider = cfg->providers[i];
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define ASSERT_CONFIG_EXIST(cfg) \
|
|
||||||
if (!cfg) { \
|
|
||||||
printf( \
|
|
||||||
"error: missing gimi config, initialize it using gimi init command."); \
|
|
||||||
return 1; \
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gimi_config_provider {
|
struct gimi_config_provider {
|
||||||
char *name;
|
char *name;
|
||||||
char *ssh;
|
char *ssh;
|
||||||
|
|
Loading…
Reference in a new issue