#PKG_ARCHES=
#PKG_FORMATS=
WEBI_UA="$(uname -a)"
+ WEBI_PKG_DOWNLOAD=""
export WEBI_HOST
##
my_dl="$HOME/Downloads/$WEBI_PKG_FILE"
fi
+ WEBI_PKG_DOWNLOAD="${my_dl}"
+ export WEBI_PKG_DOWNLOAD
+
if [ -e "$my_dl" ]; then
echo "Found $my_dl"
return 0
--- /dev/null
+# title: GnuPG (gpg alias)
+# homepage: https://webinstall.dev/gpg
+# tagline: Alias for https://webinstall.dev/gpg
+# alias: gpg
+# description: |
+# See https://webinstall.dev/gpg
+
+echo "'gnupg@${WEBI_TAG:-stable}' is an alias for 'gpg@${WEBI_VERSION:-}'"
+WEBI_HOST=${WEBI_HOST:-"https://webinstall.dev"}
+curl -fsSL "$WEBI_HOST/gpg@${WEBI_VERSION:-}" | bash
--- /dev/null
+---
+title: Gnu Privacy Guard
+homepage: https://gnupg.org/
+tagline: |
+ GnuPG: a complete implementation of OpenPGP (RFC4880), also known as **P**retty **G**ood **P**rivacy.
+---
+
+### Before you start
+
+If `~/.gitconfig` exists and has both `name` and `email` fields, then a new gpg
+key will be created after the install. Otherwise, you'll have to create one
+yourself.
+
+## Cheat Sheet
+
+> Among other things, gpg is particularly useful for signing and verifying git
+> commits (and emails too).
+
+Here we'll cover:
+
+- Important GPG Files & Directories
+- Creating New Keys
+- Listing Keys
+- Signing Git Commits
+- Exporting GPG Keys for GitHub
+- Publishing GPG Keys to "the Blockchain"
+- Running GPG Agent with launchd
+
+### Files
+
+These are the files / directories that are created and/or modified with this
+install:
+
+```txt
+~/.config/envman/PATH.env
+~/.local/opt/gnupg/bin/gpg
+~/.local/opt/gnupg/bin/gpg-agent
+~/.local/opt/gnupg/bin/pinentry-mac.app/Contents/MacOS/pinentry-mac
+~/.gnupg/gpg-agent.conf
+~/Library/LaunchAgent/gpg-agent.plist
+```
+
+### How to create a new GPG key
+
+See the [Cheat Sheet](./gpg-pubkey) at [gpg-pubkey](./gpg-pubkey).
+
+### How to List GPG Key(s)
+
+```bash
+gpg --list-secret-keys --keyid-format LONG
+```
+
+### How to configure git to sign commits
+
+See the [Cheat Sheet](./git-gpg-init) at [gpg-pubkey](./git-gpg-init).
+
+### How to Export GPG Key for GitHub
+
+See the [Cheat Sheet](./gpg-pubkey) at [gpg-pubkey](./gpg-pubkey).
+
+### How to Publish GPG Keys
+
+GPG is the OG "blockchain", as it were.
+
+If you'd like to publish your (public) key(s) to the public Key Servers for time
+and all eternity, you can:
+
+```bash
+gpg --send-keys "${MY_KEY_ID}"
+```
+
+(no IPFS needed 😉)
+
+### How to start gpg-agent with launchd
+
+(**Note**: this is **done for you** on install, but provided here for reference)
+
+It's a trick question: You can't.
+
+You need to use `gpg-connect-agent` instead.
+
+`~/Library/LaunchAgents/gpg-agent.plist`:
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Label</key>
+ <string>gpg-agent</string>
+ <key>ProgramArguments</key>
+ <array>
+ <string>MY_HOME/.local/opt/gpg/bin/gpg-connect-agent</string>
+ <string>--agent-program</string>
+ <string>MY_HOME/.local/opt/gnupg/bin/gpg-agent</string>
+ <string>--homedir</string>
+ <string>MY_HOME/.gnupg/</string>
+ <string>/bye</string>
+ </array>
+
+ <key>RunAtLoad</key>
+ <true/>
+
+ <key>WorkingDirectory</key>
+ <string>MY_HOME</string>
+
+ <key>StandardErrorPath</key>
+ <string>MY_HOME/.local/share/gpg-agent/var/log/gpg-agent.log</string>
+ <key>StandardOutPath</key>
+ <string>MY_HOME/.local/share/gpg-agent/var/log/gpg-agent.log</string>
+</dict>
+</plist>
+```
+
+And then start it with launchctl:
+
+```bash
+launchctl load -w ~/Library/LaunchAgents/gpg-agent.plist
+```
+
+### Troubleshooting 'gpg failed to sign the data'
+
+`gpg` is generally expected to be used with a Desktop client. On Linux servers
+you may get this error:
+
+```txt
+error: gpg failed to sign the data
+fatal: failed to write commit object
+```
+
+Try to load the `gpg-agent`, set `GPG_TTY`, and then run a clearsign test.
+
+```bash
+gpg-connect-agent /bye
+export GPG_TTY=$(tty)
+echo "test" | gpg --clearsign
+```
+
+If that works, update your `~/.bashrc`, `~/.zshrc`, and/or
+`~/.config/fish/config.fish` to include the following:
+
+```bash
+gpg-connect-agent /bye
+export GPG_TTY=$(tty)
+```
+
+If this is failing on Mac or Windows, then `gpg-agent` is not starting as
+expected on login (for Mac the above may work), and/or the `pinentry` command is
+not in the PATH.
+
+If you just installed `gpg`, try closing and reopening your Terminal, or
+possibly rebooting.
--- /dev/null
+#!/usr/bin/env pwsh
+
+echo "We don't yet have a way to automate the GnuPG Tools installer at the user level. In the meantime, try this:"
+echo ""
+echo " https://gnupg.org/download/#binary"
+echo ""
--- /dev/null
+#!/bin/bash
+
+set -e
+set -u
+
+function _install_gpg() {
+ if ! (uname -a | grep -i "darwin" > /dev/null); then
+ echo "No gpg installer for Linux yet. Try this instead:"
+ echo " sudo apt install -y gpg gnupg"
+ exit 1
+ fi
+
+ # Download the latest LTS
+ #curl -fsSL -o ~/Downloads/GnuPG-2.2.32.dmg 'https://sourceforge.net/projects/gpgosx/files/GnuPG-2.2.32.dmg/download'
+ webi_download
+ chmod a-w "${WEBI_PKG_DOWNLOAD}"
+
+ # Mount the DMG in /Volumes
+ hdiutil detach -quiet /Volumes/GnuPG* 2> /dev/null || true
+ hdiutil attach -quiet -readonly "${WEBI_PKG_DOWNLOAD}"
+
+ # Extract (completely) to ~/Downloads/GnuGP-VERSION.d
+ # (and detach the DMG)
+ rm -rf ~/Downloads/GnuPG-"${WEBI_VERSION}".d
+ pkgutil --expand-full /Volumes/GnuPG*/*.pkg ~/Downloads/GnuPG-"${WEBI_VERSION}".d
+ hdiutil detach -quiet /Volumes/GnuPG*
+
+ # Move to ~/.local/opt/gnugp (where it belongs!)
+ if [[ ! -e ~/.local/opt/gnupg-"${WEBI_VERSION}" ]]; then
+ mv ~/Downloads/GnuPG-"${WEBI_VERSION}".d/GnuPG.pkg/Payload/ ~/.local/opt/gnupg-"${WEBI_VERSION}"
+ fi
+
+ # Update symlink to latest
+ rm -rf ~/.local/opt/gnupg
+ ln -s gnupg-"${WEBI_VERSION}" ~/.local/opt/gnupg
+
+ pathman add ~/.local/opt/gnupg/bin
+ export PATH="$HOME/.local/opt/gnupg/bin/:$PATH"
+
+ # Prep for first use
+ mkdir -p ~/.gnupg/
+ chmod 0700 ~/.gnupg/
+ if [[ ! -e ~/.gnupg/gpg-agent.conf ]] || ! grep 'pinentry-program' ~/.gnupg/gpg-agent.conf; then
+ echo "pinentry-program $HOME/.local/opt/gnupg/bin/pinentry-mac.app/Contents/MacOS/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
+ fi
+
+ # Start with launchd
+ mkdir -p ~/Library/LaunchAgents/
+ launchctl unload -w ~/Library/LaunchAgents/gpg-agent.plist 2> /dev/null || true
+ # TODO download and use sed to replace
+ echo '<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>Label</key>
+ <string>gpg-agent</string>
+ <key>ProgramArguments</key>
+ <array>
+ <string>'"${HOME}"'/.local/opt/gpg/bin/gpg-connect-agent</string>
+ <string>--agent-program</string>
+ <string>'"${HOME}"'/.local/opt/gnupg/bin/gpg-agent</string>
+ <string>--homedir</string>
+ <string>'"${HOME}"'/.gnupg/</string>
+ <string>/bye</string>
+ </array>
+
+ <key>RunAtLoad</key>
+ <true/>
+
+ <key>WorkingDirectory</key>
+ <string>'"${HOME}"'</string>
+
+ <key>StandardErrorPath</key>
+ <string>'"${HOME}"'/.local/share/gpg-agent/var/log/gpg-agent.log</string>
+ <key>StandardOutPath</key>
+ <string>'"${HOME}"'/.local/share/gpg-agent/var/log/gpg-agent.log</string>
+</dict>
+</plist>' > ~/Library/LaunchAgents/gpg-agent.plist
+ launchctl load -w ~/Library/LaunchAgents/gpg-agent.plist
+ sleep 3
+
+ # (maybe) Create first key
+ if ! gpg --list-secret-keys | grep -q sec; then
+ _create_gpg_key
+ fi
+}
+
+function _create_gpg_key() {
+ if [[ ! -e ~/.gitconfig ]]; then
+ return 0
+ fi
+
+ MY_NAME="$(
+ grep 'name\s*=' ~/.gitconfig |
+ head -n 1 |
+ cut -d'=' -f2 |
+ sed -e 's/^[\t ]*//'
+ )"
+ if [[ -z ${MY_NAME} ]]; then
+ return 0
+ fi
+
+ MY_EMAIL="$(
+ grep 'email\s*=.*@' ~/.gitconfig |
+ tr -d '\t ' | head -n 1 |
+ cut -d'=' -f2
+ )"
+ if [[ -z ${MY_EMAIL} ]]; then
+ return 0
+ fi
+
+ MY_HOST="$(hostname)"
+
+ # Without passphrase:
+ #gpg --batch --generate-key --pinentry=loopback --passphrase=''
+
+ # With passphrase via macOS Keychain
+ gpg --batch --yes --generate-key << EOF
+ %echo Generating RSA 3072 key
+ Key-Type: RSA
+ Key-Length: 3072
+ Subkey-Type: RSA
+ Subkey-Length: 3072
+ Name-Real: ${MY_NAME}
+ Name-Comment: ${MY_HOST}
+ Name-Email: ${MY_EMAIL}
+ Expire-Date: 0
+ %commit
+EOF
+
+}
+
+_install_gpg
--- /dev/null
+'use strict';
+
+let ltsRe = /GnuPG-(2\.2\.[\d\.]+)/;
+
+function createRssMatcher() {
+ return new RegExp(
+ '<link>(https://sourceforge\\.net/projects/gpgosx/files/GnuPG-([\\d\\.]+)\\.dmg/download)</link>',
+ 'g'
+ );
+}
+
+function createUrlMatcher() {
+ return new RegExp(
+ 'https://sourceforge\\.net/projects/gpgosx/files/(GnuPG-([\\d\\.]+)\\.dmg)/download',
+ ''
+ );
+}
+
+async function getRawReleases(request) {
+ let matcher = createRssMatcher();
+
+ let resp = await request({
+ url: 'https://sourceforge.net/projects/gpgosx/rss?path=/'
+ });
+ let links = [];
+ for (;;) {
+ let m = matcher.exec(resp.body);
+ if (!m) {
+ break;
+ }
+ links.push(m[1]);
+ }
+ return links;
+}
+
+function transformReleases(links) {
+ //console.log(JSON.stringify(links, null, 2));
+ //console.log(links.length);
+
+ let matcher = createUrlMatcher();
+
+ let releases = links
+ .map(function (link) {
+ // strip 'go' prefix, standardize version
+ let isLts = ltsRe.test(link);
+ let parts = link.match(matcher);
+ if (!parts || !parts[2]) {
+ return null;
+ }
+ let segs = parts[2].split('.');
+ let version = segs.slice(0, 3).join('.');
+ if (segs.length > 3) {
+ version += '+' + segs.slice(3);
+ }
+
+ return {
+ name: parts[1],
+ version: version,
+ // all go versions >= 1.0.0 are effectively LTS
+ lts: isLts,
+ channel: 'stable',
+ // TODO <pubDate>Sat, 19 Nov 2016 16:17:33 UT</pubDate>
+ date: '1970-01-01', // the world may never know
+ os: 'macos',
+ arch: 'amd64',
+ ext: 'dmg',
+ download: link
+ };
+ })
+ .filter(Boolean);
+
+ return {
+ releases: releases
+ };
+}
+
+async function getAllReleases(request) {
+ let releases = await getRawReleases(request);
+ let all = transformReleases(releases);
+ return all;
+}
+
+module.exports = getAllReleases;
+
+if (module === require.main) {
+ getAllReleases(require('@root/request')).then(function (all) {
+ all = require('../_webi/normalize.js')(all);
+ all.releases = all.releases.slice(0, 10000);
+ console.info(JSON.stringify(all, null, 2));
+ });
+}