diff options
-rwxr-xr-x | bonus/git.cgi | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/bonus/git.cgi b/bonus/git.cgi new file mode 100755 index 00000000..824874a3 --- /dev/null +++ b/bonus/git.cgi @@ -0,0 +1,64 @@ +#!/usr/bin/env -S qjs --std +/* adds clickable links to commit hashes + * usage: + * 0. install QuickJS (https://bellard.org/quickjs) + * 1. put this script in your CGI directory + * 2. chmod +x /your/cgi-bin/directory/git.cgi + * 3. ln -s /your/cgi-bin/directory/git.cgi /usr/local/bin/gitcha + * 4. gitcha log + * other params work too, but for those it's more convenient to use git. + * (if you have ansi2html, it also works with w3m. just set GITCHA_CHA=w3m) */ + +const gitcha = std.getenv("GITCHA_GITCHA") ?? "gitcha"; +if (scriptArgs[0].split('/').at(-1) == gitcha) { + const cha = std.getenv("GITCHA_CHA") ?? 'cha'; + const params = encodeURIComponent(scriptArgs.slice(1) + .map(x => encodeURIComponent(x)).join(' ')); + const [path, _] = os.getcwd(); + const prefix = cha == "w3m" ? '/cgi-bin/' : "cgi-bin:"; + os.exec([cha, `${prefix}git.cgi?params=${params}&path=${path}&prefix=${prefix}`]); + std.exit(0); +} + +const query = {}; +for (const p of std.getenv("QUERY_STRING").split('&')) { + const sp = p.split('='); + query[decodeURIComponent(sp[0])] = decodeURIComponent(sp[1] ?? ''); +} + +os.chdir(query.path); + +const config = ["-c", "color.ui=always", "-c", "log.decorate=short"]; +const params = query.params ? decodeURIComponent(query.params).split(' ') + .map(x => decodeURIComponent(x)) : []; + +if (params[0] == "log") { + std.out.puts('Content-Type: text/html\n\n'); + const [read_fd, write_fd] = os.pipe(); + const [read_fd2, write_fd2] = os.pipe(); + os.exec(["git", ...config, ...params], { + stdout: write_fd, + block: false + }); + os.close(write_fd); + const libexecDir = std.getenv("CHA_LIBEXEC_DIR") ?? + '/usr/local/libexec/chawan'; + os.exec([libexecDir + "/ansi2html"], { + stdin: read_fd, + stdout: write_fd2, + block: false + }); + os.close(read_fd); + os.close(write_fd2); + const f = std.fdopen(read_fd2, "r"); + const cgi = `${query.prefix}git.cgi?prefix=${query.prefix}&path=${query.path}¶ms=show`; + while ((l = f.getline()) !== null) { + console.log(l.replace(/[a-f0-9]{40}/g, + x => `<a href='${cgi}%20${x}'>${x}</a>`)); + } + f.close(); +} else { + std.out.puts('Content-Type: text/x-ansi\n\n'); + const pid = os.exec(["git", ...config, ...params], {block: false}); + waitpid(pid, 0); +} |