Skip to content

Commit

Permalink
feat: 支持自动安装 msys2
Browse files Browse the repository at this point in the history
  • Loading branch information
mslxl committed Dec 4, 2023
1 parent 3cc76f5 commit 1bcb375
Show file tree
Hide file tree
Showing 31 changed files with 474 additions and 73 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tooltip": "^1.0.7",
"@replit/codemirror-emacs": "^6.0.1",
"@replit/codemirror-vim": "^6.1.0",
"@tauri-apps/api": "^1.5.1",
Expand Down
60 changes: 60 additions & 0 deletions pnpm-lock.yaml

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

30 changes: 30 additions & 0 deletions src-tauri/scripts/msys2.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
$target = $args[0]
$downloadUrl = "https://mirrors.tuna.tsinghua.edu.cn/msys2/distrib/msys2-x86_64-latest.sfx.exe"
$mirror = 'sed -i "s#https\?://mirror.msys2.org/#https://mirrors.tuna.tsinghua.edu.cn/msys2/#g" /etc/pacman.d/mirrorlist*'

$installer = "$($env:TEMP)\msys2.exe"


if (!(Test-Path $installer -PathType Leaf)) {
Write-Host "Download file to $($installer)"
Invoke-WebRequest -Uri $downloadUrl -OutFile $installer
}

& $installer "-y", "-o$($target)"

$msys2 = "$($target)/msys64/usr/bin/bash.exe"

& $msys2 "-l", "-c", $mirror
& $msys2 "-l", "-c", "pacman --noconfirm -S mingw-w64-ucrt-x86_64-clang-tools-extra mingw-w64-ucrt-x86_64-gcc"

Write-Host "Tools were installed to $($target)/msys64/ucrt64/bin"

$report = @{
'gcc' = "$($target)\msys64\ucrt64\bin\g++.exe"
'clangd' = "$($target)\msys64\ucrt64\bin\clangd.exe"
}

# $report | ConvertTo-Json | Out-File "$($target)/msys2.json" -Encoding UTF8NoBOM
$reportJson = $report | ConvertTo-Json
[IO.File]::WriteAllLines("$($target)\msys2.json", $reportJson)
Remove-Item $installer
5 changes: 5 additions & 0 deletions src-tauri/src/ipc/cmd/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ pub async fn get_hostname() -> Result<String, String> {
.to_owned();
Ok(name)
}

