mirror of
https://github.com/hustcer/deepseek-review.git
synced 2026-05-13 05:16:05 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2393375400 | ||
|
|
22e7b71776 | ||
|
|
798baee3d8 | ||
|
|
b19e2097cc | ||
|
|
699ebd30f0 | ||
|
|
a12b9c6fdd | ||
|
|
44b44de9b1 | ||
|
|
c17a3836e8 | ||
|
|
5c6cbc3c92 |
@@ -11,6 +11,8 @@ CHAT_TOKEN='Your DeepSeek API token'
|
||||
GITHUB_TOKEN='Your GitHub API token'
|
||||
# MAX_LENGTH: The maximum length of the content for review, 0 means no limit.
|
||||
MAX_LENGTH='0'
|
||||
# The maximum temperature for the model to generate the response. 1.0 by default.
|
||||
TEMPERATURE='1.0'
|
||||
# The comma separated file patterns to include in the code review.
|
||||
INCLUDE_PATTERNS=''
|
||||
# The comma separated file patterns to exclude in the code review.
|
||||
|
||||
20
CHANGELOG.md
20
CHANGELOG.md
@@ -1,6 +1,26 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [1.8.0] - 2025-02-10
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Add check for empty DeepSeek review response with error handling (#90)
|
||||
- Add `awk` binary missing check (#92)
|
||||
|
||||
### Features
|
||||
|
||||
- Add version validation for `awk`/`gawk` and implement robust semantic version comparison for compatibility checks (#91)
|
||||
- Add support for configurable `temperature` parameter in DeepSeek model setup (#93)
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Update README add `awk` or `gawk` as required tools
|
||||
|
||||
### Refactor
|
||||
|
||||
- Streamline main wrapper and simplify argument handling for `nu/review.nu` integration (#88)
|
||||
|
||||
## [1.7.0] - 2025-02-08
|
||||
|
||||
### Features
|
||||
|
||||
13
README.md
13
README.md
@@ -2,6 +2,8 @@
|
||||
|
||||
[中文说明](README.zh-CN.md)
|
||||
|
||||
`deepseek-review` also offers seamless integration with DeepSeek models on SiliconCloud. [Sign Up Now](https://cloud.siliconflow.cn/i/rqCdIxzS) to **Claim Your Free 20 Million Tokens** and start exploring its capabilities!
|
||||
|
||||
## Features
|
||||
|
||||
- Automate PR Reviews with DeepSeek via GitHub Action
|
||||
@@ -100,11 +102,12 @@ With this setup, DeepSeek code review will not run automatically upon PR creatio
|
||||
| Name | Type | Description |
|
||||
| -------------- | ------ | ----------------------------------------------------------------------- |
|
||||
| chat-token | String | Required, DeepSeek API Token |
|
||||
| model | String | Optional, the model used for code review, defaults to `deepseek-chat` |
|
||||
| model | String | Optional, The model used for code review, defaults to `deepseek-chat` |
|
||||
| base-url | String | Optional, DeepSeek API Base URL, defaults to `https://api.deepseek.com` |
|
||||
| max-length | Int | Optional, Maximum length(Unicode width) of the content for review, if the content length exceeds this value, the review will be skipped. Default `0` means no limit. |
|
||||
| sys-prompt | String | Optional, system prompt corresponding to `$sys_prompt` in the payload, default value see note below |
|
||||
| user-prompt | String | Optional, user prompt corresponding to `$user_prompt` in the payload, default value see note below |
|
||||
| sys-prompt | String | Optional, System prompt corresponding to `$sys_prompt` in the payload, default value see note below |
|
||||
| user-prompt | String | Optional, User prompt corresponding to `$user_prompt` in the payload, default value see note below |
|
||||
| temperature | Number | Optional, The temperature for the model to generate the response, between `0` and `2`, default value `1.0` |
|
||||
| include-patterns | String | Optional, The comma separated file patterns to include in the code review. No default |
|
||||
| exclude-patterns | String | Optional, The comma separated file patterns to exclude in the code review. Default to `pnpm-lock.yaml,package-lock.json,*.lock` |
|
||||
| github-token | String | Optional, The `GITHUB_TOKEN` secret or personal access token to authenticate. Defaults to `github.token`. |
|
||||
@@ -116,6 +119,7 @@ With this setup, DeepSeek code review will not run automatically upon PR creatio
|
||||
// `$model` default value: deepseek-chat
|
||||
model: $model,
|
||||
stream: false,
|
||||
temperature: $temperature,
|
||||
messages: [
|
||||
// `$sys_prompt` default value: You are a professional code review assistant responsible for
|
||||
// analyzing code changes in GitHub Pull Requests. Identify potential issues such as code
|
||||
@@ -142,7 +146,8 @@ With this setup, DeepSeek code review will not run automatically upon PR creatio
|
||||
To perform code reviews locally(should works for `macOS`, `Ubuntu`, and `Windows`), you need to install the following tools:
|
||||
|
||||
- [`Nushell`](https://www.nushell.sh/book/installation.html). It is recommended to install the latest versions.
|
||||
- Once `Nushell` was installed, simply clone this repository to your local machine, navigate to the repository directory, and run `nu cr -h`. You should see an output similar to the following:
|
||||
- The latest version of [`awk`](https://github.com/onetrueawk/awk) or [`gawk`](https://www.gnu.org/software/gawk/) is required, with `gawk` being the preferred choice.
|
||||
- Clone this repository to your local machine, navigate to the repository directory, and run `nu cr -h`. You should see an output similar to the following:
|
||||
|
||||
```console
|
||||
Use DeepSeek AI to review code changes locally or in GitHub Actions
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# DeepSeek 代码审查
|
||||
|
||||
本工具也支持使用 SiliconCloud 上的 DeepSeek 模型,[注册](https://cloud.siliconflow.cn/i/rqCdIxzS) 就**免费赠送 2000 万 Token**,赶紧试试吧!
|
||||
|
||||
## 特性
|
||||
|
||||
- 通过 GitHub Action 使用 DeepSeek 进行自动化 PR 审查
|
||||
@@ -103,6 +105,7 @@ jobs:
|
||||
| max-length | Int | 可选,待审查内容的最大 Unicode 长度, 默认 `0` 表示没有限制,超过非零值则跳过审查 |
|
||||
| sys-prompt | String | 可选,系统提示词对应入参中的 `$sys_prompt`, 默认值见后文注释 |
|
||||
| user-prompt | String | 可选,用户提示词对应入参中的 `$user_prompt`, 默认值见后文注释 |
|
||||
| temperature | Number | 可选,采样温度,介于 `0` 和 `2` 之间, 默认值 `1.0` |
|
||||
| include-patterns | String | 可选,代码审查中要包含的以逗号分隔的文件模式,无默认值 |
|
||||
| exclude-patterns | String | 可选,代码审查中要排除的以逗号分隔的文件模式,默认值为 `pnpm-lock.yaml,package-lock.json,*.lock` |
|
||||
| github-token | String | 可选,用于访问 API 进行 PR 管理的 GitHub Token,默认为 `${{ github.token }}` |
|
||||
@@ -114,6 +117,7 @@ DeepSeek 接口调用入参:
|
||||
// `$model` default value: deepseek-chat
|
||||
model: $model,
|
||||
stream: false,
|
||||
temperature: $temperature,
|
||||
messages: [
|
||||
// `$sys_prompt` default value: You are a professional code review assistant responsible for
|
||||
// analyzing code changes in GitHub Pull Requests. Identify potential issues such as code
|
||||
@@ -139,6 +143,7 @@ DeepSeek 接口调用入参:
|
||||
在本地进行代码审查,支持 `macOS`, `Ubuntu` & `Windows` 不过需要安装以下工具:
|
||||
|
||||
- [`Nushell`](https://www.nushell.sh/book/installation.html), 建议安装最新版本
|
||||
- [`awk`](https://github.com/onetrueawk/awk) 或者 [`gawk`](https://www.gnu.org/software/gawk/) 的最新版版本,优先推荐 `gawk`
|
||||
- 接下来只需要把本仓库代码克隆到本地,然后进入仓库目录执行 `nu cr -h` 即可看到类似如下输出:
|
||||
|
||||
```console
|
||||
|
||||
@@ -26,6 +26,10 @@ inputs:
|
||||
required: false
|
||||
default: 'deepseek-chat'
|
||||
description: 'The DeepSeek model to choose for code review.'
|
||||
temperature:
|
||||
required: false
|
||||
default: 1.0
|
||||
description: 'The temperature of the model.'
|
||||
base-url:
|
||||
required: false
|
||||
default: 'https://api.deepseek.com'
|
||||
@@ -74,6 +78,7 @@ runs:
|
||||
let includePatterns = '${{ inputs.include-patterns }}'
|
||||
let excludePatterns = '${{ inputs.exclude-patterns }}'
|
||||
let maxLength = try { '${{ inputs.max-length }}' | into int } catch { 0 }
|
||||
let temperature = try { '${{ inputs.temperature }}' | into float } catch { 1.0 }
|
||||
(deepseek-review $token
|
||||
--model $model
|
||||
--repo $repo
|
||||
@@ -83,6 +88,7 @@ runs:
|
||||
--max-length $maxLength
|
||||
--sys-prompt $sysPrompt
|
||||
--user-prompt $userPrompt
|
||||
--temperature $temperature
|
||||
--include $includePatterns
|
||||
--exclude $excludePatterns
|
||||
)
|
||||
|
||||
37
cr
37
cr
@@ -3,45 +3,14 @@
|
||||
# Created: 2025/02/08 19:02:15
|
||||
# Description: A wrapper for nu/review.nu as the main entry point of the project.
|
||||
|
||||
use nu/review.nu [deepseek-review, 'from env', ECODE]
|
||||
use nu/review.nu ['from env', ECODE]
|
||||
|
||||
# Use DeepSeek AI to review code changes locally or in GitHub Actions
|
||||
def main [
|
||||
token?: string, # Your DeepSeek API token, fallback to CHAT_TOKEN env var
|
||||
--debug(-d), # Debug mode
|
||||
--repo(-r): string, # GitHub repository name, e.g. hustcer/deepseek-review
|
||||
--pr-number(-n): string, # GitHub PR number
|
||||
--gh-token(-k): string, # Your GitHub token, fallback to GITHUB_TOKEN env var
|
||||
--diff-to(-t): string, # Diff to git REF
|
||||
--diff-from(-f): string, # Diff from git REF
|
||||
--max-length(-l): int, # Maximum length of the content for review, 0 means no limit.
|
||||
--model(-m): string, # Model name, or read from CHAT_MODEL env var, `deepseek-chat` by default
|
||||
--base-url(-b): string, # DeepSeek API base URL, fallback to BASE_URL env var
|
||||
--sys-prompt(-s): string # Default to $DEFAULT_OPTIONS.SYS_PROMPT,
|
||||
--user-prompt(-u): string # Default to $DEFAULT_OPTIONS.USER_PROMPT,
|
||||
--include(-i): string, # Comma separated file patterns to include in the code review
|
||||
--exclude(-x): string, # Comma separated file patterns to exclude in the code review
|
||||
] {
|
||||
|
||||
def --wrapped main [...rest] {
|
||||
if not ('.env' | path exists) {
|
||||
print $'Please refer to (ansi g)`.env.example`(ansi reset) to create a (ansi r)`.env`(ansi reset) file in the root directory of the project.'
|
||||
exit $ECODE.MISSING_DEPENDENCY
|
||||
}
|
||||
open .env | load-env
|
||||
(
|
||||
deepseek-review $token
|
||||
--repo=$repo
|
||||
--debug=$debug
|
||||
--model=$model
|
||||
--include=$include
|
||||
--exclude=$exclude
|
||||
--diff-to=$diff_to
|
||||
--base-url=$base_url
|
||||
--gh-token=$gh_token
|
||||
--diff-from=$diff_from
|
||||
--pr-number=$pr_number
|
||||
--max-length=$max_length
|
||||
--sys-prompt=$sys_prompt
|
||||
--user-prompt=$user_prompt
|
||||
)
|
||||
nu $'($env.FILE_PWD)/nu/review.nu' ...$rest
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "deepseek-review",
|
||||
"version": "1.7.0",
|
||||
"actionVer": "v1.7",
|
||||
"version": "1.8.0",
|
||||
"actionVer": "v1.8",
|
||||
"author": "hustcer",
|
||||
"license": "MIT",
|
||||
"github": "https://github.com/hustcer/deepseek-review",
|
||||
|
||||
133
nu/review.nu
133
nu/review.nu
@@ -43,6 +43,7 @@ const HTTP_HEADERS = [User-Agent curl/8.9]
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
MODEL: 'deepseek-chat',
|
||||
TEMPERATURE: 1.0,
|
||||
BASE_URL: 'https://api.deepseek.com',
|
||||
USER_PROMPT: 'Please review the following code changes:',
|
||||
SYS_PROMPT: 'You are a professional code review assistant responsible for analyzing code changes in GitHub Pull Requests. Identify potential issues such as code style violations, logical errors, security vulnerabilities, and provide improvement suggestions. Clearly list the problems and recommendations in a concise manner.',
|
||||
@@ -67,7 +68,9 @@ export def --env deepseek-review [
|
||||
--user-prompt(-u): string # Default to $DEFAULT_OPTIONS.USER_PROMPT,
|
||||
--include(-i): string, # Comma separated file patterns to include in the code review
|
||||
--exclude(-x): string, # Comma separated file patterns to exclude in the code review
|
||||
--temperature: float, # Temperature for the model
|
||||
]: nothing -> nothing {
|
||||
|
||||
$env.config.table.mode = 'psql'
|
||||
let is_action = ($env.GITHUB_ACTIONS? == 'true')
|
||||
let token = $token | default $env.CHAT_TOKEN?
|
||||
@@ -75,8 +78,13 @@ export def --env deepseek-review [
|
||||
let CHAT_HEADER = [Authorization $'Bearer ($token)']
|
||||
let local_repo = $env.DEFAULT_LOCAL_REPO? | default (pwd)
|
||||
let model = $model | default $env.CHAT_MODEL? | default $DEFAULT_OPTIONS.MODEL
|
||||
let max_length = $max_length | default ($env.MAX_LENGTH? | default 0 | into int)
|
||||
let base_url = $base_url | default $env.BASE_URL? | default $DEFAULT_OPTIONS.BASE_URL
|
||||
let max_length = try { $max_length | default ($env.MAX_LENGTH? | default 0 | into int) } catch { 0 }
|
||||
let temperature = try { $temperature | default $env.TEMPERATURE? | default $DEFAULT_OPTIONS.TEMPERATURE | into float } catch { $DEFAULT_OPTIONS.TEMPERATURE }
|
||||
if ($temperature < 0) or ($temperature > 2) {
|
||||
print $'(ansi r)Invalid temperature value, should be in the range of 0 to 2.(ansi reset)'
|
||||
exit $ECODE.INVALID_PARAMETER
|
||||
}
|
||||
let url = $'($base_url)/chat/completions'
|
||||
let setting = {
|
||||
repo: $repo,
|
||||
@@ -89,8 +97,10 @@ export def --env deepseek-review [
|
||||
pr_number: $pr_number,
|
||||
max_length: $max_length,
|
||||
local_repo: $local_repo,
|
||||
temperature: $temperature,
|
||||
}
|
||||
$env.GH_TOKEN = $gh_token | default $env.GITHUB_TOKEN?
|
||||
|
||||
if ($token | is-empty) {
|
||||
print $'(ansi r)Please provide your DeepSeek API token by setting `CHAT_TOKEN` or passing it as an argument.(ansi reset)'
|
||||
exit $ECODE.INVALID_PARAMETER
|
||||
@@ -117,6 +127,7 @@ export def --env deepseek-review [
|
||||
let payload = {
|
||||
model: $model,
|
||||
stream: false,
|
||||
temperature: $temperature,
|
||||
messages: [
|
||||
{ role: 'system', content: $sys_prompt },
|
||||
{ role: 'user', content: $"($user_prompt):\n($content)" }
|
||||
@@ -135,6 +146,10 @@ export def --env deepseek-review [
|
||||
exit $ECODE.SERVER_ERROR
|
||||
}
|
||||
let review = $response | get -i choices.0.message.content
|
||||
if ($review | is-empty) {
|
||||
print $'❌ Code review failed!No review result returned from DeepSeek API.'
|
||||
exit $ECODE.SERVER_ERROR
|
||||
}
|
||||
if not $is_action {
|
||||
print $'Code Review Result:'; hr-line; print $review
|
||||
} else {
|
||||
@@ -183,59 +198,76 @@ export def get-diff [
|
||||
}
|
||||
cd $local_repo
|
||||
mut content = if ($pr_number | is-not-empty) {
|
||||
if ($repo | is-empty) {
|
||||
print $'(ansi r)Please provide the GitHub repository name by `--repo` option.(ansi reset)'
|
||||
exit $ECODE.INVALID_PARAMETER
|
||||
}
|
||||
# TODO: Ignore keywords checking when triggering by mentioning the bot
|
||||
let description = http get -H $BASE_HEADER $'($GITHUB_API_BASE)/repos/($repo)/pulls/($pr_number)'
|
||||
| select title body | values | str join "\n"
|
||||
if ($IGNORE_REVIEW_KEYWORDS | any {|it| $description =~ $it }) {
|
||||
print $'(ansi r)The PR title or body contains keywords to skip the review, bye...(ansi reset)'
|
||||
exit $ECODE.SUCCESS
|
||||
}
|
||||
http get -H $DIFF_HEADER $'($GITHUB_API_BASE)/repos/($repo)/pulls/($pr_number)' | str trim
|
||||
} else if ($diff_from | is-not-empty) {
|
||||
if not (has-ref $diff_from) {
|
||||
print $'(ansi r)The specified git ref ($diff_from) does not exist, please check it again.(ansi reset)'
|
||||
exit $ECODE.INVALID_PARAMETER
|
||||
}
|
||||
if ($diff_to | is-not-empty) and not (has-ref $diff_to) {
|
||||
print $'(ansi r)The specified git ref ($diff_to) does not exist, please check it again.(ansi reset)'
|
||||
exit $ECODE.INVALID_PARAMETER
|
||||
}
|
||||
git diff $diff_from ($diff_to | default HEAD)
|
||||
} else if not (git-check $local_repo --check-repo=1) {
|
||||
print $'Current directory ($local_repo) is (ansi r)NOT(ansi reset) a git repo, bye...(char nl)'
|
||||
exit $ECODE.CONDITION_NOT_SATISFIED
|
||||
} else { git diff }
|
||||
if ($repo | is-empty) {
|
||||
print $'(ansi r)Please provide the GitHub repository name by `--repo` option.(ansi reset)'
|
||||
exit $ECODE.INVALID_PARAMETER
|
||||
}
|
||||
# TODO: Ignore keywords checking when triggering by mentioning the bot
|
||||
let description = http get -H $BASE_HEADER $'($GITHUB_API_BASE)/repos/($repo)/pulls/($pr_number)'
|
||||
| select title body | values | str join "\n"
|
||||
if ($IGNORE_REVIEW_KEYWORDS | any {|it| $description =~ $it }) {
|
||||
print $'(ansi r)The PR title or body contains keywords to skip the review, bye...(ansi reset)'
|
||||
exit $ECODE.SUCCESS
|
||||
}
|
||||
http get -H $DIFF_HEADER $'($GITHUB_API_BASE)/repos/($repo)/pulls/($pr_number)' | str trim
|
||||
} else if ($diff_from | is-not-empty) {
|
||||
if not (has-ref $diff_from) {
|
||||
print $'(ansi r)The specified git ref ($diff_from) does not exist, please check it again.(ansi reset)'
|
||||
exit $ECODE.INVALID_PARAMETER
|
||||
}
|
||||
if ($diff_to | is-not-empty) and not (has-ref $diff_to) {
|
||||
print $'(ansi r)The specified git ref ($diff_to) does not exist, please check it again.(ansi reset)'
|
||||
exit $ECODE.INVALID_PARAMETER
|
||||
}
|
||||
git diff $diff_from ($diff_to | default HEAD)
|
||||
} else if not (git-check $local_repo --check-repo=1) {
|
||||
print $'Current directory ($local_repo) is (ansi r)NOT(ansi reset) a git repo, bye...(char nl)'
|
||||
exit $ECODE.CONDITION_NOT_SATISFIED
|
||||
} else { git diff }
|
||||
|
||||
if ($content | is-empty) {
|
||||
print $'(ansi g)Nothing to review.(ansi reset)'; exit $ECODE.SUCCESS
|
||||
}
|
||||
let awk_bin = (prepare-awk)
|
||||
let outdated_awk = $'You may using an (ansi r)outdated awk version(ansi reset), please upgrade to the latest version or use gawk latest instead.'
|
||||
if ($include | is-not-empty) {
|
||||
let patterns = $include | split row ','
|
||||
$content = $content | ^$awk_bin (generate-include-regex $patterns)
|
||||
$content = $content | try { ^$awk_bin (generate-include-regex $patterns) } catch { print $outdated_awk; exit $ECODE.OUTDATED }
|
||||
}
|
||||
if ($exclude | is-not-empty) {
|
||||
let patterns = $exclude | split row ','
|
||||
$content = $content | ^$awk_bin (generate-exclude-regex $patterns)
|
||||
$content = $content | try { ^$awk_bin (generate-exclude-regex $patterns) } catch { print $outdated_awk; exit $ECODE.OUTDATED }
|
||||
}
|
||||
$content
|
||||
}
|
||||
|
||||
# Prepare gawk for macOS
|
||||
export def prepare-awk [] {
|
||||
if (is-installed awk) {
|
||||
print $'Current awk version: (awk --version | lines | first)'
|
||||
const MIN_GAWK_VERSION = '5.3.1'
|
||||
const MIN_AWK_VERSION = '20250116'
|
||||
let awk_installed = is-installed awk
|
||||
let gawk_installed = is-installed gawk
|
||||
|
||||
if $awk_installed {
|
||||
let awk_version = awk --version | lines | first | split row ' ' | last
|
||||
print $'Current awk version: ($awk_version)'
|
||||
if (compare-ver $awk_version $MIN_AWK_VERSION) >= 0 { return 'awk' }
|
||||
}
|
||||
if ($env.GITHUB_ACTIONS? != 'true') { return 'awk' }
|
||||
if (sys host | get name) == 'Darwin' {
|
||||
if $gawk_installed {
|
||||
let gawk_version = gawk --version | lines | first | split row , | first | split row ' ' | last
|
||||
print $'Current gawk version: ($gawk_version)'
|
||||
if (compare-ver $gawk_version $MIN_GAWK_VERSION) >= 0 { return 'gawk' }
|
||||
}
|
||||
if (sys host | get name) == 'Darwin' and (is-installed brew) {
|
||||
brew install gawk
|
||||
print $'Current gawk version: (gawk --version | lines | first)'
|
||||
return 'gawk'
|
||||
}
|
||||
'gawk'
|
||||
if (not $awk_installed) and (not $gawk_installed) {
|
||||
print $'(ansi r)Neither `awk` nor `gawk` is installed, please install the latest version of `gawk`.(ansi reset)'
|
||||
exit $ECODE.MISSING_BINARY
|
||||
}
|
||||
'awk'
|
||||
}
|
||||
|
||||
# Compact the record by removing empty columns
|
||||
@@ -323,11 +355,11 @@ def generate-exclude-regex [patterns: list<string>] {
|
||||
# Converts a .env file into a record
|
||||
# may be used like this: open .env | load-env
|
||||
# works with quoted and unquoted .env files
|
||||
export def "from env" []: string -> record {
|
||||
export def 'from env' []: string -> record {
|
||||
lines
|
||||
| split column '#' # remove comments
|
||||
| get column1
|
||||
| parse "{key}={value}"
|
||||
| parse '{key}={value}'
|
||||
| update value {
|
||||
str trim # Trim whitespace between value and inline comments
|
||||
| str trim -c '"' # unquote double-quoted values
|
||||
@@ -335,8 +367,35 @@ export def "from env" []: string -> record {
|
||||
| str replace -a "\\n" "\n" # replace `\n` with newline char
|
||||
| str replace -a "\\r" "\r" # replace `\r` with carriage return
|
||||
| str replace -a "\\t" "\t" # replace `\t` with tab
|
||||
}
|
||||
}
|
||||
| transpose -r -d
|
||||
}
|
||||
|
||||
# Compare two version number, return `1` if first one is higher than second one,
|
||||
# Return `0` if they are equal, otherwise return `-1`
|
||||
# Format: Expects semantic version strings (major.minor.patch)
|
||||
# - Optional 'v' prefix
|
||||
# - Pre-release suffixes (-beta, -rc, etc.) are ignored
|
||||
# - Missing segments default to 0
|
||||
export def compare-ver [v1: string, v2: string] {
|
||||
# Parse the version number: remove pre-release and build information,
|
||||
# only take the main version part, and convert it to a list of numbers
|
||||
def parse-ver [v: string] {
|
||||
$v | str downcase | str trim -c v | str trim
|
||||
| split row - | first | split row . | each { into int }
|
||||
}
|
||||
let a = parse-ver $v1
|
||||
let b = parse-ver $v2
|
||||
# Compare the major, minor, and patch parts; fill in the missing parts with 0
|
||||
# If you want to compare more parts use the following code:
|
||||
# for i in 0..([2 ($a | length) ($b | length)] | math max)
|
||||
for i in 0..2 {
|
||||
let x = $a | get -i $i | default 0
|
||||
let y = $b | get -i $i | default 0
|
||||
if $x > $y { return 1 }
|
||||
if $x < $y { return (-1) }
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
alias main = deepseek-review
|
||||
|
||||
Reference in New Issue
Block a user