diff --git a/.builds/alpine.yml b/.builds/alpine.yml index 44c0284..9de05c8 100644 --- a/.builds/alpine.yml +++ b/.builds/alpine.yml @@ -5,12 +5,18 @@ sources: - "https://git.sr.ht/~hyro/gimi" secrets: - 55691174-b52f-477c-81ea-dd32deff19b8 + - 3eaa5e52-e929-4822-842b-e817e0be7e39 tasks: - sync: | cd gimi set +x + git remote add gimi-github git@github.com:xhyrom/gimi.git ssh-keyscan github.com >> ~/.ssh/known_hosts - git push -f --all gimi-github - git push -f --tags gimi-github + git push -f --all --tags gimi-github + + git remote add gimi-codeberg git@codeberg.org:xHyroM/gimi.git + ssh-keyscan codeberg.org >> ~/.ssh/known_hosts + git push -f --all --tags gimi-codeberg + set -x diff --git a/.gimi/config.toml b/.gimi/config.toml old mode 100644 new mode 100755 diff --git a/src/cli/command/ci.c b/src/cli/command/ci.c index 46f4c53..0501677 100644 --- a/src/cli/command/ci.c +++ b/src/cli/command/ci.c @@ -1,21 +1,102 @@ #include "../../config.h" +#include #include #include +#include #include +#include #define SOURCEHUT \ "image: alpine/latest\n" \ "packages:\n" \ " - git\n" \ "sources:\n" \ - " - %s\n" \ + " - \"https://%s/%s/%s\"\n" \ "secrets:\n" \ " - \n" \ "tasks:\n" \ " - sync: |\n" \ - " %s\n" \ - " %s\n" \ - " %s\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[256]; + snprintf(buf, sizeof(buf), + "\n" + "\n git remote add gimi-%s %s " + "\n ssh-keyscan %s >> ~/.ssh/known_hosts" + "\n git push -f --all --tags gimi-%s", + provider->name, provider->ssh, repo->domain, 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(); @@ -42,7 +123,38 @@ int generate(int argc, char **argv) { } }; + 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; } diff --git a/src/cli/command/init.c b/src/cli/command/init.c index c4bab32..7d4d5a1 100644 --- a/src/cli/command/init.c +++ b/src/cli/command/init.c @@ -10,7 +10,7 @@ int cli_command_init(int argc, char **argv) { errno = 0; - int ret = mkdir(".gimi", S_IRWXU); + int ret = mkdir(".gimi", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); if (ret == -1 && errno != EEXIST) { printf("error: failed to initialize gimi.\n"); return 1; diff --git a/src/cli/command/push.c b/src/cli/command/push.c index 783ced2..16106c2 100644 --- a/src/cli/command/push.c +++ b/src/cli/command/push.c @@ -8,7 +8,7 @@ char *get_current_branch_name() { FILE *file_ptr; - static char output[256]; + char output[256]; file_ptr = popen("git rev-parse --abbrev-ref HEAD", "r"); if (file_ptr == NULL) { diff --git a/src/config.c b/src/config.c index 9a83c39..48e4fdd 100644 --- a/src/config.c +++ b/src/config.c @@ -64,6 +64,11 @@ struct gimi_config *config_read() { } 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); }