#[tauri::command]
pub async fn get_system_name() -> Result<String, String> {
Ok(std::env::consts::OS.to_owned())
}
5 changes: 3 additions & 2 deletions src-tauri/src/ipc/rt/checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,10 @@ pub async fn check_answer<R: Runtime>(
let checker_path = match checker {
CheckerType::Internal { name } => if cfg!(windows) {
app.path_resolver()
.resolve_resource(format!("{}.exe", name))
.resolve_resource(format!("sidecar/{}.exe", name))
} else {
app.path_resolver().resolve_resource(name)
app.path_resolver()
.resolve_resource(format!("sidecar/{}", name))
}
.ok_or(String::from("no such the checker"))?,
_ => unimplemented!(),
Expand Down
6 changes: 3 additions & 3 deletions src-tauri/src/ipc/rt/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ pub async fn run_detach<R: Runtime>(
args: Vec<String>,
) -> Result<(), String> {
let pauser = if cfg!(windows) {
app.path_resolver().resolve_resource("consolepauser.exe")
app.path_resolver().resolve_resource("sidecar/consolepauser.exe")
} else {
app.path_resolver().resolve_resource("consolepauser")
app.path_resolver().resolve_resource("sidecar/consolepauser")
}
.unwrap();
let mut cmd = std::process::Command::new(pauser);
Expand Down Expand Up @@ -205,7 +205,7 @@ pub async fn run_redirect<R: Runtime>(
Ok(result)
}

struct ChildKiller(Child);
pub struct ChildKiller(Child);
impl AsMut<Child> for ChildKiller {
fn as_mut(&mut self) -> &mut Child {
&mut self.0
Expand Down
99 changes: 99 additions & 0 deletions src-tauri/src/ipc/setup/installer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use std::{
io::Stderr,
process::{Command, Stdio},
};

use tauri::Runtime;
use tokio::{
io::{AsyncBufReadExt, BufReader},
sync::Mutex,
};

use crate::{util::console, RESOURCE_DIR};

#[derive(Default)]
pub struct PwshScriptState {
s: Mutex<()>,
}

#[tauri::command]
pub async fn execuate_pwsh_script<R: Runtime>(
app: tauri::AppHandle<R>,
window: tauri::Window<R>,
state: tauri::State<'_, PwshScriptState>,
name: String,
) -> Result<String, String> {
if !cfg!(windows) {
return Err(String::from("Installer only work on windows"));
}
let _guard = state.s.lock().await;

let script_file = app
.path_resolver()
.resolve_resource(format!("sidecar/{}.ps1", &name))
.unwrap();
let script_file = dunce::canonicalize(script_file).unwrap();
log::info!("execuate script {:?}", &script_file.to_str());
let mut cmd = Command::new(which::which("powershell").unwrap());

let target = RESOURCE_DIR.get().unwrap();
cmd.arg(&script_file.to_str().unwrap());
cmd.arg(target.to_str().unwrap());
console::hide_new_console(&mut cmd);

let mut cmd = tokio::process::Command::from(cmd);
cmd.stdout(Stdio::piped());
cmd.stderr(Stdio::piped());
cmd.stdin(Stdio::piped());
let mut proc = cmd.spawn().unwrap();
let mut stdout = BufReader::new(
proc.stdout
.take()
.ok_or(String::from("Fail to open stdout"))?,
)
.lines();
let mut stderr = BufReader::new(
proc.stderr
.take()
.ok_or(String::from("Fail to open stderr"))?,
)
.lines();

let mut stdout_eof = false;
let mut stderr_eof = false;
let result = loop {
tokio::select! {
Ok(data) = stdout.next_line(), if !stdout_eof => {
if let Some(line) = data {
window.emit("install_message", line).map_err(|e| e.to_string())?;
}else{
stdout_eof = true
}
}
Ok(data) = stderr.next_line(), if !stderr_eof => {
if let Some(line) = data{
window.emit("install_message", line).map_err(|e| e.to_string())?;
}else{
stderr_eof = true;
}
}
else => {
break proc.wait().await.map_err(|e|e.to_string())?;
}
}
};

if result.success() {
let report = target.join(format!("{}.json", name));
let content = tokio::fs::read_to_string(report)
.await
.map_err(|e| e.to_string())?;
Ok(content)
} else {
if let Some(code) = result.code() {
Err(format!("Process exit with code {}", code))
} else {
Err(String::from("Process exit with terminal signal"))
}
}
}
4 changes: 3 additions & 1 deletion src-tauri/src/ipc/setup/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::{time::Duration, process::Stdio};
pub mod installer;

use std::{process::Stdio, time::Duration};

use serde::{Deserialize, Serialize};
use tokio::process::Command;
Expand Down
39 changes: 18 additions & 21 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,22 @@ use std::{env, path::PathBuf};
use ipc::{
cmd::{bind::LSPState, competitive_companion::CompetitiveCompanionState},
rt::{checker::CheckerState, compiler::CompilerState, runner::RunnerState},
setup::installer::PwshScriptState,
};
use log::LevelFilter;
use once_cell::sync::{Lazy, OnceCell};
use once_cell::sync::OnceCell;
use tauri::{plugin::TauriPlugin, Manager, Runtime};
use tauri_plugin_log::{fern::colors::ColoredLevelConfig, LogTarget};

pub mod ipc;
pub mod util;

static CURRENT_DIR: Lazy<OnceCell<PathBuf>> = Lazy::new(|| {
let cell = OnceCell::new();
cell.set(env::current_exe().unwrap().parent().unwrap().to_path_buf())
.unwrap();
cell
});
pub static CONFIG_DIR: OnceCell<PathBuf> = OnceCell::new();
pub static RESOURCE_DIR: OnceCell<PathBuf> = OnceCell::new();

fn log_pugin<R: Runtime>() -> TauriPlugin<R> {
let log_dir = CURRENT_DIR.get().unwrap().join("logs");
let builder = tauri_plugin_log::Builder::default()
.targets([
LogTarget::Stdout,
LogTarget::Webview,
LogTarget::Folder(log_dir),
])
.targets([LogTarget::Stdout, LogTarget::Webview, LogTarget::LogDir])
.with_colors(ColoredLevelConfig::default())
.max_file_size(10240);
let builder = if cfg!(debug_assertions) {
Expand All @@ -47,26 +39,29 @@ async fn is_debug() -> Result<bool, String> {

#[tauri::command]
async fn get_settings_path() -> Result<String, String> {
Ok(CURRENT_DIR
.get()
.unwrap()
.join("settings.dat")
.to_str()
.unwrap()
.to_owned())
Ok(String::from("settings.dat"))
}

fn main() {
tauri::Builder::default()
.plugin(log_pugin())
.plugin(tauri_plugin_store::Builder::default().build())
.setup(|app| {
// provlegisto statue
// provlegisto state
CONFIG_DIR
.set(dunce::canonicalize(app.path_resolver().app_config_dir().unwrap()).unwrap())
.unwrap();
RESOURCE_DIR
.set(
dunce::canonicalize(app.path_resolver().app_local_data_dir().unwrap()).unwrap(),
)
.unwrap();
app.manage(LSPState::default());
app.manage(CompetitiveCompanionState::default());
app.manage(CompilerState::default());
app.manage(RunnerState::default());
app.manage(CheckerState::default());
app.manage(PwshScriptState::default());
Ok(())
})
.invoke_handler(tauri::generate_handler![
Expand All @@ -77,8 +72,10 @@ fn main() {
ipc::cmd::competitive_companion::enable_competitive_companion,
ipc::cmd::competitive_companion::disable_competitive_companion,
ipc::cmd::host::get_hostname,
ipc::cmd::host::get_system_name,
ipc::setup::capture_output,
ipc::setup::which,
ipc::setup::installer::execuate_pwsh_script,
ipc::rt::compiler::compile_source,
ipc::rt::runner::run_detach,
ipc::rt::runner::run_redirect,
Expand Down
3 changes: 2 additions & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"identifier": "com.mslxl.provlegisto",
"icon": ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"],
"resources": {
"src-util/build/*": "."
"src-util/build/*": "./sidecar/",
"scripts/*": "./sidecar/"
}
},
"security": {
Expand Down
2 changes: 1 addition & 1 deletion src/components/codemirror/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useImmerAtom } from "jotai-immer"
import { map } from "lodash"
import "@fontsource/jetbrains-mono"
import { filterCSSQuote } from "@/lib/utils"
import { editorFontFamily, editorFontSizeAtom } from "@/store/setting"
import { editorFontFamily, editorFontSizeAtom } from "@/store/setting/ui"

type CodemirrorProps = {
className?: string
Expand Down
Loading

0 comments on commit 1bcb375

Please sign in to comment.