Skip to content

Instantly share code, notes, and snippets.

@mattt
Created June 18, 2020 15:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattt/e212ae74adf848a450345e31e25e7911 to your computer and use it in GitHub Desktop.
Save mattt/e212ae74adf848a450345e31e25e7911 to your computer and use it in GitHub Desktop.
An example of how Git can be used as a transparent log for a package registry
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
# Returns the SHA-256 checksum of a string or file
function checksum() {
if [ -f "$1" ]; then
shasum -a 256 "$1" | cut -d ' ' -f1
else
echo "$1" | shasum -a 256 | cut -d ' ' -f1
fi
}
# Returns the content-addressable path for a qualified package name
function path() {
checksum "$1" | sed 's_._&/_2;s_._&/_5;s_._&/_8'
}
# Setup git repository
(
if [ ! -d .git ]; then
git init .
git lfs install
fi
if [ ! -f .gitattributes ]; then
cat >.gitattributes <<EOF
*.zip filter=lfs diff=lfs merge=lfs -text
*.asc binary
EOF
git add .gitattributes
git commit -m "Add .gitattributes"
fi
)
# Add a package release
(
author="Mattt <mattt@me.com>"
package="Flight-School/Money"
version="1.2.0"
mkdir -p "$(path $package)"
archive="$(path $package)/$version.zip"
if [ ! -f "$archive" ]; then
head -c 12345 </dev/urandom >"$archive"
fi
if [ ! -f "$archive.asc" ]; then
gpg --armor --detach-sign --output "$archive.asc" "$archive"
fi
git add "$(path $package)"
git commit -m "sha-256=$(checksum "$archive")" -s --author "$author"
)
# Add release metadata using git notes
(
metadata=$(mktemp)
cat >"$metadata" <<EOF
{
"url": "https://github.com/Flight-School/Money"
}
EOF
git notes add -F "$metadata"
rm -f "$metadata"
)
# Show results with git log
git log
@mattt
Copy link
Author

mattt commented Jun 18, 2020

Example output:

$ tree .
.
├── 2e
│   └── 80
│       └── 6e
│           └── 827387c39e8c594053f5c90701dbb5b5aa00a83812cb0452b5695e45be
│               ├── 1.2.0.zip
│               └── 1.2.0.zip.asc
└── registry.bash

4 directories, 3 files

# Use git tree to lookup releases for a package (according to content-addressable path)
$ git ls-files "$(checksum "$package")" -x "*.zip"
2e/80/6e/827387c39e8c594053f5c90701dbb5b5aa00a83812cb0452b5695e45be/1.2.0.zip

# Verify that release archive hasn't been modified
$ git log --follow "$(checksum "$package")/1.2.0.zip" --oneline
792276c (HEAD -> master) sha-256=c584882ef498cc6e043e0f100134483dfa04ea2d5921f56

# Changing metadata associated with a release doesn't change the commit
$ git notes edit HEAD

$ git log
commit 792276c08c3dc33a1cad102a4a391886c1967c86 (HEAD -> master)
Author: Mattt <mattt@me.com>
Date:   Thu Jun 18 08:43:31 2020 -0700

    sha-256=c584882ef498cc6e043e0f100134483dfa04ea2d5921f56f32c54c290d88ab78
    
    Signed-off-by: Swift Package Notary <notary@swift.org>

Notes:
    {
        "url": "https://github.com/Flight-School/Money"
    }

commit e967111846d318f158f3fbdacc7016e328c5fb44
Author: Mattt <mattt@me.com>
Date:   Thu Jun 18 08:43:30 2020 -0700

    Add .gitattributes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment