Preface 🌱

If you’ve ever used Deno, Go, or configured Android Studio, you’re familiar with configuring environment variables. So if we write a script or a command-line tool, how do we share it with our friends? The simplest, of course, is to simply put the script out there for someone to manually download and manually configure the environment variables. But this is neither elegant nor propagandizing. This article is a set of available binary executable distribution tutorials after reading up on Deno’s installation mechanism.

Deno supports cross-compilation in V1.7.0. This article uses Deno to implement a simple CLI tool and distribute it to MacOS, Linux, and Windows users.

Analysis of Deno installation modes

From the official website, we can see that Deno has a variety of installation methods, the main are:

  • With Shell (Linux/MacOS)curl -fsSL https://deno.land/x/install/install.sh | sh
  • With PowerShell (Windows) :iwr https://deno.land/x/install/install.ps1 -useb | iex
  • With Homebrew:brew install deno

You can also install specific versions:

  • With Shell: The curl - v1.0.0 fsSL https://deno.land/x/install/install.sh | sh - s
  • With PowerShell: $v = "1.0.0"; iwr https://deno.land/x/install/install.ps1 -useb | iex

Homebrew requires the installation script to be merged into Homebrew-core, but our scripts are generally relatively small, so you can refer to it. No way! Who doesn’t give out Homebrew packs? Publish to your tap. For Shell and PowerShell, that’s what we’ll look at in this article.

Prepare a project

I have a simple Deno project youngjuning/ Seve ready on my side. If you are interested in Deno development, can read Deno from entry to run | 🏆 technology introduction to project the first phase of the essay.

Compile the project

We can compile our project to a binary executable using the deno compile –unstable –target=

command. The optional targets are:

  • x86_64-unknown-linux-gnu
  • x86_64-pc-windows-msvc
  • x86_64-apple-darwin
  • aarch64-apple-darwin

We write a single compile.sh to batch compile the products for each platform (remember to run chmod +x 755 compile.sh to give the script executable permission).

#! /bin/bash
name="seve"
deno compile --unstable --lite --target=x86_64-unknown-linux-gnu index.ts
zip -o -q -m ${name}-x86_64-unknown-linux-gnu.zip ${name}

deno compile --unstable --lite --target=x86_64-pc-windows-msvc -o ./${name}.exe index.ts
zip -o -q -m ${name}-x86_64-pc-windows-msvc.zip ${name}.exe

deno compile --unstable --lite --target=x86_64-apple-darwin index.ts
zip -o -q -m ${name}-x86_64-apple-darwin.zip ${name}

deno compile --unstable --lite --target=aarch64-apple-darwin index.ts
zip -o -q -m ${name}-aarch64-apple-darwin.zip ${name}
Copy the code

The above script generates the following files, and we don’t need to upload them to the code base, so please ignore them in.gitignore.

Windows Installation Script

First let’s look at the script install.ps1 in deno_install:

#! /usr/bin/env pwsh
# Copyright 2018 the Deno authors. All rights reserved. MIT license.
# TODO(everyone): Keep this script simple and easily auditable.

$ErrorActionPreference = 'Stop'

if ($v) {
  $Version = "v${v}"
}
if ($args.Length -eq 1) {
  $Version = $args.Get(0)
}

$DenoInstall = $env:DENO_INSTALL
$BinDir = if ($DenoInstall) {
  "$DenoInstall\bin"
} else {
  "$Home\.deno\bin"
}

$DenoZip = "$BinDir\deno.zip"
$DenoExe = "$BinDir\deno.exe"
$Target = 'x86_64-pc-windows-msvc'

# GitHub requires TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$DenoUri = if (!$Version) {
  "https://github.com/denoland/deno/releases/latest/download/deno-${Target}.zip"
} else {
  "https://github.com/denoland/deno/releases/download/${Version}/deno-${Target}.zip"
}

if(! (Test-Path$BinDir)) {
  New-Item $BinDir -ItemType Directory | Out-Null
}

Invoke-WebRequest $DenoUri -OutFile $DenoZip -UseBasicParsing

if (Get-Command Expand-Archive -ErrorAction SilentlyContinue) {
  Expand-Archive $DenoZip -Destination $BinDir -Force
} else {
  if (Test-Path $DenoExe) {
    Remove-Item $DenoExe
  }
  Add-Type -AssemblyName System.IO.Compression.FileSystem
  [IO.Compression.ZipFile]::ExtractToDirectory($DenoZip.$BinDir)
}

Remove-Item $DenoZip

$User = [EnvironmentVariableTarget]::User
$Path = [Environment]::GetEnvironmentVariable('Path'.$User)
if(! (";$Path;".ToLower() -like "*;$BinDir; *".ToLower())) {
  [Environment]::SetEnvironmentVariable('Path'."$Path;$BinDir".$User)
  $Env:Path += ";$BinDir"
}

Write-Output "Deno was installed successfully to $DenoExe"
Write-Output "Run 'deno --help' to get started"
Copy the code

This is a PowerShell file. Without going into too much syntax here, let’s look at the core code:

.$Target = 'x86_64-pc-windows-msvc'.$DenoUri = if (!$Version) {
  "https://github.com/denoland/deno/releases/latest/download/deno-${Target}.zip"
} else {
  "https://github.com/denoland/deno/releases/download/${Version}/deno-${Target}.zip"
}
Copy the code

As you can see, the deno installation package is available as a GitHub Release zip and is versioned using Tag. Here is the attachment to the Deno 1.7.1 Release:

All of Deno’s build to publish steps are automatically implemented by GitHub Action, so I can write another post on how to parse Deno’s automation if you’re interested.

Customize the installation script

1. Manually create a Release and upload the above compiled compressed package as an attachment:

2, change the name in the above script to our own script:

If you have a CDN and you can upload it to a CDN, I’ll upload it to Github.

#! /usr/bin/env pwsh
# Copyright 2018 the Seve authors. All rights reserved. MIT license.
# TODO(everyone): Keep this script simple and easily auditable.

$ErrorActionPreference = 'Stop'

if ($v) {
  $Version = "v${v}"
}
if ($args.Length -eq 1) {
  $Version = $args.Get(0)
}

$SeveInstall = $env:SEVE_INSTALL
$BinDir = if ($SeveInstall) {
  "$SeveInstall\bin"
}
else {
  "$Home\.seve\bin"
}

$SeveZip = "$BinDir\seve.zip"
$SeveExe = "$BinDir\seve.exe"
$Target = 'x86_64-pc-windows-msvc'

# GitHub requires TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$DenoUri = if (!$Version) {
  "https://github.com/youngjuning/seve/releases/latest/download/seve-${Target}.zip"
}
else {
  "https://github.com/youngjuning/seve/releases/download/${Version}/seve-${Target}.zip"
}

if(! (Test-Path$BinDir)) {
  New-Item $BinDir -ItemType Directory | Out-Null
}

Invoke-WebRequest $DenoUri -OutFile $SeveZip -UseBasicParsing

if (Get-Command Expand-Archive -ErrorAction SilentlyContinue) {
  Expand-Archive $SeveZip -Destination $BinDir -Force
}
else {
  if (Test-Path $SeveExe) {
    Remove-Item $SeveExe
  }
  Add-Type -AssemblyName System.IO.Compression.FileSystem
  [IO.Compression.ZipFile]::ExtractToDirectory($SeveZip.$BinDir)
}

Remove-Item $SeveZip

$User = [EnvironmentVariableTarget]::User
$Path = [Environment]::GetEnvironmentVariable('Path'.$User)
if(! (";$Path;".ToLower() -like "*;$BinDir; *".ToLower())) {
  [Environment]::SetEnvironmentVariable('Path'."$Path;$BinDir".$User)
  $Env:Path += ";$BinDir"
}

Write-Output "Seve was installed successfully to $SeveExe"
Write-Output "Run 'seve --help' to get started"
Copy the code

3. Installation script

Install the latest version
iwr https://youngjuning.js.org/seve/install.ps1 -useb | iex
Install the specified version
$v="1.0.0"; iwr https://deno.land/x/install/install.ps1 -useb | iex
Copy the code

Unix-like installation script

First let’s take a look at the script install.sh in deno_install:

#! /bin/sh
# Copyright 2019 the Deno authors. All rights reserved. MIT license.
# TODO(everyone): Keep this script simple and easily auditable.

set -e

if ! command -v unzip >/dev/null; then
	echo "Error: unzip is required to install Deno (see: https://github.com/denoland/deno_install#unzip-is-required)."> 1 & 2exit 1
fi

if [ "$OS" = "Windows_NT" ]; then
	target="x86_64-pc-windows-msvc"
else
	case $(uname -sm) in
	"Darwin x86_64") target="x86_64-apple-darwin" ;;
	"Darwin arm64") target="aarch64-apple-darwin" ;;
	*) target="x86_64-unknown-linux-gnu" ;;
	esac
fi

