From db174e304b8917098e7a3fa1e6362c5764f5c165 Mon Sep 17 00:00:00 2001 From: Daylin Morgan Date: Tue, 19 Sep 2023 14:03:19 -0500 Subject: [PATCH] let soft-serve do the mirroring --- .gitignore | 3 +- soft/config/soft-serve.config.json | 21 ------ soft/config/update-soft-serve-repos.py | 48 ------------- soft/repos.txt | 9 +++ soft/setup.nim | 94 ++++++++++++++++++++++++++ 5 files changed, 105 insertions(+), 70 deletions(-) delete mode 100644 soft/config/soft-serve.config.json delete mode 100755 soft/config/update-soft-serve-repos.py create mode 100644 soft/repos.txt create mode 100644 soft/setup.nim diff --git a/.gitignore b/.gitignore index b4b8061..1de0750 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ gitea/gitea/* !gitea/gitea/public/ soft/* -!soft/config/ +!soft/setup.nim +!soft/repos.txt diff --git a/soft/config/soft-serve.config.json b/soft/config/soft-serve.config.json deleted file mode 100644 index 46b19c0..0000000 --- a/soft/config/soft-serve.config.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "paths": { - "src": "./gitea/git/repositories/daylin", - "dest": "./soft/data/repos" - }, - "repos": { - "src": [ - "dotfiles", - "git-server", - "monolisa-nerdfont-patch", - "yartsu", - "task.mk", - "viv", - "logo", - "forge" - ], - "dest": [ - ".soft-serve" - ] - } -} diff --git a/soft/config/update-soft-serve-repos.py b/soft/config/update-soft-serve-repos.py deleted file mode 100755 index 40eec52..0000000 --- a/soft/config/update-soft-serve-repos.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python3 - -import json -from pathlib import Path -import shutil - - -def get_config(): - with (Path(__file__).parent / "soft-serve.config.json").open("r") as f: - return json.load(f) - - -def get_name(config, repo): - name = repo.name.replace(".git","") - dest = Path(config["paths"]["dest"]) / repo.name - return name, dest - - -def get_repo_path(config, repos): - return Path(__file__).parent.parent.parent / config["paths"][repos] - - -def main(): - - config = get_config() - - for repo in get_repo_path(config, "src").iterdir(): - name, dest = get_name(config, repo) - - if name not in config["repos"]["src"]: - continue - - print(f"{repo} >> {dest}") - - if dest.is_dir(): - shutil.rmtree(dest) - shutil.copytree(repo, dest) - - for repo in get_repo_path(config, "dest").iterdir(): - name, dest = get_name(config, repo) - - if name not in [*config["repos"]["src"], *config["repos"]["dest"]]: - print(f"pruning {name}") - shutil.rmtree(repo) - - -if __name__ == "__main__": - main() diff --git a/soft/repos.txt b/soft/repos.txt new file mode 100644 index 0000000..c6ec0a9 --- /dev/null +++ b/soft/repos.txt @@ -0,0 +1,9 @@ +bbansi +dotfiles +git-server +monolisa-nerdfont-patch +yartsu +task.mk +viv +logo +forge diff --git a/soft/setup.nim b/soft/setup.nim new file mode 100644 index 0000000..01c7940 --- /dev/null +++ b/soft/setup.nim @@ -0,0 +1,94 @@ +#[ +# fetch all repos from user -> first 100 +curl -L \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + 'https://api.github.com/users/daylinmorgan/repos?per_page=100' > repos.json +]# +{.define: ssl.} +import std/[ + httpclient, json, + os, osproc, + options, sequtils, + strformat, strutils, +] + +type + Repo = object + name: string + description: string + html_url: string + +template use(client: HttpClient, body: untyped) = + try: + body + finally: + client.close() + +proc getGhRepos(): seq[Repo] = + let + token = getEnv("GITHUB_TOKEN") + url = "https://api.github.com/users/daylinmorgan/repos?per_page=100" + var + response: string + headers = @[ + ("Accept", "application/vnd.github+json"), + ("X-GitHub-Api-Version", "2022-11-28") + ] + if token != "": headers.add ("Authorization", "Bearer " & token) + var client = newHttpClient(headers = newHttpHeaders(headers)) + use client: + response = client.getContent(url) + parseJson(response).to(seq[Repo]) + + +proc getSoftRepos(): seq[string] = + let (output, errCode) = execCmdEx("ssh -p 23231 localhost repos list") + if errCode != 0: + echo "error fetching repos" + echo "result:" + echo output + quit(QuitFailure) + return output.strip().split "\n" + +proc mirrorToSoft(repo: Repo, dryRun: bool) = + var cmd = "ssh -p 23231 localhost repos import " + cmd.add fmt"{repo.name} {repo.html_url} -m " + if repo.description != "": + # I've never had such problems with quotes before + cmd.add fmt("""-d \"{quoteshell(repo.description)}\"""") + echo cmd + if not dryrun: + let (output, errCode) = execCmdEx(cmd) + if errCode != 0: + echo "ERROR:" + echo output + +when isMainModule: + import std/parseopt + # const reposList = slurp("repos.txt").strip().split("\n") + let reposList = readFile("repos.txt").strip().split('\n') + var dryrun = false + var p = initOptParser() + for kind, key, val in p.getopt(): + case kind: + of cmdEnd: break + of cmdShortOption, cmdLongOption: + case key: + of "n", "--dryrun": dryrun = true + else: + echo "unexpected option/value -> ", key, ", ", val + of cmdArgument: + echo "unknown argument: ", key + + let + ghRepos = getGhRepos() + softRepos = getSoftRepos() + + let repos = ghRepos.filterIt(it.name in reposList) + let toBeMirrored: seq[Repo] = repos.filterIt(it.name notin softRepos) + if toBeMirrored.len > 0: + for repo in toBeMirrored: + mirrorToSoft(repo, dryrun) +