Automate sidecar bundling and simplify sidecar path resolution
This commit is contained in:
parent
4e2eaf9059
commit
f8760155e4
@ -6,6 +6,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev",
|
"dev": "vite dev",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
|
"tauri:prebuild": "pwsh -NoProfile -ExecutionPolicy Bypass -File ../scripts/tauri-prebuild.ps1",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||||
|
|||||||
@ -110,8 +110,8 @@ struct ManagedSidecar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ManagedSidecar {
|
impl ManagedSidecar {
|
||||||
fn start(root: &Path) -> Result<Self, String> {
|
fn start(root: &Path, resource_dir: Option<&Path>) -> Result<Self, String> {
|
||||||
let sidecar_path = resolve_sidecar_path(root)?;
|
let sidecar_path = resolve_sidecar_path(root, resource_dir)?;
|
||||||
let mut cmd = Command::new(sidecar_path);
|
let mut cmd = Command::new(sidecar_path);
|
||||||
cmd.stdin(Stdio::piped())
|
cmd.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
@ -186,6 +186,7 @@ struct SidecarState {
|
|||||||
process: Mutex<Option<ManagedSidecar>>,
|
process: Mutex<Option<ManagedSidecar>>,
|
||||||
root_override: Mutex<Option<PathBuf>>,
|
root_override: Mutex<Option<PathBuf>>,
|
||||||
config_path: PathBuf,
|
config_path: PathBuf,
|
||||||
|
resource_dir: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_settings(path: &Path) -> AppSettings {
|
fn load_settings(path: &Path) -> AppSettings {
|
||||||
@ -221,44 +222,37 @@ fn effective_root(root_override: &Option<PathBuf>) -> Result<PathBuf, String> {
|
|||||||
auto_detect_root()
|
auto_detect_root()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_sidecar_path(root: &Path) -> Result<PathBuf, String> {
|
fn resolve_sidecar_path(root: &Path, resource_dir: Option<&Path>) -> Result<PathBuf, String> {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
let exe_name = "Journal.Sidecar.exe";
|
let exe_name = "Journal.Sidecar.exe";
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
let exe_name = "Journal.Sidecar";
|
let exe_name = "Journal.Sidecar";
|
||||||
|
|
||||||
// 1. If root is explicitly pointing to the executable file itself:
|
|
||||||
if root.is_file() && root.file_name().and_then(|n| n.to_str()) == Some(exe_name) {
|
if root.is_file() && root.file_name().and_then(|n| n.to_str()) == Some(exe_name) {
|
||||||
return Ok(root.to_path_buf());
|
return Ok(root.to_path_buf());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Direct paths relative to the folder:
|
let root_exe_path = root.join(exe_name);
|
||||||
let direct_paths = [
|
if root_exe_path.exists() {
|
||||||
root.join(exe_name),
|
return Ok(root_exe_path);
|
||||||
root.join("output").join(exe_name),
|
|
||||||
root.join("publish").join(exe_name),
|
|
||||||
root.join("Journal.Sidecar/bin/Debug/net10.0").join(exe_name),
|
|
||||||
root.join("Journal.Sidecar/bin/Release/net10.0/win-x64/publish").join(exe_name),
|
|
||||||
];
|
|
||||||
|
|
||||||
for path in direct_paths {
|
|
||||||
if path.exists() {
|
|
||||||
return Ok(path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Fallback: recursively search the known sidecar folder
|
|
||||||
let sidecar_src_root = root.join("Journal.Sidecar");
|
let sidecar_src_root = root.join("Journal.Sidecar");
|
||||||
if let Some(path) = find_sidecar_executable(&sidecar_src_root, exe_name) {
|
if let Some(path) = find_sidecar_executable(&sidecar_src_root, exe_name) {
|
||||||
return Ok(path);
|
return Ok(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Fallback: recursively search the provided root itself
|
if let Some(resource_dir) = resource_dir {
|
||||||
if let Some(path) = find_sidecar_executable(root, exe_name) {
|
let resource_sidecar_path = resource_dir.join("bin").join(exe_name);
|
||||||
return Ok(path);
|
if resource_sidecar_path.exists() {
|
||||||
|
return Ok(resource_sidecar_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(format!("{exe_name} not found in {}. Build Journal.Sidecar first.", root.display()))
|
Err(format!(
|
||||||
|
"{exe_name} not found in root, Journal.Sidecar tree, or resource dir for {}.",
|
||||||
|
root.display()
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_sidecar_executable(search_root: &Path, exe_name: &str) -> Option<PathBuf> {
|
fn find_sidecar_executable(search_root: &Path, exe_name: &str) -> Option<PathBuf> {
|
||||||
@ -317,7 +311,7 @@ async fn send_with_managed_sidecar(
|
|||||||
None => true,
|
None => true,
|
||||||
};
|
};
|
||||||
if should_start {
|
if should_start {
|
||||||
*guard = Some(ManagedSidecar::start(&root)?);
|
*guard = Some(ManagedSidecar::start(&root, state.resource_dir.as_deref())?);
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(process) = guard.as_mut() else {
|
let Some(process) = guard.as_mut() else {
|
||||||
@ -369,7 +363,7 @@ async fn set_sidecar_root(
|
|||||||
new_root.display()
|
new_root.display()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
resolve_sidecar_path(&new_root)?;
|
resolve_sidecar_path(&new_root, state.resource_dir.as_deref())?;
|
||||||
(Some(new_root.clone()), new_root)
|
(Some(new_root.clone()), new_root)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -476,6 +470,7 @@ pub fn run() {
|
|||||||
process: Mutex::new(None),
|
process: Mutex::new(None),
|
||||||
root_override: Mutex::new(root_override),
|
root_override: Mutex::new(root_override),
|
||||||
config_path,
|
config_path,
|
||||||
|
resource_dir: app.path().resource_dir().ok(),
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "npm run dev",
|
"beforeDevCommand": "npm run dev",
|
||||||
"devUrl": "http://localhost:1420",
|
"devUrl": "http://localhost:1420",
|
||||||
"beforeBuildCommand": "npm run build",
|
"beforeBuildCommand": "npm run tauri:prebuild && npm run build",
|
||||||
"frontendDist": "../build"
|
"frontendDist": "../build"
|
||||||
},
|
},
|
||||||
"app": {
|
"app": {
|
||||||
@ -24,6 +24,9 @@
|
|||||||
"bundle": {
|
"bundle": {
|
||||||
"active": true,
|
"active": true,
|
||||||
"targets": "all",
|
"targets": "all",
|
||||||
|
"resources": [
|
||||||
|
"bin/Journal.Sidecar.exe"
|
||||||
|
],
|
||||||
"icon": [
|
"icon": [
|
||||||
"icons/32x32.png",
|
"icons/32x32.png",
|
||||||
"icons/128x128.png",
|
"icons/128x128.png",
|
||||||
|
|||||||
52
scripts/tauri-prebuild.ps1
Normal file
52
scripts/tauri-prebuild.ps1
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
param(
|
||||||
|
[ValidateSet("Release", "Debug")]
|
||||||
|
[string]$Configuration = "Release",
|
||||||
|
[string]$Runtime = "win-x64"
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..")
|
||||||
|
$sidecarProject = Join-Path $repoRoot "Journal.Sidecar\Journal.Sidecar.csproj"
|
||||||
|
$publishOutputDir = Join-Path $repoRoot "output"
|
||||||
|
$publishedSidecarExe = Join-Path $publishOutputDir "Journal.Sidecar.exe"
|
||||||
|
$tauriBinDir = Join-Path $repoRoot "Journal.App\src-tauri\bin"
|
||||||
|
$tauriBundledSidecarExe = Join-Path $tauriBinDir "Journal.Sidecar.exe"
|
||||||
|
|
||||||
|
if (-not (Get-Command dotnet -ErrorAction SilentlyContinue)) {
|
||||||
|
throw "dotnet was not found in PATH. Install .NET SDK and retry."
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-Path $sidecarProject)) {
|
||||||
|
throw "Sidecar project not found: $sidecarProject"
|
||||||
|
}
|
||||||
|
|
||||||
|
New-Item -ItemType Directory -Force -Path $publishOutputDir | Out-Null
|
||||||
|
|
||||||
|
$publishArgs = @(
|
||||||
|
"publish", $sidecarProject,
|
||||||
|
"-c", $Configuration,
|
||||||
|
"-r", $Runtime,
|
||||||
|
"--self-contained",
|
||||||
|
"-p:PublishSingleFile=true",
|
||||||
|
"-p:IncludeNativeLibrariesForSelfExtract=true",
|
||||||
|
"-p:RestoreIgnoreFailedSources=true",
|
||||||
|
"-p:NuGetAudit=false",
|
||||||
|
"-o", $publishOutputDir
|
||||||
|
)
|
||||||
|
|
||||||
|
Write-Host "Publishing Journal.Sidecar for Tauri bundle..." -ForegroundColor Cyan
|
||||||
|
Write-Host "> dotnet $($publishArgs -join ' ')" -ForegroundColor DarkGray
|
||||||
|
& dotnet @publishArgs
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw "dotnet publish failed with exit code $LASTEXITCODE."
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-Path $publishedSidecarExe)) {
|
||||||
|
throw "Sidecar publish output not found: $publishedSidecarExe"
|
||||||
|
}
|
||||||
|
|
||||||
|
New-Item -ItemType Directory -Force -Path $tauriBinDir | Out-Null
|
||||||
|
Copy-Item -Force $publishedSidecarExe $tauriBundledSidecarExe
|
||||||
|
Write-Host "Staged sidecar for Tauri: $tauriBundledSidecarExe" -ForegroundColor Green
|
||||||
Loading…
x
Reference in New Issue
Block a user