mirror of
https://github.com/dexoron/dcr.git
synced 2026-10-21 08:48:30 +00:00
feat: add download mirrors and drop legacy install scripts
Introduce `--mirror` and `DCRUP_MIRROR` so `dcrup` can fetch prebuilt binaries from multiple CDNs. Default `auto` tries cf → gh → sf → ya and uses the first successful download. - dcrup.sh / dcrup.ps1: mirror chain, CLI flag, env override - remove install.sh / install.ps1 / install_bsd.sh (superseded by dcrup) - GitHub Actions: upload releases to Cloudflare R2 next to Yandex S3 - docs: README, FAQ, changelog, installation, env vars, contributing
This commit is contained in:
14
.github/workflows/release.yml
vendored
14
.github/workflows/release.yml
vendored
@@ -1313,3 +1313,17 @@ jobs:
|
|||||||
aws s3 sync dist/ "s3://${{ secrets.S3_BUCKET_NAME }}/${TAG}/" \
|
aws s3 sync dist/ "s3://${{ secrets.S3_BUCKET_NAME }}/${TAG}/" \
|
||||||
--endpoint-url https://storage.yandexcloud.net \
|
--endpoint-url https://storage.yandexcloud.net \
|
||||||
--region ru-central1
|
--region ru-central1
|
||||||
|
|
||||||
|
- name: Upload Everything to Cloudflare R2
|
||||||
|
env:
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_EC2_METADATA_DISABLED: true
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
TAG="${{ needs.setup.outputs.tag }}"
|
||||||
|
|
||||||
|
aws s3 sync dist/ "s3://${{ secrets.R2_BUCKET_NAME }}/${TAG}/" \
|
||||||
|
--endpoint-url https://${{ secrets.R2_ACCOUNT_ID }}.r2.cloudflarestorage.com \
|
||||||
|
--region auto
|
||||||
24
CHANGELOG.md
24
CHANGELOG.md
@@ -1,5 +1,29 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### RU
|
||||||
|
|
||||||
|
**Добавлено:**
|
||||||
|
|
||||||
|
- **Зеркала загрузок в `dcrup`** — `--mirror auto|cf|gh|sf|ya` и `DCRUP_MIRROR`.
|
||||||
|
По умолчанию `auto`: **cf → gh → sf → ya** (CloudFlare CDN, GitHub, SourceForge, Yandex CDN).
|
||||||
|
|
||||||
|
**Удалено:**
|
||||||
|
|
||||||
|
- **`install.sh` / `install.ps1` / `install_bsd.sh`** — устарели, заменены `dcrup`.
|
||||||
|
|
||||||
|
### EN
|
||||||
|
|
||||||
|
**Added:**
|
||||||
|
|
||||||
|
- **Download mirrors in `dcrup`** — `--mirror auto|cf|gh|sf|ya` and `DCRUP_MIRROR`.
|
||||||
|
Default `auto` tries **cf → gh → sf → ya** (CloudFlare CDN, GitHub, SourceForge, Yandex CDN).
|
||||||
|
|
||||||
|
**Removed:**
|
||||||
|
|
||||||
|
- **`install.sh` / `install.ps1` / `install_bsd.sh`** — superseded by `dcrup`.
|
||||||
|
|
||||||
## [v0.8.5] - 2026-08-08 "Фиксация версии dcr-version и предупреждения совместимости / Config Version Pinning & Compatibility Warnings"
|
## [v0.8.5] - 2026-08-08 "Фиксация версии dcr-version и предупреждения совместимости / Config Version Pinning & Compatibility Warnings"
|
||||||
|
|
||||||
### RU
|
### RU
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ Thanks for your interest in the project.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/dexoron/dcr.git
|
git clone https://github.com/dexoron/dcr.git
|
||||||
|
# or a source mirror: GitVerse / SourceCraft / SourceForge / GitLab (see README)
|
||||||
cd dcr
|
cd dcr
|
||||||
cargo check
|
cargo check
|
||||||
```
|
```
|
||||||
|
|||||||
11
FAQ.md
11
FAQ.md
@@ -61,8 +61,19 @@ Available installation methods may vary by project version.
|
|||||||
Recommended path:
|
Recommended path:
|
||||||
|
|
||||||
- check instructions in `README.md`;
|
- check instructions in `README.md`;
|
||||||
|
- use `dcrup install stable` (default mirror chain: **cf → gh → sf → ya**);
|
||||||
|
- pin a host with `--mirror cf|gh|sf|ya` or `DCRUP_MIRROR` if needed;
|
||||||
- if there is no prebuilt package for your platform, build from source using `cargo build --release`.
|
- if there is no prebuilt package for your platform, build from source using `cargo build --release`.
|
||||||
|
|
||||||
|
## How do I choose a download mirror?
|
||||||
|
|
||||||
|
`dcrup` defaults to `--mirror auto`: CloudFlare CDN, then GitHub, then SourceForge, then Yandex CDN.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
dcrup install stable --mirror cf
|
||||||
|
export DCRUP_MIRROR=ya
|
||||||
|
```
|
||||||
|
|
||||||
## How can I get started quickly?
|
## How can I get started quickly?
|
||||||
|
|
||||||
Minimal workflow:
|
Minimal workflow:
|
||||||
|
|||||||
27
README.md
27
README.md
@@ -83,7 +83,9 @@ cargo install dcr
|
|||||||
```sh
|
```sh
|
||||||
curl -fsSL https://sh.dcr-tool.ru | sh -s -- self-install
|
curl -fsSL https://sh.dcr-tool.ru | sh -s -- self-install
|
||||||
export PATH="$HOME/.dcr/bin:$PATH"
|
export PATH="$HOME/.dcr/bin:$PATH"
|
||||||
dcrup install stable
|
dcrup install stable # auto: cf → gh → sf → ya
|
||||||
|
# dcrup install stable --mirror cf # CloudFlare CDN
|
||||||
|
# dcrup install stable --mirror ya # Yandex CDN (RU)
|
||||||
```
|
```
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
@@ -98,7 +100,9 @@ irm https://ps1.dcr-tool.ru | iex
|
|||||||
# irm https://ps1.dcr-tool.ru -OutFile dcrup.ps1
|
# irm https://ps1.dcr-tool.ru -OutFile dcrup.ps1
|
||||||
# powershell -File .\dcrup.ps1 self-install
|
# powershell -File .\dcrup.ps1 self-install
|
||||||
# $env:Path += ";$env:USERPROFILE\.dcr\bin"
|
# $env:Path += ";$env:USERPROFILE\.dcr\bin"
|
||||||
dcrup install stable
|
dcrup install stable # auto: cf → gh → sf → ya
|
||||||
|
# dcrup install stable --mirror cf # CloudFlare CDN
|
||||||
|
# dcrup install stable --mirror ya # Yandex CDN (RU)
|
||||||
```
|
```
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
@@ -218,14 +222,25 @@ Full docs at **[dcr.dexoron.su](https://dcr.dexoron.su)** or in the [`docs/`](do
|
|||||||
|
|
||||||
## Repository Mirrors
|
## Repository Mirrors
|
||||||
|
|
||||||
The primary repository is hosted on GitHub. The following mirrors are available for source code and releases:
|
The primary repository is hosted on GitHub. Source and release mirrors:
|
||||||
|
|
||||||
| Region | Mirror | Contents |
|
| Region | Mirror | Contents |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Russia | [GitVerse](https://gitverse.ru/dcr_labs/dcr) **(recommended)** | Source code |
|
| Worldwide | [GitHub](https://github.com/dexoron/dcr) | Source code and releases |
|
||||||
|
| Worldwide | [SourceForge](https://sourceforge.net/projects/dcr-tool/) | Source code and releases |
|
||||||
|
| Russia | [GitVerse](https://gitverse.ru/dcr_labs/dcr) | Source code |
|
||||||
| Russia | [SourceCraft](https://sourcecraft.dev/dexoron-dev/dcr) | Source code |
|
| Russia | [SourceCraft](https://sourcecraft.dev/dexoron-dev/dcr) | Source code |
|
||||||
| Worldwide | [SourceForge](https://sourceforge.net/projects/dcr-tool/) **(recommended)** | Source code and releases |
|
|
||||||
| Worldwide | [GitLab](https://gitlab.com/dexoron-dev/dcr-tool/dcr) | Source code and releases |
|
Release CDN (used by `dcrup`):
|
||||||
|
|
||||||
|
| Code | Host | Role |
|
||||||
|
|---|---|---|
|
||||||
|
| `cf` | [cdn-global.dcr-tool.ru](https://cdn-global.dcr-tool.ru) (CloudFlare) | Worldwide CDN |
|
||||||
|
| `gh` | GitHub Releases | Primary host |
|
||||||
|
| `sf` | SourceForge | Worldwide fallback |
|
||||||
|
| `ya` | [cdn-ru.dcr-tool.ru](https://cdn-ru.dcr-tool.ru) (Yandex) | Paid RU fallback for restrictions |
|
||||||
|
|
||||||
|
`dcrup install` defaults to `--mirror auto` and tries **cf → gh → sf → ya**. Override with `--mirror cf|gh|sf|ya` or `DCRUP_MIRROR`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
93
dcrup.ps1
93
dcrup.ps1
@@ -6,6 +6,7 @@ $DcrupBin = if ($env:DCRUP_BIN) { $env:DCRUP_BIN } else { Join-Path $DcrupHom
|
|||||||
$DcrupTc = Join-Path $DcrupHome 'toolchains'
|
$DcrupTc = Join-Path $DcrupHome 'toolchains'
|
||||||
$DcrupMeta = Join-Path $DcrupHome 'meta'
|
$DcrupMeta = Join-Path $DcrupHome 'meta'
|
||||||
$RepoUrl = if ($env:DCRUP_REPO) { $env:DCRUP_REPO } else { 'https://github.com/dexoron/dcr' }
|
$RepoUrl = if ($env:DCRUP_REPO) { $env:DCRUP_REPO } else { 'https://github.com/dexoron/dcr' }
|
||||||
|
$DcrupMirror = if ($env:DCRUP_MIRROR) { $env:DCRUP_MIRROR } else { 'auto' }
|
||||||
$ApiLatest = 'https://api.github.com/repos/dexoron/dcr/releases/latest'
|
$ApiLatest = 'https://api.github.com/repos/dexoron/dcr/releases/latest'
|
||||||
$ApiAll = 'https://api.github.com/repos/dexoron/dcr/releases'
|
$ApiAll = 'https://api.github.com/repos/dexoron/dcr/releases'
|
||||||
$Features = if ($env:DCR_FEATURES) { $env:DCR_FEATURES } else { 'archive' }
|
$Features = if ($env:DCR_FEATURES) { $env:DCR_FEATURES } else { 'archive' }
|
||||||
@@ -20,7 +21,7 @@ function Show-Usage {
|
|||||||
dcrup — install and switch DCR versions (Windows)
|
dcrup — install and switch DCR versions (Windows)
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
dcrup install <spec> [--build|--release] [--force]
|
dcrup install <spec> [--build|--release] [--force] [--mirror auto|cf|gh|sf|ya]
|
||||||
dcrup default <spec>
|
dcrup default <spec>
|
||||||
dcrup update
|
dcrup update
|
||||||
dcrup list
|
dcrup list
|
||||||
@@ -38,15 +39,24 @@ Spec:
|
|||||||
night → always build from branch "dev" HEAD
|
night → always build from branch "dev" HEAD
|
||||||
|
|
||||||
Modes:
|
Modes:
|
||||||
--release download GitHub Release binary (default for stable/dev)
|
--release download prebuilt binary (default for stable/dev)
|
||||||
--build cargo build --release --features archive
|
--build cargo build --release --features archive
|
||||||
night always --build (prebuilt not available)
|
night always --build (prebuilt not available)
|
||||||
|
|
||||||
|
Mirrors (prebuilt download only):
|
||||||
|
--mirror auto try cf → gh → sf → ya, first successful download wins (default)
|
||||||
|
--mirror cf download from cdn-global.dcr-tool.ru
|
||||||
|
--mirror gh download from github.com/dexoron/dcr
|
||||||
|
--mirror sf download from sourceforge.net/projects/dcr-tool
|
||||||
|
--mirror ya download from cdn-ru.dcr-tool.ru
|
||||||
|
DCRUP_MIRROR env override (default: auto)
|
||||||
|
|
||||||
Env:
|
Env:
|
||||||
DCRUP_HOME default ~/.dcr
|
DCRUP_HOME default ~/.dcr
|
||||||
DCRUP_BIN default $DCRUP_HOME/bin
|
DCRUP_BIN default $DCRUP_HOME/bin
|
||||||
DCR_FEATURES default archive
|
DCR_FEATURES default archive
|
||||||
DCRUP_REPO git/GitHub repo URL
|
DCRUP_REPO git/GitHub repo URL
|
||||||
|
DCRUP_MIRROR auto|cf|gh|sf|ya (default: auto)
|
||||||
'@ | Write-Host
|
'@ | Write-Host
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +133,53 @@ function Link-Default([string]$id) {
|
|||||||
Ok "default → $id ($dst)"
|
Ok "default → $id ($dst)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Set-Mirror([string]$value) {
|
||||||
|
if ($value -notin @('auto', 'cf', 'gh', 'sf', 'ya')) {
|
||||||
|
Die "invalid --mirror: $value (use auto|cf|gh|sf|ya)"
|
||||||
|
}
|
||||||
|
$script:DcrupMirror = $value
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-MirrorUrl([string]$mirror, [string]$tag, [string]$asset) {
|
||||||
|
switch ($mirror) {
|
||||||
|
'cf' { return "https://cdn-global.dcr-tool.ru/$tag/$asset" }
|
||||||
|
'gh' { return "https://github.com/dexoron/dcr/releases/download/$tag/$asset" }
|
||||||
|
'sf' { return "https://sourceforge.net/projects/dcr-tool/files/$tag/$asset/download" }
|
||||||
|
'ya' { return "https://cdn-ru.dcr-tool.ru/$tag/$asset" }
|
||||||
|
default { Die "invalid mirror: $mirror" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-MirrorsToTry {
|
||||||
|
switch ($script:DcrupMirror) {
|
||||||
|
'auto' { return @('cf', 'gh', 'sf', 'ya') }
|
||||||
|
{ $_ -in @('cf', 'gh', 'sf', 'ya') } { return @($script:DcrupMirror) }
|
||||||
|
default { Die "invalid mirror: $($script:DcrupMirror) (use auto|cf|gh|sf|ya)" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Download-FromMirrors([string]$tag, [string]$asset, [string]$destFile) {
|
||||||
|
$tmp = "$destFile.download"
|
||||||
|
foreach ($m in (Get-MirrorsToTry)) {
|
||||||
|
$url = Get-MirrorUrl $m $tag $asset
|
||||||
|
Info "trying mirror $m …"
|
||||||
|
Remove-Item $tmp -ErrorAction SilentlyContinue
|
||||||
|
try {
|
||||||
|
Invoke-WebRequest -Uri $url -OutFile $tmp -UserAgent 'dcrup'
|
||||||
|
$size = (Get-Item $tmp).Length
|
||||||
|
if ($size -gt 100000) {
|
||||||
|
Move-Item $tmp $destFile -Force
|
||||||
|
return $m
|
||||||
|
}
|
||||||
|
Warn "mirror $m returned a too-small file ($size bytes)"
|
||||||
|
} catch {
|
||||||
|
Warn "mirror $m failed"
|
||||||
|
}
|
||||||
|
Remove-Item $tmp -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
function Fetch-Release($channel, $version) {
|
function Fetch-Release($channel, $version) {
|
||||||
if ($version) {
|
if ($version) {
|
||||||
return Invoke-RestMethod -Uri "https://api.github.com/repos/dexoron/dcr/releases/tags/v$version"
|
return Invoke-RestMethod -Uri "https://api.github.com/repos/dexoron/dcr/releases/tags/v$version"
|
||||||
@@ -142,8 +199,6 @@ function Install-Prebuilt([switch]$Force) {
|
|||||||
$tag = $rel.tag_name
|
$tag = $rel.tag_name
|
||||||
$ver = Normalize-Version $tag
|
$ver = Normalize-Version $tag
|
||||||
$assetName = "dcr-$triple-$ver.exe"
|
$assetName = "dcr-$triple-$ver.exe"
|
||||||
$asset = $rel.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1
|
|
||||||
if (-not $asset) { Die "asset not found: $assetName" }
|
|
||||||
|
|
||||||
$id = if ($script:SpecFloating) { Toolchain-Id $ver } else { Toolchain-Id }
|
$id = if ($script:SpecFloating) { Toolchain-Id $ver } else { Toolchain-Id }
|
||||||
$dest = Join-Path $DcrupTc $id
|
$dest = Join-Path $DcrupTc $id
|
||||||
@@ -155,16 +210,19 @@ function Install-Prebuilt([switch]$Force) {
|
|||||||
}
|
}
|
||||||
Ensure-Dirs
|
Ensure-Dirs
|
||||||
New-Item -ItemType Directory -Force -Path $dest | Out-Null
|
New-Item -ItemType Directory -Force -Path $dest | Out-Null
|
||||||
Info "downloading $assetName …"
|
Info "downloading $assetName (mirror=$($script:DcrupMirror)) …"
|
||||||
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $bin
|
$mirror = Download-FromMirrors $tag $assetName $bin
|
||||||
|
if (-not $mirror) { Die "no mirror reachable for $assetName (try: --mirror cf|gh|sf|ya)" }
|
||||||
|
Info "mirror → $mirror"
|
||||||
@"
|
@"
|
||||||
channel=$($script:SpecChannel)
|
channel=$($script:SpecChannel)
|
||||||
version=$ver
|
version=$ver
|
||||||
tag=$tag
|
tag=$tag
|
||||||
source=release
|
source=release
|
||||||
triple=$triple
|
triple=$triple
|
||||||
|
mirror=$mirror
|
||||||
"@ | Set-Content (Join-Path $dest 'dcrup-meta')
|
"@ | Set-Content (Join-Path $dest 'dcrup-meta')
|
||||||
Ok "installed prebuilt $id"
|
Ok "installed prebuilt $id ($triple via $mirror)"
|
||||||
Link-Default $id
|
Link-Default $id
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,23 +328,32 @@ function Cmd-Install {
|
|||||||
$mode = 'release'
|
$mode = 'release'
|
||||||
$force = $false
|
$force = $false
|
||||||
$spec = $null
|
$spec = $null
|
||||||
foreach ($a in $Args) {
|
$i = 0
|
||||||
|
while ($i -lt $Args.Count) {
|
||||||
|
$a = $Args[$i]
|
||||||
switch -Regex ($a) {
|
switch -Regex ($a) {
|
||||||
'^--build$' { $mode = 'build'; continue }
|
'^--build$' { $mode = 'build' }
|
||||||
'^--release$' { $mode = 'release'; continue }
|
'^--release$' { $mode = 'release' }
|
||||||
'^--force$' { $force = $true; continue }
|
'^--force$' { $force = $true }
|
||||||
|
'^--mirror$' {
|
||||||
|
if ($i + 1 -ge $Args.Count) { Die '--mirror needs auto|cf|gh|sf|ya' }
|
||||||
|
$i++
|
||||||
|
Set-Mirror $Args[$i]
|
||||||
|
}
|
||||||
|
'^--mirror=(.+)$' { Set-Mirror $Matches[1] }
|
||||||
'^-' { Die "unknown flag: $a" }
|
'^-' { Die "unknown flag: $a" }
|
||||||
default {
|
default {
|
||||||
if ($spec) { Die "unexpected: $a" }
|
if ($spec) { Die "unexpected: $a" }
|
||||||
$spec = $a
|
$spec = $a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$i++
|
||||||
}
|
}
|
||||||
if (-not $spec) { Die 'usage: dcrup install <spec> [--build|--release] [--force]' }
|
if (-not $spec) { Die 'usage: dcrup install <spec> [--build|--release] [--force] [--mirror auto|cf|gh|sf|ya]' }
|
||||||
Parse-Spec $spec
|
Parse-Spec $spec
|
||||||
Ensure-Dirs
|
Ensure-Dirs
|
||||||
if ($script:SpecChannel -eq 'night') { $mode = 'build' }
|
if ($script:SpecChannel -eq 'night') { $mode = 'build' }
|
||||||
Info "install spec=$spec channel=$($script:SpecChannel) mode=$mode"
|
Info "install spec=$spec channel=$($script:SpecChannel) mode=$mode mirror=$($script:DcrupMirror)"
|
||||||
if ($mode -eq 'build') { Install-Build -Force:$force } else { Install-Prebuilt -Force:$force }
|
if ($mode -eq 'build') { Install-Build -Force:$force } else { Install-Prebuilt -Force:$force }
|
||||||
Ensure-UserPath
|
Ensure-UserPath
|
||||||
Install-CmdShim
|
Install-CmdShim
|
||||||
|
|||||||
95
dcrup.sh
95
dcrup.sh
@@ -6,6 +6,7 @@ DCRUP_BIN="${DCRUP_BIN:-$DCRUP_HOME/bin}"
|
|||||||
DCRUP_TC="${DCRUP_HOME}/toolchains"
|
DCRUP_TC="${DCRUP_HOME}/toolchains"
|
||||||
DCRUP_META="${DCRUP_HOME}/meta"
|
DCRUP_META="${DCRUP_HOME}/meta"
|
||||||
REPO_URL="${DCRUP_REPO:-https://github.com/dexoron/dcr}"
|
REPO_URL="${DCRUP_REPO:-https://github.com/dexoron/dcr}"
|
||||||
|
DCRUP_MIRROR="${DCRUP_MIRROR:-auto}"
|
||||||
API_LATEST="https://api.github.com/repos/dexoron/dcr/releases/latest"
|
API_LATEST="https://api.github.com/repos/dexoron/dcr/releases/latest"
|
||||||
API_ALL="https://api.github.com/repos/dexoron/dcr/releases"
|
API_ALL="https://api.github.com/repos/dexoron/dcr/releases"
|
||||||
FEATURES="${DCR_FEATURES:-archive}"
|
FEATURES="${DCR_FEATURES:-archive}"
|
||||||
@@ -26,7 +27,7 @@ usage() {
|
|||||||
dcrup — install and switch DCR versions
|
dcrup — install and switch DCR versions
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
dcrup install <spec> [--build|--release] [--force] [--libc gnu|musl|auto]
|
dcrup install <spec> [--build|--release] [--force] [--libc gnu|musl|auto] [--mirror auto|cf|gh|sf|ya]
|
||||||
dcrup default <spec>
|
dcrup default <spec>
|
||||||
dcrup update
|
dcrup update
|
||||||
dcrup list
|
dcrup list
|
||||||
@@ -44,7 +45,7 @@ Spec:
|
|||||||
night → always build from branch "dev" HEAD
|
night → always build from branch "dev" HEAD
|
||||||
|
|
||||||
Modes:
|
Modes:
|
||||||
--release download GitHub Release binary (default for stable/dev)
|
--release download prebuilt binary (default for stable/dev)
|
||||||
--build cargo build --release --features archive
|
--build cargo build --release --features archive
|
||||||
night always --build (prebuilt not available)
|
night always --build (prebuilt not available)
|
||||||
|
|
||||||
@@ -53,12 +54,21 @@ Linux libc (prebuilt triple only):
|
|||||||
--libc musl x86_64-unknown-linux-musl
|
--libc musl x86_64-unknown-linux-musl
|
||||||
--libc auto musl if host ldd/libc is musl, else gnu
|
--libc auto musl if host ldd/libc is musl, else gnu
|
||||||
|
|
||||||
|
Mirrors (prebuilt download only):
|
||||||
|
--mirror auto try cf → gh → sf → ya, first successful download wins (default)
|
||||||
|
--mirror cf download from cdn-global.dcr-tool.ru
|
||||||
|
--mirror gh download from github.com/dexoron/dcr
|
||||||
|
--mirror sf download from sourceforge.net/projects/dcr-tool
|
||||||
|
--mirror ya download from cdn-ru.dcr-tool.ru
|
||||||
|
DCRUP_MIRROR env override (default: auto)
|
||||||
|
|
||||||
Env:
|
Env:
|
||||||
DCRUP_HOME default ~/.dcr
|
DCRUP_HOME default ~/.dcr
|
||||||
DCRUP_BIN default $DCRUP_HOME/bin
|
DCRUP_BIN default $DCRUP_HOME/bin
|
||||||
DCR_FEATURES default archive
|
DCR_FEATURES default archive
|
||||||
DCRUP_REPO git/GitHub repo URL
|
DCRUP_REPO git/GitHub repo URL
|
||||||
DCRUP_LIBC gnu|musl|auto (default: gnu)
|
DCRUP_LIBC gnu|musl|auto (default: gnu)
|
||||||
|
DCRUP_MIRROR auto|cf|gh|sf|ya (default: auto)
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,9 +249,57 @@ json_tag() {
|
|||||||
printf '%s' "$1" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n1
|
printf '%s' "$1" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n1
|
||||||
}
|
}
|
||||||
|
|
||||||
json_asset_url() {
|
set_mirror() {
|
||||||
local json="$1" asset="$2"
|
case "$1" in
|
||||||
printf '%s' "$json" | sed -n "s#.*\"browser_download_url\"[[:space:]]*:[[:space:]]*\"\([^\"]*/${asset}\)\"#\1#p" | head -n1
|
auto|cf|gh|sf|ya) DCRUP_MIRROR="$1" ;;
|
||||||
|
*) die "invalid --mirror: $1 (use auto|cf|gh|sf|ya)" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
mirror_url() {
|
||||||
|
local mirror="$1" tag="$2" asset="$3"
|
||||||
|
case "$mirror" in
|
||||||
|
cf) printf 'https://cdn-global.dcr-tool.ru/%s/%s' "$tag" "$asset" ;;
|
||||||
|
gh) printf 'https://github.com/dexoron/dcr/releases/download/%s/%s' "$tag" "$asset" ;;
|
||||||
|
sf) printf 'https://sourceforge.net/projects/dcr-tool/files/%s/%s/download' "$tag" "$asset" ;;
|
||||||
|
ya) printf 'https://cdn-ru.dcr-tool.ru/%s/%s' "$tag" "$asset" ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
mirror_chain() { echo "cf gh sf ya"; }
|
||||||
|
|
||||||
|
mirrors_to_try() {
|
||||||
|
case "$DCRUP_MIRROR" in
|
||||||
|
auto) mirror_chain ;;
|
||||||
|
cf|gh|sf|ya) echo "$DCRUP_MIRROR" ;;
|
||||||
|
*) die "invalid mirror: $DCRUP_MIRROR (use auto|cf|gh|sf|ya)" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
download_from_mirrors() {
|
||||||
|
local tag="$1" asset="$2" dest="$3"
|
||||||
|
local tmp="$dest/dcr.download" m url size
|
||||||
|
USED_MIRROR=""
|
||||||
|
for m in $(mirrors_to_try); do
|
||||||
|
url="$(mirror_url "$m" "$tag" "$asset")"
|
||||||
|
log "trying mirror $m …"
|
||||||
|
rm -f "$tmp"
|
||||||
|
if curl -fL --retry 2 --retry-delay 1 --connect-timeout 10 --max-time 180 \
|
||||||
|
-A "dcrup" "$url" -o "$tmp"; then
|
||||||
|
size="$(wc -c <"$tmp" | tr -d ' ')"
|
||||||
|
if [[ "${size:-0}" -gt 100000 ]]; then
|
||||||
|
mv "$tmp" "$dest/dcr"
|
||||||
|
USED_MIRROR="$m"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
warn "mirror $m returned a too-small file (${size:-0} bytes)"
|
||||||
|
else
|
||||||
|
warn "mirror $m failed"
|
||||||
|
fi
|
||||||
|
rm -f "$tmp"
|
||||||
|
done
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
latest_stable_json() {
|
latest_stable_json() {
|
||||||
@@ -281,7 +339,7 @@ release_json_for_spec() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
install_prebuilt() {
|
install_prebuilt() {
|
||||||
local triple asset tag version url json id dest
|
local triple asset tag version id dest mirror
|
||||||
need_cmd curl
|
need_cmd curl
|
||||||
triple="$(detect_triple)"
|
triple="$(detect_triple)"
|
||||||
json="$(release_json_for_spec)"
|
json="$(release_json_for_spec)"
|
||||||
@@ -292,8 +350,6 @@ install_prebuilt() {
|
|||||||
case "$triple" in
|
case "$triple" in
|
||||||
*windows*) asset="${asset}.exe" ;;
|
*windows*) asset="${asset}.exe" ;;
|
||||||
esac
|
esac
|
||||||
url="$(json_asset_url "$json" "$asset")"
|
|
||||||
[[ -n "$url" ]] || die "asset not found: $asset (tag $tag)"
|
|
||||||
|
|
||||||
id="$(toolchain_id "$version")"
|
id="$(toolchain_id "$version")"
|
||||||
dest="$DCRUP_TC/$id"
|
dest="$DCRUP_TC/$id"
|
||||||
@@ -303,9 +359,12 @@ install_prebuilt() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "downloading $asset …"
|
|
||||||
mkdir -p "$dest"
|
mkdir -p "$dest"
|
||||||
curl -fL "$url" -o "$dest/dcr"
|
log "downloading $asset (mirror=$DCRUP_MIRROR) …"
|
||||||
|
download_from_mirrors "$tag" "$asset" "$dest" \
|
||||||
|
|| die "no mirror reachable for $asset (try: --mirror cf|gh|sf|ya)"
|
||||||
|
mirror="$USED_MIRROR"
|
||||||
|
log "mirror → $mirror"
|
||||||
chmod +x "$dest/dcr"
|
chmod +x "$dest/dcr"
|
||||||
printf '%s\n' \
|
printf '%s\n' \
|
||||||
"channel=$SPEC_CHANNEL" \
|
"channel=$SPEC_CHANNEL" \
|
||||||
@@ -313,9 +372,10 @@ install_prebuilt() {
|
|||||||
"tag=$tag" \
|
"tag=$tag" \
|
||||||
"source=release" \
|
"source=release" \
|
||||||
"triple=$triple" \
|
"triple=$triple" \
|
||||||
|
"mirror=$mirror" \
|
||||||
"libc=${DCRUP_LIBC:-gnu}" \
|
"libc=${DCRUP_LIBC:-gnu}" \
|
||||||
>"$dest/dcrup-meta"
|
>"$dest/dcrup-meta"
|
||||||
ok "installed prebuilt $id ($triple)"
|
ok "installed prebuilt $id ($triple via $mirror)"
|
||||||
link_default "$id"
|
link_default "$id"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,6 +465,15 @@ cmd_install() {
|
|||||||
libc_cli="${1#--libc=}"
|
libc_cli="${1#--libc=}"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
--mirror)
|
||||||
|
[[ $# -ge 2 ]] || die "--mirror needs auto|cf|gh|sf|ya"
|
||||||
|
set_mirror "$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--mirror=*)
|
||||||
|
set_mirror "${1#--mirror=}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
-h|--help) usage; exit 0 ;;
|
-h|--help) usage; exit 0 ;;
|
||||||
-*) die "unknown flag: $1" ;;
|
-*) die "unknown flag: $1" ;;
|
||||||
*)
|
*)
|
||||||
@@ -414,7 +483,7 @@ cmd_install() {
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
[[ -n "$spec" ]] || die "usage: dcrup install <spec> [--build|--release] [--force] [--libc gnu|musl|auto]"
|
[[ -n "$spec" ]] || die "usage: dcrup install <spec> [--build|--release] [--force] [--libc gnu|musl|auto] [--mirror auto|cf|gh|sf|ya]"
|
||||||
parse_spec "$spec"
|
parse_spec "$spec"
|
||||||
ensure_dirs
|
ensure_dirs
|
||||||
|
|
||||||
@@ -431,7 +500,7 @@ cmd_install() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
export FORCE
|
export FORCE
|
||||||
log "install spec=$SPEC_RAW channel=$SPEC_CHANNEL version=${SPEC_VERSION:-∅} mode=$mode libc=$DCRUP_LIBC"
|
log "install spec=$SPEC_RAW channel=$SPEC_CHANNEL version=${SPEC_VERSION:-∅} mode=$mode libc=$DCRUP_LIBC mirror=$DCRUP_MIRROR"
|
||||||
if [[ "$mode" == "build" ]]; then
|
if [[ "$mode" == "build" ]]; then
|
||||||
install_build
|
install_build
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ sidebar_label: Introduction
|
|||||||
# Installation (dcrup)
|
# Installation (dcrup)
|
||||||
curl -fsSL https://sh.dcr-tool.ru | sh -s -- self-install
|
curl -fsSL https://sh.dcr-tool.ru | sh -s -- self-install
|
||||||
export PATH="$HOME/.dcr/bin:$PATH"
|
export PATH="$HOME/.dcr/bin:$PATH"
|
||||||
dcrup install stable
|
dcrup install stable # auto: cf → gh → sf → ya
|
||||||
|
# dcrup install stable --mirror cf # CloudFlare / GitHub / SourceForge / Yandex
|
||||||
|
|
||||||
# Create a project
|
# Create a project
|
||||||
dcr new my-app
|
dcr new my-app
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ sidebar_label: Changelog
|
|||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
- **Download mirrors in `dcrup`** — `--mirror auto|cf|gh|sf|ya` and `DCRUP_MIRROR`.
|
||||||
|
Default `auto` tries **cf → gh → sf → ya** (CloudFlare CDN, GitHub, SourceForge, Yandex CDN).
|
||||||
|
- **Removed `install.sh` / `install.ps1` / `install_bsd.sh`** — superseded by `dcrup`.
|
||||||
|
|
||||||
## 0.8.5 (2026-08-08)
|
## 0.8.5 (2026-08-08)
|
||||||
|
|
||||||
- **`package.dcr-version`** — optional CLI version pin in `dcr.toml`.
|
- **`package.dcr-version`** — optional CLI version pin in `dcr.toml`.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ sidebar_label: Contributing
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/dexoron/dcr
|
git clone https://github.com/dexoron/dcr
|
||||||
|
# or a source mirror: GitVerse / SourceCraft / SourceForge / GitLab (see README)
|
||||||
cd dcr
|
cd dcr
|
||||||
cargo build
|
cargo build
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -61,6 +61,15 @@ Use `kind = "flat-bin"` (NASM `-f bin`) and optional `[archive]` for a FAT disk
|
|||||||
|
|
||||||
See [OS-dev recipe](/docs/recipes/os-flat-bin-archive).
|
See [OS-dev recipe](/docs/recipes/os-flat-bin-archive).
|
||||||
|
|
||||||
|
## How do I choose a download mirror?
|
||||||
|
|
||||||
|
`dcrup install` uses `--mirror auto` by default and tries **cf → gh → sf → ya**.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dcrup install stable --mirror cf
|
||||||
|
export DCRUP_MIRROR=ya
|
||||||
|
```
|
||||||
|
|
||||||
## Lock file
|
## Lock file
|
||||||
|
|
||||||
`dcr.lock` is created during builds (`dcr build`) when registry dependencies are present. To force an update — delete `dcr.lock` and run `dcr build`.
|
`dcr.lock` is created during builds (`dcr build`) when registry dependencies are present. To force an update — delete `dcr.lock` and run `dcr build`.
|
||||||
|
|||||||
@@ -45,10 +45,12 @@ After `self-install`, the command is **`dcrup`** (no `.sh` / `.ps1`): shims live
|
|||||||
### Common dcrup commands
|
### Common dcrup commands
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
dcrup install stable # latest stable prebuilt
|
dcrup install stable # latest stable prebuilt (auto: cf → gh → sf → ya)
|
||||||
dcrup install 0.8.2 # pin → 0.8.2@stable
|
dcrup install 0.8.2 # pin → 0.8.2@stable
|
||||||
dcrup install 0.8.2@dev
|
dcrup install 0.8.2@dev
|
||||||
dcrup install stable --libc musl # Linux: musl asset (default: gnu)
|
dcrup install stable --libc musl # Linux: musl asset (default: gnu)
|
||||||
|
dcrup install stable --mirror cf # CloudFlare CDN
|
||||||
|
dcrup install stable --mirror ya # Yandex CDN (RU fallback)
|
||||||
dcrup install stable --build # cargo build --features archive
|
dcrup install stable --build # cargo build --features archive
|
||||||
dcrup install night # always build from branch dev HEAD
|
dcrup install night # always build from branch dev HEAD
|
||||||
dcrup default 0.8.2
|
dcrup default 0.8.2
|
||||||
@@ -60,6 +62,22 @@ dcrup which
|
|||||||
|
|
||||||
Layout: `~/.dcr/toolchains/<id>/dcr` and `~/.dcr/bin/dcr` → active version.
|
Layout: `~/.dcr/toolchains/<id>/dcr` and `~/.dcr/bin/dcr` → active version.
|
||||||
|
|
||||||
|
### Download mirrors
|
||||||
|
|
||||||
|
Prebuilt installs try **cf → gh → sf → ya** unless you pin a host.
|
||||||
|
|
||||||
|
| Code | URL | Notes |
|
||||||
|
|------|-----|--------|
|
||||||
|
| `cf` | `https://cdn-global.dcr-tool.ru/<tag>/<asset>` | CloudFlare CDN (worldwide) |
|
||||||
|
| `gh` | `https://github.com/dexoron/dcr/releases/download/<tag>/<asset>` | GitHub Releases |
|
||||||
|
| `sf` | `https://sourceforge.net/projects/dcr-tool/files/<tag>/<asset>/download` | SourceForge |
|
||||||
|
| `ya` | `https://cdn-ru.dcr-tool.ru/<tag>/<asset>` | Yandex CDN (RU fallback) |
|
||||||
|
|
||||||
|
```sh
|
||||||
|
dcrup install stable --mirror auto # default
|
||||||
|
export DCRUP_MIRROR=cf # persist for this shell
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Arch Linux (AUR)
|
## Arch Linux (AUR)
|
||||||
|
|||||||
@@ -57,3 +57,27 @@ export DCR_INDEX_PATH=/custom/path/index.json
|
|||||||
```
|
```
|
||||||
|
|
||||||
Default: `~/.dcr/index.json`.
|
Default: `~/.dcr/index.json`.
|
||||||
|
|
||||||
|
## DCRUP_MIRROR
|
||||||
|
|
||||||
|
Download mirror for `dcrup` (prebuilt binaries only).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export DCRUP_MIRROR=auto # cf → gh → sf → ya (default)
|
||||||
|
export DCRUP_MIRROR=cf # CloudFlare CDN
|
||||||
|
export DCRUP_MIRROR=gh # GitHub Releases
|
||||||
|
export DCRUP_MIRROR=sf # SourceForge
|
||||||
|
export DCRUP_MIRROR=ya # Yandex CDN (RU fallback)
|
||||||
|
```
|
||||||
|
|
||||||
|
CLI override: `dcrup install stable --mirror cf`.
|
||||||
|
|
||||||
|
## DCRUP_HOME / DCRUP_BIN / DCRUP_REPO
|
||||||
|
|
||||||
|
Installer layout and source clone URL:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export DCRUP_HOME=~/.dcr
|
||||||
|
export DCRUP_BIN=~/.dcr/bin
|
||||||
|
export DCRUP_REPO=https://github.com/dexoron/dcr
|
||||||
|
```
|
||||||
|
|||||||
160
install.ps1
160
install.ps1
@@ -1,160 +0,0 @@
|
|||||||
$ErrorActionPreference = 'Stop'
|
|
||||||
|
|
||||||
$RepoUrl = 'https://github.com/dexoron/dcr'
|
|
||||||
$ApiLatest = 'https://api.github.com/repos/dexoron/dcr/releases/latest'
|
|
||||||
$ApiAll = 'https://api.github.com/repos/dexoron/dcr/releases'
|
|
||||||
$InstallPath = Join-Path $env:LOCALAPPDATA 'dcr'
|
|
||||||
$BinPath = Join-Path $env:USERPROFILE '.local\bin'
|
|
||||||
$BinaryPath = Join-Path $InstallPath 'dcr.exe'
|
|
||||||
|
|
||||||
function Info($msg) { Write-Host "[INFO] $msg" -ForegroundColor Cyan }
|
|
||||||
function Ok($msg) { Write-Host "[OK] $msg" -ForegroundColor Green }
|
|
||||||
function Warn($msg) { Write-Host "[WARN] $msg" -ForegroundColor Yellow }
|
|
||||||
function Fail($msg) { Write-Host "[ERROR] $msg" -ForegroundColor Red; exit 1 }
|
|
||||||
|
|
||||||
function Require-Cmd($name) {
|
|
||||||
if (-not (Get-Command $name -ErrorAction SilentlyContinue)) {
|
|
||||||
Fail "Not found: $name"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Select-Channel {
|
|
||||||
Write-Host "Choose channel:"
|
|
||||||
Write-Host " 1) Latest stable release (default)"
|
|
||||||
Write-Host " 2) Latest dev (pre-release)"
|
|
||||||
$choice = Read-Host "Enter 1 or 2 [1]"
|
|
||||||
if ([string]::IsNullOrWhiteSpace($choice)) { $choice = '1' }
|
|
||||||
|
|
||||||
switch ($choice) {
|
|
||||||
'1' { return 'stable' }
|
|
||||||
'2' { return 'dev' }
|
|
||||||
default { Fail 'Unknown option' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Select-Mode {
|
|
||||||
Write-Host "Choose installation mode:"
|
|
||||||
Write-Host " 1) Download prebuilt binary from GitHub Release (recommended)"
|
|
||||||
Write-Host " 2) Build from git"
|
|
||||||
$choice = Read-Host "Enter 1 or 2 [1]"
|
|
||||||
if ([string]::IsNullOrWhiteSpace($choice)) { $choice = '1' }
|
|
||||||
|
|
||||||
switch ($choice) {
|
|
||||||
'1' { return 'release' }
|
|
||||||
'2' { return 'build' }
|
|
||||||
default { Fail 'Unknown option' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Get-Target {
|
|
||||||
$arch = $env:PROCESSOR_ARCHITECTURE
|
|
||||||
if ($env:PROCESSOR_ARCHITEW6432) {
|
|
||||||
$arch = $env:PROCESSOR_ARCHITEW6432
|
|
||||||
}
|
|
||||||
switch ($arch) {
|
|
||||||
'AMD64' { return 'x86_64-pc-windows-msvc' }
|
|
||||||
'ARM64' { return 'aarch64-pc-windows-msvc' }
|
|
||||||
'x86' { return 'i686-pc-windows-msvc' }
|
|
||||||
default { Fail "Unsupported Windows architecture: $arch" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Fetch-ReleaseJson($channel) {
|
|
||||||
if ($channel -eq 'dev') {
|
|
||||||
Info "Looking for latest dev (pre-release)..."
|
|
||||||
$releases = Invoke-RestMethod -Method Get -Uri $ApiAll
|
|
||||||
$pre = $releases | Where-Object { $_.prerelease -eq $true } | Select-Object -First 1
|
|
||||||
if (-not $pre) { Fail "No dev (pre-release) found on GitHub" }
|
|
||||||
return $pre
|
|
||||||
} else {
|
|
||||||
return Invoke-RestMethod -Method Get -Uri $ApiLatest
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Install-FromRelease {
|
|
||||||
param([string]$target, [string]$channel)
|
|
||||||
|
|
||||||
New-Item -ItemType Directory -Path $InstallPath -Force | Out-Null
|
|
||||||
|
|
||||||
$release = Fetch-ReleaseJson $channel
|
|
||||||
$tag = $release.tag_name
|
|
||||||
$version = $tag.TrimStart('v')
|
|
||||||
|
|
||||||
# Имя бинарника: dcr-<triple>-<version>.exe
|
|
||||||
$assetName = "dcr-$target-$version.exe"
|
|
||||||
|
|
||||||
Info "Fetching release $tag (channel: $channel)..."
|
|
||||||
|
|
||||||
$asset = $release.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1
|
|
||||||
if (-not $asset) {
|
|
||||||
Fail "Asset $assetName not found in release $tag"
|
|
||||||
}
|
|
||||||
|
|
||||||
Info "Downloading $assetName..."
|
|
||||||
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $BinaryPath
|
|
||||||
Ok "Binary downloaded: $assetName"
|
|
||||||
}
|
|
||||||
|
|
||||||
function Install-FromSource {
|
|
||||||
param([string]$target, [string]$channel)
|
|
||||||
|
|
||||||
Require-Cmd 'git'
|
|
||||||
Require-Cmd 'cargo'
|
|
||||||
|
|
||||||
$tmp = Join-Path $env:TEMP 'dcr-install'
|
|
||||||
if (Test-Path $tmp) { Remove-Item -Recurse -Force $tmp }
|
|
||||||
|
|
||||||
Info 'Cloning repository...'
|
|
||||||
if ($channel -eq 'dev') {
|
|
||||||
# Пробуем ветку dev
|
|
||||||
$result = git clone --depth 1 --branch dev $RepoUrl $tmp 2>&1
|
|
||||||
if ($LASTEXITCODE -ne 0) {
|
|
||||||
git clone --depth 1 $RepoUrl $tmp | Out-Null
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
git clone --depth 1 $RepoUrl $tmp | Out-Null
|
|
||||||
}
|
|
||||||
|
|
||||||
Info 'Building release binary...'
|
|
||||||
Push-Location $tmp
|
|
||||||
cargo build --release --target $target
|
|
||||||
Pop-Location
|
|
||||||
|
|
||||||
New-Item -ItemType Directory -Path $InstallPath -Force | Out-Null
|
|
||||||
Copy-Item (Join-Path $tmp "target\$target\release\dcr.exe") $BinaryPath -Force
|
|
||||||
Ok 'Binary installed from source'
|
|
||||||
|
|
||||||
Remove-Item -Recurse -Force $tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
function Setup-Path {
|
|
||||||
New-Item -ItemType Directory -Path $BinPath -Force | Out-Null
|
|
||||||
$linkPath = Join-Path $BinPath 'dcr.exe'
|
|
||||||
Copy-Item $BinaryPath $linkPath -Force
|
|
||||||
|
|
||||||
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
|
|
||||||
if (-not $userPath) { $userPath = '' }
|
|
||||||
|
|
||||||
if (-not ($userPath -split ';' | Where-Object { $_ -eq $BinPath })) {
|
|
||||||
$newPath = if ($userPath) { "$userPath;$BinPath" } else { $BinPath }
|
|
||||||
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
|
|
||||||
$env:Path = "$env:Path;$BinPath"
|
|
||||||
Warn "Added path to PATH: $BinPath"
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok "dcr command is available via $linkPath"
|
|
||||||
}
|
|
||||||
|
|
||||||
Info 'Starting DCR installation'
|
|
||||||
$channel = Select-Channel
|
|
||||||
$mode = Select-Mode
|
|
||||||
$target = Get-Target
|
|
||||||
|
|
||||||
if ($mode -eq 'build') {
|
|
||||||
Install-FromSource -target $target -channel $channel
|
|
||||||
} else {
|
|
||||||
Install-FromRelease -target $target -channel $channel
|
|
||||||
}
|
|
||||||
|
|
||||||
Setup-Path
|
|
||||||
Ok 'Installation completed successfully'
|
|
||||||
253
install.sh
253
install.sh
@@ -1,253 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -Eeuo pipefail
|
|
||||||
|
|
||||||
TMPDIR="/tmp/dcr-install"
|
|
||||||
INSTALL_PATH="$HOME/.local/share/dcr"
|
|
||||||
BINPATH="$HOME/.local/bin"
|
|
||||||
MANPATH="${XDG_DATA_HOME:-$HOME/.local/share}/man"
|
|
||||||
LOGFILE="$HOME/.cache/dcr-install.log"
|
|
||||||
REPO_URL="https://github.com/dexoron/dcr"
|
|
||||||
GITHUB_API_LATEST="https://api.github.com/repos/dexoron/dcr/releases/latest"
|
|
||||||
GITHUB_API_ALL="https://api.github.com/repos/dexoron/dcr/releases"
|
|
||||||
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m'
|
|
||||||
|
|
||||||
mkdir -p "$(dirname "$LOGFILE")"
|
|
||||||
exec > >(tee -a "$LOGFILE") 2>&1
|
|
||||||
|
|
||||||
log() { echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"; }
|
|
||||||
success() { echo -e "${GREEN}✔ $1${NC}"; }
|
|
||||||
warn() { echo -e "${YELLOW}⚠ $1${NC}"; }
|
|
||||||
error() { echo -e "${RED}✖ $1${NC}"; }
|
|
||||||
|
|
||||||
trap 'error "Error on line $LINENO"; exit 1' ERR
|
|
||||||
|
|
||||||
INSTALL_MODE=""
|
|
||||||
CHANNEL=""
|
|
||||||
|
|
||||||
check_os() {
|
|
||||||
case "$(uname -s)" in
|
|
||||||
Linux|Darwin|FreeBSD|OpenBSD|NetBSD) ;;
|
|
||||||
*) error "Only Linux, macOS, and BSD systems are supported"; exit 1 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
detect_target() {
|
|
||||||
local os arch
|
|
||||||
os="$(uname -s)"
|
|
||||||
arch="$(uname -m)"
|
|
||||||
|
|
||||||
case "$os:$arch" in
|
|
||||||
Linux:x86_64) TARGET_TRIPLE="x86_64-unknown-linux-gnu" ;;
|
|
||||||
Linux:aarch64|Linux:arm64) TARGET_TRIPLE="aarch64-unknown-linux-gnu" ;;
|
|
||||||
Linux:i686|Linux:i386) TARGET_TRIPLE="i686-unknown-linux-gnu" ;;
|
|
||||||
Linux:armv7l|Linux:armv7) TARGET_TRIPLE="armv7-unknown-linux-gnueabihf" ;;
|
|
||||||
Linux:riscv64) TARGET_TRIPLE="riscv64gc-unknown-linux-gnu" ;;
|
|
||||||
Darwin:x86_64) TARGET_TRIPLE="x86_64-apple-darwin" ;;
|
|
||||||
Darwin:arm64|Darwin:aarch64) TARGET_TRIPLE="aarch64-apple-darwin" ;;
|
|
||||||
FreeBSD:x86_64|FreeBSD:amd64) TARGET_TRIPLE="x86_64-unknown-freebsd" ;;
|
|
||||||
FreeBSD:aarch64|FreeBSD:arm64) TARGET_TRIPLE="aarch64-unknown-freebsd" ;;
|
|
||||||
FreeBSD:i686|FreeBSD:i386) TARGET_TRIPLE="i686-unknown-freebsd" ;;
|
|
||||||
OpenBSD:x86_64|OpenBSD:amd64) TARGET_TRIPLE="x86_64-unknown-openbsd" ;;
|
|
||||||
OpenBSD:aarch64|OpenBSD:arm64) TARGET_TRIPLE="aarch64-unknown-openbsd" ;;
|
|
||||||
OpenBSD:i686|OpenBSD:i386) TARGET_TRIPLE="i686-unknown-openbsd" ;;
|
|
||||||
NetBSD:x86_64|NetBSD:amd64) TARGET_TRIPLE="x86_64-unknown-netbsd" ;;
|
|
||||||
NetBSD:aarch64|NetBSD:arm64) TARGET_TRIPLE="aarch64-unknown-netbsd" ;;
|
|
||||||
NetBSD:i686|NetBSD:i386) TARGET_TRIPLE="i686-unknown-netbsd" ;;
|
|
||||||
|
|
||||||
*) error "Unsupported platform: $os/$arch"; exit 1 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
check_common_dependencies() {
|
|
||||||
command -v curl >/dev/null 2>&1 || { error "curl is not installed"; exit 1; }
|
|
||||||
if [[ "$CHANNEL" == "dev" ]]; then
|
|
||||||
if ! command -v python3 >/dev/null 2>&1 && ! command -v jq >/dev/null 2>&1; then
|
|
||||||
error "For dev installations, either 'python3' or 'jq' must be installed to parse GitHub API response."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
check_build_dependencies() {
|
|
||||||
command -v git >/dev/null 2>&1 || { error "git is not installed"; exit 1; }
|
|
||||||
command -v cargo >/dev/null 2>&1 || { error "cargo is not installed"; exit 1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
select_channel() {
|
|
||||||
echo "Choose channel:"
|
|
||||||
echo " 1) Latest stable release (default)"
|
|
||||||
echo " 2) Latest dev (pre-release)"
|
|
||||||
read -r -p "Enter 1 or 2 [1]: " choice < /dev/tty
|
|
||||||
|
|
||||||
case "${choice:-1}" in
|
|
||||||
1) CHANNEL="stable" ;;
|
|
||||||
2) CHANNEL="dev" ;;
|
|
||||||
*) error "Unknown option"; exit 1 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
select_install_mode() {
|
|
||||||
echo "Choose installation mode:"
|
|
||||||
echo " 1) Download prebuilt binary from GitHub Release (recommended)"
|
|
||||||
echo " 2) Build from git"
|
|
||||||
read -r -p "Enter 1 or 2 [1]: " choice < /dev/tty
|
|
||||||
|
|
||||||
case "${choice:-1}" in
|
|
||||||
1) INSTALL_MODE="release" ;;
|
|
||||||
2) INSTALL_MODE="build" ;;
|
|
||||||
*) error "Unknown option"; exit 1 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Returns JSON of the requested release to stdout
|
|
||||||
fetch_release_json() {
|
|
||||||
if [[ "$CHANNEL" == "dev" ]]; then
|
|
||||||
log "Looking for latest dev (pre-release)..."
|
|
||||||
local json result
|
|
||||||
json="$(curl -fsSL "$GITHUB_API_ALL")"
|
|
||||||
if command -v jq >/dev/null 2>&1; then
|
|
||||||
result="$(printf '%s' "$json" | jq -e -c 'map(select(.prerelease == true))[0]')"
|
|
||||||
else
|
|
||||||
result="$(printf '%s' "$json" | python3 - <<'EOF'
|
|
||||||
import sys, json
|
|
||||||
releases = json.load(sys.stdin)
|
|
||||||
pre = [r for r in releases if r.get("prerelease", False)]
|
|
||||||
if not pre:
|
|
||||||
print("{}", end="")
|
|
||||||
else:
|
|
||||||
print(json.dumps(pre[0]), end="")
|
|
||||||
EOF
|
|
||||||
)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "$result" || "$result" == "{}" || "$result" == "null" ]]; then
|
|
||||||
error "No dev (pre-release) found on GitHub"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
printf '%s' "$result"
|
|
||||||
else
|
|
||||||
curl -fsSL "$GITHUB_API_LATEST"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
download_binary() {
|
|
||||||
local release_json tag version asset_name download_url
|
|
||||||
|
|
||||||
release_json="$(fetch_release_json)"
|
|
||||||
|
|
||||||
tag="$(printf '%s\n' "$release_json" | \
|
|
||||||
sed -n 's/.*"tag_name": "\([^"]*\)".*/\1/p' | head -n1)"
|
|
||||||
if [[ -z "$tag" ]]; then
|
|
||||||
error "Failed to determine release version"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Version without leading 'v'
|
|
||||||
version="${tag#v}"
|
|
||||||
# Binary name: dcr-<triple>-<version>
|
|
||||||
asset_name="dcr-${TARGET_TRIPLE}-${version}"
|
|
||||||
|
|
||||||
log "Fetching release ${tag} (channel: ${CHANNEL})..."
|
|
||||||
|
|
||||||
download_url="$(printf '%s\n' "$release_json" | \
|
|
||||||
sed -n "s#.*\"browser_download_url\": \"\([^\"]*/${asset_name}\)\".*#\1#p" | head -n1)"
|
|
||||||
|
|
||||||
if [[ -z "$download_url" ]]; then
|
|
||||||
error "Asset ${asset_name} not found in release ${tag}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "$INSTALL_PATH"
|
|
||||||
curl -fL "$download_url" -o "$INSTALL_PATH/dcr"
|
|
||||||
chmod +x "$INSTALL_PATH/dcr"
|
|
||||||
success "Binary ${asset_name} downloaded (${tag})"
|
|
||||||
}
|
|
||||||
|
|
||||||
prepare_sources() {
|
|
||||||
log "Fetching sources..."
|
|
||||||
rm -rf "$TMPDIR"
|
|
||||||
git clone --depth 1 "$REPO_URL" "$TMPDIR"
|
|
||||||
if [[ "$CHANNEL" == "dev" ]]; then
|
|
||||||
# Clone dev branch if it exists
|
|
||||||
git clone --depth 1 --branch dev "$REPO_URL" "$TMPDIR" 2>/dev/null || \
|
|
||||||
git clone --depth 1 "$REPO_URL" "$TMPDIR"
|
|
||||||
fi
|
|
||||||
success "Sources fetched"
|
|
||||||
}
|
|
||||||
|
|
||||||
build_binary() {
|
|
||||||
log "Building release binary..."
|
|
||||||
(cd "$TMPDIR" && cargo build --release)
|
|
||||||
success "Build completed"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_built_binary() {
|
|
||||||
mkdir -p "$INSTALL_PATH"
|
|
||||||
cp "$TMPDIR/target/release/dcr" "$INSTALL_PATH/dcr"
|
|
||||||
chmod +x "$INSTALL_PATH/dcr"
|
|
||||||
success "Binary installed from source"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_link() {
|
|
||||||
log "Creating symlink..."
|
|
||||||
mkdir -p "$BINPATH"
|
|
||||||
ln -sf "$INSTALL_PATH/dcr" "$BINPATH/dcr"
|
|
||||||
success "Command 'dcr' added to $BINPATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_man() {
|
|
||||||
log "Installing man pages..."
|
|
||||||
local man_src="$TMPDIR/man/man1"
|
|
||||||
if [[ -d "$man_src" ]]; then
|
|
||||||
mkdir -p "$MANPATH/man1"
|
|
||||||
cp "$man_src"/*.1 "$MANPATH/man1/"
|
|
||||||
success "Man pages installed to $MANPATH/man1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
check_path() {
|
|
||||||
if ! echo "$PATH" | grep -q "$BINPATH"; then
|
|
||||||
warn "Directory $BINPATH not found in PATH"
|
|
||||||
echo "Add this to ~/.bashrc or ~/.zshrc:"
|
|
||||||
echo "export PATH=\"$BINPATH:\$PATH\""
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
rm -rf "$TMPDIR" 2>/dev/null || true
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
|
||||||
log "Starting DCR installation"
|
|
||||||
|
|
||||||
check_os
|
|
||||||
detect_target
|
|
||||||
select_channel
|
|
||||||
check_common_dependencies
|
|
||||||
select_install_mode
|
|
||||||
cleanup
|
|
||||||
|
|
||||||
if [[ "$INSTALL_MODE" == "build" ]]; then
|
|
||||||
check_build_dependencies
|
|
||||||
prepare_sources
|
|
||||||
build_binary
|
|
||||||
install_built_binary
|
|
||||||
else
|
|
||||||
download_binary
|
|
||||||
fi
|
|
||||||
|
|
||||||
install_link
|
|
||||||
install_man
|
|
||||||
check_path
|
|
||||||
cleanup
|
|
||||||
|
|
||||||
success "Installation completed successfully"
|
|
||||||
log "Log saved to $LOGFILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
241
install_bsd.sh
241
install_bsd.sh
@@ -1,241 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
TMPDIR="/tmp/dcr-install"
|
|
||||||
INSTALL_PATH="$HOME/.local/share/dcr"
|
|
||||||
BINPATH="$HOME/.local/bin"
|
|
||||||
MANPATH="${XDG_DATA_HOME:-$HOME/.local/share}/man"
|
|
||||||
LOGFILE="$HOME/.cache/dcr-install.log"
|
|
||||||
REPO_URL="https://github.com/dexoron/dcr"
|
|
||||||
GITHUB_API_LATEST="https://api.github.com/repos/dexoron/dcr/releases/latest"
|
|
||||||
GITHUB_API_ALL="https://api.github.com/repos/dexoron/dcr/releases"
|
|
||||||
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m'
|
|
||||||
|
|
||||||
mkdir -p "$(dirname "$LOGFILE")"
|
|
||||||
|
|
||||||
log() { printf "${BLUE}[%s]${NC} %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1" | tee -a "$LOGFILE"; }
|
|
||||||
success() { printf "${GREEN}✔ %s${NC}\n" "$1" | tee -a "$LOGFILE"; }
|
|
||||||
warn() { printf "${YELLOW}⚠ %s${NC}\n" "$1" | tee -a "$LOGFILE"; }
|
|
||||||
error() { printf "${RED}✖ %s${NC}\n" "$1" | tee -a "$LOGFILE" >&2; }
|
|
||||||
|
|
||||||
INSTALL_MODE=""
|
|
||||||
CHANNEL=""
|
|
||||||
|
|
||||||
check_os() {
|
|
||||||
case "$(uname -s)" in
|
|
||||||
FreeBSD|OpenBSD|NetBSD|DragonFly) ;;
|
|
||||||
*) error "Only BSD systems (FreeBSD, OpenBSD, NetBSD, DragonFly) are supported by this script"; exit 1 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
detect_target() {
|
|
||||||
local os arch
|
|
||||||
os="$(uname -s)"
|
|
||||||
arch="$(uname -m)"
|
|
||||||
|
|
||||||
case "$os:$arch" in
|
|
||||||
FreeBSD:x86_64|FreeBSD:amd64) TARGET_TRIPLE="x86_64-unknown-freebsd" ;;
|
|
||||||
FreeBSD:aarch64|FreeBSD:arm64) TARGET_TRIPLE="aarch64-unknown-freebsd" ;;
|
|
||||||
FreeBSD:i686|FreeBSD:i386) TARGET_TRIPLE="i686-unknown-freebsd" ;;
|
|
||||||
OpenBSD:x86_64|OpenBSD:amd64) TARGET_TRIPLE="x86_64-unknown-openbsd" ;;
|
|
||||||
OpenBSD:aarch64|OpenBSD:arm64) TARGET_TRIPLE="aarch64-unknown-openbsd" ;;
|
|
||||||
OpenBSD:i686|OpenBSD:i386) TARGET_TRIPLE="i686-unknown-openbsd" ;;
|
|
||||||
NetBSD:x86_64|NetBSD:amd64) TARGET_TRIPLE="x86_64-unknown-netbsd" ;;
|
|
||||||
NetBSD:aarch64|NetBSD:arm64) TARGET_TRIPLE="aarch64-unknown-netbsd" ;;
|
|
||||||
NetBSD:i686|NetBSD:i386) TARGET_TRIPLE="i686-unknown-netbsd" ;;
|
|
||||||
DragonFly:x86_64|DragonFly:amd64) TARGET_TRIPLE="x86_64-unknown-dragonfly" ;;
|
|
||||||
*) error "Unsupported BSD platform: $os/$arch"; exit 1 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
check_common_dependencies() {
|
|
||||||
command -v curl >/dev/null 2>&1 || { error "curl is not installed"; exit 1; }
|
|
||||||
if [ "$CHANNEL" = "dev" ]; then
|
|
||||||
if ! command -v python3 >/dev/null 2>&1 && ! command -v jq >/dev/null 2>&1; then
|
|
||||||
error "For dev installations, either 'python3' or 'jq' must be installed to parse GitHub API response."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
check_build_dependencies() {
|
|
||||||
command -v git >/dev/null 2>&1 || { error "git is not installed"; exit 1; }
|
|
||||||
command -v cargo >/dev/null 2>&1 || { error "cargo is not installed"; exit 1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
select_channel() {
|
|
||||||
echo "Choose channel:"
|
|
||||||
echo " 1) Latest stable release (default)"
|
|
||||||
echo " 2) Latest dev (pre-release)"
|
|
||||||
printf "Enter 1 or 2 [1]: "
|
|
||||||
read -r choice
|
|
||||||
|
|
||||||
case "${choice:-1}" in
|
|
||||||
1) CHANNEL="stable" ;;
|
|
||||||
2) CHANNEL="dev" ;;
|
|
||||||
*) error "Unknown option"; exit 1 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
select_install_mode() {
|
|
||||||
echo "Choose installation mode:"
|
|
||||||
echo " 1) Download prebuilt binary from GitHub Release (recommended)"
|
|
||||||
echo " 2) Build from git"
|
|
||||||
printf "Enter 1 or 2 [1]: "
|
|
||||||
read -r choice
|
|
||||||
|
|
||||||
case "${choice:-1}" in
|
|
||||||
1) INSTALL_MODE="release" ;;
|
|
||||||
2) INSTALL_MODE="build" ;;
|
|
||||||
*) error "Unknown option"; exit 1 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
fetch_release_json() {
|
|
||||||
if [ "$CHANNEL" = "dev" ]; then
|
|
||||||
log "Looking for latest dev (pre-release)..."
|
|
||||||
local json result
|
|
||||||
json="$(curl -fsSL "$GITHUB_API_ALL")"
|
|
||||||
if command -v jq >/dev/null 2>&1; then
|
|
||||||
result="$(printf '%s' "$json" | jq -e -c 'map(select(.prerelease == true))[0]')"
|
|
||||||
else
|
|
||||||
result="$(printf '%s' "$json" | python3 - <<'EOF'
|
|
||||||
import sys, json
|
|
||||||
releases = json.load(sys.stdin)
|
|
||||||
pre = [r for r in releases if r.get("prerelease", False)]
|
|
||||||
if not pre:
|
|
||||||
print("{}", end="")
|
|
||||||
else:
|
|
||||||
print(json.dumps(pre[0]), end="")
|
|
||||||
EOF
|
|
||||||
)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$result" ] || [ "$result" = "{}" ] || [ "$result" = "null" ]; then
|
|
||||||
error "No dev (pre-release) found on GitHub"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
printf '%s' "$result"
|
|
||||||
else
|
|
||||||
curl -fsSL "$GITHUB_API_LATEST"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
download_binary() {
|
|
||||||
local release_json tag version asset_name download_url
|
|
||||||
|
|
||||||
release_json="$(fetch_release_json)"
|
|
||||||
|
|
||||||
tag="$(printf '%s\n' "$release_json" | \
|
|
||||||
sed -n 's/.*"tag_name": "\([^"]*\)".*/\1/p' | head -n1)"
|
|
||||||
if [ -z "$tag" ]; then
|
|
||||||
error "Failed to determine release version"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
version="${tag#v}"
|
|
||||||
asset_name="dcr-${TARGET_TRIPLE}-${version}"
|
|
||||||
|
|
||||||
log "Fetching release ${tag} (channel: ${CHANNEL})..."
|
|
||||||
|
|
||||||
download_url="$(printf '%s\n' "$release_json" | \
|
|
||||||
sed -n "s#.*\"browser_download_url\": \"\([^\"]*/${asset_name}\)\".*#\1#p" | head -n1)"
|
|
||||||
|
|
||||||
if [ -z "$download_url" ]; then
|
|
||||||
error "Asset ${asset_name} not found in release ${tag}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "$INSTALL_PATH"
|
|
||||||
curl -fL "$download_url" -o "$INSTALL_PATH/dcr"
|
|
||||||
chmod +x "$INSTALL_PATH/dcr"
|
|
||||||
success "Binary ${asset_name} downloaded (${tag})"
|
|
||||||
}
|
|
||||||
|
|
||||||
prepare_sources() {
|
|
||||||
log "Fetching sources..."
|
|
||||||
rm -rf "$TMPDIR"
|
|
||||||
git clone --depth 1 "$REPO_URL" "$TMPDIR"
|
|
||||||
if [ "$CHANNEL" = "dev" ]; then
|
|
||||||
git clone --depth 1 --branch dev "$REPO_URL" "$TMPDIR" 2>/dev/null || \
|
|
||||||
git clone --depth 1 "$REPO_URL" "$TMPDIR"
|
|
||||||
fi
|
|
||||||
success "Sources fetched"
|
|
||||||
}
|
|
||||||
|
|
||||||
build_binary() {
|
|
||||||
log "Building release binary..."
|
|
||||||
(cd "$TMPDIR" && cargo build --release)
|
|
||||||
success "Build completed"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_built_binary() {
|
|
||||||
mkdir -p "$INSTALL_PATH"
|
|
||||||
cp "$TMPDIR/target/release/dcr" "$INSTALL_PATH/dcr"
|
|
||||||
chmod +x "$INSTALL_PATH/dcr"
|
|
||||||
success "Binary installed from source"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_link() {
|
|
||||||
log "Creating symlink..."
|
|
||||||
mkdir -p "$BINPATH"
|
|
||||||
ln -sf "$INSTALL_PATH/dcr" "$BINPATH/dcr"
|
|
||||||
success "Command 'dcr' added to $BINPATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
install_man() {
|
|
||||||
log "Installing man pages..."
|
|
||||||
man_src="$TMPDIR/man/man1"
|
|
||||||
if [ -d "$man_src" ]; then
|
|
||||||
mkdir -p "$MANPATH/man1"
|
|
||||||
cp "$man_src"/*.1 "$MANPATH/man1/"
|
|
||||||
success "Man pages installed to $MANPATH/man1"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
check_path() {
|
|
||||||
if ! echo "$PATH" | grep -q "$BINPATH"; then
|
|
||||||
warn "Directory $BINPATH not found in PATH"
|
|
||||||
echo "Add this to ~/.bashrc, ~/.zshrc or ~/.profile:"
|
|
||||||
echo "export PATH=\"$BINPATH:\$PATH\""
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
rm -rf "$TMPDIR" 2>/dev/null || true
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
|
||||||
log "Starting DCR installation for BSD"
|
|
||||||
|
|
||||||
check_os
|
|
||||||
select_channel
|
|
||||||
check_common_dependencies
|
|
||||||
detect_target
|
|
||||||
select_install_mode
|
|
||||||
cleanup
|
|
||||||
|
|
||||||
if [ "$INSTALL_MODE" = "build" ]; then
|
|
||||||
check_build_dependencies
|
|
||||||
prepare_sources
|
|
||||||
build_binary
|
|
||||||
install_built_binary
|
|
||||||
else
|
|
||||||
download_binary
|
|
||||||
fi
|
|
||||||
|
|
||||||
install_link
|
|
||||||
install_man
|
|
||||||
check_path
|
|
||||||
cleanup
|
|
||||||
|
|
||||||
success "Installation completed successfully"
|
|
||||||
log "Log saved to $LOGFILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
Reference in New Issue
Block a user