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]