Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions bin/set_version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/bash

# 版本设置脚本
# 用法: ./bin/set_version.sh <version>
# 例如: ./bin/set_version.sh 25.0.5

set -e

if [ -z "$1" ]; then
echo "错误: 请提供版本号"
echo "用法: $0 <version>"
echo "例如: $0 25.0.5"
exit 1
fi

NEW_VERSION=$1
CURRENT_BRANCH=$(git branch --show-current)

echo "=========================================="
echo "设置新版本: $NEW_VERSION"
echo "当前分支: $CURRENT_BRANCH"
echo "=========================================="

# 1. 更新 package.json
echo "更新 package.json..."
if [ -f "package.json" ]; then
sed -i.bak "s/\"version\": \".*\"/\"version\": \"$NEW_VERSION\"/" package.json
rm -f package.json.bak
echo "✓ package.json 已更新"
else
echo "⚠ package.json 不存在"
fi

# 2. 更新 src-tauri/Cargo.toml
echo "更新 src-tauri/Cargo.toml..."
if [ -f "src-tauri/Cargo.toml" ]; then
sed -i.bak "s/^version = \".*\"/version = \"$NEW_VERSION\"/" src-tauri/Cargo.toml
rm -f src-tauri/Cargo.toml.bak
echo "✓ src-tauri/Cargo.toml 已更新"
else
echo "⚠ src-tauri/Cargo.toml 不存在"
fi

# 3. 更新 src-tauri/tauri.conf.json
echo "更新 src-tauri/tauri.conf.json..."
if [ -f "src-tauri/tauri.conf.json" ]; then
sed -i.bak "s/\"version\": \".*\"/\"version\": \"$NEW_VERSION\"/" src-tauri/tauri.conf.json
rm -f src-tauri/tauri.conf.json.bak
echo "✓ src-tauri/tauri.conf.json 已更新"
else
echo "⚠ src-tauri/tauri.conf.json 不存在"
fi

# 4. 创建新的开发分支
NEW_BRANCH="dev-$NEW_VERSION"
echo ""
echo "创建新的开发分支: $NEW_BRANCH"
read -p "是否创建新分支并切换? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
git checkout -b "$NEW_BRANCH"
echo "✓ 已创建并切换到分支: $NEW_BRANCH"
else
echo "跳过创建新分支"
fi

echo ""
echo "=========================================="
echo "版本更新完成!"
echo "新版本: $NEW_VERSION"
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "新分支: $NEW_BRANCH"
fi
echo "=========================================="
echo ""
echo "接下来的步骤:"
echo "1. 检查更改: git diff"
echo "2. 提交更改: git add . && git commit -m 'chore: bump version to $NEW_VERSION'"
echo "3. 推送到远程: git push -u origin $NEW_BRANCH"
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "codeforge",
"private": true,
"version": "25.0.4",
"version": "25.0.5",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "CodeForge"
version = "25.0.4"
version = "25.0.5"
description = "CodeForge 是一款轻量级、高性能的桌面代码执行器,专为开发者、学生和编程爱好者设计。"
authors = ["devlive-community"]
edition = "2024"
Expand Down
28 changes: 28 additions & 0 deletions src-tauri/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ pub struct EditorConfig {
pub space_dot_omission: Option<bool>, // 是否显示空格省略
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnvironmentMirrorConfig {
pub enabled: Option<bool>,
pub base_url: Option<String>,
pub fallback_enabled: Option<bool>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppConfig {
pub log_directory: Option<String>,
Expand All @@ -30,6 +37,7 @@ pub struct AppConfig {
pub theme: Option<String>,
pub plugins: Option<Vec<PluginConfig>>,
pub editor: Option<EditorConfig>,
pub environment_mirror: Option<EnvironmentMirrorConfig>,
}

impl Default for AppConfig {
Expand All @@ -50,6 +58,11 @@ impl Default for AppConfig {
show_function_help: Some(false),
space_dot_omission: Some(false),
}),
environment_mirror: Some(EnvironmentMirrorConfig {
enabled: Some(true),
base_url: Some("http://cdn.global.devlive.top".to_string()),
fallback_enabled: Some(false),
}),
}
}
}
Expand Down Expand Up @@ -113,6 +126,16 @@ impl ConfigManager {
println!("读取配置 -> 添加默认 editor 配置");
}

// 检查并设置 environment_mirror 默认配置
if config.environment_mirror.is_none() {
config.environment_mirror = Some(EnvironmentMirrorConfig {
enabled: Some(true),
base_url: Some("http://cdn.global.devlive.top".to_string()),
fallback_enabled: Some(false),
});
println!("读取配置 -> 添加默认 environment_mirror 配置");
}

Ok(config)
}
Err(e) => {
Expand Down Expand Up @@ -218,6 +241,11 @@ impl ConfigManager {
show_function_help: Some(false),
space_dot_omission: Some(false),
}),
environment_mirror: Some(EnvironmentMirrorConfig {
enabled: Some(true),
base_url: Some("http://cdn.global.devlive.top".to_string()),
fallback_enabled: Some(false),
}),
}
}

Expand Down
27 changes: 22 additions & 5 deletions src-tauri/src/env_commands.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::env_manager::{EnvironmentInfo, EnvironmentManager};
use log::info;
use tauri::{AppHandle, State};
use tauri::{AppHandle, Emitter, State};
use tokio::sync::Mutex;

