mirror of
https://github.com/webinstall/webi-installers.git
synced 2026-05-28 11:33:09 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e86b7c4374 | ||
|
|
0e7c22ec2c | ||
|
|
7d6a01c200 | ||
|
|
946a340423 | ||
|
|
c3fff12f2b | ||
|
|
d62cbb1be0 | ||
|
|
49f2f26c91 | ||
|
|
ac88090aed | ||
|
|
d0fa554117 | ||
|
|
d0a9fdda05 | ||
|
|
e6ad76382d | ||
|
|
3fc6dcdb73 | ||
|
|
cd5f06c653 | ||
|
|
aafb6ffabe | ||
|
|
f112a1c90b |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -18,15 +18,21 @@ install-*.ps1
|
|||||||
*.env
|
*.env
|
||||||
.env
|
.env
|
||||||
!example.env
|
!example.env
|
||||||
|
LOCAL.md
|
||||||
|
|
||||||
# caches
|
# caches
|
||||||
_cache/
|
_cache/
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
# temporary & backup files
|
# temporary & backup files
|
||||||
|
agents/
|
||||||
.*.sw*
|
.*.sw*
|
||||||
*.bak
|
*.bak
|
||||||
*.bak.*
|
*.bak.*
|
||||||
|
tmp
|
||||||
|
*.tmp
|
||||||
|
tmp.*
|
||||||
|
*.tmp.*
|
||||||
|
|
||||||
# agent session files
|
# agent session files
|
||||||
agents/
|
agents/
|
||||||
@@ -38,3 +44,4 @@ desktop.ini
|
|||||||
LIVE_cache
|
LIVE_cache
|
||||||
/webid
|
/webid
|
||||||
bin/
|
bin/
|
||||||
|
.claude/
|
||||||
|
|||||||
@@ -71,6 +71,14 @@ Builds.getPackage({ name: projName }).then(async function (/*projInfo*/) {
|
|||||||
var nodeOs = os.platform();
|
var nodeOs = os.platform();
|
||||||
var nodeOsRelease = os.release();
|
var nodeOsRelease = os.release();
|
||||||
var nodeArch = os.arch();
|
var nodeArch = os.arch();
|
||||||
|
|
||||||
|
// To make arch names compatible across all helpers
|
||||||
|
if (nodeArch === 'x64') {
|
||||||
|
nodeArch = 'amd64';
|
||||||
|
} else if (nodeArch === 'arm64') {
|
||||||
|
nodeArch = 'arm64';
|
||||||
|
}
|
||||||
|
|
||||||
var nodeLibc = 'libc';
|
var nodeLibc = 'libc';
|
||||||
if (process.platform === 'linux') {
|
if (process.platform === 'linux') {
|
||||||
nodeLibc = 'gnu';
|
nodeLibc = 'gnu';
|
||||||
|
|||||||
128
basecamp/README.md
Normal file
128
basecamp/README.md
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
---
|
||||||
|
title: basecamp
|
||||||
|
homepage: https://github.com/basecamp/basecamp-cli
|
||||||
|
tagline: |
|
||||||
|
basecamp: CLI for Basecamp 3 — manage projects, todos, messages, cards, and more from the terminal.
|
||||||
|
---
|
||||||
|
|
||||||
|
To update or switch versions, run `webi basecamp@stable` (or `@v0.7`,
|
||||||
|
`@beta`, etc).
|
||||||
|
|
||||||
|
### Files
|
||||||
|
|
||||||
|
These are the files / directories that are created and/or modified with this
|
||||||
|
install:
|
||||||
|
|
||||||
|
```text
|
||||||
|
~/.config/envman/PATH.env
|
||||||
|
~/.local/bin/basecamp
|
||||||
|
~/.local/opt/basecamp-VERSION/bin/basecamp
|
||||||
|
~/.local/opt/basecamp-VERSION/completions/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cheat Sheet
|
||||||
|
|
||||||
|
> `basecamp` is the official CLI for Basecamp 3. It provides full API coverage
|
||||||
|
> for projects, todos, messages, cards, schedule, files, and more — all from the
|
||||||
|
> command line.
|
||||||
|
|
||||||
|
### How to authenticate
|
||||||
|
|
||||||
|
```sh
|
||||||
|
basecamp auth login
|
||||||
|
```
|
||||||
|
|
||||||
|
For headless environments (CI, remote servers):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
basecamp auth login --device-code
|
||||||
|
```
|
||||||
|
|
||||||
|
Check auth status:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
basecamp auth status
|
||||||
|
```
|
||||||
|
|
||||||
|
### How to list projects and todos
|
||||||
|
|
||||||
|
```sh
|
||||||
|
basecamp projects list --md
|
||||||
|
|
||||||
|
basecamp todos list --assignee me --in PROJECT_ID --md
|
||||||
|
```
|
||||||
|
|
||||||
|
Cross-project view of your assigned work:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
basecamp assignments --md
|
||||||
|
```
|
||||||
|
|
||||||
|
### How to create and complete todos
|
||||||
|
|
||||||
|
```sh
|
||||||
|
basecamp todo "Write release notes" --in PROJECT_ID --list TODOLIST_ID --assignee me --due tomorrow
|
||||||
|
|
||||||
|
basecamp done TODO_ID
|
||||||
|
```
|
||||||
|
|
||||||
|
### How to post a message or comment
|
||||||
|
|
||||||
|
```sh
|
||||||
|
basecamp message "Sprint Update" "Shipped v2.1 to production." --in PROJECT_ID
|
||||||
|
|
||||||
|
basecamp comment RECORDING_ID "Looks good." --in PROJECT_ID
|
||||||
|
```
|
||||||
|
|
||||||
|
### How to move cards through a workflow
|
||||||
|
|
||||||
|
```sh
|
||||||
|
basecamp cards columns --in PROJECT_ID --md
|
||||||
|
|
||||||
|
basecamp cards move CARD_ID --to COLUMN_ID --in PROJECT_ID
|
||||||
|
```
|
||||||
|
|
||||||
|
### How to set up per-project defaults
|
||||||
|
|
||||||
|
Create `.basecamp/config.json` in your repo (commit it):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"project_id": "12345",
|
||||||
|
"todolist_id": "67890"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then trust it once:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
basecamp config trust
|
||||||
|
```
|
||||||
|
|
||||||
|
After that, you can omit `--in` for most commands in that repo.
|
||||||
|
|
||||||
|
### Shell completions
|
||||||
|
|
||||||
|
Completions for bash, fish, and zsh ship with the installer. Find them at:
|
||||||
|
|
||||||
|
```text
|
||||||
|
~/.local/opt/basecamp-VERSION/completions/
|
||||||
|
```
|
||||||
|
|
||||||
|
Bash:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
echo "source ~/.local/opt/basecamp-VERSION/completions/basecamp.bash" >> ~/.bashrc
|
||||||
|
```
|
||||||
|
|
||||||
|
Fish:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ln -s ~/.local/opt/basecamp-VERSION/completions/basecamp.fish ~/.config/fish/completions/
|
||||||
|
```
|
||||||
|
|
||||||
|
Zsh:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
echo "fpath+=( ~/.local/opt/basecamp-VERSION/completions )" >> ~/.zshrc
|
||||||
|
```
|
||||||
46
basecamp/install.ps1
Normal file
46
basecamp/install.ps1
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
|
||||||
|
$pkg_cmd_name = "basecamp"
|
||||||
|
|
||||||
|
$pkg_dst_cmd = "$Env:USERPROFILE\.local\bin\basecamp.exe"
|
||||||
|
$pkg_dst = "$pkg_dst_cmd"
|
||||||
|
|
||||||
|
$pkg_src_cmd = "$Env:USERPROFILE\.local\opt\basecamp-v$Env:WEBI_VERSION\bin\basecamp.exe"
|
||||||
|
$pkg_src_bin = "$Env:USERPROFILE\.local\opt\basecamp-v$Env:WEBI_VERSION\bin"
|
||||||
|
$pkg_src_dir = "$Env:USERPROFILE\.local\opt\basecamp-v$Env:WEBI_VERSION"
|
||||||
|
$pkg_src = "$pkg_src_cmd"
|
||||||
|
|
||||||
|
New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | Out-Null
|
||||||
|
$pkg_download = "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE"
|
||||||
|
|
||||||
|
if (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE")) {
|
||||||
|
Write-Output "Downloading basecamp from $Env:WEBI_PKG_URL to $pkg_download"
|
||||||
|
& curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_PKG_URL" -o "$pkg_download.part"
|
||||||
|
& Move-Item "$pkg_download.part" "$pkg_download"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Test-Path -Path "$pkg_src_cmd")) {
|
||||||
|
Write-Output "Installing basecamp"
|
||||||
|
|
||||||
|
Push-Location .local\tmp
|
||||||
|
|
||||||
|
Remove-Item -Path ".\basecamp-*" -Recurse -ErrorAction Ignore
|
||||||
|
Remove-Item -Path ".\basecamp.exe" -Recurse -ErrorAction Ignore
|
||||||
|
|
||||||
|
Write-Output "Unpacking $pkg_download"
|
||||||
|
& tar xf "$pkg_download"
|
||||||
|
|
||||||
|
New-Item "$pkg_src_bin" -ItemType Directory -Force | Out-Null
|
||||||
|
Move-Item -Path ".\basecamp.exe" -Destination "$pkg_src_bin"
|
||||||
|
|
||||||
|
New-Item "$pkg_src_dir\completions" -ItemType Directory -Force | Out-Null
|
||||||
|
if (Test-Path -Path ".\completions") {
|
||||||
|
Copy-Item -Path ".\completions\*" -Destination "$pkg_src_dir\completions" -Recurse
|
||||||
|
}
|
||||||
|
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Output "Copying into '$pkg_dst_cmd' from '$pkg_src_cmd'"
|
||||||
|
Remove-Item -Path "$pkg_dst_cmd" -Recurse -ErrorAction Ignore | Out-Null
|
||||||
|
Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse
|
||||||
44
basecamp/install.sh
Normal file
44
basecamp/install.sh
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
|
||||||
|
__init_basecamp() {
|
||||||
|
pkg_cmd_name="basecamp"
|
||||||
|
|
||||||
|
pkg_src_dir="$HOME/.local/opt/basecamp-v$WEBI_VERSION"
|
||||||
|
pkg_src_cmd="$pkg_src_dir/bin/basecamp"
|
||||||
|
pkg_src="$pkg_src_cmd"
|
||||||
|
|
||||||
|
pkg_dst_cmd="$HOME/.local/bin/basecamp"
|
||||||
|
pkg_dst="$pkg_dst_cmd"
|
||||||
|
|
||||||
|
pkg_install() {
|
||||||
|
mkdir -p "$(dirname "$pkg_src_cmd")"
|
||||||
|
mkdir -p "$pkg_src_dir/completions"
|
||||||
|
|
||||||
|
if test -f ./basecamp; then
|
||||||
|
mv ./basecamp "$pkg_src_cmd"
|
||||||
|
elif test -e ./basecamp-*/basecamp; then
|
||||||
|
mv ./basecamp-*/basecamp "$pkg_src_cmd"
|
||||||
|
elif test -e ./basecamp-*; then
|
||||||
|
mv ./basecamp-* "$pkg_src_cmd"
|
||||||
|
else
|
||||||
|
echo >&2 "failed to find 'basecamp' executable"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -d ./completions; then
|
||||||
|
cp -a ./completions/. "$pkg_src_dir/completions/"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
pkg_get_current_version() {
|
||||||
|
basecamp --version 2> /dev/null |
|
||||||
|
head -n 1 |
|
||||||
|
cut -d' ' -f3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__init_basecamp
|
||||||
2
basecamp/releases.conf
Normal file
2
basecamp/releases.conf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
github_releases = basecamp/basecamp-cli
|
||||||
|
exclude = .bundle .txt
|
||||||
188
brew/install.sh
188
brew/install.sh
@@ -4,73 +4,143 @@ set -e
|
|||||||
set -u
|
set -u
|
||||||
|
|
||||||
_install_brew() {
|
_install_brew() {
|
||||||
# Straight from https://brew.sh
|
# Straight from https://brew.sh
|
||||||
#/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
|
#/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||||
|
|
||||||
if test "Darwin" = "$(uname -s)"; then
|
if test "Darwin" = "$(uname -s)"; then
|
||||||
needs_xcode="$(/usr/bin/xcode-select -p > /dev/null 2> /dev/null || echo "true")"
|
needs_xcode="$(/usr/bin/xcode-select -p > /dev/null 2> /dev/null || echo "true")"
|
||||||
if test -n "${needs_xcode}"; then
|
if test -n "${needs_xcode}"; then
|
||||||
echo ""
|
echo ""
|
||||||
echo ""
|
echo ""
|
||||||
echo "ERROR: Run this command to install XCode Command Line Tools first:"
|
echo "ERROR: Run this command to install XCode Command Line Tools first:"
|
||||||
echo ""
|
echo ""
|
||||||
echo " xcode-select --install"
|
echo " xcode-select --install"
|
||||||
echo ""
|
echo ""
|
||||||
echo "After the install, close this terminal, open a new one, and try again."
|
echo "After the install, close this terminal, open a new one, and try again."
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if ! command -v gcc > /dev/null; then
|
if ! command -v gcc > /dev/null; then
|
||||||
echo >&2 "Warning: to install 'gcc' et al on Linux use the built-in package manager."
|
echo >&2 "Warning: to install 'gcc' et al on Linux use the built-in package manager."
|
||||||
echo >&2 " For example, try: sudo apt install -y build-essential"
|
echo >&2 " For example, try: sudo apt install -y build-essential"
|
||||||
fi
|
fi
|
||||||
if ! command -v git > /dev/null; then
|
if ! command -v git > /dev/null; then
|
||||||
echo >&2 "Error: to install 'git' on Linux use the built-in package manager."
|
echo >&2 "Error: to install 'git' on Linux use the built-in package manager."
|
||||||
echo >&2 " For example, try: sudo apt install -y git"
|
echo >&2 " For example, try: sudo apt install -y git"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# From Straight from https://brew.sh
|
# From Straight from https://brew.sh
|
||||||
if ! test -d "$HOME/.local/opt/brew"; then
|
if ! test -d "$HOME/.local/opt/brew"; then
|
||||||
echo "Installing to '$HOME/.local/opt/brew'"
|
echo "Installing to '$HOME/.local/opt/brew'"
|
||||||
echo ""
|
echo ""
|
||||||
echo "If you prefer to have brew installed to '/usr/local' cancel now and do the following:"
|
echo "If you prefer to have brew installed to '/usr/local' cancel now and do the following:"
|
||||||
echo " rm -rf '$HOME/.local/opt/brew'"
|
echo " rm -rf '$HOME/.local/opt/brew'"
|
||||||
# shellcheck disable=2016
|
# shellcheck disable=2016
|
||||||
echo ' /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"'
|
echo ' /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
|
||||||
echo ""
|
echo ""
|
||||||
sleep 3
|
sleep 3
|
||||||
git clone --depth=1 https://github.com/Homebrew/brew "$HOME/.local/opt/brew"
|
#mkdir -p "$HOME/.local/opt/brew"
|
||||||
fi
|
#curl -fsSL https://github.com/Homebrew/brew/tarball/main |
|
||||||
|
# tar xz --strip-components 1 -C "$HOME/.local/opt/brew"
|
||||||
|
git clone --depth 3 https://github.com/Homebrew/brew "$HOME/.local/opt/brew"
|
||||||
|
fi
|
||||||
|
|
||||||
rm -rf "$HOME/.local/bin/brew-update-service-install"
|
my_shellenv="$("$HOME/.local/opt/brew/bin/brew" shellenv)"
|
||||||
webi_download \
|
eval "${my_shellenv}"
|
||||||
"$WEBI_HOST/packages/brew/brew-update-service-install" \
|
chmod -R go-w "$(brew --prefix)/share/zsh" 2> /dev/null || true
|
||||||
"$HOME/.local/bin/brew-update-service-install" \
|
|
||||||
brew-update-service-install
|
|
||||||
chmod a+x "$HOME/.local/bin/brew-update-service-install"
|
|
||||||
|
|
||||||
webi_path_add "$HOME/.local/opt/brew/bin"
|
rm -rf "$HOME/.local/bin/brew-update-service-install"
|
||||||
export PATH="$HOME/.local/opt/brew/bin:$PATH"
|
webi_download \
|
||||||
|
"$WEBI_HOST/packages/brew/brew-update-service-install" \
|
||||||
|
"$HOME/.local/bin/brew-update-service-install" \
|
||||||
|
brew-update-service-install
|
||||||
|
chmod a+x "$HOME/.local/bin/brew-update-service-install"
|
||||||
|
|
||||||
echo "Updating brew..."
|
webi_path_add "$HOME/.local/opt/brew/bin"
|
||||||
brew update
|
webi_path_add "$HOME/.local/opt/brew/sbin"
|
||||||
|
|
||||||
webi_path_add "$HOME/.local/opt/brew/sbin"
|
fn_brew_shell_integrate_bash
|
||||||
export PATH="$HOME/.local/opt/brew/sbin:$PATH"
|
fn_brew_shell_integrate_zsh
|
||||||
|
fn_brew_shell_integrate_fish
|
||||||
|
|
||||||
echo "Installed 'brew' to '$HOME/.local/opt/brew'"
|
echo "Installed 'brew' to '$HOME/.local/opt/brew'"
|
||||||
echo ""
|
echo ""
|
||||||
echo "If you prefer to have brew installed to '/usr/local' do the following:"
|
echo "If you prefer to have brew installed to '/usr/local' do the following:"
|
||||||
echo " mv '$HOME/.local/opt/brew' '$HOME/.local/opt/brew.$(date '+%F_%H-%M-%S').bak'"
|
echo " mv '$HOME/.local/opt/brew' '$HOME/.local/opt/brew.$(date '+%F_%H-%M-%S').bak'"
|
||||||
# shellcheck disable=2016
|
# shellcheck disable=2016
|
||||||
echo ' /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"'
|
echo ' /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
echo "To register 'brew update' as a hourly system service:"
|
echo "To register 'brew update' as a hourly system service:"
|
||||||
echo " brew-update-service-install"
|
echo " brew-update-service-install"
|
||||||
echo ""
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
fn_brew_shell_integrate_bash() {
|
||||||
|
if ! command -v bash > /dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if ! test -e ~/.bashrc && ! test -e ~/.bash_history; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
touch -a ~/.bashrc
|
||||||
|
if grep -q 'brew shellenv' ~/.bashrc; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo >&2 " Edit ~/.bashrc to init brew"
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
{
|
||||||
|
echo ''
|
||||||
|
echo '# Generated by Webi. Do not edit.'
|
||||||
|
echo 'eval "$('"$HOME/.local/opt/brew/bin/brew"' shellenv)"'
|
||||||
|
} >> ~/.bashrc
|
||||||
|
}
|
||||||
|
|
||||||
|
fn_brew_shell_integrate_zsh() {
|
||||||
|
if ! command -v zsh > /dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if ! test -e ~/.zshrc &&
|
||||||
|
! test -e ~/.zsh_sessions &&
|
||||||
|
! test -e ~/.zsh_history; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
touch -a ~/.zshrc
|
||||||
|
if grep -q 'brew shellenv' ~/.zshrc; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo >&2 " Edit ~/.zshrc to init brew"
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
{
|
||||||
|
echo ''
|
||||||
|
echo '# Generated by Webi. Do not edit.'
|
||||||
|
echo 'eval "$('"$HOME/.local/opt/brew/bin/brew"' shellenv)"'
|
||||||
|
} >> ~/.zshrc
|
||||||
|
}
|
||||||
|
|
||||||
|
fn_brew_shell_integrate_fish() {
|
||||||
|
if ! command -v fish > /dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p ~/.config/fish
|
||||||
|
touch -a ~/.config/fish/config.fish
|
||||||
|
if grep -q 'brew shellenv' ~/.config/fish/config.fish; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo >&2 " Edit ~/.config/fish/config.fish to init brew"
|
||||||
|
{
|
||||||
|
echo ''
|
||||||
|
echo '# Generated by Webi. Do not edit.'
|
||||||
|
echo "$HOME/.local/opt/brew/bin/brew shellenv | source"
|
||||||
|
} >> ~/.config/fish/config.fish
|
||||||
}
|
}
|
||||||
|
|
||||||
_install_brew
|
_install_brew
|
||||||
|
|||||||
109
btop/README.md
Normal file
109
btop/README.md
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
---
|
||||||
|
title: btop
|
||||||
|
homepage: https://github.com/aristocratos/btop
|
||||||
|
tagline: |
|
||||||
|
btop: a beautiful, interactive resource monitor
|
||||||
|
description: |
|
||||||
|
btop++ is a fast, feature-rich terminal resource monitor written in C++.
|
||||||
|
It shows real-time usage and stats for CPU, memory, disks, network, and
|
||||||
|
processes — with full mouse support, customizable themes, and an
|
||||||
|
easy-to-use menu system. The spiritual successor to bashtop and bpytop.
|
||||||
|
---
|
||||||
|
|
||||||
|
To update or switch versions, run `webi btop@stable` (or `@v1.4`, `@beta`, etc).
|
||||||
|
|
||||||
|
### Files
|
||||||
|
|
||||||
|
These are the files / directories that are created and/or modified with this
|
||||||
|
install:
|
||||||
|
|
||||||
|
```
|
||||||
|
~/.config/envman/PATH.env
|
||||||
|
~/.local/bin/btop
|
||||||
|
~/.local/opt/btop/
|
||||||
|
~/.local/opt/btop-<VERSION>/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cheat Sheet
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> btop gives you a gorgeous, interactive view of what your system is doing —
|
||||||
|
> CPU cores, RAM, swap, disk I/O, network throughput, and a filterable process
|
||||||
|
> list — all in one terminal window.
|
||||||
|
|
||||||
|
### Launch btop
|
||||||
|
|
||||||
|
```sh
|
||||||
|
btop
|
||||||
|
```
|
||||||
|
|
||||||
|
### Navigation
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
| -------------- | ----------------------------------- |
|
||||||
|
| `Arrow keys` | Move selection in process list |
|
||||||
|
| `Enter` | Show detailed stats for process |
|
||||||
|
| `F` | Filter / search processes |
|
||||||
|
| `K` | Send signal (kill, SIGTERM, etc.) |
|
||||||
|
| `R` | Renice (change process priority) |
|
||||||
|
| `T` | Toggle tree / flat process view |
|
||||||
|
| `M` | Change sort field |
|
||||||
|
| `ESC` | Open settings menu |
|
||||||
|
| `Q` | Quit |
|
||||||
|
|
||||||
|
Mouse support is fully enabled by default — scroll and click anywhere in the UI.
|
||||||
|
|
||||||
|
### Change the color theme
|
||||||
|
|
||||||
|
Press `ESC` to open the menu, navigate to **Options → Color theme**, and pick
|
||||||
|
from the built-in themes (Default, TTY, Dracula, Gruvbox, and more).
|
||||||
|
|
||||||
|
Custom themes can be placed in:
|
||||||
|
|
||||||
|
```
|
||||||
|
~/.config/btop/themes/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adjust update interval
|
||||||
|
|
||||||
|
In the Options menu, set **Update interval** (in milliseconds). The default is
|
||||||
|
`2000` (2 seconds). Lower values give a more live feel; higher values reduce CPU
|
||||||
|
overhead from btop itself.
|
||||||
|
|
||||||
|
### Config file location
|
||||||
|
|
||||||
|
btop's settings are saved automatically at:
|
||||||
|
|
||||||
|
```
|
||||||
|
~/.config/btop/btop.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
You can edit this file directly to set options like `update_ms`, `color_theme`,
|
||||||
|
`proc_sorting`, or `net_iface`.
|
||||||
|
|
||||||
|
### Run btop with a specific network interface shown
|
||||||
|
|
||||||
|
```sh
|
||||||
|
btop --utf-foce # force UTF-8 box drawing
|
||||||
|
btop --debug # verbose debug output to btop.log
|
||||||
|
```
|
||||||
|
|
||||||
|
Network interface selection is done interactively inside btop via the network
|
||||||
|
panel — press `B` / `N` to cycle interfaces.
|
||||||
|
|
||||||
|
### GPU monitoring (Linux x86\_64)
|
||||||
|
|
||||||
|
On Linux, btop supports Nvidia, AMD, and Intel GPUs out of the box provided the
|
||||||
|
correct drivers are installed. If wattage or GPU stats are missing, you may need
|
||||||
|
to grant extended capabilities:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Run once after install (requires sudo)
|
||||||
|
sudo setcap cap_perfmon,cap_sys_ptrace+ep ~/.local/bin/btop
|
||||||
|
```
|
||||||
|
|
||||||
|
### See also
|
||||||
|
|
||||||
|
- [btop releases](https://github.com/aristocratos/btop/releases)
|
||||||
|
- [Theme gallery](https://github.com/aristocratos/btop/tree/main/themes)
|
||||||
58
btop/install.sh
Normal file
58
btop/install.sh
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
__init_btop() {
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
|
||||||
|
################
|
||||||
|
# Install btop #
|
||||||
|
################
|
||||||
|
|
||||||
|
# Every package should define these 6 variables
|
||||||
|
pkg_cmd_name="btop"
|
||||||
|
|
||||||
|
pkg_dst_cmd="$HOME/.local/bin/btop"
|
||||||
|
pkg_dst="$pkg_dst_cmd"
|
||||||
|
|
||||||
|
pkg_src_cmd="$HOME/.local/opt/btop-v$WEBI_VERSION/bin/btop"
|
||||||
|
pkg_src_dir="$HOME/.local/opt/btop-v$WEBI_VERSION"
|
||||||
|
pkg_src="$pkg_src_cmd"
|
||||||
|
|
||||||
|
# pkg_install must be defined by every package
|
||||||
|
pkg_install() {
|
||||||
|
# ~/.local/opt/btop-v1.4.6/bin
|
||||||
|
mkdir -p "$(dirname "${pkg_src_cmd}")"
|
||||||
|
|
||||||
|
# mv ./btop/bin/btop ~/.local/opt/btop-v1.4.6/bin/btop
|
||||||
|
mv ./btop/bin/btop "${pkg_src_cmd}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# pkg_get_current_version is recommended, but not required
|
||||||
|
pkg_get_current_version() {
|
||||||
|
# 'btop --version' has output in this format:
|
||||||
|
# btop 1.4.6 (rev abcdef0123)
|
||||||
|
# This trims it down to just the version number:
|
||||||
|
# 1.4.6
|
||||||
|
btop --version 2> /dev/null |
|
||||||
|
head -n 1 |
|
||||||
|
cut -d ' ' -f 2
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn_btop_brew_install() {
|
||||||
|
if ! command -v brew > /dev/null; then
|
||||||
|
"$HOME/.local/bin/webi" brew
|
||||||
|
export PATH="$HOME/.local/opt/brew/bin:$HOME/.local/opt/brew/sbin:$PATH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export HOMEBREW_NO_AUTO_UPDATE=1
|
||||||
|
export HOMEBREW_NO_ENV_HINTS=1
|
||||||
|
brew install btop
|
||||||
|
}
|
||||||
|
|
||||||
|
my_os=$(uname -s)
|
||||||
|
if test "Darwin" = "${my_os}" && test "$WEBI_CHANNEL" = "error"; then
|
||||||
|
fn_btop_brew_install
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
__init_btop
|
||||||
2
btop/releases.conf
Normal file
2
btop/releases.conf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
github_releases = aristocratos/btop
|
||||||
|
exclude = -m68k -bigsur -monterey -ventura -macos
|
||||||
@@ -332,14 +332,13 @@ func (wc *WebiCache) stalest(packages []pkgConf) []pkgConf {
|
|||||||
for _, pkg := range packages {
|
for _, pkg := range packages {
|
||||||
data, err := wc.Store.Load(ctx, pkg.name)
|
data, err := wc.Store.Load(ctx, pkg.name)
|
||||||
var t time.Time
|
var t time.Time
|
||||||
hasAssets := false
|
|
||||||
if err == nil && data != nil {
|
if err == nil && data != nil {
|
||||||
t = data.UpdatedAt
|
t = data.UpdatedAt
|
||||||
hasAssets = len(data.Assets) > 0
|
|
||||||
}
|
}
|
||||||
// Never fetched, or has no assets despite having a timestamp
|
// Never fetched, or older than 10 minutes.
|
||||||
// (e.g. classified from empty rawcache), or older than 10 minutes.
|
// 0-asset results are not treated as perpetually stale — packages that
|
||||||
if t.IsZero() || !hasAssets || time.Since(t) > 10*time.Minute {
|
// produce no classifiable assets (e.g. galera) respect the timestamp.
|
||||||
|
if t.IsZero() || time.Since(t) > 10*time.Minute {
|
||||||
stale = append(stale, stamped{pkg: pkg, updatedAt: t})
|
stale = append(stale, stamped{pkg: pkg, updatedAt: t})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
149
fish/install.sh
149
fish/install.sh
@@ -3,23 +3,19 @@ set -e
|
|||||||
set -u
|
set -u
|
||||||
|
|
||||||
if command -v fish > /dev/null; then
|
if command -v fish > /dev/null; then
|
||||||
if [ ! -e ~/.config/fish/config.fish ]; then
|
if ! test -e ~/.config/fish/config.fish; then
|
||||||
mkdir -p ~/.config/fish
|
mkdir -p ~/.config/fish
|
||||||
touch ~/.config/fish/config.fish
|
touch ~/.config/fish/config.fish
|
||||||
chmod 0600 ~/.config/fish/config.fish
|
chmod 0600 ~/.config/fish/config.fish
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "Darwin" != "$(uname -s)" ]; then
|
|
||||||
echo "No fish installer for Linux yet. Try this instead:"
|
|
||||||
echo " sudo apt install -y fish"
|
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
################
|
################
|
||||||
# Install fish #
|
# Install fish #
|
||||||
################
|
################
|
||||||
|
|
||||||
|
my_os=$(uname -s)
|
||||||
|
|
||||||
# Every package should define these 6 variables
|
# Every package should define these 6 variables
|
||||||
# shellcheck disable=2034
|
# shellcheck disable=2034
|
||||||
pkg_cmd_name="fish"
|
pkg_cmd_name="fish"
|
||||||
@@ -34,70 +30,109 @@ pkg_src_dir="$HOME/.local/opt/fish-v$WEBI_VERSION"
|
|||||||
# shellcheck disable=2034
|
# shellcheck disable=2034
|
||||||
pkg_src="$pkg_src_cmd"
|
pkg_src="$pkg_src_cmd"
|
||||||
|
|
||||||
# pkg_install must be defined by every package
|
if test "Darwin" = "${my_os}"; then
|
||||||
|
pkg_src_cmd="/Applications/fish.app/Contents/Resources/base/usr/local/bin/fish"
|
||||||
|
# shellcheck disable=2034
|
||||||
|
pkg_src="${pkg_src_cmd}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_linux_post_install() {
|
||||||
|
if ! test -e "$HOME/.local/bin/fish"; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "To set fish as your default shell, run:"
|
||||||
|
echo " chsh -s $HOME/.local/bin/fish"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
_macos_post_install() {
|
_macos_post_install() {
|
||||||
if ! [ -e "$HOME/.local/bin/fish" ]; then
|
if ! test -e "$HOME/.local/bin/fish"; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Trying to set fish as the default shell..."
|
echo "Trying to set fish as the default shell..."
|
||||||
echo ""
|
echo ""
|
||||||
# stop the caching of preferences
|
# stop the caching of preferences
|
||||||
killall cfprefsd
|
killall cfprefsd
|
||||||
|
|
||||||
# Set default Terminal.app shell to fish
|
# Set default Terminal.app shell to fish
|
||||||
defaults write com.apple.Terminal "Shell" -string "$HOME/.local/bin/fish"
|
defaults write com.apple.Terminal "Shell" -string "$HOME/.local/bin/fish"
|
||||||
echo "To set 'fish' as the default Terminal.app shell:"
|
echo "To set 'fish' as the default Terminal.app shell:"
|
||||||
echo " Terminal > Preferences > General > Shells open with:"
|
echo " Terminal > Preferences > General > Shells open with:"
|
||||||
echo " $HOME/.local/bin/fish"
|
echo " $HOME/.local/bin/fish"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Set default iTerm2 shell to fish
|
# Set default iTerm2 shell to fish
|
||||||
if [ -e "$HOME/Library/Preferences/com.googlecode.iterm2.plist" ]; then
|
if test -e "$HOME/Library/Preferences/com.googlecode.iterm2.plist"; then
|
||||||
/usr/libexec/PlistBuddy \
|
/usr/libexec/PlistBuddy \
|
||||||
-c "SET ':New Bookmarks:0:Custom Command' 'Custom Shell'" \
|
-c "SET ':New Bookmarks:0:Custom Command' 'Custom Shell'" \
|
||||||
"$HOME/Library/Preferences/com.googlecode.iterm2.plist"
|
"$HOME/Library/Preferences/com.googlecode.iterm2.plist"
|
||||||
/usr/libexec/PlistBuddy \
|
/usr/libexec/PlistBuddy \
|
||||||
-c "SET ':New Bookmarks:0:Command' $HOME/.local/bin/fish" \
|
-c "SET ':New Bookmarks:0:Command' $HOME/.local/bin/fish" \
|
||||||
"$HOME/Library/Preferences/com.googlecode.iterm2.plist"
|
"$HOME/Library/Preferences/com.googlecode.iterm2.plist"
|
||||||
echo "To set 'fish' as the default iTerm2 shell:"
|
echo "To set 'fish' as the default iTerm2 shell:"
|
||||||
echo " iTerm2 > Preferences > Profiles > General > Command >"
|
echo " iTerm2 > Preferences > Profiles > General > Command >"
|
||||||
echo " Custom Shell: $HOME/.local/bin/fish"
|
echo " Custom Shell: $HOME/.local/bin/fish"
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
killall cfprefsd
|
killall cfprefsd
|
||||||
}
|
}
|
||||||
|
|
||||||
# always try to reset the default shells
|
# always try to reset the default shells
|
||||||
_macos_post_install
|
if test "Darwin" = "${my_os}"; then
|
||||||
|
_macos_post_install
|
||||||
|
fi
|
||||||
|
|
||||||
pkg_install() {
|
pkg_install() {
|
||||||
mv fish.app/Contents/Resources/base/usr/local "$HOME/.local/opt/fish-v${WEBI_VERSION}"
|
if test "Darwin" = "${my_os}"; then
|
||||||
|
rm -rf "/Applications/fish-v${WEBI_VERSION}.app"
|
||||||
|
mv -f fish*.app "/Applications/fish-v${WEBI_VERSION}.app"
|
||||||
|
rm -rf /Applications/fish.app
|
||||||
|
mv "/Applications/fish-v${WEBI_VERSION}.app" "/Applications/fish.app"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$pkg_src_dir/bin"
|
||||||
|
mv fish "$pkg_src_dir/bin/"
|
||||||
|
}
|
||||||
|
|
||||||
|
pkg_link() {
|
||||||
|
if test "Darwin" = "${my_os}"; then
|
||||||
|
mkdir -p "$HOME/.local/bin"
|
||||||
|
ln -sf /Applications/fish.app/Contents/Resources/base/usr/local/bin/fish "$HOME/.local/bin/fish"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf "$pkg_dst_cmd"
|
||||||
|
ln -s "$pkg_src_cmd" "$pkg_dst_cmd"
|
||||||
}
|
}
|
||||||
|
|
||||||
pkg_post_install() {
|
pkg_post_install() {
|
||||||
# don't skip what webi would do automatically
|
# don't skip what webi would do automatically
|
||||||
webi_post_install
|
webi_post_install
|
||||||
|
|
||||||
# try again to update default shells, now that all files should exist
|
# try again to update default shells, now that all files should exist
|
||||||
_macos_post_install
|
if test "Darwin" = "${my_os}"; then
|
||||||
|
_macos_post_install
|
||||||
if [ ! -e ~/.config/fish/config.fish ]; then
|
else
|
||||||
mkdir -p ~/.config/fish
|
_linux_post_install
|
||||||
touch ~/.config/fish/config.fish
|
fi
|
||||||
chmod 0600 ~/.config/fish/config.fish
|
if ! test -e ~/.config/fish/config.fish; then
|
||||||
fi
|
mkdir -p ~/.config/fish
|
||||||
|
touch ~/.config/fish/config.fish
|
||||||
|
chmod 0600 ~/.config/fish/config.fish
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# pkg_get_current_version is recommended, but (soon) not required
|
# pkg_get_current_version is recommended, but (soon) not required
|
||||||
pkg_get_current_version() {
|
pkg_get_current_version() {
|
||||||
# 'fish --version' has output in this format:
|
# 'fish --version' has output in this format:
|
||||||
# fish, version 3.1.2
|
# fish, version 4.3.3
|
||||||
# This trims it down to just the version number:
|
# This trims it down to just the version number:
|
||||||
# 3.1.2
|
# 4.3.3
|
||||||
fish --version 2> /dev/null | head -n 1 | cut -d ' ' -f 3
|
fish --version 2> /dev/null | head -n 1 | cut -d ' ' -f 3
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ __init_gh() {
|
|||||||
# ~/.local/opt/gh-v0.99.9/bin
|
# ~/.local/opt/gh-v0.99.9/bin
|
||||||
mkdir -p "$(dirname "$pkg_src_cmd")"
|
mkdir -p "$(dirname "$pkg_src_cmd")"
|
||||||
|
|
||||||
# mv ./gh-*/gh ~/.local/opt/gh-v0.99.9/bin/gh
|
# mv ./gh_*/bin/gh ~/.local/opt/gh-v0.99.9/bin/gh
|
||||||
mv ./"$pkg_cmd_name"*/bin/gh "$pkg_src_cmd"
|
mv ./"$pkg_cmd_name"*/bin/gh "$pkg_src_cmd"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
github_releases = go-gitea/gitea
|
github_releases = go-gitea/gitea
|
||||||
exclude = -src- -docs-
|
exclude = -src- -docs-
|
||||||
|
variants = gogit
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ __init_goreleaser() {
|
|||||||
# ~/.local/opt/goreleaser-v1.21.2/bin
|
# ~/.local/opt/goreleaser-v1.21.2/bin
|
||||||
mkdir -p "$(dirname "$pkg_src_cmd")"
|
mkdir -p "$(dirname "$pkg_src_cmd")"
|
||||||
|
|
||||||
# mv ./goreleaser-*/goreleaser ~/.local/opt/goreleaser-v1.21.2/bin/goreleaser
|
# mv ./goreleaser ~/.local/opt/goreleaser-v1.21.2/bin/goreleaser
|
||||||
mv ./goreleaser "$pkg_src_cmd"
|
mv ./goreleaser "$pkg_src_cmd"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ package classify
|
|||||||
import (
|
import (
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/webinstall/webi-installers/internal/buildmeta"
|
"github.com/webinstall/webi-installers/internal/buildmeta"
|
||||||
@@ -268,16 +269,11 @@ func IsMetaAsset(name string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, exact := range []string{
|
return slices.Contains([]string{
|
||||||
"install.sh",
|
"install.sh",
|
||||||
"install.ps1",
|
"install.ps1",
|
||||||
"compat.json",
|
"compat.json",
|
||||||
"b3sums",
|
"b3sums",
|
||||||
"dist-manifest.json",
|
"dist-manifest.json",
|
||||||
} {
|
}, lower)
|
||||||
if lower == exact {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import (
|
|||||||
"github.com/webinstall/webi-installers/internal/releases/chromedist"
|
"github.com/webinstall/webi-installers/internal/releases/chromedist"
|
||||||
"github.com/webinstall/webi-installers/internal/releases/cmake"
|
"github.com/webinstall/webi-installers/internal/releases/cmake"
|
||||||
"github.com/webinstall/webi-installers/internal/releases/fish"
|
"github.com/webinstall/webi-installers/internal/releases/fish"
|
||||||
"github.com/webinstall/webi-installers/internal/releases/gitea"
|
|
||||||
"github.com/webinstall/webi-installers/internal/releases/flutterdist"
|
"github.com/webinstall/webi-installers/internal/releases/flutterdist"
|
||||||
"github.com/webinstall/webi-installers/internal/releases/git"
|
"github.com/webinstall/webi-installers/internal/releases/git"
|
||||||
"github.com/webinstall/webi-installers/internal/releases/golang"
|
"github.com/webinstall/webi-installers/internal/releases/golang"
|
||||||
@@ -41,7 +40,7 @@ import (
|
|||||||
"github.com/webinstall/webi-installers/internal/releases/postgres"
|
"github.com/webinstall/webi-installers/internal/releases/postgres"
|
||||||
"github.com/webinstall/webi-installers/internal/releases/sass"
|
"github.com/webinstall/webi-installers/internal/releases/sass"
|
||||||
"github.com/webinstall/webi-installers/internal/releases/servicemandist"
|
"github.com/webinstall/webi-installers/internal/releases/servicemandist"
|
||||||
"github.com/webinstall/webi-installers/internal/releases/sttr"
|
sttrdist "github.com/webinstall/webi-installers/internal/releases/sttr"
|
||||||
"github.com/webinstall/webi-installers/internal/releases/uuidv7"
|
"github.com/webinstall/webi-installers/internal/releases/uuidv7"
|
||||||
"github.com/webinstall/webi-installers/internal/releases/watchexec"
|
"github.com/webinstall/webi-installers/internal/releases/watchexec"
|
||||||
"github.com/webinstall/webi-installers/internal/releases/xcaddy"
|
"github.com/webinstall/webi-installers/internal/releases/xcaddy"
|
||||||
@@ -98,7 +97,7 @@ func Package(pkg string, conf *installerconf.Conf, d *rawcache.Dir, gitTagDir *r
|
|||||||
assets = append(assets, gitAssets...)
|
assets = append(assets, gitAssets...)
|
||||||
}
|
}
|
||||||
|
|
||||||
TagVariants(pkg, assets)
|
TagVariants(pkg, conf.Variants, assets)
|
||||||
assets = expandUniversal(assets)
|
assets = expandUniversal(assets)
|
||||||
NormalizeVersions(pkg, assets)
|
NormalizeVersions(pkg, assets)
|
||||||
processGitTagHEAD(assets)
|
processGitTagHEAD(assets)
|
||||||
@@ -194,9 +193,19 @@ func NormalizeVersions(pkg string, assets []storage.Asset) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TagVariants applies package-specific variant tags to classified assets.
|
// TagVariants applies variant tags to classified assets.
|
||||||
// Each case delegates to a per-installer package under internal/releases/.
|
// conf variants (from releases.conf) are applied first: each variant is
|
||||||
func TagVariants(pkg string, assets []storage.Asset) {
|
// matched as a case-folded substring of the filename. Package-specific
|
||||||
|
// logic runs after for cases that require more than a substring check.
|
||||||
|
func TagVariants(pkg string, confVariants []string, assets []storage.Asset) {
|
||||||
|
for i := range assets {
|
||||||
|
lower := strings.ToLower(assets[i].Filename)
|
||||||
|
for _, v := range confVariants {
|
||||||
|
if strings.Contains(lower, strings.ToLower(v)) {
|
||||||
|
assets[i].Variants = append(assets[i].Variants, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
switch pkg {
|
switch pkg {
|
||||||
case "atomicparsley":
|
case "atomicparsley":
|
||||||
atomicparsleydist.TagVariants(assets)
|
atomicparsleydist.TagVariants(assets)
|
||||||
@@ -210,8 +219,6 @@ func TagVariants(pkg string, assets []storage.Asset) {
|
|||||||
flutterdist.TagVariants(assets)
|
flutterdist.TagVariants(assets)
|
||||||
case "git":
|
case "git":
|
||||||
gitdist.TagVariants(assets)
|
gitdist.TagVariants(assets)
|
||||||
case "gitea":
|
|
||||||
gitea.TagVariants(assets)
|
|
||||||
case "lsd":
|
case "lsd":
|
||||||
lsddist.TagVariants(assets)
|
lsddist.TagVariants(assets)
|
||||||
case "node":
|
case "node":
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ import (
|
|||||||
func TagVariants(assets []storage.Asset) {
|
func TagVariants(assets []storage.Asset) {
|
||||||
for i := range assets {
|
for i := range assets {
|
||||||
lower := strings.ToLower(assets[i].Filename)
|
lower := strings.ToLower(assets[i].Filename)
|
||||||
if strings.Contains(lower, "-profile") {
|
|
||||||
assets[i].Variants = append(assets[i].Variants, "profile")
|
|
||||||
}
|
|
||||||
if assets[i].Arch == "x86_64" {
|
if assets[i].Arch == "x86_64" {
|
||||||
if strings.Contains(lower, "-baseline") {
|
if strings.Contains(lower, "-baseline") {
|
||||||
// Baseline is plain x86_64 — strip the suffix from
|
// Baseline is plain x86_64 — strip the suffix from
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
// Package lsd provides variant tagging for lsd (LSDeluxe) releases.
|
// Package lsd provides variant tagging for lsd (LSDeluxe) releases.
|
||||||
//
|
//
|
||||||
// lsd publishes .deb packages and windows-msvc builds alongside
|
// lsd publishes .deb packages alongside the standard archives.
|
||||||
// the standard archives.
|
// msvc builds are excluded via releases.conf variants.
|
||||||
package lsddist
|
package lsddist
|
||||||
|
|
||||||
import (
|
import "github.com/webinstall/webi-installers/internal/storage"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/webinstall/webi-installers/internal/storage"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TagVariants tags lsd-specific build variants.
|
// TagVariants tags lsd-specific build variants.
|
||||||
func TagVariants(assets []storage.Asset) {
|
func TagVariants(assets []storage.Asset) {
|
||||||
@@ -16,8 +12,5 @@ func TagVariants(assets []storage.Asset) {
|
|||||||
if assets[i].Format == ".deb" {
|
if assets[i].Format == ".deb" {
|
||||||
assets[i].Variants = append(assets[i].Variants, "deb")
|
assets[i].Variants = append(assets[i].Variants, "deb")
|
||||||
}
|
}
|
||||||
if strings.Contains(strings.ToLower(assets[i].Filename), "-msvc") {
|
|
||||||
assets[i].Variants = append(assets[i].Variants, "msvc")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
// Package ollama provides variant tagging for Ollama releases.
|
// Package ollama provides variant tagging for Ollama releases.
|
||||||
//
|
|
||||||
// Ollama publishes GPU accelerator builds: -rocm (AMD), -jetpack5
|
|
||||||
// and -jetpack6 (NVIDIA Jetson).
|
|
||||||
package ollamadist
|
package ollamadist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -11,14 +8,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// TagVariants tags ollama-specific build variants.
|
// TagVariants tags ollama-specific build variants.
|
||||||
|
// Suffix variants (mlx, rocm, jetpack5, jetpack6) are handled by the
|
||||||
|
// conf-driven loop in classifypkg.TagVariants; this handles the rest.
|
||||||
func TagVariants(assets []storage.Asset) {
|
func TagVariants(assets []storage.Asset) {
|
||||||
for i := range assets {
|
for i := range assets {
|
||||||
lower := strings.ToLower(assets[i].Filename)
|
|
||||||
for _, v := range []string{"rocm", "jetpack5", "jetpack6"} {
|
|
||||||
if strings.Contains(lower, "-"+v) {
|
|
||||||
assets[i].Variants = append(assets[i].Variants, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Ollama-darwin.zip (capital O) is the macOS .app bundle.
|
// Ollama-darwin.zip (capital O) is the macOS .app bundle.
|
||||||
// Installable by Go (extract .app), but not in legacy cache.
|
// Installable by Go (extract .app), but not in legacy cache.
|
||||||
if strings.HasPrefix(assets[i].Filename, "Ollama-") {
|
if strings.HasPrefix(assets[i].Filename, "Ollama-") {
|
||||||
|
|||||||
@@ -23,15 +23,8 @@ var winVersionRe = regexp.MustCompile(`(?i)-win(?:7|8|81|10|2008|2012|2016)`)
|
|||||||
func TagVariants(assets []storage.Asset) {
|
func TagVariants(assets []storage.Asset) {
|
||||||
for i := range assets {
|
for i := range assets {
|
||||||
lower := strings.ToLower(assets[i].Filename)
|
lower := strings.ToLower(assets[i].Filename)
|
||||||
switch {
|
if winVersionRe.MatchString(lower) {
|
||||||
case strings.Contains(lower, "-fxdependentwindesktop"):
|
|
||||||
assets[i].Variants = append(assets[i].Variants, "fxdependentWinDesktop")
|
|
||||||
case strings.Contains(lower, "-fxdependent"):
|
|
||||||
assets[i].Variants = append(assets[i].Variants, "fxdependent")
|
|
||||||
case winVersionRe.MatchString(lower):
|
|
||||||
assets[i].Variants = append(assets[i].Variants, "win-version-specific")
|
assets[i].Variants = append(assets[i].Variants, "win-version-specific")
|
||||||
case strings.HasSuffix(lower, ".appimage"):
|
|
||||||
assets[i].Variants = append(assets[i].Variants, "appimage")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
// Package sttr provides variant tagging for sttr releases.
|
// Package sttr provides variant tagging for sttr releases.
|
||||||
//
|
//
|
||||||
// sttr ships a darwin_all (universal macOS) archive alongside per-arch builds.
|
// sttr_Darwin_all.tar.gz is the only macOS release — a universal binary
|
||||||
// These universal archives have no arch in the filename — Go classifies them as
|
// with no arch token. Mark it universal2 so expandUniversal serves it
|
||||||
// os="darwin", arch="" which the Node builds-cacher rejects with FORMAT CHANGE
|
// to both arm64 and amd64 Mac users.
|
||||||
// (Node's classifier extracts a different arch from "all"). Production Node
|
|
||||||
// also stores these as os="", arch="" (unroutable).
|
|
||||||
//
|
|
||||||
// .sbom.json files are software bill-of-materials metadata — not installable
|
|
||||||
// archives. They pass through the format filter (ext="") but should not be
|
|
||||||
// served.
|
|
||||||
package sttrdist
|
package sttrdist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -17,20 +11,11 @@ import (
|
|||||||
"github.com/webinstall/webi-installers/internal/storage"
|
"github.com/webinstall/webi-installers/internal/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TagVariants tags sttr-specific build variants for exclusion from legacy export.
|
// TagVariants tags sttr-specific build variants.
|
||||||
func TagVariants(assets []storage.Asset) {
|
func TagVariants(assets []storage.Asset) {
|
||||||
for i := range assets {
|
for i := range assets {
|
||||||
lower := strings.ToLower(assets[i].Filename)
|
if strings.Contains(strings.ToLower(assets[i].Filename), "darwin_all") {
|
||||||
// darwin_all / Darwin_all: universal macOS archive with no arch info.
|
assets[i].Arch = "universal2"
|
||||||
// Node's classifier extracts a different result → FORMAT CHANGE.
|
|
||||||
// Production LIVE_cache has these as os="", arch="" (unroutable).
|
|
||||||
if strings.Contains(lower, "darwin_all") {
|
|
||||||
assets[i].Variants = append(assets[i].Variants, "universal-all")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// .sbom.json: software bill-of-materials, not an installable archive.
|
|
||||||
if strings.HasSuffix(lower, ".sbom.json") {
|
|
||||||
assets[i].Variants = append(assets[i].Variants, "metadata")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
github_releases = lsd-rs/lsd
|
github_releases = lsd-rs/lsd
|
||||||
|
variants = msvc
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
source = mariadbdist
|
|
||||||
asset_filter = galera
|
|
||||||
@@ -2,62 +2,67 @@
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
|
|
||||||
__init_ollama() {
|
__init_ollama() {
|
||||||
set -e
|
set -e
|
||||||
set -u
|
set -u
|
||||||
|
|
||||||
##################
|
##################
|
||||||
# Install ollama #
|
# Install ollama #
|
||||||
##################
|
##################
|
||||||
|
|
||||||
# Every package should define these 6 variables
|
# Every package should define these 6 variables
|
||||||
pkg_cmd_name="ollama"
|
pkg_cmd_name="ollama"
|
||||||
|
|
||||||
pkg_dst_cmd="${HOME}/.local/opt/ollama/bin/ollama"
|
pkg_dst_dir="${HOME}/.local/opt/ollama"
|
||||||
pkg_dst_dir="${HOME}/.local/opt/ollama"
|
pkg_dst_cmd="${HOME}/.local/bin/ollama"
|
||||||
pkg_dst="${pkg_dst_dir}"
|
|
||||||
|
|
||||||
pkg_src_cmd="${HOME}/.local/opt/ollama-v${WEBI_VERSION}/bin/ollama"
|
pkg_src_dir="${HOME}/.local/opt/ollama-v${WEBI_VERSION}"
|
||||||
pkg_src_dir="${HOME}/.local/opt/ollama-v${WEBI_VERSION}"
|
pkg_src_cmd="${HOME}/.local/opt/ollama-v${WEBI_VERSION}/bin/ollama"
|
||||||
pkg_src="${pkg_src_dir}"
|
|
||||||
|
|
||||||
# pkg_install must be defined by every package
|
my_os=$(uname -s)
|
||||||
pkg_install() {
|
if test "Darwin" = "${my_os}"; then
|
||||||
# ~/.local/opt/
|
pkg_dst_cmd="${HOME}/.local/bin/ollama"
|
||||||
mkdir -p "$(dirname "${pkg_src_dir}")"
|
pkg_src_cmd="${HOME}/.local/opt/ollama-v${WEBI_VERSION}/ollama"
|
||||||
|
fi
|
||||||
|
|
||||||
if test -d ./ollama-*/; then
|
pkg_dst="${pkg_dst_cmd}"
|
||||||
# the de facto way (in case it's supported in the future)
|
pkg_src="${pkg_src_cmd}"
|
||||||
# mv ./ollama-*/ ~/.local/opt/ollama-v3.27.0/
|
|
||||||
mv ./ollama-*/ "${pkg_src}"
|
|
||||||
elif test -d ./bin; then
|
|
||||||
# how linux is presently done
|
|
||||||
mkdir -p "${pkg_src_dir}"
|
|
||||||
mv ./bin "${pkg_src_dir}"
|
|
||||||
if test -f ./lib; then
|
|
||||||
mv ./lib "${pkg_src_dir}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# how macOS is presently done
|
|
||||||
mkdir -p "$(dirname "${pkg_src_cmd}")"
|
|
||||||
mv ./ollama-* "${pkg_src_cmd}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# remove previous location
|
# pkg_install must be defined by every package
|
||||||
if test -f ~/.local/bin/ollama; then
|
pkg_install() {
|
||||||
rm ~/.local/bin/ollama
|
if test -d ./bin; then
|
||||||
fi
|
# linux tar.zst: bin/ollama + lib/ollama/
|
||||||
}
|
mkdir -p "${pkg_src_dir}"
|
||||||
|
mv ./bin "${pkg_src_dir}/bin"
|
||||||
|
if test -d ./lib; then
|
||||||
|
mv ./lib "${pkg_src_dir}/lib"
|
||||||
|
fi
|
||||||
|
elif test -f ./ollama; then
|
||||||
|
# macOS tgz: flat — bare binary + dylibs/mlx backends in root
|
||||||
|
mkdir -p "${pkg_src_dir}"
|
||||||
|
mv ./* "${pkg_src_dir}/"
|
||||||
|
elif test -d ./Ollama.app; then
|
||||||
|
# macOS zip: install app bundle to /Applications
|
||||||
|
mv -f ./Ollama.app /Applications/Ollama.app
|
||||||
|
elif test -f ./ollama-*; then
|
||||||
|
# older bare binary format
|
||||||
|
mkdir -p "$(dirname "${pkg_src_cmd}")"
|
||||||
|
mv ./ollama-* "${pkg_src_cmd}"
|
||||||
|
else
|
||||||
|
echo "error: unrecognized ollama archive format" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
pkg_get_current_version() {
|
pkg_get_current_version() {
|
||||||
# 'ollama --version' has output in this format:
|
# 'ollama --version' has output in this format:
|
||||||
# ollama version is 0.3.10
|
# ollama version is 0.3.10
|
||||||
# This trims it down to just the version number:
|
# This trims it down to just the version number:
|
||||||
# 0.3.10
|
# 0.3.10
|
||||||
ollama --version 2> /dev/null |
|
ollama --version 2> /dev/null |
|
||||||
head -n 1 |
|
head -n 1 |
|
||||||
cut -d' ' -f4 |
|
cut -d' ' -f4 |
|
||||||
sed 's:^v::'
|
sed 's:^v::'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__init_ollama
|
__init_ollama
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
github_releases = jmorganca/ollama
|
github_releases = jmorganca/ollama
|
||||||
variants = rocm jetpack5 jetpack6
|
variants = mlx rocm jetpack5 jetpack6
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
github_releases = powershell/powershell
|
github_releases = powershell/powershell
|
||||||
variants = fxdependent fxdependentWinDesktop
|
variants = fxdependent fxdependentWinDesktop appimage
|
||||||
|
|||||||
@@ -11,14 +11,22 @@ g_out="agents/tmp/${g_bin}"
|
|||||||
g_remote_bin="~/bin/${g_bin}"
|
g_remote_bin="~/bin/${g_bin}"
|
||||||
|
|
||||||
case "${g_host}" in
|
case "${g_host}" in
|
||||||
beta.webi.sh) g_remote_conf="~/srv/beta.webinstall.dev/installers/" ;;
|
beta.webi.sh) g_remote_conf="~/srv/beta.webinstall.dev/installers/" ;;
|
||||||
next.webi.sh) g_remote_conf="~/srv/next.webinstall.dev/installers/" ;;
|
next.webi.sh) g_remote_conf="~/srv/next.webinstall.dev/installers/" ;;
|
||||||
*) g_remote_conf="~/srv/webid/installers/" ;;
|
webi.sh) g_remote_conf="~/srv/webinstall.dev/installers/" ;;
|
||||||
|
*) g_remote_conf="~/srv/webinstall.dev/installers/" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
fn_build() {
|
fn_build() {
|
||||||
b_version="$(git describe --tags --always 2>/dev/null || echo '0.0.0-dev')"
|
b_tag="$(git describe --tags --abbrev=0 --match 'cmd/webicached/*' 2> /dev/null || echo 'cmd/webicached/v0.0.0')"
|
||||||
|
b_tag_ver="$(printf '%s' "${b_tag}" | sed 's:^cmd/webicached/::')"
|
||||||
|
b_count="$(git log --oneline "${b_tag}..HEAD" -- cmd/ internal/ 2> /dev/null | wc -l | tr -d ' \t')"
|
||||||
b_commit="$(git rev-parse --short HEAD)"
|
b_commit="$(git rev-parse --short HEAD)"
|
||||||
|
if test "${b_count}" -gt 0; then
|
||||||
|
b_version="${b_tag_ver}-${b_count}-g${b_commit}"
|
||||||
|
else
|
||||||
|
b_version="${b_tag_ver}"
|
||||||
|
fi
|
||||||
b_date="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
b_date="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||||
b_ldflags="-X main.version=${b_version} -X main.commit=${b_commit} -X main.date=${b_date}"
|
b_ldflags="-X main.version=${b_version} -X main.commit=${b_commit} -X main.date=${b_date}"
|
||||||
|
|
||||||
@@ -29,7 +37,7 @@ fn_build() {
|
|||||||
|
|
||||||
fn_deploy() {
|
fn_deploy() {
|
||||||
printf 'Stopping %s on %s...\n' "${g_bin}" "${g_host}"
|
printf 'Stopping %s on %s...\n' "${g_bin}" "${g_host}"
|
||||||
ssh "${g_host}" "~/.local/bin/serviceman stop ${g_bin}" 2>/dev/null || true
|
ssh "${g_host}" "~/.local/bin/serviceman stop ${g_bin}" 2> /dev/null || true
|
||||||
|
|
||||||
printf 'Uploading binary...\n'
|
printf 'Uploading binary...\n'
|
||||||
scp "${g_out}" "${g_host}:${g_remote_bin}"
|
scp "${g_out}" "${g_host}:${g_remote_bin}"
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ __init_sd() {
|
|||||||
pkg_install() {
|
pkg_install() {
|
||||||
# mv ./sd-*/sd "$pkg_src_cmd"
|
# mv ./sd-*/sd "$pkg_src_cmd"
|
||||||
if test -f sd-*; then
|
if test -f sd-*; then
|
||||||
# ~/.local/opt/sd-v0.99.9/bin
|
# old format: bare binary named sd-{triplet}
|
||||||
mkdir -p "$(dirname "$pkg_src_cmd")"
|
mkdir -p "$(dirname "$pkg_src_cmd")"
|
||||||
mv sd-* "$pkg_src_cmd"
|
mv sd-* "$pkg_src_cmd"
|
||||||
elif test -f sd-*/sd; then
|
elif test -f sd-*/sd; then
|
||||||
# ~/.local/opt/sd-v0.99.9/bin
|
# current format: sd-v{ver}-{triplet}/ directory
|
||||||
mkdir -p "$(dirname "$pkg_src_cmd")"
|
mkdir -p "$(dirname "$pkg_src_cmd")"
|
||||||
mv sd-*/sd "$pkg_src_cmd"
|
mv sd-*/sd "$pkg_src_cmd"
|
||||||
if test -f sd-*/sd.1; then
|
if test -f sd-*/sd.1; then
|
||||||
|
|||||||
118
sql-migrate/README.md
Normal file
118
sql-migrate/README.md
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
---
|
||||||
|
title: sql-migrate
|
||||||
|
homepage: https://github.com/therootcompany/golib/tree/main/cmd/sql-migrate
|
||||||
|
tagline: |
|
||||||
|
sql-migrate: A lightweight, feature-branch-friendly SQL migrator.
|
||||||
|
---
|
||||||
|
|
||||||
|
To update or switch versions, run `webi sql-migrate@stable` (or `@v2`, `@beta`,
|
||||||
|
etc).
|
||||||
|
|
||||||
|
### Files
|
||||||
|
|
||||||
|
These are the files that are created and/or modified with this installer:
|
||||||
|
|
||||||
|
```text
|
||||||
|
~/.config/envman/PATH.env
|
||||||
|
~/.local/bin/sql-migrate
|
||||||
|
~/.local/opt/sql-migrate-VERSION/bin/sql-migrate
|
||||||
|
|
||||||
|
<PROJECT-DIR>/migrations.log
|
||||||
|
<PROJECT-DIR>/sql/migrations/<yyyy-mm-dd>-<number>_<name>.<up|down>.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cheat Sheet
|
||||||
|
|
||||||
|
> `sql-migrate` is a lightweight migration tool that gets out of your way - it
|
||||||
|
> works with your existing SQL tools and allows working with distinct sets of
|
||||||
|
> migrations, such as is typical in feature branches.
|
||||||
|
|
||||||
|
### How to use sql-migrate
|
||||||
|
|
||||||
|
Migration commands output a POSIX shell script which should be run with `sh`.
|
||||||
|
|
||||||
|
`init`, `sync`, `up`, `down`, `list`, `status`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Initialize a migration directory
|
||||||
|
sql-migrate -d ./sql/migrations/ init --sql-command psql
|
||||||
|
|
||||||
|
# Export ENVs for your database
|
||||||
|
export PG_URL='postgres://user:pass@example.com/dbname?sslmode=require&sslnegotiation=direct'
|
||||||
|
|
||||||
|
# Create a new migration (auto-generates up/down pair with incrementing number)
|
||||||
|
sql-migrate -d ./sql/migrations/ create add-users-table
|
||||||
|
|
||||||
|
# SELECT and log existing migrations
|
||||||
|
sql-migrate -d ./sql/migrations/ sync | sh
|
||||||
|
|
||||||
|
# Run all pending migrations up
|
||||||
|
sql-migrate -d ./sql/migrations/ up | sh
|
||||||
|
|
||||||
|
# Run 3 migrations up
|
||||||
|
sql-migrate -d ./sql/migrations/ up 3 | sh
|
||||||
|
|
||||||
|
# Run 1 migration down (roll back)
|
||||||
|
sql-migrate -d ./sql/migrations/ down | sh
|
||||||
|
|
||||||
|
# Run 2 migrations down
|
||||||
|
sql-migrate -d ./sql/migrations/ down 2 | sh
|
||||||
|
|
||||||
|
# List all migrations
|
||||||
|
sql-migrate -d ./sql/migrations/ list
|
||||||
|
|
||||||
|
# See which migrations have been applied
|
||||||
|
sql-migrate -d ./sql/migrations/ status
|
||||||
|
```
|
||||||
|
|
||||||
|
### Migration directory layout
|
||||||
|
|
||||||
|
Migrations follow the naming format
|
||||||
|
`<yyyy-mm-dd>-<number>_<name>.<up|down>.sql`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
sql/
|
||||||
|
├── migrations.log # transaction log (auto-managed)
|
||||||
|
└── migrations/
|
||||||
|
├── 0001-01-01-001000_init-migrations.up.sql # generated by 'init' (has config vars)
|
||||||
|
├── 2021-02-03-001000_init-app.up.sql
|
||||||
|
├── 2021-02-03-001000_init-app.down.sql
|
||||||
|
├── 2021-02-03-002000_add-products.up.sql
|
||||||
|
├── 2021-02-03-002000_add-products.down.sql
|
||||||
|
└── 2021-02-03-003000_add-customers.up.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
The initial `0001-01-01-001000_init-migrations.up.sql` migration contains
|
||||||
|
configuration variables:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- migrations_log: ./sql/migrations.log
|
||||||
|
-- sql_command: psql "$PG_URL" -v ON_ERROR_STOP=on --no-align --tuples-only --file %s
|
||||||
|
```
|
||||||
|
|
||||||
|
Environment variables by database:
|
||||||
|
|
||||||
|
- PostgreSQL: `PG_URL` (auth url), `PGOPTIONS` (to set `schema` and other
|
||||||
|
specific options)
|
||||||
|
- SQLite3: `SQLITE_PATH`
|
||||||
|
- SQL Server: `SQLCMDSERVER`, `SQLCMDDATABASE`, `SQLCMDUSER`, `SQLCMDPASSWORD`
|
||||||
|
- MySQL / MariaDB: `MY_CNF` (path to `my.cnf`, containing credentials)
|
||||||
|
|
||||||
|
### Database client compatibility
|
||||||
|
|
||||||
|
The `--sql-command` flag tells sql-migrate how to talk to your database:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sql-migrate -d ./sql/migrations/ init --sql-command psql
|
||||||
|
```
|
||||||
|
|
||||||
|
The following clients are known and will have the correct options applied:
|
||||||
|
|
||||||
|
- psql (PostgreSQL)
|
||||||
|
- sqlite3
|
||||||
|
- sqlcmd (mssql / Microsoft SQL Server)
|
||||||
|
- mariadb / mysql
|
||||||
|
|
||||||
|
Since the migrations run via shell commands, you can make `sql-migrate`
|
||||||
|
compatible with any SQL client by setting `sql_command` in
|
||||||
|
`migrations/0001-01-01-001000_init-migrations.up.sql`.
|
||||||
78
sql-migrate/SKILL.md
Normal file
78
sql-migrate/SKILL.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
---
|
||||||
|
name: sql-migrate
|
||||||
|
description:
|
||||||
|
Manage SQL database migrations as plain .sql files with a transaction log. Use
|
||||||
|
when asked about sql-migrate, database migrations, or how to set up migration
|
||||||
|
tooling.
|
||||||
|
---
|
||||||
|
|
||||||
|
# sql-migrate (CLI)
|
||||||
|
|
||||||
|
The agent skill is embedded in the help output.
|
||||||
|
|
||||||
|
Run `sql-migrate --help` use its output to guide usage decisions.
|
||||||
|
|
||||||
|
The `up`, `down`, and `sync` subcommands produce POSIX shell scripts - pipe them
|
||||||
|
to `sh` to run.
|
||||||
|
|
||||||
|
## Migration layout
|
||||||
|
|
||||||
|
Migrations follow the naming format
|
||||||
|
`<yyyy-mm-dd>-<number>_<name>.<up|down>.sql`:
|
||||||
|
|
||||||
|
```
|
||||||
|
sql/
|
||||||
|
├── migrations.log # transaction log (auto-managed)
|
||||||
|
└── migrations/
|
||||||
|
├── 0001-01-01-001000_init-migrations.up.sql # generated by 'init'
|
||||||
|
├── 2021-02-03-001000_init-app.up.sql
|
||||||
|
├── 2021-02-03-001000_init-app.down.sql
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
The initial migration file contains configuration variables:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- migrations_log: ./sql/migrations.log
|
||||||
|
-- sql_command: psql "$PG_URL" -v ON_ERROR_STOP=on --no-align --tuples-only --file %s
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration file structure
|
||||||
|
|
||||||
|
The migration files contain their own management, including a randomly-generated
|
||||||
|
id:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- change_me (up)
|
||||||
|
SELECT 'place your UP migration here';
|
||||||
|
|
||||||
|
-- leave this as the last line
|
||||||
|
INSERT INTO _migrations (name, id) VALUES ('2026-05-27-002000_change_me', 'e22295e5');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment variables by database
|
||||||
|
|
||||||
|
- PostgreSQL: `PG_URL` (auth URL), `PGOPTIONS` (set `schema` and other options)
|
||||||
|
- SQLite3: `SQLITE_PATH`
|
||||||
|
- SQL Server: `SQLCMDSERVER`, `SQLCMDDATABASE`, `SQLCMDUSER`, `SQLCMDPASSWORD`
|
||||||
|
- MySQL / MariaDB: `MY_CNF` (path to `my.cnf` containing credentials)
|
||||||
|
|
||||||
|
## SQL client extensibility
|
||||||
|
|
||||||
|
The `--sql-command` flag tells sql-migrate how to talk to your database. Known
|
||||||
|
clients (`psql`, `sqlite3`, `sqlcmd`, `mariadb`/`mysql`) have correct options
|
||||||
|
applied automatically. Since migrations run via shell commands, you can make
|
||||||
|
sql-migrate compatible with any SQL client by setting `sql_command` in the init
|
||||||
|
migration file.
|
||||||
|
|
||||||
|
# sqlmigrate (Go module)
|
||||||
|
|
||||||
|
See `go doc` for each independent module (golib is a monorepo):
|
||||||
|
|
||||||
|
- `github.com/therootcompany/golib/database/sqlmigrate/v2`
|
||||||
|
- `github.com/therootcompany/golib/database/sqlmigrate/pgmigrate`
|
||||||
|
- `github.com/therootcompany/golib/database/sqlmigrate/litemigrate`
|
||||||
|
- `github.com/therootcompany/golib/database/sqlmigrate/msmigrate`
|
||||||
|
- `github.com/therootcompany/golib/database/sqlmigrate/mymigrate`
|
||||||
|
|
||||||
|
DO NOT search the parent golib module.
|
||||||
47
sql-migrate/install.ps1
Normal file
47
sql-migrate/install.ps1
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Install sql-migrate #
|
||||||
|
######################
|
||||||
|
|
||||||
|
$pkg_cmd_name = "sql-migrate"
|
||||||
|
|
||||||
|
$pkg_dst_cmd = "$Env:USERPROFILE\.local\bin\sql-migrate.exe"
|
||||||
|
$pkg_dst = "$pkg_dst_cmd"
|
||||||
|
|
||||||
|
$pkg_src_cmd = "$Env:USERPROFILE\.local\opt\sql-migrate-v$Env:WEBI_VERSION\bin\sql-migrate.exe"
|
||||||
|
$pkg_src_bin = "$Env:USERPROFILE\.local\opt\sql-migrate-v$Env:WEBI_VERSION\bin"
|
||||||
|
$pkg_src_dir = "$Env:USERPROFILE\.local\opt\sql-migrate-v$Env:WEBI_VERSION"
|
||||||
|
$pkg_src = "$pkg_src_cmd"
|
||||||
|
|
||||||
|
New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | Out-Null
|
||||||
|
$pkg_download = "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE"
|
||||||
|
|
||||||
|
# Fetch archive
|
||||||
|
if (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE")) {
|
||||||
|
Write-Output "Downloading sql-migrate from $Env:WEBI_PKG_URL to $pkg_download"
|
||||||
|
& curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_PKG_URL" -o "$pkg_download.part"
|
||||||
|
& Move-Item "$pkg_download.part" "$pkg_download"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Test-Path -Path "$pkg_src_cmd")) {
|
||||||
|
Write-Output "Installing sql-migrate"
|
||||||
|
|
||||||
|
Push-Location .local\tmp
|
||||||
|
|
||||||
|
Remove-Item -Path ".\sql-migrate-v*" -Recurse -ErrorAction Ignore
|
||||||
|
Remove-Item -Path ".\sql-migrate.exe" -Recurse -ErrorAction Ignore
|
||||||
|
|
||||||
|
Write-Output "Unpacking $pkg_download"
|
||||||
|
& tar xf "$pkg_download"
|
||||||
|
|
||||||
|
Write-Output "Install Location: $pkg_src_cmd"
|
||||||
|
New-Item "$pkg_src_bin" -ItemType Directory -Force | Out-Null
|
||||||
|
Move-Item -Path ".\sql-migrate.exe" -Destination "$pkg_src_bin"
|
||||||
|
|
||||||
|
Pop-Location
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Output "Copying into '$pkg_dst_cmd' from '$pkg_src_cmd'"
|
||||||
|
Remove-Item -Path "$pkg_dst_cmd" -Recurse -ErrorAction Ignore | Out-Null
|
||||||
|
Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse
|
||||||
33
sql-migrate/install.sh
Normal file
33
sql-migrate/install.sh
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
|
||||||
|
__init_sql_migrate() {
|
||||||
|
pkg_cmd_name="sql-migrate"
|
||||||
|
|
||||||
|
pkg_dst_cmd="${HOME}/.local/bin/sql-migrate"
|
||||||
|
pkg_dst="${pkg_dst_cmd}"
|
||||||
|
|
||||||
|
pkg_src_cmd="${HOME}/.local/opt/sql-migrate-v${WEBI_VERSION}/bin/sql-migrate"
|
||||||
|
pkg_src_dir="${HOME}/.local/opt/sql-migrate-v${WEBI_VERSION}"
|
||||||
|
pkg_src="${pkg_src_cmd}"
|
||||||
|
|
||||||
|
pkg_install() {
|
||||||
|
pkg_src_bin=$(dirname "${pkg_src_cmd}")
|
||||||
|
mkdir -p "${pkg_src_bin}"
|
||||||
|
mv ./sql-migrate "${pkg_src_cmd}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# pkg_get_current_version is recommended, but (soon) not required
|
||||||
|
pkg_get_current_version() {
|
||||||
|
# 'sql-migrate version' has output in this format:
|
||||||
|
# sql-migrate v0.0.0-dev 0000000 (0001-01-01)
|
||||||
|
# This trims it down to just the version number:
|
||||||
|
# v0.0.0-dev
|
||||||
|
sql-migrate version 2> /dev/null | head -n 1 | cut -d ' ' -f 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__init_sql_migrate
|
||||||
2
sql-migrate/releases.conf
Normal file
2
sql-migrate/releases.conf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
github_releases = therootcompany/golib
|
||||||
|
tag_prefix = cmd/sql-migrate/v
|
||||||
@@ -1 +1,3 @@
|
|||||||
github_releases = abhimanyu003/sttr
|
github_releases = abhimanyu003/sttr
|
||||||
|
exclude = .sbom.json
|
||||||
|
variants = .pkg.tar.
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ __rmrf_local() {
|
|||||||
arc \
|
arc \
|
||||||
archiver \
|
archiver \
|
||||||
awless \
|
awless \
|
||||||
|
basecamp \
|
||||||
bat \
|
bat \
|
||||||
|
btop \
|
||||||
caddy \
|
caddy \
|
||||||
chromedriver \
|
chromedriver \
|
||||||
cmake \
|
cmake \
|
||||||
@@ -106,6 +108,7 @@ __rmrf_local() {
|
|||||||
arc \
|
arc \
|
||||||
archiver \
|
archiver \
|
||||||
awless \
|
awless \
|
||||||
|
basecamp \
|
||||||
bat \
|
bat \
|
||||||
caddy \
|
caddy \
|
||||||
chromedriver \
|
chromedriver \
|
||||||
@@ -205,6 +208,7 @@ __test() {
|
|||||||
arc \
|
arc \
|
||||||
archiver \
|
archiver \
|
||||||
awless \
|
awless \
|
||||||
|
basecamp \
|
||||||
bat \
|
bat \
|
||||||
caddy \
|
caddy \
|
||||||
chromedriver \
|
chromedriver \
|
||||||
|
|||||||
@@ -4,34 +4,34 @@ set -u
|
|||||||
|
|
||||||
__init_yq() {
|
__init_yq() {
|
||||||
|
|
||||||
pkg_cmd_name="yq"
|
pkg_cmd_name="yq"
|
||||||
|
|
||||||
pkg_dst_cmd="$HOME/.local/bin/yq"
|
pkg_dst_cmd="$HOME/.local/bin/yq"
|
||||||
pkg_dst="$pkg_dst_cmd"
|
pkg_dst="$pkg_dst_cmd"
|
||||||
|
|
||||||
pkg_src_cmd="$HOME/.local/opt/yq-v$WEBI_VERSION/bin/yq"
|
pkg_src_cmd="$HOME/.local/opt/yq-v$WEBI_VERSION/bin/yq"
|
||||||
pkg_src_dir="$HOME/.local/opt/yq-v$WEBI_VERSION"
|
pkg_src_dir="$HOME/.local/opt/yq-v$WEBI_VERSION"
|
||||||
pkg_src="$pkg_src_cmd"
|
pkg_src="$pkg_src_cmd"
|
||||||
|
|
||||||
pkg_install() {
|
pkg_install() {
|
||||||
mkdir -p "$(dirname "$pkg_src_cmd")"
|
mkdir -p "$(dirname "$pkg_src_cmd")"
|
||||||
# yq_linux_amd64.tar.gz contains:
|
# yq_linux_amd64.tar.gz contains:
|
||||||
# - yq_linux_amd64
|
# - yq_linux_amd64
|
||||||
# - yq.1
|
# - yq.1
|
||||||
# - install-man-page.sh
|
# - install-man-page.sh
|
||||||
if [ -e ./yq.1 ]; then
|
if [ -e ./yq.1 ]; then
|
||||||
mkdir -p ~/.local/share/man/man1
|
mkdir -p ~/.local/share/man/man1
|
||||||
mv ./yq.1 ~/.local/share/man/man1/
|
mv ./yq.1 ~/.local/share/man/man1/
|
||||||
fi
|
fi
|
||||||
mv ./"$pkg_cmd_name"* "$pkg_src_cmd"
|
mv ./"$pkg_cmd_name"* "$pkg_src_cmd"
|
||||||
chmod a+x "$pkg_src_cmd"
|
chmod a+x "$pkg_src_cmd"
|
||||||
}
|
}
|
||||||
|
|
||||||
pkg_get_current_version() {
|
pkg_get_current_version() {
|
||||||
yq --version 2> /dev/null |
|
yq --version 2> /dev/null |
|
||||||
head -n 1 |
|
head -n 1 |
|
||||||
cut -d ' ' -f 2
|
cut -d ' ' -f 2
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user