git-nostr-tools

git nostr tools
git clone git://jb55.com/git-nostr-tools
Log | Files | Refs

commit 5f5ecc9d74a6e0d66eca6f9850d3d55206729b78
Author: William Casarin <jb55@jb55.com>
Date:   Thu, 17 Nov 2022 18:52:27 -0800

initial commit

Diffstat:
A.envrc | 6++++++
A.gitignore | 4++++
AMakefile | 6++++++
AREADME.txt | 28++++++++++++++++++++++++++++
Agit-send-nostr | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agit-show-nostr | 137+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 276 insertions(+), 0 deletions(-)

diff --git a/.envrc b/.envrc @@ -0,0 +1,6 @@ + +source .privenv || : + +export PATH=$PATH:. + + diff --git a/.gitignore b/.gitignore @@ -0,0 +1,4 @@ + +*.json +.privenv +.direnv diff --git a/Makefile b/Makefile @@ -0,0 +1,6 @@ + +PREFIX ?= /usr/local + +install: + install -Dm755 git-send-nostr $(PREFIX)/bin/git-send-nostr + install -Dm755 git-show-nostr $(PREFIX)/bin/git-show-nostr diff --git a/README.txt b/README.txt @@ -0,0 +1,28 @@ + +git-nostr-tools +=============== + +Send and receive patches over nostr + +Install +------- + +sudo make install + + +Dependencies +------------ + +jq, fzf, nostril, nostcat + +nostril: https://cdn.jb55.com/tarballs/nostril/ +nostcat: https://github.com/blakejakopovic/nostcat + + +Tools +----- + +git-show-nostr: list patches and show patches +git-send-nostr: send patches to nostr + + diff --git a/git-send-nostr b/git-send-nostr @@ -0,0 +1,95 @@ +#!/usr/bin/env bash + +NOSTR_RELAYER=${NOSTR_RELAYER:-nostcat} + +if ! command -v $NOSTR_RELAYER >&2 >/dev/null; then + printf "error: nostr relayer '%s' not found, set \$NOSTR_RELAYER or install '%s'\n" $NOSTR_RELAYER $NOSTR_RELAYER + exit 1 +fi + +check_cmd "nostril" + +check_cmd() { + if ! command -v $1 >&2 >/dev/null; then + printf "error: $1 is required. please install. \n" + exit 0 + fi +} + +usage() { + printf "usage: git-send-nostr [OPTIONS...] <commit> [NOSTRIL OPTIONS...]\n\n" + + printf "OPTIONS\n\n" + printf " -r Relay to broadcast to. Will use 'git config nostr.relays' by default\n" + printf " -d Dry run. Just print event to stdout instead of relaying.\n" + printf "\n" + printf " any other nostril option is supported here:\n\n" + printf "NOSTRIL OPTIONS\n" + nostril | sed '1,/OPTIONS/d' + printf "\nEXAMPLES\n\n" + printf "git send-nostr -d HEAD^- -t nostril -t nostrildev --pow 15\n\n" + exit 0 +} + +while getopts "dr:t:" o; do + case "${o}" in + r) + relay=${OPTARG} + ;; + t) + tag=${OPTARG} + ;; + d) + dryrun=1 + ;; + *) + usage + ;; + esac +done +shift $((OPTIND-1)) + + +if [ -z $relay ]; then + relay=$(git config nostr.relays) + if [[ $relay == "" ]]; then + unset relay + fi +fi + +if [ -z $1 ]; then + usage + exit 0 +fi + +commit=$1 +shift + +# this can be overridden +sec="$(git config nostr.secretkey)" +if [[ $sec != "" ]]; then + sec="--sec $sec" +fi + +patch="$(git format-patch --stdout $commit)" +subject=$(<<<"$patch" grep "^Subject:"| head -n1 | sed 's,^Subject: ,,') +author=$(<<<"$patch" grep "^From:"| head -n1 | sed 's,^From: ,,') +json=$(nostril --envelope $sec --kind 19691228 --tag author "$author" --tag subject "$subject" --content "$patch" "$@") + +id=$(jq -r '.[1].id' <<<"$json") + +if [ -n "$dryrun" ]; then + echo "$json" + printf "\nDRY RUN. printing event data\n" >&2 +elif [ -z "$relay" ]; then + echo "$json" + printf "\nRELAY NOT SET, not relaying. Use -r wss://relay.damus.io or 'git config --global nostr.relays wss://relay.damus.io'\n" >&2 +else + echo "$id" + printf "relaying to $relay using $NOSTR_RELAYER...\n" >&2 + <<<$json $NOSTR_RELAYER "$relay" +fi + +if [[ $sec == "" ]]; then + printf "NOSTR SECRET KEY NOT SET, using random key. Use --sec <key> or 'git config --global nostr.secretkey <hexkey>'\n" >&2 +fi diff --git a/git-show-nostr b/git-show-nostr @@ -0,0 +1,137 @@ +#!/usr/bin/env bash + +set -eo pipefail + +NOSTR_RELAYER=${NOSTR_RELAYER:-nostcat} +FUZZER=${FUZZER:-fzf} + +check_cmd() { + if ! command -v $1 >&2 >/dev/null; then + printf "error: $1 is required. please install. \n" + exit 0 + fi +} + +if ! command -v $NOSTR_RELAYER >&2 >/dev/null; then + printf "error: nostr relayer '%s' not found, set \$NOSTR_RELAYER or install '%s'\n" $NOSTR_RELAYER $NOSTR_RELAYER + exit 1 +fi + +if ! command -v $FUZZER >&2 >/dev/null; then + printf "error: fuzzer '%s' not found, set \$FUZZER or install '%s'\n" $FUZZER $FUZZER + exit 1 +fi + +check_cmd "nostril" +check_cmd "jq" + +usage() { + printf "usage: git-show-nostr [OPTIONS...]\n" + printf "\n" + printf "OPTIONS\n\n" + printf " -O output patches to a local file.\n" + printf " -o name output patches to a local file with a specific filename.\n" + printf " -r relay nostr relay to query. Uses 'git config nostr.relays' option by default\n" + printf "\n" + printf "Including query OPTIONS from nostril-query:\n\n" + nostril query -h | grep -A100 ^options: + exit 0 +} + +if [ "$1" == "--help" ]; then + usage + exit 1 +fi + +limit=20 + +while true; do +if [ -z $1 ]; then + break +fi +case "$1" in + -O) + writeout=1 + shift + ;; + -o) + writeout=1 + fname=$OPTARG + shift + ;; + -r) + relay=$2 + shift + shift + ;; + *) + break + ;; +esac +done + +if [ -z $relay ]; then + relay="$(git config nostr.relays)" +fi + +if [ -z $relay ]; then + usage + exit 0 +fi + +target=$tag + +fullquery=$(nostril query --kinds 19691228 --limit $limit "$@") + +if [ -z $fname ]; then + target=${target:-all} + outname="nostr-patches-$target.json" +else + outname=$fname +fi + +if [ -z $writeout ]; then + outname=$(mktemp) +fi + +echo "$fullquery" | $NOSTR_RELAYER $relay | jq -c '.[2]' > "$outname" + +if [ ! -z $writeout ]; then + printf "saved results to %s\n" "$outname" >&2 +fi + +pager="$(git config core.pager)" +if [ ! -t 1 ]; then + pager=cat +fi + +ev_count=$(wc -l < "$outname") +if [ $ev_count = 1 ]; then + jq -r .content "$outname" | $pager + exit 1 +fi + +dateformatter="" +if ! command -v datefmt >&2 >/dev/null; then + printf "install https://jb55.com/datefmt if you want nice relative timestamp formatting\n" >&2 + dateformatter=cat +else + dateformatter="datefmt --relative" +fi + +evid=$(jq -r ' +def tag(name): .tags[] | select(.[0] == name) | .[1]; + +. | [(.created_at | tostring), (.|tag("t")), (.|tag("author")), (.|tag("subject")), .pubkey[0:20], "id:\(.id)"] | @tsv' "$outname" | +sort -rn | +$dateformatter | +column -t -s $'\t' | +$FUZZER | +sed -E -n 's,.*id:(.*)$,\1,p' +) + +jq -r 'select(.id == "'$evid'") | .content' "$outname" | $pager + +if [ -z $writeout ]; then + rm -f "$outname" +fi