pub type EnvironmentManagerState = Mutex<EnvironmentManager>;
Expand All @@ -24,20 +24,37 @@ pub async fn download_and_install_version(
) -> Result<String, String> {
info!("下载并安装 {} 版本 {}", language, version);
let manager = env_manager.lock().await;
manager
.download_and_install_version(&language, &version, app_handle)
.await
let result = manager
.download_and_install_version(&language, &version, app_handle.clone())
.await;

if result.is_ok() {
// 发送配置更新事件通知前端刷新配置
app_handle.emit("config-updated", ()).ok();
info!("已发送配置更新事件");
}

result
}

#[tauri::command]
pub async fn switch_environment_version(
language: String,
version: String,
app_handle: AppHandle,
env_manager: State<'_, EnvironmentManagerState>,
) -> Result<(), String> {
info!("切换 {} 到版本 {}", language, version);
let manager = env_manager.lock().await;
manager.switch_version(&language, &version).await
let result = manager.switch_version(&language, &version).await;

if result.is_ok() {
// 发送配置更新事件通知前端刷新配置
app_handle.emit("config-updated", ()).ok();
info!("已发送配置更新事件");
}

result
}

#[tauri::command]
Expand Down
106 changes: 103 additions & 3 deletions src-tauri/src/env_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use tauri::{AppHandle, Emitter};
pub struct EnvironmentVersion {
pub version: String,
pub download_url: String,
pub fallback_url: Option<String>, // 备用下载地址(如 GitHub URL)
pub install_path: Option<String>,
pub is_installed: bool,
pub size: Option<u64>,
Expand Down Expand Up @@ -98,7 +99,7 @@ impl EnvironmentManager {
let provider = self
.providers
.get(language)
.ok_or_else(|| format!("暂未支持 {} 语言,请前往 github 提供 issus", language))?;
.ok_or_else(|| format!("暂未支持 {} 语言,请前往 github 提供 issues", language))?;

info!("获取 {} 环境信息", language);

Expand Down Expand Up @@ -126,7 +127,7 @@ impl EnvironmentManager {
let provider = self
.providers
.get(language)
.ok_or_else(|| format!("暂未支持 {} 语言,请前往 github 提供 issus", language))?;
.ok_or_else(|| format!("暂未支持 {} 语言,请前往 github 提供 issues", language))?;

info!("开始下载并安装 {} 版本 {}", language, version);
provider.download_and_install(version, app_handle).await
Expand All @@ -136,7 +137,7 @@ impl EnvironmentManager {
let provider = self
.providers
.get(language)
.ok_or_else(|| format!("暂未支持 {} 语言,请前往 github 提供 issus", language))?;
.ok_or_else(|| format!("暂未支持 {} 语言,请前往 github 提供 issues", language))?;

info!("切换 {} 到版本 {}", language, version);
provider.switch_version(version).await
Expand Down Expand Up @@ -175,3 +176,102 @@ pub fn emit_download_progress(
error!("发送下载进度事件失败: {}", e);
}
}

// 将 GitHub 下载 URL 转换为 CDN 镜像 URL
pub fn convert_to_cdn_url(
original_url: &str,
language: &str,
version: &str,
) -> Result<String, String> {
use crate::config::get_app_config_internal;

let config = get_app_config_internal().map_err(|e| format!("获取配置失败: {}", e))?;

let mirror_config = config.environment_mirror.as_ref();
let enabled = mirror_config.and_then(|m| m.enabled).unwrap_or(false);

if !enabled {
return Ok(original_url.to_string());
}

let base_url = mirror_config
.and_then(|m| m.base_url.as_ref())
.ok_or_else(|| "CDN 基础 URL 未配置".to_string())?;

// 从原始 URL 中提取文件名
let file_name = original_url
.split('/')
.last()
.ok_or_else(|| "无效的下载 URL".to_string())?;

// 构建 CDN URL: {base_url}/{language}/{version}/{filename}
let cdn_url = format!(
"{}/{}/{}/{}",
base_url.trim_end_matches('/'),
language,
version,
file_name
);

info!("转换下载 URL: {} -> {}", original_url, cdn_url);
Ok(cdn_url)
}

// 尝试从 CDN 下载,失败则回退到原始 URL
pub async fn download_with_fallback(
client: &reqwest::Client,
original_url: &str,
language: &str,
version: &str,
) -> Result<reqwest::Response, String> {
use crate::config::get_app_config_internal;

// 检查是否启用自动回退
let fallback_enabled = get_app_config_internal()
.ok()
.and_then(|config| config.environment_mirror)
.and_then(|mirror| mirror.fallback_enabled)
.unwrap_or(false);

// 首先尝试从 CDN 下载
match convert_to_cdn_url(original_url, language, version) {
Ok(cdn_url) if cdn_url != original_url => {
info!("尝试从 CDN 下载: {}", cdn_url);
match client.get(&cdn_url).send().await {
Ok(response) if response.status().is_success() => {
info!("CDN 下载成功");
return Ok(response);
}
Ok(response) => {
let status = response.status();
if fallback_enabled {
info!("CDN 下载失败 (HTTP {}), 回退到原始 URL", status);
} else {
return Err(format!("CDN 下载失败 (HTTP {}), 未启用自动回退", status));
}
}
Err(e) => {
if fallback_enabled {
info!("CDN 下载失败 ({}), 回退到原始 URL", e);
} else {
return Err(format!("CDN 下载失败 ({}), 未启用自动回退", e));
}
}
}
}
Ok(_) => {
info!("CDN 镜像未启用,使用原始 URL");
}
Err(e) => {
info!("CDN URL 转换失败 ({}), 使用原始 URL", e);
}
}

// 回退到原始 URL
info!("从原始 URL 下载: {}", original_url);
client
.get(original_url)
.send()
.await
.map_err(|e| format!("下载失败: {}", e))
}
Loading
Loading