if [ $# -eq 0 ]; then
	deno_uri="https://github.com/denoland/deno/releases/latest/download/deno-${target}.zip"
else
	deno_uri="https://github.com/denoland/deno/releases/download/The ${1}/deno-${target}.zip"
fi

deno_install="${DENO_INSTALL:-$HOME/.deno}"
bin_dir="$deno_install/bin"
exe="$bin_dir/deno"

if [ ! -d "$bin_dir" ]; then
	mkdir -p "$bin_dir"
fi

curl --fail --location --progress-bar --output "$exe.zip" "$deno_uri"
unzip -d "$bin_dir" -o "$exe.zip"
chmod +x "$exe"
rm "$exe.zip"

echo "Deno was installed successfully to $exe"
if command -v deno >/dev/null; then
	echo "Run 'deno --help' to get started"
else
	case $SHELL in
	/bin/zsh) shell_profile=".zshrc" ;;
	*) shell_profile=".bash_profile" ;;
	esac
	echo "Manually add the directory to your \$HOME/$shell_profile (or similar)"
	echo "  export DENO_INSTALL=\"$deno_install\ ""
	echo " export PATH=\"\$DENO_INSTALL/bin:\$PATH\""
	echo "Run '$exe --help' to get started"
fi
Copy the code

The installation script above is the familiar Shell script, the core code:

if [ "$OS" = "Windows_NT" ]; then
	target="x86_64-pc-windows-msvc"
else
	case $(uname -sm) in
	"Darwin x86_64") target="x86_64-apple-darwin" ;;
	"Darwin arm64") target="aarch64-apple-darwin" ;;
	*) target="x86_64-unknown-linux-gnu" ;;
	esac
fi
Copy the code

As you can see, $(uname-sm) represents the system architecture, which allows the script to dynamically determine which platform scripts to install.

Custom script

I’ve talked about you before, so I won’t go into more detail here.

1, change the name in the above script to our own script and upload it to the appropriate place:

Here we add the ability to set environment variables automatically. PS: The Deno writer rejected my PR in order to keep the script concise.

#! /bin/sh
# Copyright 2021 the Seve authors. All rights reserved. MIT license.
# TODO(everyone): Keep this script simple and easily auditable.

set -e

if ! command -v unzip >/dev/null; then
	echo "Error: unzip is required to install Seve (see: https://github.com/youngjuning/seve#unzip-is-required)."> 1 & 2exit 1
fi

if [ "$OS" = "Windows_NT" ]; then
	target="x86_64-pc-windows-msvc"
else
	case $(uname -sm) in
	"Darwin x86_64") target="x86_64-apple-darwin" ;;
	"Darwin arm64") target="aarch64-apple-darwin" ;;
	*) target="x86_64-unknown-linux-gnu" ;;
	esac
fi

if [ $# -eq 0 ]; then
	seve_uri="https://github.com/youngjuning/seve/releases/latest/download/seve-${target}.zip"
else
	seve_uri="https://github.com/youngjuning/seve/releases/download/The ${1}/seve-${target}.zip"
fi

seve_install="${SEVE_INSTALL:-$HOME/.seve}"
bin_dir="$seve_install/bin"
exe="$bin_dir/seve"

if [ ! -d "$bin_dir" ]; then
	mkdir -p "$bin_dir"
fi

curl --fail --location --progress-bar --output "$exe.zip" "$seve_uri"
unzip -d "$bin_dir" -o "$exe.zip"
chmod +x "$exe"
rm "$exe.zip"

echo "Seve was installed successfully to $exe"
if command -v seve >/dev/null; then
	echo "Run 'seve --help' to get started"
else
	case $SHELL in
	/bin/zsh) shell_profile=".zshrc" ;;
	*) shell_profile=".bash_profile" ;;
	esac
	echo "# Seve" >> $HOME/$shell_profile
	echo "export SEVE_INSTALL=\"$seve_install\ "" >> $HOME/$shell_profile
	echo "export PATH=\"\$SEVE_INSTALL/bin:\$PATH\"" >> $HOME/$shell_profile
	source $HOME/$shell_profile
	echo "Run 'seve' to get started"
fi
Copy the code

2. Installation script

Install the latest version
curl -fsSL https://youngjuning.js.org/seve/install.sh | sh
Install the specified versionThe curl - v0.0.1 fsSL https://youngjuning.js.org/seve/install.sh | sh - sCopy the code

So far we have implemented our own script management, sample code in Youngjuning /seve, if helpful, welcome to Star.

Domestic accelerated

This is another story, and we can do a copy of it just like the JustJavac boss did in JustJavac/deno_Releases. Different from the original script, the CDN acceleration is made based on jsdelivr.

Due to the 20M limit of JSDeliver, I opened a warehouse on coding. You can use https://youngjuning.js.org/deno/install.sh and https://youngjuning.js.org/deno/install.ps1 script to install. Thanks for reminding us in the comments section. Use the same way as deno, replace the link.

trailer

  • Powershell Programming Basics
  • Deno GitHub Action Automates process resolution
  • Deno Getting started with CLI development

Doodle Smart has a large number of high-quality HC, welcome to join, you need to add my wechat yang_jun_ning, or directly send your resume to [email protected]