fix: Download binaries for new versioning system (#302)
This commit is contained in:
committed by
GitHub
parent
85130958bd
commit
aee5fbb8c4
@@ -90,6 +90,10 @@ jobs:
|
||||
shell: bash
|
||||
run: make test-lua
|
||||
|
||||
- name: Run version resolution tests
|
||||
shell: bash
|
||||
run: make test-version
|
||||
|
||||
- name: Run bun tests
|
||||
shell: bash
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
|
||||
@@ -2,7 +2,7 @@ name: Prebuild
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
branches: [main, fix/download-version]
|
||||
tags:
|
||||
- "v*"
|
||||
pull_request:
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
run: rustup target add ${{ matrix.target }}
|
||||
|
||||
- name: Install Zig
|
||||
uses: goto-bus-stop/setup-zig@v2
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.15.2
|
||||
|
||||
@@ -206,7 +206,7 @@ jobs:
|
||||
run: rustup target add ${{ matrix.target }}
|
||||
|
||||
- name: Install Zig
|
||||
uses: goto-bus-stop/setup-zig@v2
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.15.2
|
||||
|
||||
@@ -319,7 +319,7 @@ jobs:
|
||||
run: rustup target add ${{ matrix.target }}
|
||||
|
||||
- name: Install Zig
|
||||
uses: goto-bus-stop/setup-zig@v2
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.15.2
|
||||
|
||||
@@ -367,6 +367,9 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Install Lua
|
||||
uses: leafo/gh-actions-lua@v12
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
@@ -432,7 +435,7 @@ jobs:
|
||||
|
||||
- name: Determine version
|
||||
id: version
|
||||
run: ./scripts/determine-version.sh
|
||||
run: lua scripts/determine-version.lua
|
||||
|
||||
- name: Upload Release Assets
|
||||
uses: softprops/action-gh-release@v2
|
||||
@@ -466,11 +469,15 @@ jobs:
|
||||
needs: [build-nvim, build-c, build-mcp]
|
||||
runs-on: ubuntu-latest
|
||||
if: >-
|
||||
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/node' || startsWith(github.ref, 'refs/tags/v')))
|
||||
|| (github.event_name == 'pull_request' && (github.head_ref == 'main' || github.head_ref == 'node'))
|
||||
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/fix/download-version' || startsWith(github.ref, 'refs/tags/v')))
|
||||
|| (github.event_name == 'pull_request' && github.head_ref == 'main')
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Install Lua
|
||||
uses: leafo/gh-actions-lua@v12
|
||||
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
@@ -479,7 +486,7 @@ jobs:
|
||||
|
||||
- name: Determine version
|
||||
id: version
|
||||
run: ./scripts/determine-version.sh
|
||||
run: lua scripts/determine-version.lua
|
||||
|
||||
- name: Publish crates
|
||||
env:
|
||||
@@ -491,13 +498,16 @@ jobs:
|
||||
needs: [build-c]
|
||||
runs-on: ubuntu-latest
|
||||
if: >-
|
||||
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/node' || startsWith(github.ref, 'refs/tags/v')))
|
||||
|| (github.event_name == 'pull_request' && (github.head_ref == 'main' || github.head_ref == 'node'))
|
||||
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/fix/download-version' || startsWith(github.ref, 'refs/tags/v')))
|
||||
|| (github.event_name == 'pull_request' && github.head_ref == 'main')
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Install Lua
|
||||
uses: leafo/gh-actions-lua@v12
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
@@ -506,7 +516,7 @@ jobs:
|
||||
|
||||
- name: Determine version
|
||||
id: version
|
||||
run: ./scripts/determine-version.sh
|
||||
run: lua scripts/determine-version.lua
|
||||
|
||||
- name: Download npm package artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -559,5 +569,5 @@ jobs:
|
||||
|
||||
cd packages/fff-node
|
||||
npm install
|
||||
npx tsc
|
||||
npm run build
|
||||
npm publish --tag "$TAG" --access public || echo "Failed to publish @ff-labs/fff-node (may already exist)"
|
||||
|
||||
Generated
+612
-473
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
PLENARY_DIR ?= ../plenary.nvim
|
||||
|
||||
.PHONY: build test test-rust test-lua test-bun test-node prepare-bun prepare-node set-npm-version header
|
||||
.PHONY: build test test-rust test-lua test-version test-bun test-node prepare-bun prepare-node set-npm-version header
|
||||
|
||||
build:
|
||||
cargo build --release --features zlob
|
||||
@@ -21,6 +21,10 @@ test-lua: test-setup build
|
||||
nvim --headless -u tests/minimal_init.lua \
|
||||
-c "PlenaryBustedFile tests/fff_core_spec.lua" 2>&1
|
||||
|
||||
test-version: test-setup
|
||||
nvim --headless -u tests/minimal_init.lua \
|
||||
-c "PlenaryBustedFile tests/version_spec.lua" 2>&1
|
||||
|
||||
prepare-bun: build
|
||||
mkdir -p packages/fff-bun/bin
|
||||
cp target/release/libfff_c.dylib packages/fff-bun/bin/ 2>/dev/null; \
|
||||
@@ -41,7 +45,7 @@ test-bun: prepare-bun
|
||||
test-node: prepare-node
|
||||
cd packages/fff-node && npm run build && node test/e2e.mjs
|
||||
|
||||
test: test-rust test-lua test-bun test-node
|
||||
test: test-rust test-lua test-version test-bun test-node
|
||||
|
||||
# Update version in a package.json, including optionalDependencies.
|
||||
# Usage: make set-npm-version PKG=packages/fff-bun VERSION=1.0.0-nightly.abc1234
|
||||
|
||||
@@ -24,7 +24,7 @@ rayon = { workspace = true }
|
||||
smallvec = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
fff-query-parser = { workspace = true , version = "0.4.2" }
|
||||
fff-query-parser = { workspace = true }
|
||||
|
||||
# External dependencies
|
||||
bindet = { workspace = true }
|
||||
@@ -35,7 +35,7 @@ git2 = { workspace = true }
|
||||
glidesort = { workspace = true }
|
||||
globset = { workspace = true }
|
||||
grep-matcher = { workspace = true }
|
||||
fff-grep = { workspace = true , version = "0.4.2" }
|
||||
fff-grep = { workspace = true }
|
||||
aho-corasick = "1"
|
||||
memchr = "2"
|
||||
heed = { workspace = true }
|
||||
|
||||
+24
-15
@@ -1,19 +1,10 @@
|
||||
local M = {}
|
||||
local system = require('fff.utils.system')
|
||||
local fs_utils = require('fff.utils.fs')
|
||||
local fff_version = require('fff.utils.version')
|
||||
|
||||
local GITHUB_REPO = 'dmtrKovalenko/fff.nvim'
|
||||
|
||||
local function get_current_version(plugin_dir, callback)
|
||||
vim.system({ 'git', 'rev-parse', '--short', 'HEAD' }, { cwd = plugin_dir }, function(result)
|
||||
if result.code ~= 0 or not result.stdout or result.stdout == '' then
|
||||
callback(nil)
|
||||
return
|
||||
end
|
||||
callback(result.stdout:gsub('%s+', ''))
|
||||
end)
|
||||
end
|
||||
|
||||
local function get_binary_dir(plugin_dir) return plugin_dir .. '/../target/release' end
|
||||
|
||||
local function get_binary_path(plugin_dir)
|
||||
@@ -168,20 +159,38 @@ function M.ensure_downloaded(opts, callback)
|
||||
return
|
||||
end
|
||||
|
||||
local function on_version(target_version)
|
||||
if not target_version then
|
||||
local function on_release_tag(release_tag)
|
||||
if not release_tag then
|
||||
callback(false, 'Could not determine target version')
|
||||
return
|
||||
end
|
||||
|
||||
local binary_path = get_binary_path(plugin_dir)
|
||||
download_from_github(target_version, binary_path, opts, callback)
|
||||
download_from_github(release_tag, binary_path, opts, callback)
|
||||
end
|
||||
|
||||
if opts.version then
|
||||
on_version(opts.version)
|
||||
on_release_tag(opts.version)
|
||||
else
|
||||
get_current_version(plugin_dir, on_version)
|
||||
-- plugin_dir is <repo>/lua; parent is the repo root
|
||||
local repo_root = vim.fn.fnamemodify(plugin_dir, ':h')
|
||||
|
||||
-- 1. Try reading the CI-created tag on HEAD (no version computation)
|
||||
local tag = fff_version.current_release_tag(repo_root)
|
||||
if tag then
|
||||
on_release_tag(tag)
|
||||
return
|
||||
end
|
||||
|
||||
-- 2. No local tag — construct the nightly version (bumps patch so
|
||||
-- the prerelease is higher than Cargo.toml base in semver)
|
||||
local info, err = fff_version.resolve(repo_root)
|
||||
if info then
|
||||
on_release_tag(info.release_tag)
|
||||
return
|
||||
end
|
||||
|
||||
callback(false, err or 'Could not determine target version')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
local M = {}
|
||||
|
||||
local is_windows = (package.config:sub(1, 1) == '\\')
|
||||
|
||||
--- Shell-quote a string for safe interpolation into a command.
|
||||
---@param s string
|
||||
---@return string
|
||||
local function shell_quote(s)
|
||||
if is_windows then return '"' .. s:gsub('"', '\\"') .. '"' end
|
||||
return "'" .. s:gsub("'", "'\\''") .. "'"
|
||||
end
|
||||
|
||||
--- Run a git command in the given repository and return trimmed stdout.
|
||||
---@param repo_root string
|
||||
---@return string|nil output trimmed stdout, or nil on failure
|
||||
local function git(repo_root, ...)
|
||||
local parts = { 'git', '-C', shell_quote(repo_root) }
|
||||
for i = 1, select('#', ...) do
|
||||
parts[#parts + 1] = shell_quote(select(i, ...))
|
||||
end
|
||||
|
||||
local redirect = is_windows and ' 2>NUL' or ' 2>/dev/null'
|
||||
local handle = io.popen(table.concat(parts, ' ') .. redirect)
|
||||
if not handle then return nil end
|
||||
|
||||
local output = handle:read('*a')
|
||||
handle:close()
|
||||
|
||||
if not output or output:match('^%s*$') then return nil end
|
||||
return output:gsub('%s+$', '')
|
||||
end
|
||||
|
||||
function M.current_release_tag(repo_root)
|
||||
local raw = git(repo_root, 'tag', '--points-at', 'HEAD')
|
||||
if not raw then return nil end
|
||||
|
||||
local stable, nightly, dev, other
|
||||
for tag in raw:gmatch('[^\n]+') do
|
||||
if tag:match('^v%d') then
|
||||
stable = tag
|
||||
elseif tag:match('%-nightly%.') then
|
||||
nightly = tag
|
||||
elseif tag:match('%-dev%.') then
|
||||
dev = tag
|
||||
else
|
||||
other = tag
|
||||
end
|
||||
end
|
||||
|
||||
return stable or nightly or dev or other
|
||||
end
|
||||
|
||||
function M.read_base_version(repo_root)
|
||||
local cargo_path = repo_root .. '/crates/fff-core/Cargo.toml'
|
||||
local f = io.open(cargo_path, 'r')
|
||||
if not f then return nil end
|
||||
|
||||
for line in f:lines() do
|
||||
local ver = line:match('^version%s*=%s*"([^"]+)"')
|
||||
if ver then
|
||||
f:close()
|
||||
return ver
|
||||
end
|
||||
end
|
||||
|
||||
f:close()
|
||||
return nil
|
||||
end
|
||||
|
||||
---@class FFFVersionInfo
|
||||
---@field version string semver version (e.g. "0.4.0" or "0.4.1-nightly.abc1234")
|
||||
---@field release_tag string GitHub release tag for download URLs
|
||||
---@field is_release boolean true for tagged stable releases
|
||||
---@field npm_tag string "latest"|"nightly"|"dev"
|
||||
|
||||
--- Bump the patch component of a semver string.
|
||||
--- "1.2.3" → "1.2.4"
|
||||
---@param version string
|
||||
---@return string|nil bumped version, or nil if parsing fails
|
||||
local function bump_patch(version)
|
||||
local major, minor, patch = version:match('^(%d+)%.(%d+)%.(%d+)')
|
||||
if not major then return nil end
|
||||
return string.format('%s.%s.%d', major, minor, tonumber(patch) + 1)
|
||||
end
|
||||
|
||||
--- Compute the version for a new release based on git state.
|
||||
--- Used by CI to determine what tag to create — NOT for downloads.
|
||||
---
|
||||
--- For prerelease versions the patch is bumped so that the result is
|
||||
--- higher than the current Cargo.toml version in semver ordering.
|
||||
--- This is required for `cargo set-version` / crates.io publishing
|
||||
--- (0.4.1-nightly.x > 0.4.0, whereas 0.4.0-nightly.x < 0.4.0).
|
||||
---
|
||||
--- tagged release (v*) → version from tag, npm_tag = "latest"
|
||||
--- main branch → {base+1}-nightly.{sha}, npm_tag = "nightly"
|
||||
--- detached HEAD → {base+1}-nightly.{sha}, npm_tag = "nightly"
|
||||
--- other branch (PR / feature) → {base+1}-dev.{sha}, npm_tag = "dev"
|
||||
---
|
||||
---@param repo_root string absolute path to the repository root
|
||||
---@return FFFVersionInfo|nil info
|
||||
---@return string|nil err
|
||||
function M.resolve(repo_root)
|
||||
local tag = git(repo_root, 'describe', '--exact-match', '--tags', '--match', 'v*', 'HEAD')
|
||||
|
||||
if tag and tag:match('^v%d') then
|
||||
return {
|
||||
version = tag:sub(2),
|
||||
release_tag = tag,
|
||||
is_release = true,
|
||||
npm_tag = 'latest',
|
||||
}
|
||||
end
|
||||
|
||||
local short_sha = git(repo_root, 'rev-parse', '--short', 'HEAD')
|
||||
if not short_sha then return nil, 'Failed to determine git SHA' end
|
||||
|
||||
local base_version = M.read_base_version(repo_root)
|
||||
if not base_version then return nil, 'Could not read base version from crates/fff-core/Cargo.toml' end
|
||||
|
||||
local next_version = bump_patch(base_version)
|
||||
if not next_version then return nil, 'Could not parse base version: ' .. base_version end
|
||||
|
||||
local branch = git(repo_root, 'symbolic-ref', '--short', 'HEAD')
|
||||
|
||||
local prerelease_label, npm_tag
|
||||
if not branch then
|
||||
prerelease_label = 'nightly'
|
||||
npm_tag = 'nightly'
|
||||
elseif branch == 'main' or branch == 'fix/download-version' then
|
||||
prerelease_label = 'nightly'
|
||||
npm_tag = 'nightly'
|
||||
else
|
||||
prerelease_label = 'dev'
|
||||
npm_tag = 'dev'
|
||||
end
|
||||
|
||||
local version = string.format('%s-%s.%s', next_version, prerelease_label, short_sha)
|
||||
return {
|
||||
version = version,
|
||||
release_tag = version,
|
||||
is_release = false,
|
||||
npm_tag = npm_tag,
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -0,0 +1,30 @@
|
||||
local script_path = arg[0]
|
||||
local script_dir = script_path:match('(.*[/\\])') or './'
|
||||
local repo_root = script_dir .. '..'
|
||||
|
||||
-- Add the plugin's lua/ directory to the module search path
|
||||
package.path = repo_root .. '/lua/?.lua;' .. repo_root .. '/lua/?/init.lua;' .. package.path
|
||||
|
||||
local version = require('fff.utils.version')
|
||||
|
||||
local info, err = version.resolve(repo_root)
|
||||
if not info then
|
||||
io.stderr:write('Error: ' .. (err or 'unknown') .. '\n')
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
print('version=' .. info.version)
|
||||
print('npm_tag=' .. info.npm_tag)
|
||||
print('is_release=' .. tostring(info.is_release))
|
||||
|
||||
-- Write to GITHUB_OUTPUT when running in CI
|
||||
local github_output = os.getenv('GITHUB_OUTPUT')
|
||||
if github_output and github_output ~= '' then
|
||||
local f = io.open(github_output, 'a')
|
||||
if f then
|
||||
f:write('version=' .. info.version .. '\n')
|
||||
f:write('npm_tag=' .. info.npm_tag .. '\n')
|
||||
f:write('is_release=' .. tostring(info.is_release) .. '\n')
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
@@ -1,62 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Determines the release version based on git context.
|
||||
#
|
||||
# Tagged release (refs/tags/v*) → uses the tag version (e.g. v0.2.4 → 0.2.4)
|
||||
# Push to main → nightly prerelease (e.g. 0.2.5-nightly.abc1234)
|
||||
# Other (PR / dev branch) → dev prerelease (e.g. 0.2.5-dev.abc1234)
|
||||
#
|
||||
# For prerelease builds the patch version is bumped so that the resulting
|
||||
# semver is strictly greater than the current Cargo.toml version.
|
||||
# (In semver 0.2.4-nightly.x < 0.2.4, so we need 0.2.5-nightly.x > 0.2.4.)
|
||||
#
|
||||
# Outputs (appended to $GITHUB_OUTPUT when running in CI):
|
||||
# version – semver string
|
||||
# npm_tag – npm dist-tag (latest | nightly | dev)
|
||||
# is_release – "true" for tagged releases, "false" otherwise
|
||||
#
|
||||
# Can also be run locally for debugging:
|
||||
# GITHUB_REF=refs/tags/v0.3.0 ./scripts/determine-version.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
# Single source of truth: base version lives in fff-core
|
||||
base_version=$(grep '^version' "$REPO_ROOT/crates/fff-core/Cargo.toml" \
|
||||
| head -1 \
|
||||
| sed 's/version = "\(.*\)"/\1/')
|
||||
|
||||
short_sha=$(git -C "$REPO_ROOT" rev-parse --short HEAD)
|
||||
|
||||
# Bump the patch component: 0.2.4 → 0.2.5
|
||||
IFS='.' read -r major minor patch <<< "$base_version"
|
||||
next_patch_version="${major}.${minor}.$((patch + 1))"
|
||||
|
||||
ref="${GITHUB_REF:-}"
|
||||
|
||||
if [[ "$ref" == refs/tags/v* ]]; then
|
||||
# Tagged release – strip the leading "v"
|
||||
version="${ref#refs/tags/v}"
|
||||
npm_tag="latest"
|
||||
is_release="true"
|
||||
elif [[ "$ref" == "refs/heads/main" || "$ref" == "refs/heads/node" ]]; then
|
||||
version="${next_patch_version}-nightly.${short_sha}"
|
||||
npm_tag="nightly"
|
||||
is_release="false"
|
||||
else
|
||||
version="${next_patch_version}-dev.${short_sha}"
|
||||
npm_tag="dev"
|
||||
is_release="false"
|
||||
fi
|
||||
|
||||
echo "version=${version}"
|
||||
echo "npm_tag=${npm_tag}"
|
||||
echo "is_release=${is_release}"
|
||||
|
||||
# Write to GITHUB_OUTPUT when running in CI
|
||||
if [ -n "${GITHUB_OUTPUT:-}" ]; then
|
||||
echo "version=${version}" >> "$GITHUB_OUTPUT"
|
||||
echo "npm_tag=${npm_tag}" >> "$GITHUB_OUTPUT"
|
||||
echo "is_release=${is_release}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
@@ -8,6 +8,8 @@ VERSION="${VERSION#v}"
|
||||
|
||||
TAG="v${VERSION}"
|
||||
|
||||
git pull
|
||||
|
||||
# Check for clean working tree
|
||||
if ! git diff --quiet || ! git diff --cached --quiet; then
|
||||
echo "Error: Working tree is not clean. Commit or stash changes first."
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
---@diagnostic disable: undefined-field, need-check-nil, param-type-mismatch
|
||||
local version = require('fff.utils.version')
|
||||
|
||||
describe('fff.utils.version', function()
|
||||
local repo_root
|
||||
|
||||
before_each(function()
|
||||
repo_root = vim.fn.fnamemodify(debug.getinfo(1, 'S').source:sub(2), ':h:h')
|
||||
if vim.fn.isdirectory(repo_root) ~= 1 then repo_root = vim.fn.getcwd() end
|
||||
end)
|
||||
|
||||
describe('read_base_version', function()
|
||||
it('should read version from Cargo.toml', function()
|
||||
local ver = version.read_base_version(repo_root)
|
||||
assert.is_not_nil(ver)
|
||||
assert.is_string(ver)
|
||||
assert.is_truthy(ver:match('^%d+%.%d+%.%d+'), 'expected semver, got: ' .. ver)
|
||||
end)
|
||||
|
||||
it(
|
||||
'should return nil for missing directory',
|
||||
function() assert.is_nil(version.read_base_version('/nonexistent_path_12345')) end
|
||||
)
|
||||
|
||||
it('should parse version from a temp Cargo.toml', function()
|
||||
local tmp = vim.fn.tempname()
|
||||
vim.fn.mkdir(tmp .. '/crates/fff-core', 'p')
|
||||
|
||||
local f = io.open(tmp .. '/crates/fff-core/Cargo.toml', 'w')
|
||||
f:write('[package]\nname = "test"\nversion = "1.2.3"\n')
|
||||
f:close()
|
||||
|
||||
assert.are.equal('1.2.3', version.read_base_version(tmp))
|
||||
vim.fn.delete(tmp, 'rf')
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('current_release_tag', function()
|
||||
it('should return a string or nil for the real repo', function()
|
||||
local tag = version.current_release_tag(repo_root)
|
||||
-- On CI the commit has a tag; locally it might not
|
||||
if tag then
|
||||
assert.is_string(tag)
|
||||
else
|
||||
assert.is_nil(tag)
|
||||
end
|
||||
end)
|
||||
|
||||
it('should return nil for a repo with no tags', function()
|
||||
local tmp = vim.fn.tempname()
|
||||
vim.fn.mkdir(tmp, 'p')
|
||||
|
||||
vim.fn.system({ 'git', 'init', '-q', tmp })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'config', 'user.email', 'test@test.com' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'config', 'user.name', 'Test' })
|
||||
|
||||
local f = io.open(tmp .. '/file.txt', 'w')
|
||||
f:write('hello')
|
||||
f:close()
|
||||
|
||||
vim.fn.system({ 'git', '-C', tmp, 'add', '.' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'commit', '-q', '-m', 'init' })
|
||||
|
||||
assert.is_nil(version.current_release_tag(tmp))
|
||||
vim.fn.delete(tmp, 'rf')
|
||||
end)
|
||||
|
||||
it('should prefer v* tags over nightly/dev/legacy', function()
|
||||
local tmp = vim.fn.tempname()
|
||||
vim.fn.mkdir(tmp, 'p')
|
||||
|
||||
vim.fn.system({ 'git', 'init', '-q', tmp })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'config', 'user.email', 'test@test.com' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'config', 'user.name', 'Test' })
|
||||
|
||||
local f = io.open(tmp .. '/file.txt', 'w')
|
||||
f:write('hello')
|
||||
f:close()
|
||||
|
||||
vim.fn.system({ 'git', '-C', tmp, 'add', '.' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'commit', '-q', '-m', 'init' })
|
||||
|
||||
-- Add multiple tags on the same commit
|
||||
vim.fn.system({ 'git', '-C', tmp, 'tag', '0.4.0-dev.abc1234' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'tag', '0.4.0-nightly.abc1234' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'tag', 'v0.4.0' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'tag', 'deadbeef' })
|
||||
|
||||
assert.are.equal('v0.4.0', version.current_release_tag(tmp))
|
||||
vim.fn.delete(tmp, 'rf')
|
||||
end)
|
||||
|
||||
it('should prefer nightly over dev', function()
|
||||
local tmp = vim.fn.tempname()
|
||||
vim.fn.mkdir(tmp, 'p')
|
||||
|
||||
vim.fn.system({ 'git', 'init', '-q', tmp })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'config', 'user.email', 'test@test.com' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'config', 'user.name', 'Test' })
|
||||
|
||||
local f = io.open(tmp .. '/file.txt', 'w')
|
||||
f:write('hello')
|
||||
f:close()
|
||||
|
||||
vim.fn.system({ 'git', '-C', tmp, 'add', '.' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'commit', '-q', '-m', 'init' })
|
||||
|
||||
vim.fn.system({ 'git', '-C', tmp, 'tag', '0.4.0-dev.abc1234' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'tag', '0.4.0-nightly.abc1234' })
|
||||
|
||||
assert.are.equal('0.4.0-nightly.abc1234', version.current_release_tag(tmp))
|
||||
vim.fn.delete(tmp, 'rf')
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('resolve', function()
|
||||
it('should resolve a version from the real repo', function()
|
||||
local info, err = version.resolve(repo_root)
|
||||
assert.is_nil(err)
|
||||
assert.is_not_nil(info)
|
||||
assert.is_string(info.version)
|
||||
assert.is_string(info.release_tag)
|
||||
assert.is_string(info.npm_tag)
|
||||
assert.is_not_nil(info.is_release)
|
||||
end)
|
||||
|
||||
it('should produce a version higher than Cargo.toml base', function()
|
||||
local info = version.resolve(repo_root)
|
||||
local base = version.read_base_version(repo_root)
|
||||
assert.is_not_nil(info)
|
||||
assert.is_not_nil(base)
|
||||
-- For prereleases, patch is bumped: 0.4.0 → 0.4.1-nightly.{sha}
|
||||
if not info.is_release then
|
||||
local base_major, base_minor, base_patch = base:match('^(%d+)%.(%d+)%.(%d+)')
|
||||
local expected_patch = tostring(tonumber(base_patch) + 1)
|
||||
assert.is_truthy(
|
||||
info.version:find(base_major .. '%.' .. base_minor .. '%.' .. expected_patch),
|
||||
'version "' .. info.version .. '" should have bumped patch from base "' .. base .. '"'
|
||||
)
|
||||
end
|
||||
end)
|
||||
|
||||
it('should return dev on a non-main branch', function()
|
||||
local tmp = vim.fn.tempname()
|
||||
vim.fn.mkdir(tmp .. '/crates/fff-core', 'p')
|
||||
|
||||
vim.fn.system({ 'git', 'init', '-q', tmp })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'config', 'user.email', 'test@test.com' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'config', 'user.name', 'Test' })
|
||||
|
||||
local f = io.open(tmp .. '/crates/fff-core/Cargo.toml', 'w')
|
||||
f:write('[package]\nname = "test"\nversion = "1.0.0"\nedition = "2024"\n')
|
||||
f:close()
|
||||
|
||||
vim.fn.system({ 'git', '-C', tmp, 'add', '.' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'commit', '-q', '-m', 'init' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'checkout', '-b', 'feature-x' })
|
||||
|
||||
local info = version.resolve(tmp)
|
||||
assert.is_not_nil(info)
|
||||
assert.are.equal('dev', info.npm_tag)
|
||||
assert.is_false(info.is_release)
|
||||
assert.is_truthy(info.version:find('-dev%.'), 'expected dev prerelease, got: ' .. info.version)
|
||||
assert.is_truthy(info.version:find('^1%.0%.1%-'), 'expected bumped patch 1.0.1, got: ' .. info.version)
|
||||
|
||||
vim.fn.delete(tmp, 'rf')
|
||||
end)
|
||||
|
||||
it('should return nightly on main branch', function()
|
||||
local tmp = vim.fn.tempname()
|
||||
vim.fn.mkdir(tmp .. '/crates/fff-core', 'p')
|
||||
|
||||
vim.fn.system({ 'git', 'init', '-q', '-b', 'main', tmp })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'config', 'user.email', 'test@test.com' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'config', 'user.name', 'Test' })
|
||||
|
||||
local f = io.open(tmp .. '/crates/fff-core/Cargo.toml', 'w')
|
||||
f:write('[package]\nname = "test"\nversion = "2.0.0"\nedition = "2024"\n')
|
||||
f:close()
|
||||
|
||||
vim.fn.system({ 'git', '-C', tmp, 'add', '.' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'commit', '-q', '-m', 'init' })
|
||||
|
||||
local info = version.resolve(tmp)
|
||||
assert.is_not_nil(info)
|
||||
assert.are.equal('nightly', info.npm_tag)
|
||||
assert.is_false(info.is_release)
|
||||
assert.is_truthy(info.version:find('2%.0%.1%-nightly%.'), 'expected 2.0.1-nightly, got: ' .. info.version)
|
||||
|
||||
vim.fn.delete(tmp, 'rf')
|
||||
end)
|
||||
|
||||
it('should return stable release for v* tagged commit', function()
|
||||
local tmp = vim.fn.tempname()
|
||||
vim.fn.mkdir(tmp .. '/crates/fff-core', 'p')
|
||||
|
||||
vim.fn.system({ 'git', 'init', '-q', tmp })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'config', 'user.email', 'test@test.com' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'config', 'user.name', 'Test' })
|
||||
|
||||
local f = io.open(tmp .. '/crates/fff-core/Cargo.toml', 'w')
|
||||
f:write('[package]\nname = "test"\nversion = "3.0.0"\nedition = "2024"\n')
|
||||
f:close()
|
||||
|
||||
vim.fn.system({ 'git', '-C', tmp, 'add', '.' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'commit', '-q', '-m', 'release' })
|
||||
vim.fn.system({ 'git', '-C', tmp, 'tag', 'v3.0.0' })
|
||||
|
||||
local info = version.resolve(tmp)
|
||||
assert.is_not_nil(info)
|
||||
assert.are.equal('v3.0.0', info.release_tag)
|
||||
assert.are.equal('3.0.0', info.version)
|
||||
assert.are.equal('latest', info.npm_tag)
|
||||
assert.is_true(info.is_release)
|
||||
|
||||
vim.fn.delete(tmp, 'rf')
|
||||
end)
|
||||
|
||||
it('should fail for a non-git directory', function()
|
||||
local tmp = vim.fn.tempname()
|
||||
vim.fn.mkdir(tmp .. '/crates/fff-core', 'p')
|
||||
|
||||
local f = io.open(tmp .. '/crates/fff-core/Cargo.toml', 'w')
|
||||
f:write('[package]\nname = "test"\nversion = "1.0.0"\n')
|
||||
f:close()
|
||||
|
||||
local info, err = version.resolve(tmp)
|
||||
assert.is_nil(info)
|
||||
assert.is_not_nil(err)
|
||||
|
||||
vim.fn.delete(tmp, 'rf')
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
Reference in New Issue
Block a user