Merge pull request #33 from starkSV/feat/install-script
feat: add curl | bash installer for Linux/macOS without Homebrew
This commit is contained in:
commit
2fae096b15
7 changed files with 99 additions and 0 deletions
1
.gitattributes
vendored
1
.gitattributes
vendored
|
|
@ -1,2 +1,3 @@
|
||||||
aur/msdl-bin/PKGBUILD text eol=lf
|
aur/msdl-bin/PKGBUILD text eol=lf
|
||||||
aur/msdl-bin/.SRCINFO text eol=lf
|
aur/msdl-bin/.SRCINFO text eol=lf
|
||||||
|
backend/install.sh text eol=lf
|
||||||
|
|
|
||||||
6
.github/workflows/cli-release.yml
vendored
6
.github/workflows/cli-release.yml
vendored
|
|
@ -73,6 +73,12 @@ jobs:
|
||||||
brew install msdl
|
brew install msdl
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**macOS/Linux (no Homebrew):**
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://api.msdl.tech-latest.com/install.sh | bash
|
||||||
|
```
|
||||||
|
Auto-detects OS/arch (including Termux on Android) and installs the latest release.
|
||||||
|
|
||||||
**Linux/macOS (direct download):**
|
**Linux/macOS (direct download):**
|
||||||
```bash
|
```bash
|
||||||
# Linux x86_64
|
# Linux x86_64
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,12 @@ brew tap starkSV/msdl
|
||||||
brew install msdl
|
brew install msdl
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**macOS / Linux (no Homebrew):**
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://api.msdl.tech-latest.com/install.sh | bash
|
||||||
|
```
|
||||||
|
Auto-detects OS/arch (including Termux on Android) and installs the latest release.
|
||||||
|
|
||||||
**Direct download:** Grab the latest binary from [GitHub Releases](https://github.com/starkSV/windows-iso-downloader/releases/latest) and rename it:
|
**Direct download:** Grab the latest binary from [GitHub Releases](https://github.com/starkSV/windows-iso-downloader/releases/latest) and rename it:
|
||||||
|
|
||||||
| Platform | File | Rename to |
|
| Platform | File | Rename to |
|
||||||
|
|
|
||||||
48
backend/install.sh
Normal file
48
backend/install.sh
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Installs the msdl CLI. Usage: curl -fsSL https://api.msdl.tech-latest.com/install.sh | bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO="starkSV/windows-iso-downloader"
|
||||||
|
|
||||||
|
os="$(uname -s)"
|
||||||
|
arch="$(uname -m)"
|
||||||
|
|
||||||
|
case "$os" in
|
||||||
|
Linux) platform="linux" ;;
|
||||||
|
Darwin) platform="darwin" ;;
|
||||||
|
*)
|
||||||
|
echo "msdl: unsupported OS: $os (Windows users: winget install starkSV.msdl)" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$arch" in
|
||||||
|
x86_64|amd64) goarch="amd64" ;;
|
||||||
|
aarch64|arm64) goarch="arm64" ;;
|
||||||
|
*)
|
||||||
|
echo "msdl: unsupported architecture: $arch" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
asset="msdl-${platform}-${goarch}"
|
||||||
|
url="https://github.com/${REPO}/releases/latest/download/${asset}"
|
||||||
|
|
||||||
|
tmp="$(mktemp)"
|
||||||
|
echo "Downloading ${asset}..."
|
||||||
|
curl -fsSL "$url" -o "$tmp"
|
||||||
|
chmod +x "$tmp"
|
||||||
|
|
||||||
|
if [ -n "${PREFIX:-}" ] && [ -d "${PREFIX}/bin" ]; then
|
||||||
|
# Termux (or similar $PREFIX-based environment) -- no sudo available or needed
|
||||||
|
mv "$tmp" "${PREFIX}/bin/msdl"
|
||||||
|
echo "Installed to ${PREFIX}/bin/msdl"
|
||||||
|
elif [ -w /usr/local/bin ]; then
|
||||||
|
mv "$tmp" /usr/local/bin/msdl
|
||||||
|
echo "Installed to /usr/local/bin/msdl"
|
||||||
|
else
|
||||||
|
sudo mv "$tmp" /usr/local/bin/msdl
|
||||||
|
echo "Installed to /usr/local/bin/msdl"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Run 'msdl --help' to get started."
|
||||||
|
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
_ "embed"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html"
|
"html"
|
||||||
|
|
@ -27,6 +28,9 @@ import (
|
||||||
"golang.org/x/sync/singleflight"
|
"golang.org/x/sync/singleflight"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:embed install.sh
|
||||||
|
var installScript []byte
|
||||||
|
|
||||||
// Package-level rand source — avoids global mutex contention under concurrent load.
|
// Package-level rand source — avoids global mutex contention under concurrent load.
|
||||||
// Go 1.20+ auto-seeds the global rand, but a local source is faster at high QPS.
|
// Go 1.20+ auto-seeds the global rand, but a local source is faster at high QPS.
|
||||||
var rng = rand.New(rand.NewSource(time.Now().UnixNano()))
|
var rng = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
|
@ -1701,6 +1705,20 @@ func handleCLIVersion(w http.ResponseWriter, r *http.Request) {
|
||||||
json.NewEncoder(w).Encode(map[string]string{"latest": latestCLIVersion})
|
json.NewEncoder(w).Encode(map[string]string{"latest": latestCLIVersion})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- /install.sh endpoint ---
|
||||||
|
|
||||||
|
// handleInstallScript serves the Linux/macOS install script embedded at
|
||||||
|
// build time from install.sh. Auto-detects OS/arch and always resolves the
|
||||||
|
// latest GitHub release, so it needs no per-release maintenance.
|
||||||
|
func handleInstallScript(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != http.MethodGet {
|
||||||
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "text/x-sh; charset=utf-8")
|
||||||
|
w.Write(installScript)
|
||||||
|
}
|
||||||
|
|
||||||
// --- /metrics endpoint ---
|
// --- /metrics endpoint ---
|
||||||
|
|
||||||
// loadTelemetryFromRedis reads all telemetry counters from Redis.
|
// loadTelemetryFromRedis reads all telemetry counters from Redis.
|
||||||
|
|
@ -1865,6 +1883,7 @@ func main() {
|
||||||
mux.HandleFunc("/metrics", handleMetrics)
|
mux.HandleFunc("/metrics", handleMetrics)
|
||||||
mux.HandleFunc("/telemetry", handleTelemetry)
|
mux.HandleFunc("/telemetry", handleTelemetry)
|
||||||
mux.HandleFunc("/cli/version", handleCLIVersion)
|
mux.HandleFunc("/cli/version", handleCLIVersion)
|
||||||
|
mux.HandleFunc("/install.sh", handleInstallScript)
|
||||||
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.Write([]byte(`{"status":"ok"}`))
|
w.Write([]byte(`{"status":"ok"}`))
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ const RELEASES_URL = 'https://minxl.ink/msdl-github-release'
|
||||||
function InstallSteps() {
|
function InstallSteps() {
|
||||||
const [copied, setCopied] = useState(false)
|
const [copied, setCopied] = useState(false)
|
||||||
const [brewCopied, setBrewCopied] = useState(false)
|
const [brewCopied, setBrewCopied] = useState(false)
|
||||||
|
const [curlCopied, setCurlCopied] = useState(false)
|
||||||
|
|
||||||
function handleCopy() {
|
function handleCopy() {
|
||||||
navigator.clipboard.writeText('winget install starkSV.msdl')
|
navigator.clipboard.writeText('winget install starkSV.msdl')
|
||||||
|
|
@ -29,6 +30,12 @@ function InstallSteps() {
|
||||||
setTimeout(() => setBrewCopied(false), 2000)
|
setTimeout(() => setBrewCopied(false), 2000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleCurlCopy() {
|
||||||
|
navigator.clipboard.writeText('curl -fsSL https://api.msdl.tech-latest.com/install.sh | bash')
|
||||||
|
setCurlCopied(true)
|
||||||
|
setTimeout(() => setCurlCopied(false), 2000)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<p className="text-[10px] font-mono font-semibold uppercase tracking-widest text-zinc-600">1. Install</p>
|
<p className="text-[10px] font-mono font-semibold uppercase tracking-widest text-zinc-600">1. Install</p>
|
||||||
|
|
@ -56,6 +63,12 @@ function InstallSteps() {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex items-center justify-between gap-2 rounded-lg bg-white/4 border border-white/7 px-3 py-2">
|
||||||
|
<code className="text-[11px] font-mono text-zinc-400 truncate">curl -fsSL .../install.sh | bash</code>
|
||||||
|
<button onClick={handleCurlCopy} className="flex-shrink-0 text-zinc-500 hover:text-white transition-colors">
|
||||||
|
{curlCopied ? <Check size={12} className="text-green-400" /> : <Copy size={12} />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<a
|
<a
|
||||||
href={RELEASES_URL}
|
href={RELEASES_URL}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,12 @@ export default function CliPage() {
|
||||||
<CodeBlock code="brew tap starkSV/msdl && brew install msdl" />
|
<CodeBlock code="brew tap starkSV/msdl && brew install msdl" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* No Homebrew — curl installer */}
|
||||||
|
<div className="rounded-xl border border-white/7 bg-[#111113] p-4 space-y-2">
|
||||||
|
<p className="text-[12px] text-zinc-400">No Homebrew? One-line installer (auto-detects OS/arch, incl. Termux):</p>
|
||||||
|
<CodeBlock code="curl -fsSL https://api.msdl.tech-latest.com/install.sh | bash" />
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Manual / other platforms */}
|
{/* Manual / other platforms */}
|
||||||
<div className="rounded-xl border border-white/7 bg-[#111113] p-4 space-y-3">
|
<div className="rounded-xl border border-white/7 bg-[#111113] p-4 space-y-3">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue