v0.1.4-pre.004
This commit is contained in:
30
crates/ksp-app-config-desk/Cargo.toml
Normal file
30
crates/ksp-app-config-desk/Cargo.toml
Normal file
@@ -0,0 +1,30 @@
|
||||
# file: crates/ksp-app-config-desk/Cargo.toml
|
||||
# version: 1
|
||||
|
||||
[package]
|
||||
name = "ksp-app-config-desk"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish.workspace = true
|
||||
|
||||
[lib]
|
||||
name = "ksp_app_config_desk_lib"
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[[bin]]
|
||||
name = "ksp-app-config-desk"
|
||||
path = "src/main.rs"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build.workspace = true
|
||||
|
||||
[dependencies]
|
||||
fs2.workspace = true
|
||||
ksp-core-lib = { path = "../ksp-core-lib" }
|
||||
tauri.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
55
crates/ksp-app-config-desk/README.md
Normal file
55
crates/ksp-app-config-desk/README.md
Normal file
@@ -0,0 +1,55 @@
|
||||
<!-- file: crates/ksp-app-config-desk/README.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# `ksp-app-config-desk`
|
||||
|
||||
`ksp-app-config-desk` est l'application desktop spécialisée de management et de validation de la configuration KSP.
|
||||
|
||||
La crate est un package Tauri mixte :
|
||||
|
||||
```text
|
||||
package : ksp-app-config-desk
|
||||
lib : ksp_app_config_desk_lib
|
||||
bin : ksp-app-config-desk
|
||||
```
|
||||
|
||||
## Responsabilités
|
||||
|
||||
L'application restera une couche d'interface/composition. Les responsabilités de parsing, validation, profils, environnement, `.env`, secrets et persistence restent dans `ksp-config-lib`; le runtime Logging restera possédé par `ksp-logging-lib`.
|
||||
|
||||
La première tranche de squelette établit uniquement :
|
||||
|
||||
- le membre workspace Rust ;
|
||||
- le couple `lib` + `bin` ;
|
||||
- le verrou single-instance ;
|
||||
- l'assemblage Tauri minimal dans `src/tauri.rs` ;
|
||||
- les fenêtres `splash` et `main` ;
|
||||
- les capabilities initiales ;
|
||||
- l'icône de référence reprise du gabarit desktop éprouvé ;
|
||||
- le port de développement réservé `1430`, avec `1431` réservé au HMR Vite ;
|
||||
- le répertoire frontend cible `frontend/`, dont `frontend/ts/` et `frontend/ts/bindings/`.
|
||||
|
||||
Le frontend Vite/TypeScript/SCSS et les dépendances npm sont introduits dans la tranche suivante. Tant que cette tranche n'est pas appliquée, `cargo tauri dev` n'est pas un scénario de validation attendu de ce squelette.
|
||||
|
||||
## Artefacts frontend
|
||||
|
||||
Les artefacts frontend construits ne doivent pas être versionnés. `tauri.conf.json` fixe dès maintenant la destination contractuelle :
|
||||
|
||||
```text
|
||||
../../builds/khadhroony-solana-project/ksp-app-config-desk/dist
|
||||
```
|
||||
|
||||
`vite.config.ts` utilisera la même destination lors de son introduction.
|
||||
|
||||
Les commandes npm servent uniquement à installer/mettre à jour les dépendances. Le cycle normal de développement/build de l'application passe par Tauri, qui déclenche les scripts frontend déclarés dans sa configuration.
|
||||
|
||||
## Ports desktop
|
||||
|
||||
KSP réserve des couples de ports distincts par application desk. `ksp-app-config-desk`, première application, utilise :
|
||||
|
||||
```text
|
||||
Vite HTTP : 1430
|
||||
Vite HMR : 1431
|
||||
```
|
||||
|
||||
Les applications desk suivantes incrémentent le couple de deux ports afin de pouvoir fonctionner simultanément sans collision.
|
||||
16
crates/ksp-app-config-desk/TODO.md
Normal file
16
crates/ksp-app-config-desk/TODO.md
Normal file
@@ -0,0 +1,16 @@
|
||||
<!-- file: crates/ksp-app-config-desk/TODO.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# TODO `ksp-app-config-desk`
|
||||
|
||||
Les éléments suivants appartiennent aux prochaines tranches de `0.1.4` :
|
||||
|
||||
- ajouter le gabarit frontend Vite/TypeScript/SCSS sous `frontend/` ;
|
||||
- ajouter `package.json`, `tsconfig.json` et `vite.config.ts` ;
|
||||
- réserver strictement `1430` pour Vite et `1431` pour HMR ;
|
||||
- introduire SimpleBar, `resize-observer-polyfill`, Bootstrap et Font Awesome selon le gabarit retenu ;
|
||||
- intégrer `tauri-plugin-tracing` et `@fltsci/tauri-plugin-tracing` ;
|
||||
- introduire les DTO TS-RS au premier contrat Tauri réel, avec bindings générés sous `frontend/ts/bindings/` ;
|
||||
- introduire `AppState`, Config et l'ownership de `LoggingGuard` ;
|
||||
- développer les panneaux Documents, Profils, Environnement/`.env`, Secrets et Logging ;
|
||||
- démontrer le hot reload Logging et le panneau de test de routage.
|
||||
34
crates/ksp-app-config-desk/USAGE.md
Normal file
34
crates/ksp-app-config-desk/USAGE.md
Normal file
@@ -0,0 +1,34 @@
|
||||
<!-- file: crates/ksp-app-config-desk/USAGE.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Utilisation de `ksp-app-config-desk`
|
||||
|
||||
## État actuel
|
||||
|
||||
La tranche `0.1.4-pre.004` introduit le squelette Rust/Tauri uniquement. Les fenêtres frontend ne deviennent exécutables qu'après l'ajout du gabarit Vite/TypeScript prévu par la tranche suivante.
|
||||
|
||||
## Entrée binaire
|
||||
|
||||
Le binaire `ksp-app-config-desk` :
|
||||
|
||||
1. acquiert un verrou single-instance dans le répertoire temporaire du système ;
|
||||
2. collecte les arguments de processus sans lire directement de variable `KSP_*`/`KSPB_*` ;
|
||||
3. appelle `ksp_app_config_desk_lib::run()` ;
|
||||
4. convertit explicitement le résultat en `ExitCode`.
|
||||
|
||||
Les arguments Config `--cfgpath`, `--schemapath` et `--filemap` seront consommés par les APIs `ksp-config-lib` dans la tranche de bootstrap applicatif prévue plus loin ; le binaire ne doit pas en réimplémenter le parsing.
|
||||
|
||||
## Fenêtres réservées
|
||||
|
||||
Deux fenêtres sont déjà déclarées dans `tauri.conf.json` :
|
||||
|
||||
- `splash` : lifecycle de démarrage commun ;
|
||||
- `main` : shell de management Config.
|
||||
|
||||
Leur contenu HTML/TypeScript est ajouté avec le gabarit frontend.
|
||||
|
||||
## Développement frontend
|
||||
|
||||
Le cycle normal utilisera `cargo tauri dev`. Tauri déclenchera alors `npm run dev` via `beforeDevCommand` et chargera le serveur Vite sur le port `1430`.
|
||||
|
||||
Les commandes npm directes sont réservées à la gestion des dépendances (`npm i -D ...` selon la politique du projet), et non au lancement quotidien de l'application.
|
||||
12
crates/ksp-app-config-desk/build.rs
Normal file
12
crates/ksp-app-config-desk/build.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
// file: crates/ksp-app-config-desk/build.rs
|
||||
// version: 1
|
||||
|
||||
//! Build script for the KSP configuration desktop application.
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(unreachable_pub)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
12
crates/ksp-app-config-desk/capabilities/default.json
Normal file
12
crates/ksp-app-config-desk/capabilities/default.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "Default capability for KSP Config Desk",
|
||||
"windows": [
|
||||
"splash",
|
||||
"main"
|
||||
],
|
||||
"permissions": [
|
||||
"core:default"
|
||||
]
|
||||
}
|
||||
BIN
crates/ksp-app-config-desk/icons/favicon.ico
Normal file
BIN
crates/ksp-app-config-desk/icons/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 448 KiB |
BIN
crates/ksp-app-config-desk/icons/favicon.png
Normal file
BIN
crates/ksp-app-config-desk/icons/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
7
crates/ksp-app-config-desk/src/errors.rs
Normal file
7
crates/ksp-app-config-desk/src/errors.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
// file: crates/ksp-app-config-desk/src/errors.rs
|
||||
// version: 1
|
||||
|
||||
//! Application-local error codes for the configuration desktop shell.
|
||||
|
||||
/// Tauri runtime assembly or execution failed.
|
||||
pub(crate) const ERROR_CODE_TAURI_RUNTIME_FAILED: ksp_core_lib::ErrorCode = ksp_core_lib::ErrorCode::new("config_desk", "tauri_runtime_failed");
|
||||
16
crates/ksp-app-config-desk/src/lib.rs
Normal file
16
crates/ksp-app-config-desk/src/lib.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
// file: crates/ksp-app-config-desk/src/lib.rs
|
||||
// version: 1
|
||||
|
||||
//! Tauri desktop application for managing and validating KSP configuration.
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(unreachable_pub)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
mod errors;
|
||||
mod tauri;
|
||||
|
||||
/// Runs the KSP configuration desktop application.
|
||||
pub use self::tauri::run;
|
||||
|
||||
pub(crate) use self::errors::ERROR_CODE_TAURI_RUNTIME_FAILED;
|
||||
41
crates/ksp-app-config-desk/src/main.rs
Normal file
41
crates/ksp-app-config-desk/src/main.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
// file: crates/ksp-app-config-desk/src/main.rs
|
||||
// version: 1
|
||||
|
||||
//! Binary entry point for the KSP configuration desktop application.
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(unreachable_pub)]
|
||||
#![warn(missing_docs)]
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
use fs2::FileExt; // rust-rules: trait-import
|
||||
|
||||
fn main() -> std::process::ExitCode {
|
||||
let mut lock_path = std::env::temp_dir();
|
||||
lock_path.push("com_sasedev_ksp_app_config_desk.lock");
|
||||
let lock_file = match std::fs::OpenOptions::new().read(true).write(true).create(true).open(&lock_path) {
|
||||
std::result::Result::Ok(file) => file,
|
||||
std::result::Result::Err(error) => {
|
||||
eprintln!("cannot create application lock '{}': {error}", lock_path.display());
|
||||
return std::process::ExitCode::FAILURE;
|
||||
},
|
||||
};
|
||||
if let std::result::Result::Err(error) = lock_file.try_lock_exclusive() {
|
||||
if error.kind() == std::io::ErrorKind::WouldBlock {
|
||||
eprintln!("another ksp-app-config-desk instance is already running");
|
||||
return std::process::ExitCode::FAILURE;
|
||||
}
|
||||
eprintln!("cannot acquire application lock '{}': {error}", lock_path.display());
|
||||
return std::process::ExitCode::FAILURE;
|
||||
}
|
||||
let _lock_file = lock_file;
|
||||
let arguments = std::env::args_os().collect::<std::vec::Vec<std::ffi::OsString>>();
|
||||
let run_result = ksp_app_config_desk_lib::run(arguments.as_slice());
|
||||
return match run_result {
|
||||
std::result::Result::Ok(()) => std::process::ExitCode::SUCCESS,
|
||||
std::result::Result::Err(error) => {
|
||||
eprintln!("application error: {error}");
|
||||
std::process::ExitCode::FAILURE
|
||||
},
|
||||
};
|
||||
}
|
||||
33
crates/ksp-app-config-desk/src/tauri.rs
Normal file
33
crates/ksp-app-config-desk/src/tauri.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
// file: crates/ksp-app-config-desk/src/tauri.rs
|
||||
// version: 1
|
||||
|
||||
//! Tauri runtime assembly for the KSP configuration desktop application.
|
||||
|
||||
use tauri::Manager; // rust-rules: trait-import
|
||||
|
||||
/// Runs the configuration desktop application.
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run(_arguments: &[std::ffi::OsString]) -> ksp_core_lib::Result<()> {
|
||||
let mut builder = tauri::Builder::default();
|
||||
builder = configure_setup(builder);
|
||||
let run_result = builder.run(tauri::generate_context!());
|
||||
return match run_result {
|
||||
std::result::Result::Ok(()) => std::result::Result::Ok(()),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(
|
||||
ksp_core_lib::Error::new(crate::ERROR_CODE_TAURI_RUNTIME_FAILED, "Cannot run KSP Config Desk Tauri runtime")
|
||||
.with_context("tauri_error", error.to_string()),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
fn configure_setup(builder: tauri::Builder<tauri::Wry>) -> tauri::Builder<tauri::Wry> {
|
||||
return builder.setup(|app| {
|
||||
if app.get_webview_window("splash").is_none() {
|
||||
return std::result::Result::Err(std::boxed::Box::new(std::io::Error::new(std::io::ErrorKind::NotFound, "splash window is missing")));
|
||||
}
|
||||
if app.get_webview_window("main").is_none() {
|
||||
return std::result::Result::Err(std::boxed::Box::new(std::io::Error::new(std::io::ErrorKind::NotFound, "main window is missing")));
|
||||
}
|
||||
return std::result::Result::Ok(());
|
||||
});
|
||||
}
|
||||
50
crates/ksp-app-config-desk/tauri.conf.json
Normal file
50
crates/ksp-app-config-desk/tauri.conf.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "KSP Config Desk",
|
||||
"version": "0.1.4",
|
||||
"identifier": "com.sasedev.ksp-app-config-desk",
|
||||
"build": {
|
||||
"beforeDevCommand": "npm run dev",
|
||||
"devUrl": "http://localhost:1430",
|
||||
"beforeBuildCommand": "npm run build",
|
||||
"frontendDist": "../../builds/khadhroony-solana-project/ksp-app-config-desk/dist"
|
||||
},
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"label": "splash",
|
||||
"url": "splash.html",
|
||||
"title": "Chargement — KSP Config Desk",
|
||||
"width": 960,
|
||||
"height": 637,
|
||||
"resizable": false,
|
||||
"decorations": false,
|
||||
"transparent": true,
|
||||
"center": true,
|
||||
"alwaysOnTop": true
|
||||
},
|
||||
{
|
||||
"label": "main",
|
||||
"url": "main.html",
|
||||
"title": "KSP Config Desk",
|
||||
"width": 1500,
|
||||
"height": 960,
|
||||
"minWidth": 1024,
|
||||
"minHeight": 768,
|
||||
"center": true,
|
||||
"visible": false
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": null
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"icon": [
|
||||
"icons/favicon.png",
|
||||
"icons/favicon.ico"
|
||||
]
|
||||
}
|
||||
}
|
||||
14
crates/ksp-app-config-desk/tests/public_api.rs
Normal file
14
crates/ksp-app-config-desk/tests/public_api.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
// file: crates/ksp-app-config-desk/tests/public_api.rs
|
||||
// version: 1
|
||||
|
||||
//! Public API checks for the KSP configuration desktop application library.
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(unreachable_pub)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
#[test]
|
||||
fn run_entry_point_is_available_from_crate_root() {
|
||||
let run_entry_point: fn(&[std::ffi::OsString]) -> ksp_core_lib::Result<()> = ksp_app_config_desk_lib::run;
|
||||
assert_eq!(std::mem::size_of_val(&run_entry_point), std::mem::size_of::<fn(&[std::ffi::OsString]) -> ksp_core_lib::Result<()>>());
|
||||
}
|
||||
Reference in New Issue
Block a user