]> Cypherpunks.ru repositories - prepro.git/commitdiff
Initial commit
authorSergey Matveev <stargrave@stargrave.org>
Mon, 14 Aug 2023 15:07:43 +0000 (18:07 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Mon, 14 Aug 2023 15:07:43 +0000 (18:07 +0300)
README [new file with mode: 0644]
USAGE [new file with mode: 0644]
go.mod [new file with mode: 0644]
go.sum [new file with mode: 0644]
main.go [new file with mode: 0644]
mk-goget [new file with mode: 0755]
mk-list [new file with mode: 0755]
mk-mod [new file with mode: 0755]

diff --git a/README b/README
new file mode 100644 (file)
index 0000000..622ec91
--- /dev/null
+++ b/README
@@ -0,0 +1,32 @@
+prepro -- prepare GOPROXY and go-import friendly website
+
+Go modules (https://go.dev/ref/mod), that are not located on hard-coded
+well-known hosting platforms like GitHub, are discovered by go-get using
+the go-import-protocol: it requests special URL, based on module's name,
+to get HTML with <meta name="go-import"> tag. That tag will redirect
+go-get further either to VCS, or to GOPROXY-capable URL.
+
+If VCS is in use, then go-get will invoke external utilities to checkout
+the code from VCS. After that, it will create ZIP-archive with the
+snapshot of the code and store it locally in cache directory.
+
+GOPROXY protocol can be treated just like a HTTP-transport to that cache
+directory. Only several prepared static files per each module's version
+is enough.
+
+* VCS solution is usually quicker to setup, because development VCS
+  repositories are publicly available in most cases too
+* VCS requires corresponding external tools to be installed. Hardly
+  either Fossil or GNU Bazaar are often installed on many systems
+* VCS checkout requires more disk space: for the VCS itself and for the
+  cached module's archive
+* VCS is slower to check and download in general, because it requires
+  several round-trips during the handshake between server and client
+* GOPROXY is easier to scale on multiple hosts, because you have to
+  replicate only several static files
+
+Another advantage of GOPROXY is actually the reason why "prepro" was
+born: current go-get can not handle SHA256-driven Git repositories. It
+git-init-s empty repository first and then tries to git-fetch it, that
+won't work if git-init was not aware of SHA256-based format. GOPROXY
+gives easy ability to make that module's repository publicly fetchable.
diff --git a/USAGE b/USAGE
new file mode 100644 (file)
index 0000000..ea0d790
--- /dev/null
+++ b/USAGE
@@ -0,0 +1,23 @@
+mk-mod utility creates GOPROXY-compatible version of the module in the
+current directory:
+    mk-mod VCS-URL VCS-PATH MODULE-NAME VERSION.
+Only Git VCS is supported. Git tag's name must be equal to VERSION.
+
+mk-list utility collects all known versions in current GOPROXY directory
+and creates corresponding "list" files.
+
+mk-goget creates go-import-compatible static files:
+    mk-goget VCS-WEB-URL MODULE-NAME.
+
+For example:
+    mkdir proxy
+    cd proxy
+    mk-mod https://git.cypherpunks.ru/balloon.git ~w/balloon go.cypherpunks.ru/balloon v1.1.1
+    mk-mod https://git.cypherpunks.ru/balloon.git ~w/balloon go.cypherpunks.ru/balloon/v2 v2.0.0
+    mk-list
+    cd ..
+
+    mkdir goget
+    cd goget
+    mk-goget "http://www.git.cypherpunks.ru/?p=balloon.git" go.cypherpunks.ru/balloon
+    mk-goget "http://www.git.cypherpunks.ru/?p=balloon.git" go.cypherpunks.ru/balloon/v2
diff --git a/go.mod b/go.mod
new file mode 100644 (file)
index 0000000..5e62cbd
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
+module go.cypherpunks.ru/prepro
+
+go 1.21.0
+
+require golang.org/x/mod v0.12.0
diff --git a/go.sum b/go.sum
new file mode 100644 (file)
index 0000000..6a42504
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,4 @@
+golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
diff --git a/main.go b/main.go
new file mode 100644 (file)
index 0000000..2a0524b
--- /dev/null
+++ b/main.go
@@ -0,0 +1,26 @@
+package main
+
+import (
+       "flag"
+       "log"
+       "os"
+
+       "golang.org/x/mod/module"
+       "golang.org/x/mod/zip"
+)
+
+func main() {
+       modName := flag.String("mod", "", "Module name")
+       version := flag.String("version", "", "Version")
+       root := flag.String("vcs", "", "Path to VCS root")
+       sub := flag.String("sub", "", "Optional subdirectory path")
+       flag.Parse()
+       err := zip.CreateFromVCS(
+               os.Stdout,
+               module.Version{Path: *modName, Version: *version},
+               *root, *version, *sub,
+       )
+       if err != nil {
+               log.Fatal(err)
+       }
+}
diff --git a/mk-goget b/mk-goget
new file mode 100755 (executable)
index 0000000..850103e
--- /dev/null
+++ b/mk-goget
@@ -0,0 +1,24 @@
+#!/usr/bin/env zsh
+
+set -e
+
+vcsurl=$1
+modname=$2
+
+cols=(${(s#/#)modname})
+[[ ${cols[-1]} =~ v[0-9]+ ]] || cols=($cols v1)
+moddir=${(j:/:)cols[1,-2]}
+v=${cols[-1]}
+[[ -s $moddir/$v ]] && exit
+mkdir -p $moddir
+cat > $moddir/$v <<EOF
+<!DOCTYPE html>
+<html>
+<head>
+<meta name="go-import" content="$modname mod https://proxy.${cols[1]}">
+<head>
+<body>
+<a href="$vcsurl">$modname</a>
+</body>
+</html>
+EOF
diff --git a/mk-list b/mk-list
new file mode 100755 (executable)
index 0000000..67cbc44
--- /dev/null
+++ b/mk-list
@@ -0,0 +1,11 @@
+#!/usr/bin/env zsh
+
+set -e
+setopt EXTENDED_GLOB
+for d (**/*(/)) {
+    list=()
+    for f ($d/*.info(onN)) list=($list $f:t:r)
+    [[ ${#list} != 0 ]] || continue
+    print ${(F)list} > $d/list
+    touch -r $d/${list[-1]}.info $d/list
+}
diff --git a/mk-mod b/mk-mod
new file mode 100755 (executable)
index 0000000..ba13815
--- /dev/null
+++ b/mk-mod
@@ -0,0 +1,32 @@
+#!/usr/bin/env zsh
+
+set -e
+
+vcsurl=$1
+vcspath=$2
+modname=$3
+version=$4
+
+dst=$modname/@v
+mkdir -p $dst
+cd $dst
+[[ -s $version.zip ]] && exit
+
+prepro=$0:h:a/prepro
+zmodload -F zsh/datetime b:strftime
+git -C $vcspath cat-file -p $version | while read line ; do
+    [[ $line =~ ^object ]] && hsh=${${=line}[-1]}
+    [[ $line =~ ^tagger ]] && {
+        strftime -s sec -r "%s %z" "${${=line}[-2,-1]}"
+        break
+    }
+done
+[[ -n $hsh ]]
+[[ -n $sec ]]
+strftime -s when %Y-%m-%dT%H:%M:%SZ $sec
+
+$prepro -vcs $vcspath -mod $modname -version $version > $version.zip
+unzip -p $version.zip ${modname}@${version}/go.mod > $version.mod
+printf '{"Version":"%s","Time":"%s","Origin":{"VCS":"git","URL":"%s","Ref":"refs/tags/%s","Hash":"%s"}}' \
+    $version $when $vcsurl $version $hsh > $version.info
+touch -d $when $version.info $version.mod $version.zip