scripts/release-npm.sh
#!/usr/bin/env bash
set -euxo pipefail

error() {
	echo "$@" >&2
	exit 1
}

if [[ -z ${NODE_AUTH_TOKEN:-} ]]; then
	echo "NODE_AUTH_TOKEN must be set" >&2
	exit 0
fi

mkdir -p "$RELEASE_DIR/npm"

dist_tag_from_version() {
	IFS="-" read -r -a version_split <<<"$1"
	IFS="." read -r -a version_split <<<"${version_split[1]:-latest}"
	echo "${version_split[0]}"
}
dist_tag="$(dist_tag_from_version "$MISE_VERSION")"

platforms=(
	linux-x64
	linux-x64-musl
	linux-arm64
	linux-arm64-musl
	linux-armv7
	linux-armv7-musl
	macos-x64
	macos-arm64
)
for platform in "${platforms[@]}"; do
	# shellcheck disable=SC2206
	platform_split=(${platform//-/ })
	os="${platform_split[0]}"
	arch="${platform_split[1]}"

	if [[ $os == "macos" ]]; then
		os="darwin"
	fi

	cp "$RELEASE_DIR/$MISE_VERSION/mise-$MISE_VERSION-$platform.tar.gz" "$RELEASE_DIR/mise-latest-$platform.tar.gz"
	cp "$RELEASE_DIR/$MISE_VERSION/mise-$MISE_VERSION-$platform.tar.xz" "$RELEASE_DIR/mise-latest-$platform.tar.xz"
	tar -xzvf "$RELEASE_DIR/mise-latest-$platform.tar.gz" -C "$RELEASE_DIR"
	rm -rf "$RELEASE_DIR/npm"
	mv "$RELEASE_DIR/mise" "$RELEASE_DIR/npm"
	cat <<EOF >"$RELEASE_DIR/npm/package.json"
{
  "name": "$NPM_PREFIX-$os-$arch",
  "version": "$MISE_VERSION",
  "description": "polyglot runtime manager",
  "bin": {
    "mise": "bin/mise"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/jdx/mise"
  },
  "files": [
    "bin",
    "README.md"
  ],
  "license": "MIT",
  "os": "$os",
  "cpu": "$arch"
}
EOF
	pushd "$RELEASE_DIR/npm"
	tree || true
	if [ "$DRY_RUN" != "0" ]; then
		echo DRY_RUN
		echo npm publish --access public --tag "$dist_tag"
		echo DRY_RUN
	else
		npm publish --access public --tag "$dist_tag" || true
	fi
	popd
done

cat <<EOF >"$RELEASE_DIR/npm/installArchSpecificPackage.js"
var spawn = require('child_process').spawn;
var path = require('path');
var fs = require('fs');

function installArchSpecificPackage(version) {

    process.env.npm_config_global = 'false';

    var platform = process.platform == 'win32' ? 'windows' : process.platform;
    var arch = platform == 'windows' && process.arch == 'ia32' ? 'x86' : process.arch;

    var cp = spawn(platform == 'windows' ? 'npm.cmd' : 'npm', ['install', '--no-save', ['$NPM_PREFIX', platform, arch].join('-') + '@' + version], {
        stdio: 'inherit',
        shell: true
    });

    cp.on('close', function(code) {
        var pkgJson = require.resolve(['$NPM_PREFIX', platform, arch].join('-') + '/package.json');
        var subpkg = JSON.parse(fs.readFileSync(pkgJson, 'utf8'));
        var executable = subpkg.bin.mise;
        var bin = path.resolve(path.dirname(pkgJson), executable);

        try {
            fs.mkdirSync(path.resolve(process.cwd(), 'bin'));
        } catch (e) {
            if (e.code != 'EEXIST') {
                throw e;
            }
        }

        linkSync(bin, path.resolve(process.cwd(), executable));

        if (platform == 'windows') {
            var pkg = JSON.parse(fs.readFileSync(path.resolve(process.cwd(), 'package.json')));
            fs.writeFileSync(path.resolve(process.cwd(), 'bin/mise'), 'This file intentionally left blank');
            pkg.bin.mise = 'bin/mise.exe';
            fs.writeFileSync(path.resolve(process.cwd(), 'package.json'), JSON.stringify(pkg, null, 2));
        }

        return process.exit(code);

    });
}

function linkSync(src, dest) {
    try {
        fs.unlinkSync(dest);
    } catch (e) {
        if (e.code != 'ENOENT') {
            throw e;
        }
    }
    return fs.linkSync(src, dest);
}

const pjson = require('./package.json')
installArchSpecificPackage(pjson.version)
EOF

cat <<EOF >"$RELEASE_DIR/npm/package.json"
{
  "name": "$NPM_PREFIX",
  "description": "polyglot runtime manager",
  "version": "$MISE_VERSION",
  "repository": {
    "type": "git",
    "url": "https://github.com/jdx/mise"
  },
  "files": [
    "installArchSpecificPackage.js",
    "README.md"
  ],
  "scripts": {
    "prepack": "rm -rf bin",
    "preinstall": "node installArchSpecificPackage.js"
  },
  "bin": {
    "mise": "./bin/mise"
  },
  "license": "MIT",
  "engines": {
    "node": ">=5.0.0"
  }
}
EOF
pushd "$RELEASE_DIR/npm"
if [ "$DRY_RUN" != "0" ]; then
	echo DRY_RUN
	echo npm publish --access public --tag "$dist_tag"
	echo DRY_RUN
else
	npm publish --access public --tag "$dist_tag" || true
fi
popd
