Skip to content

Commit

Permalink
feat(crates): prebuilt binaries (yetone#473)
Browse files Browse the repository at this point in the history
* feat(crates): prebuilt binaries

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

* chore: update name

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

* chore: build on PR

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

* chore: only build for lua51 and luajit

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

* feat: build stuff

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

* chore: only build if changes in Rust

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

* fix: remove deadcode

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>

---------

Signed-off-by: Aaron Pham <contact@aarnphm.xyz>
  • Loading branch information
aarnphm authored Sep 3, 2024
1 parent 9765eac commit a5726bd
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 62 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Nightly Build

on:
schedule:
- cron: '0 2 * * *' # Runs at 2 AM UTC every day
push:
branches:
- main
pull_request:
branches:
- main
paths:
- 'crates/**'
- '**/Cargo.toml'
workflow_dispatch: # Allows manual triggering

env:
CARGO_TERM_COLOR: always

jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
feature: [lua51, luajit]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.80.0
- name: Build all crates
run: cargo build --release --features ${{ matrix.feature }}
- name: handle binaries
shell: bash
run: |
mkdir -p results
if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then
OS="linux"
EXT="so"
elif [ "${{ matrix.os }}" == "macos-latest" ]; then
OS="macOS"
EXT="dylib"
else
OS="windows"
EXT="dll"
fi
if [ "${{ matrix.os }}" == "windows-latest" ]; then
cp target/release/avante_templates.$EXT results/avante_templates.$EXT
cp target/release/avante_tokenizers.$EXT results/avante_tokenizers.$EXT
else
cp target/release/libavante_templates.$EXT results/avante_templates.$EXT
cp target/release/libavante_tokenizers.$EXT results/avante_tokenizers.$EXT
fi
- name: Upload binaries
uses: actions/upload-artifact@v4
with:
name: avante_lib-${{ matrix.os }}-${{ matrix.feature }}
path: results/
14 changes: 13 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
with:
token: ${{ secrets.GITHUB_TOKEN }}
version: latest
args: --check ./lua/
args: --check ./lua/ ./plugin/
luacheck:
name: Lint Lua
runs-on: ubuntu-latest
Expand All @@ -29,3 +29,15 @@ jobs:
uses: lunarmodules/luacheck@v1
with:
args: ./lua/
rust:
name: Check Rust style
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
components: clippy, rustfmt
- name: Run rustfmt
run: make ruststylecheck
39 changes: 28 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ else
$(error Unsupported operating system: $(UNAME))
endif

LUA_VERSIONS := luajit lua51 lua52 lua53 lua54
LUA_VERSIONS := luajit lua51

BUILD_DIR := build
BUILD_FROM_SOURCE ?= false
TARGET_LIBRARY ?= all

all: luajit

define make_definitions
ifeq ($(BUILD_FROM_SOURCE),true)
ifeq ($(TARGET_LIBRARY), all)
$1: $(BUILD_DIR)/libAvanteTokenizers-$1.$(EXT) $(BUILD_DIR)/libAvanteTemplates-$1.$(EXT)
else ifeq ($(TARGET_LIBRARY), tokenizers)
Expand All @@ -28,35 +30,50 @@ $1: $(BUILD_DIR)/libAvanteTemplates-$1.$(EXT)
else
$$(error TARGET_LIBRARY must be one of all, tokenizers, templates)
endif
else
$1:
LUA_VERSION=$1 sh ./build.sh
endif
endef

$(foreach lua_version,$(LUA_VERSIONS),$(eval $(call make_definitions,$(lua_version))))

define build_from_source
define build_package
$1-$2:
cargo build --release --features=$1 -p avante-$2
cp target/release/libavante_$2.$(EXT) $(BUILD_DIR)/avante_$2.$(EXT)
endef

define build_targets
$(BUILD_DIR)/libAvanteTokenizers-$1.$(EXT): $(BUILD_DIR)
$$(call build_from_source,$1,tokenizers)
$(BUILD_DIR)/libAvanteTemplates-$1.$(EXT): $(BUILD_DIR)
$$(call build_from_source,$1,templates)
$(BUILD_DIR)/libAvanteTokenizers-$1.$(EXT): $(BUILD_DIR) $1-tokenizers
$(BUILD_DIR)/libAvanteTemplates-$1.$(EXT): $(BUILD_DIR) $1-templates
endef

$(foreach lua_version,$(LUA_VERSIONS),$(eval $(call build_package,$(lua_version),tokenizers)))
$(foreach lua_version,$(LUA_VERSIONS),$(eval $(call build_package,$(lua_version),templates)))
$(foreach lua_version,$(LUA_VERSIONS),$(eval $(call build_targets,$(lua_version))))

$(BUILD_DIR):
mkdir -p $(BUILD_DIR)
@mkdir -p $(BUILD_DIR)

clean:
rm -rf $(BUILD_DIR)
@rm -rf $(BUILD_DIR)

luacheck:
luacheck `find -name "*.lua"` --codes
@luacheck `find -name "*.lua"` --codes

stylecheck:
stylua --check lua/
@stylua --check lua/ plugin/

stylefix:
stylua lua/ plugin/
@stylua lua/ plugin/

.PHONY: ruststylecheck
ruststylecheck:
@rustup component add rustfmt 2> /dev/null
@cargo fmt --all -- --check

.PHONY: rustlint
rustlint:
@rustup component add clippy 2> /dev/null
@cargo clippy -F luajit --all -- -F clippy::dbg-macro -D warnings
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ https://github.com/user-attachments/assets/86140bfd-08b4-483d-a887-1b701d9e37dd
opts = {
-- add any opts here
},
build = ":AvanteBuild", -- Also note that this will block the startup for a bit since we are compiling bindings in Rust.
-- if you want to build from source, then pass source=true (requires cargo).
-- Also note that building from source will block startuptime since
-- we are compiling bindings in Rust.
build = ":AvanteBuild",
dependencies = {
"stevearc/dressing.nvim",
"nvim-lua/plenary.nvim",
Expand Down Expand Up @@ -87,7 +90,7 @@ Plug 'nvim-tree/nvim-web-devicons' "or Plug 'echasnovski/mini.icons'
Plug 'HakonHarnes/img-clip.nvim'
Plug 'zbirenbaum/copilot.lua'
" Yay
" Yay, pass source=true if you want to build from source
Plug 'yetone/avante.nvim', { 'branch': 'main', 'do': { -> avante#build() }, 'on': 'AvanteAsk' }
```

Expand Down
5 changes: 3 additions & 2 deletions autoload/avante.vim
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
function avante#build() abort
return join(luaeval("require('avante').build()"), "\n")
function avante#build(...) abort
let l:source = get(a:, 1, v:false)
return join(luaeval("require('avante').build(_A)", l:source), "\n")
endfunction
47 changes: 47 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash

set -eo pipefail

REPO_OWNER="yetone"
REPO_NAME="avante.nvim"

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"

# Set the target directory to clone the artifact
TARGET_DIR="${SCRIPT_DIR}/build"

# Get the latest successful run ID of the workflow
RUN_ID=$(curl -s -H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/actions/workflows/build.yaml/runs?status=success&branch=main" |
\grep -oP '(?<="id": )\d+' | head -1)

# Get the artifact download URL based on the platform and Lua version
case "$(uname -s)" in
Linux*)
PLATFORM="linux"
;;
Darwin*)
PLATFORM="macos"
;;
CYGWIN* | MINGW* | MSYS*)
PLATFORM="windows"
;;
*)
echo "Unsupported platform"
exit 1
;;
esac

# Set the Lua version (lua54 or luajit)
LUA_VERSION="${LUA_VERSION:-luajit}"

# Set the artifact name pattern
ARTIFACT_NAME_PATTERN="avante_lib-$PLATFORM-latest-$LUA_VERSION"

# Get the artifact download URL
ARTIFACT_URL=$(curl -s -H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/actions/runs/$RUN_ID/artifacts" |
\grep -oP "(?<=\"archive_download_url\": \")https://[^\"]+/$ARTIFACT_NAME_PATTERN[^\"]+")

mkdir -p "$TARGET_DIR"
curl -L "$ARTIFACT_URL" | tar -xz -C "$TARGET_DIR" --strip-components=1
53 changes: 52 additions & 1 deletion lua/avante/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ local Utils = require("avante.utils")
---@field ask fun(question:string?): boolean
---@field edit fun(question:string?): nil
---@field refresh fun(): nil
---@field build fun(): boolean
---@field build fun(opts: {source: boolean}): boolean
---@field switch_provider fun(target: string): nil
---@field toggle avante.ApiToggle
---@field get_suggestion fun(): avante.Suggestion | nil
Expand All @@ -20,6 +20,57 @@ local M = {}
---@param target Provider
M.switch_provider = function(target) require("avante.providers").refresh(target) end

---@param path string
local function to_windows_path(path)
local winpath = path:gsub("/", "\\")

if winpath:match("^%a:") then winpath = winpath:sub(1, 2):upper() .. winpath:sub(3) end

winpath = winpath:gsub("\\$", "")

return winpath
end

---@param opts {source: boolean}
M.build = function(opts)
local dirname = Utils.trim(string.sub(debug.getinfo(1).source, 2, #"/init.lua" * -1), { suffix = "/" })
local git_root = vim.fs.find(".git", { path = dirname, upward = true })[1]
local build_directory = git_root and vim.fn.fnamemodify(git_root, ":h") or (dirname .. "/../../")

if opts.source and not vim.fn.executable("cargo") then
error("Building avante.nvim requires cargo to be installed.", 2)
end

---@type string[]
local cmd
local os_name = Utils.get_os_name()

if vim.tbl_contains({ "linux", "darwin" }, os_name) then
cmd = {
"sh",
"-c",
string.format("make BUILD_FROM_SOURCE=%s -C %s", opts.source == true and "true" or "false", build_directory),
}
elseif os_name == "windows" then
build_directory = to_windows_path(build_directory)
cmd = {
"powershell",
"-ExecutionPolicy",
"Bypass",
"-File",
string.format("%s\\Build.ps1", build_directory),
"-WorkingDirectory",
build_directory,
}
else
error("Unsupported operating system: " .. os_name, 2)
end

local job = vim.system(cmd, { text = true }):wait()

return vim.tbl_contains({ 0 }, job.code) and true or false
end

---@param question? string
M.ask = function(question)
if not require("avante").toggle() then return false end
Expand Down
59 changes: 14 additions & 45 deletions lua/avante/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,20 @@ H.commands = function()
{ desc = "avante: edit selected block", nargs = "*" }
)
cmd("Refresh", function() require("avante.api").refresh() end, { desc = "avante: refresh windows" })
cmd("Build", function() M.build() end, { desc = "avante: build dependencies" })
cmd("Build", function(opts)
local args = {}
for _, arg in ipairs(opts.fargs) do
local key, value = arg:match("(%w+)=(%w+)")
if key and value then args[key] = value == "true" end
end
if args.source == nil then args.source = Config.debug and true or false end

require("avante.api").build(args)
end, {
desc = "avante: build dependencies",
nargs = "*",
complete = function(_, _, _) return { "source=true", "source=false" } end,
})
cmd("SwitchProvider", function(opts) require("avante.api").switch_provider(vim.trim(opts.args or "")) end, {
nargs = 1,
desc = "avante: switch provider",
Expand Down Expand Up @@ -269,50 +282,6 @@ setmetatable(M.toggle, {
end,
})

---@param path string
local function to_windows_path(path)
local winpath = path:gsub("/", "\\")

if winpath:match("^%a:") then winpath = winpath:sub(1, 2):upper() .. winpath:sub(3) end

winpath = winpath:gsub("\\$", "")

return winpath
end

M.build = H.api(function()
local dirname = Utils.trim(string.sub(debug.getinfo(1).source, 2, #"/init.lua" * -1), { suffix = "/" })
local git_root = vim.fs.find(".git", { path = dirname, upward = true })[1]
local build_directory = git_root and vim.fn.fnamemodify(git_root, ":h") or (dirname .. "/../../")

if not vim.fn.executable("cargo") then error("Building avante.nvim requires cargo to be installed.", 2) end

---@type string[]
local cmd
local os_name = Utils.get_os_name()

if vim.tbl_contains({ "linux", "darwin" }, os_name) then
cmd = { "sh", "-c", string.format("make -C %s", build_directory) }
elseif os_name == "windows" then
build_directory = to_windows_path(build_directory)
cmd = {
"powershell",
"-ExecutionPolicy",
"Bypass",
"-File",
string.format("%s\\Build.ps1", build_directory),
"-WorkingDirectory",
build_directory,
}
else
error("Unsupported operating system: " .. os_name, 2)
end

local job = vim.system(cmd, { text = true }):wait()

return vim.tbl_contains({ 0 }, job.code) and true or false
end)

---@param opts? avante.Config
function M.setup(opts)
---PERF: we can still allow running require("avante").setup() multiple times to override config if users wish to
Expand Down

0 comments on commit a5726bd

Please sign in to comment.