diff --git a/Cargo.lock b/Cargo.lock index 4bd89cef..fadacdb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1615,6 +1615,16 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "libmimalloc-sys" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23aa6811d3bd4deb8a84dde645f943476d13b248d818edcf8ce0b2f37f036b44" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "linked-hash-map" version = "0.5.6" @@ -1710,6 +1720,15 @@ dependencies = [ "libc", ] +[[package]] +name = "mimalloc" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68914350ae34959d83f732418d51e2427a794055d0b9529f48259ac07af65633" +dependencies = [ + "libmimalloc-sys", +] + [[package]] name = "mime" version = "0.3.17" @@ -2171,10 +2190,12 @@ dependencies = [ "bytes", "clap", "hex", + "mimalloc", "rama", "serde", "serde_json", "terminal-prompt", + "tikv-jemallocator", "tokio", "tracing", "tracing-subscriber", @@ -3061,6 +3082,26 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tikv-jemalloc-sys" +version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "tikv-jemallocator" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cec5ff18518d81584f477e9bfdf957f5bb0979b0bac3af4ca30b5b3ae2d2865" +dependencies = [ + "libc", + "tikv-jemalloc-sys", +] + [[package]] name = "time" version = "0.3.37" diff --git a/Cargo.toml b/Cargo.toml index e6d2aa86..6e6ea6b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -150,6 +150,8 @@ want = "0.3" futures-util = "0.3" futures-channel = "0.3" sha2 = "0.10.8" +jemallocator = { package = "tikv-jemallocator", version = "0.6" } +mimalloc = { version = "0.1.39" } [workspace.lints.rust] unreachable_pub = "deny" diff --git a/docs/book/src/deploy/rama-cli.md b/docs/book/src/deploy/rama-cli.md index ad85c17f..48a9fd04 100644 --- a/docs/book/src/deploy/rama-cli.md +++ b/docs/book/src/deploy/rama-cli.md @@ -31,7 +31,7 @@ Options: The easiest way to install `rama` is by using `cargo`: ```sh -cargo install rama-cli +cargo install rama-cli@0.2.0-alpha.6 ``` This will install `rama-cli` from source and make it available @@ -40,7 +40,7 @@ a pre-built binary when available for your platform you can do so using [`cargo binstall`](https://github.com/cargo-bins/cargo-binstall): ```sh -cargo binstall rama-cli +cargo binstall rama-cli@0.2.0-alpha.6 ``` On 🍎 MacOS you can also install the `rama` binary using [HomeBrew](https://brew.sh/): @@ -52,6 +52,18 @@ brew install plabayo/rama/rama > Contributions to the homebrew distributions can be made via > . +You can also install it from `curl`: + +``` +curl https://raw.githubusercontent.com/plabayo/rama/main/rama-cli/scripts/install.sh | bash +``` + +or `wget`: + +``` +wget -qO- https://raw.githubusercontent.com/plabayo/rama/main/rama-cli/scripts/install.sh | bash +``` + ## Docker The `rama` "cli" is also available as a docker image: diff --git a/justfile b/justfile index 5eb836d4..742363e8 100644 --- a/justfile +++ b/justfile @@ -132,16 +132,8 @@ detect-biggest-crates: mdbook-serve: cd docs/book && mdbook serve -rama-cli-release-build TARGET: - cargo build -p rama-cli --bin rama --release --target {{TARGET}} - VERSION="$(cat Cargo.toml | grep -E '^version = "' | cut -d\" -f2)" && \ - cd target/{{TARGET}}/release && \ - tar -czf rama-cli-${VERSION}-{{TARGET}}.tar.gz rama && \ - shasum -a 256 rama-cli-${VERSION}-{{TARGET}}.tar.gz > rama-cli-${VERSION}-{{TARGET}}.tar.gz.sha256 - -rama-cli-release-build-all: - just rama-cli-release-build x86_64-apple-darwin - just rama-cli-release-build aarch64-apple-darwin +rama-cli-build: + rama-cli/scripts/build.sh publish: cargo publish -p rama-error diff --git a/rama-cli/Cargo.toml b/rama-cli/Cargo.toml index e5217cc4..4b70c9a1 100644 --- a/rama-cli/Cargo.toml +++ b/rama-cli/Cargo.toml @@ -14,6 +14,10 @@ default-run = "rama" [lints] workspace = true +[features] +jemalloc = ["dep:jemallocator"] +mimalloc = ["dep:mimalloc"] + [dependencies] base64 = { workspace = true } bytes = { workspace = true } @@ -26,6 +30,8 @@ terminal-prompt = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } tracing = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } +jemallocator = { workspace = true, optional = true } +mimalloc = { workspace = true, default-features = false, optional = true } [[bin]] name = "rama" diff --git a/rama-cli/scripts/build.sh b/rama-cli/scripts/build.sh new file mode 100755 index 00000000..3927cca4 --- /dev/null +++ b/rama-cli/scripts/build.sh @@ -0,0 +1,166 @@ +#!/bin/bash + +: ${root=$(pwd)} +: ${tag=latest} +: ${os=linux} +: ${name=rama} + +# Function to print colored text based on log level +log() { + local level=$1 + local message=$2 + local NC='\033[0m' # Reset to default color + + case "$level" in + "info") + echo -e "\033[0;32m[INFO] $message${NC}" # Green for INFO + ;; + "warning") + echo -e "\033[0;33m[WARNING] $message${NC}" # Yellow for WARNING + ;; + "error") + echo -e "\033[0;31m[ERROR] $message${NC}" # Red for ERROR + ;; + *) + echo "$message" # Default to printing message without color for other levels + ;; + esac +} + +[ ! -d target ] && mkdir target + +# Build support paltform target +# 1. Linux +linux_target=( + "x86_64-unknown-linux-gnu:mimalloc" + "aarch64-unknown-linux-gnu:mimalloc" + "armv7-unknown-linux-gnueabihf:jemalloc" + "arm-unknown-linux-gnueabi:jemalloc" + "i686-unknown-linux-gnu:jemalloc" +) + +# 2. MacOS +macos_target=( + "x86_64-apple-darwin" + "aarch64-apple-darwin" +) + +# 3. Windows +windows_target=( + "x86_64-pc-windows-gnu" + "i686-pc-windows-gnu" +) + +# Check linux rustup target installed +check_linux_rustup_target_installed() { + for target in ${linux_target[@]}; do + target=$(echo $target | cut -d':' -f1) + installed=$(rustup target list | grep "${target} (installed)") + if [ -z "$installed" ]; then + log "info" "Installing ${target}..." + rustup target add ${target} + fi + done +} + +# Check macos rustup target installed +check_macos_rustup_target_installed() { + for target in ${macos_target[@]}; do + installed=$(rustup target list | grep "${target} (installed)") + if [ -z "$installed" ]; then + log "info" "Installing ${target}..." + rustup target add ${target} + fi + done +} + +# Check windows rustup target installed +check_windows_rustup_target_installed() { + for target in ${windows_target[@]}; do + installed=$(rustup target list | grep "${target} (installed)") + if [ -z "$installed" ]; then + log "info" "Installing ${target}..." + rustup target add ${target} + fi + done +} + +# Build linux target +build_linux_target() { + for target in "${linux_target[@]}"; do + build_target=$(echo $target | cut -d':' -f1) + feature=$(echo $target | cut -d':' -f2) + log "info" "Building ${target}..." + if cargo zigbuild --release -p rama-cli --target "${build_target}" --features "${feature}"; then + compress_and_move $build_target + log "info" "Build ${target} done" + else + log "error" "Build ${target} failed" + exit 1 + fi + done +} + +# Build macos target +build_macos_target() { + for target in "${macos_target[@]}"; do + log "info" "Building ${target}..." + if CARGO_PROFILE_RELEASE_STRIP=none cargo zigbuild --release -p rama-cli --target "${target}"; then + compress_and_move $target + log "info" "Build ${target} done" + else + log "error" "Build ${target} failed" + exit 1 + fi + done +} + +# Build windows target +build_windows_target() { + for target in "${windows_target[@]}"; do + log "info" "Building ${target}..." + if cargo build --release -p rama-cli --target "${target}"; then + compress_and_move $target + log "info" "Build ${target} done" + else + log "error" "Build ${target} failed" + exit 1 + fi + done +} + +# upx and move target +compress_and_move() { + build_target=$1 + target_dir="target/${build_target}/release" + bin_name=$name + if [[ $build_target == *windows* ]]; then + bin_name="${name}.exe" + fi + upx "${target_dir}/${bin_name}" + chmod +x "${target_dir}/${bin_name}" + cd "${target_dir}" + tar czvf $name-$tag-${build_target}.tar.gz $bin_name + shasum -a 256 $name-$tag-${build_target}.tar.gz >$name-$tag-${build_target}.tar.gz.sha256 + mv $name-$tag-${build_target}.tar.gz $root/target/ + mv $name-$tag-${build_target}.tar.gz.sha256 $root/target/ + cd - +} + +# Execute +if [ "$os" == "linux" ]; then + log "info" "Building linux target..." + check_linux_rustup_target_installed + build_linux_target +elif [ "$os" == "macos" ]; then + log "info" "Building macos target..." + check_macos_rustup_target_installed + build_macos_target +elif [ "$os" == "windows" ]; then + log "info" "Building windows target..." + check_windows_rustup_target_installed + build_windows_target +else + log "error" "Unsupported os: ${os}" + exit 1 +fi diff --git a/rama-cli/scripts/install.sh b/rama-cli/scripts/install.sh new file mode 100755 index 00000000..b82bd334 --- /dev/null +++ b/rama-cli/scripts/install.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# Fetch the latest release information +tag=$(jq -r 'map(select(.prerelease)) | first | .tag_name' <<< $(curl --silent https://api.github.com/repos/plabayo/rama/releases)) +version=${tag#v} + +# Get system architecture and OS +ARCH=$(uname -m) +OS=$(uname -s | tr '[:upper:]' '[:lower:]') + +# Select the appropriate filename based on the system architecture and OS +case "$ARCH-$OS" in + "aarch64-darwin") FILENAME="rama-aarch64-apple-darwin.tar.gz" ;; + "arm64-darwin") FILENAME="rama-aarch64-apple-darwin.tar.gz" ;; + # "aarch64-linux") FILENAME="rama-aarch64-unknown-linux-musl.tar.gz" ;; + # "arm-linux") FILENAME="rama-arm-unknown-linux-musleabihf.tar.gz" ;; + # "armv7l-linux") FILENAME="rama-armv7-unknown-linux-musleabihf.tar.gz" ;; + # "i686-windows") FILENAME="rama-i686-pc-windows-gnu.tar.gz" ;; + # "i686-linux") FILENAME="rama-i686-unknown-linux-musl.tar.gz" ;; + "x86_64-darwin") FILENAME="rama-x86_64-apple-darwin.tar.gz" ;; + # "x86_64-windows") FILENAME="rama-x86_64-pc-windows-gnu.tar.gz" ;; + # "x86_64-linux") FILENAME="rama-x86_64-unknown-linux-musl.tar.gz" ;; + *) echo "Unknown system architecture: $ARCH-$OS"; exit 1 ;; +esac + +# Construct the download URL +download_url="https://github.com/plabayo/rama/releases/download/$tag/$FILENAME" + +echo "Download URL: $download_url" + +if [ -z "$download_url" ]; then + echo "Could not find a suitable package for your system architecture." + exit 1 +fi + +# Download the binary package +curl -L -o $FILENAME $download_url + +echo "Download complete: $FILENAME" + +# Extract the binary package +tar -xzf $FILENAME +rm -rf $FILENAME + +echo "Extraction complete: $FILENAME" + +# Move the extracted files to the installation path +# Assuming the binary file is named `rama` +sudo mv rama /usr/local/bin/rama +echo "Installation complete: /usr/local/bin/rama" diff --git a/rama-cli/src/main.rs b/rama-cli/src/main.rs index 087c1fc6..6e804777 100644 --- a/rama-cli/src/main.rs +++ b/rama-cli/src/main.rs @@ -12,6 +12,14 @@ use cmd::{echo, fp, http, ip, proxy}; pub mod error; +#[cfg(all(not(feature = "mimalloc"), feature = "jemalloc"))] +#[global_allocator] +static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; + +#[cfg(feature = "mimalloc")] +#[global_allocator] +static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; + #[derive(Debug, Parser)] #[command(name = "rama")] #[command(bin_name = "rama")]