mirror of
https://github.com/tuono-labs/tuono
synced 2026-07-25 12:52:47 -07:00
refactor: source builder (#655)
This commit is contained in:
@@ -68,7 +68,7 @@ impl App {
|
|||||||
app
|
app
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_routes(&mut self) {
|
pub fn collect_routes(&mut self) {
|
||||||
glob(
|
glob(
|
||||||
self.base_path
|
self.base_path
|
||||||
.join("src/routes/**/*.*")
|
.join("src/routes/**/*.*")
|
||||||
@@ -203,7 +203,7 @@ impl App {
|
|||||||
.expect("Failed to run the rust server")
|
.expect("Failed to run the rust server")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_tuono_config(&mut self) -> Result<std::process::Output, std::io::Error> {
|
pub fn build_tuono_config(&mut self) -> io::Result<std::process::Output> {
|
||||||
if !Path::new(BUILD_TUONO_CONFIG).exists() {
|
if !Path::new(BUILD_TUONO_CONFIG).exists() {
|
||||||
eprintln!("Failed to find the build script. Please run `npm install`");
|
eprintln!("Failed to find the build script. Please run `npm install`");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
|
|||||||
+8
-38
@@ -1,15 +1,9 @@
|
|||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use tracing::{span, Level};
|
use tracing::{span, Level};
|
||||||
use tracing_subscriber::EnvFilter;
|
|
||||||
|
|
||||||
use crate::app::App;
|
|
||||||
use crate::commands::{build, dev, new};
|
use crate::commands::{build, dev, new};
|
||||||
use crate::mode::Mode;
|
use crate::mode::Mode;
|
||||||
use crate::source_builder::{
|
use crate::source_builder::SourceBuilder;
|
||||||
bundle_axum_source, check_tuono_folder, create_client_entry_files, generate_fallback_html,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
enum Actions {
|
enum Actions {
|
||||||
@@ -46,29 +40,7 @@ struct Args {
|
|||||||
action: Actions,
|
action: Actions,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_for_tuono_config() {
|
|
||||||
if !PathBuf::from("tuono.config.ts").exists() {
|
|
||||||
eprintln!("Cannot find tuono.config.ts - is this a tuono project?");
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init_tuono_folder(mode: Mode) -> std::io::Result<App> {
|
|
||||||
check_for_tuono_config();
|
|
||||||
check_tuono_folder()?;
|
|
||||||
let app = bundle_axum_source(mode)?;
|
|
||||||
create_client_entry_files()?;
|
|
||||||
|
|
||||||
Ok(app)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn app() -> std::io::Result<()> {
|
pub fn app() -> std::io::Result<()> {
|
||||||
tracing_subscriber::fmt()
|
|
||||||
// Not need for the time since the code is synchronous
|
|
||||||
.without_time()
|
|
||||||
.with_env_filter(EnvFilter::from_default_env())
|
|
||||||
.init();
|
|
||||||
|
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
match args.action {
|
match args.action {
|
||||||
@@ -77,24 +49,22 @@ pub fn app() -> std::io::Result<()> {
|
|||||||
|
|
||||||
let _guard = span.enter();
|
let _guard = span.enter();
|
||||||
|
|
||||||
let mut app = init_tuono_folder(Mode::Dev)?;
|
let mut source_builder = SourceBuilder::new(Mode::Dev)?;
|
||||||
|
|
||||||
app.build_tuono_config()
|
source_builder.base_build()?;
|
||||||
.expect("Failed to build tuono.config.ts");
|
|
||||||
|
|
||||||
generate_fallback_html(&app)?;
|
source_builder.app.check_server_availability(Mode::Dev);
|
||||||
app.check_server_availability(Mode::Dev);
|
|
||||||
|
|
||||||
dev::watch().unwrap();
|
dev::watch(source_builder).unwrap();
|
||||||
}
|
}
|
||||||
Actions::Build { ssg, no_js_emit } => {
|
Actions::Build { ssg, no_js_emit } => {
|
||||||
let span = span!(Level::TRACE, "BUILD");
|
let span = span!(Level::TRACE, "BUILD");
|
||||||
|
|
||||||
let _guard = span.enter();
|
let _guard = span.enter();
|
||||||
|
|
||||||
let app = init_tuono_folder(Mode::Prod)?;
|
let mut source_builder = SourceBuilder::new(Mode::Prod)?;
|
||||||
|
source_builder.base_build()?;
|
||||||
build::build(app, ssg, no_js_emit);
|
build::build(source_builder.app, ssg, no_js_emit);
|
||||||
}
|
}
|
||||||
Actions::New {
|
Actions::New {
|
||||||
folder_name,
|
folder_name,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, RwLock};
|
||||||
use watchexec_supervisor::command::{Command, Program};
|
use watchexec_supervisor::command::{Command, Program};
|
||||||
|
|
||||||
use miette::{IntoDiagnostic, Result};
|
use miette::{IntoDiagnostic, Result};
|
||||||
@@ -8,8 +8,7 @@ use watchexec::Watchexec;
|
|||||||
use watchexec_signals::Signal;
|
use watchexec_signals::Signal;
|
||||||
use watchexec_supervisor::job::{start_job, Job};
|
use watchexec_supervisor::job::{start_job, Job};
|
||||||
|
|
||||||
use crate::mode::Mode;
|
use crate::source_builder::SourceBuilder;
|
||||||
use crate::source_builder::bundle_axum_source;
|
|
||||||
use console::Term;
|
use console::Term;
|
||||||
use spinners::{Spinner, Spinners};
|
use spinners::{Spinner, Spinners};
|
||||||
|
|
||||||
@@ -87,7 +86,8 @@ fn ssr_reload_needed(path: &Path) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
pub async fn watch() -> Result<()> {
|
pub async fn watch(source_builder: SourceBuilder) -> Result<()> {
|
||||||
|
let source_builder = RwLock::new(source_builder);
|
||||||
let term = Term::stdout();
|
let term = Term::stdout();
|
||||||
let mut sp = Spinner::new(Spinners::Dots, "Starting dev server...".into());
|
let mut sp = Spinner::new(Spinners::Dots, "Starting dev server...".into());
|
||||||
|
|
||||||
@@ -138,7 +138,9 @@ pub async fn watch() -> Result<()> {
|
|||||||
if should_reload_rust_server {
|
if should_reload_rust_server {
|
||||||
println!(" Reloading...");
|
println!(" Reloading...");
|
||||||
rust_server.stop();
|
rust_server.stop();
|
||||||
bundle_axum_source(Mode::Dev).expect("Failed to bundle rust source");
|
let mut builder = source_builder.write().unwrap();
|
||||||
|
builder.app.collect_routes();
|
||||||
|
_ = builder.refresh_axum_source();
|
||||||
rust_server.start();
|
rust_server.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
|
use tracing::error;
|
||||||
|
use tracing_subscriber::EnvFilter;
|
||||||
use tuono::cli::app;
|
use tuono::cli::app;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
app().expect("Failed to start the CLI")
|
tracing_subscriber::fmt()
|
||||||
|
// Time not needed since the execution is synchronous
|
||||||
|
.without_time()
|
||||||
|
.with_env_filter(EnvFilter::from_default_env())
|
||||||
|
.init();
|
||||||
|
|
||||||
|
if let Err(e) = app() {
|
||||||
|
// Generic error.
|
||||||
|
// Recoverable errors should be managed locally
|
||||||
|
error!("Failed to run the tuono CLI: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::fs;
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::crate_version;
|
use clap::crate_version;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
@@ -77,16 +78,144 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
"##;
|
"##;
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
const MAIN_FILE_PATH: &str = ".\\.tuono\\main.rs";
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
const FALLBACK_HTML_PATH: &str = ".\\.tuono\\index.html";
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
const MAIN_FILE_PATH: &str = "./.tuono/main.rs";
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
const FALLBACK_HTML_PATH: &str = "./.tuono/index.html";
|
||||||
|
|
||||||
const ROUTE_FOLDER: &str = "src/routes";
|
const ROUTE_FOLDER: &str = "src/routes";
|
||||||
const DEV_FOLDER: &str = ".tuono";
|
const DEV_FOLDER: &str = ".tuono";
|
||||||
|
|
||||||
fn create_main_file(base_path: &Path, bundled_file: &String) {
|
// Use this function to instruct the users on how to
|
||||||
let mut data_file =
|
// fix their setup to make tuono work
|
||||||
fs::File::create(base_path.join(".tuono/main.rs")).expect("creation failed");
|
fn recoverable_error(message: &str) -> ! {
|
||||||
|
error!("{}", message);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
data_file
|
// Struct to build the source code
|
||||||
.write_all(bundled_file.as_bytes())
|
// on both "dev" and "build" commands
|
||||||
.expect("write failed");
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct SourceBuilder {
|
||||||
|
pub app: App,
|
||||||
|
mode: Mode,
|
||||||
|
base_path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SourceBuilder {
|
||||||
|
pub fn new(mode: Mode) -> io::Result<Self> {
|
||||||
|
if !PathBuf::from("tuono.config.ts").exists() {
|
||||||
|
recoverable_error("Cannot find tuono.config.ts - is this a tuono project?");
|
||||||
|
}
|
||||||
|
|
||||||
|
let dev_folder = Path::new(DEV_FOLDER);
|
||||||
|
if !&dev_folder.is_dir() {
|
||||||
|
fs::create_dir(dev_folder)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let app = App::new();
|
||||||
|
|
||||||
|
let base_path = std::env::current_dir()?;
|
||||||
|
|
||||||
|
create_client_entry_files()?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
app,
|
||||||
|
mode,
|
||||||
|
base_path,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the source code needed for both build and dev
|
||||||
|
pub fn base_build(&mut self) -> io::Result<()> {
|
||||||
|
let Self { mode, .. } = &self;
|
||||||
|
|
||||||
|
self.refresh_axum_source()?;
|
||||||
|
|
||||||
|
if mode == &Mode::Dev {
|
||||||
|
self.app.build_tuono_config()?;
|
||||||
|
let fallback_html = create_html_fallback(&self.app);
|
||||||
|
self.create_file(FALLBACK_HTML_PATH, &fallback_html)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_axum_source(&self) -> String {
|
||||||
|
let Self { app, mode, .. } = &self;
|
||||||
|
|
||||||
|
let src = AXUM_ENTRY_POINT
|
||||||
|
.replace(
|
||||||
|
"// ROUTE_BUILDER\n",
|
||||||
|
&create_routes_declaration(&app.route_map),
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
"// MODULE_IMPORTS\n",
|
||||||
|
&create_modules_declaration(&app.route_map),
|
||||||
|
)
|
||||||
|
.replace("/*VERSION*/", crate_version!())
|
||||||
|
.replace("/*MODE*/", mode.as_str())
|
||||||
|
.replace(
|
||||||
|
"//MAIN_FILE_IMPORT//",
|
||||||
|
if app.has_app_state {
|
||||||
|
r#"#[path="../src/app.rs"]
|
||||||
|
mod tuono_main_state;
|
||||||
|
"#
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
"//MAIN_FILE_DEFINITION//",
|
||||||
|
if app.has_app_state {
|
||||||
|
"let user_custom_state = tuono_main_state::main();"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
"//MAIN_FILE_USAGE//",
|
||||||
|
if app.has_app_state {
|
||||||
|
".with_state(user_custom_state)"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut import_http_handler = String::new();
|
||||||
|
|
||||||
|
let used_http_methods = app.get_used_http_methods();
|
||||||
|
|
||||||
|
for method in used_http_methods.into_iter() {
|
||||||
|
let method = method.to_string().to_lowercase();
|
||||||
|
import_http_handler.push_str(&format!("use tuono_lib::axum::routing::{method};\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
src.replace("// AXUM_GET_ROUTE_HANDLER", &import_http_handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn refresh_axum_source(&self) -> io::Result<()> {
|
||||||
|
let axum_source = self.generate_axum_source();
|
||||||
|
|
||||||
|
self.create_file(MAIN_FILE_PATH, &axum_source)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_file(&self, path: &str, content: &str) -> io::Result<()> {
|
||||||
|
let mut data_file = fs::File::create(self.base_path.join(path))?;
|
||||||
|
|
||||||
|
data_file.write_all(content.as_bytes())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_routes_declaration(routes: &HashMap<String, Route>) -> String {
|
fn create_routes_declaration(routes: &HashMap<String, Route>) -> String {
|
||||||
@@ -141,67 +270,6 @@ fn create_modules_declaration(routes: &HashMap<String, Route>) -> String {
|
|||||||
route_declarations
|
route_declarations
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bundle_axum_source(mode: Mode) -> io::Result<App> {
|
|
||||||
let base_path = std::env::current_dir()?;
|
|
||||||
|
|
||||||
let app = App::new();
|
|
||||||
let bundled_file = generate_axum_source(&app, mode);
|
|
||||||
create_main_file(&base_path, &bundled_file);
|
|
||||||
|
|
||||||
Ok(app)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generate_axum_source(app: &App, mode: Mode) -> String {
|
|
||||||
let src = AXUM_ENTRY_POINT
|
|
||||||
.replace(
|
|
||||||
"// ROUTE_BUILDER\n",
|
|
||||||
&create_routes_declaration(&app.route_map),
|
|
||||||
)
|
|
||||||
.replace(
|
|
||||||
"// MODULE_IMPORTS\n",
|
|
||||||
&create_modules_declaration(&app.route_map),
|
|
||||||
)
|
|
||||||
.replace("/*VERSION*/", crate_version!())
|
|
||||||
.replace("/*MODE*/", mode.as_str())
|
|
||||||
.replace(
|
|
||||||
"//MAIN_FILE_IMPORT//",
|
|
||||||
if app.has_app_state {
|
|
||||||
r#"#[path="../src/app.rs"]
|
|
||||||
mod tuono_main_state;
|
|
||||||
"#
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.replace(
|
|
||||||
"//MAIN_FILE_DEFINITION//",
|
|
||||||
if app.has_app_state {
|
|
||||||
"let user_custom_state = tuono_main_state::main();"
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.replace(
|
|
||||||
"//MAIN_FILE_USAGE//",
|
|
||||||
if app.has_app_state {
|
|
||||||
".with_state(user_custom_state)"
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut import_http_handler = String::new();
|
|
||||||
|
|
||||||
let used_http_methods = app.get_used_http_methods();
|
|
||||||
|
|
||||||
for method in used_http_methods.into_iter() {
|
|
||||||
let method = method.to_string().to_lowercase();
|
|
||||||
import_http_handler.push_str(&format!("use tuono_lib::axum::routing::{method};\n"))
|
|
||||||
}
|
|
||||||
|
|
||||||
src.replace("// AXUM_GET_ROUTE_HANDLER", &import_http_handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_html_fallback(app: &App) -> String {
|
fn create_html_fallback(app: &App) -> String {
|
||||||
if let Some(config) = app.config.as_ref() {
|
if let Some(config) = app.config.as_ref() {
|
||||||
if let Some(origin) = &config.server.origin {
|
if let Some(origin) = &config.server.origin {
|
||||||
@@ -215,29 +283,6 @@ fn create_html_fallback(app: &App) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_fallback_html(app: &App) -> io::Result<()> {
|
|
||||||
let base_path = std::env::current_dir().unwrap_or_else(|_| {
|
|
||||||
error!("Failed to get current directory");
|
|
||||||
std::process::exit(1);
|
|
||||||
});
|
|
||||||
let mut data_file = fs::File::create(base_path.join(".tuono/index.html"))?;
|
|
||||||
|
|
||||||
let fallback_html = create_html_fallback(app);
|
|
||||||
|
|
||||||
data_file.write_all(fallback_html.as_bytes())?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn check_tuono_folder() -> io::Result<()> {
|
|
||||||
let dev_folder = Path::new(DEV_FOLDER);
|
|
||||||
if !&dev_folder.is_dir() {
|
|
||||||
fs::create_dir(dev_folder)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_client_entry_files() -> io::Result<()> {
|
pub fn create_client_entry_files() -> io::Result<()> {
|
||||||
let dev_folder = Path::new(DEV_FOLDER);
|
let dev_folder = Path::new(DEV_FOLDER);
|
||||||
|
|
||||||
@@ -257,10 +302,19 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_set_the_correct_mode() {
|
fn should_set_the_correct_mode() {
|
||||||
let source_builder = App::new();
|
let dev_bundle = SourceBuilder {
|
||||||
|
app: App::new(),
|
||||||
|
mode: Mode::Dev,
|
||||||
|
base_path: PathBuf::new(),
|
||||||
|
}
|
||||||
|
.generate_axum_source();
|
||||||
|
|
||||||
let dev_bundle = generate_axum_source(&source_builder, Mode::Dev);
|
let prod_bundle = SourceBuilder {
|
||||||
let prod_bundle = generate_axum_source(&source_builder, Mode::Prod);
|
app: App::new(),
|
||||||
|
mode: Mode::Prod,
|
||||||
|
base_path: PathBuf::new(),
|
||||||
|
}
|
||||||
|
.generate_axum_source();
|
||||||
|
|
||||||
assert!(dev_bundle.contains("const MODE: Mode = Mode::Dev;"));
|
assert!(dev_bundle.contains("const MODE: Mode = Mode::Dev;"));
|
||||||
assert!(prod_bundle.contains("const MODE: Mode = Mode::Prod;"));
|
assert!(prod_bundle.contains("const MODE: Mode = Mode::Prod;"));
|
||||||
@@ -268,25 +322,33 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_not_load_the_axum_get_function() {
|
fn should_not_load_the_axum_get_function() {
|
||||||
let source_builder = App::new();
|
let dev_bundle = SourceBuilder {
|
||||||
|
app: App::new(),
|
||||||
let dev_bundle = generate_axum_source(&source_builder, Mode::Dev);
|
mode: Mode::Dev,
|
||||||
|
base_path: PathBuf::new(),
|
||||||
|
}
|
||||||
|
.generate_axum_source();
|
||||||
|
|
||||||
assert!(!dev_bundle.contains("use tuono_lib::axum::routing::get;"));
|
assert!(!dev_bundle.contains("use tuono_lib::axum::routing::get;"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_load_the_axum_get_function() {
|
fn should_load_the_axum_get_function() {
|
||||||
let mut source_builder = App::new();
|
let mut source_builder = SourceBuilder {
|
||||||
|
app: App::new(),
|
||||||
|
mode: Mode::Dev,
|
||||||
|
base_path: PathBuf::new(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut route = Route::new(String::from("index.tsx"));
|
let mut route = Route::new(String::from("index.tsx"));
|
||||||
route.update_axum_info();
|
route.update_axum_info();
|
||||||
|
|
||||||
source_builder
|
source_builder
|
||||||
|
.app
|
||||||
.route_map
|
.route_map
|
||||||
.insert(String::from("index.rs"), route);
|
.insert(String::from("index.rs"), route);
|
||||||
|
|
||||||
let dev_bundle = generate_axum_source(&source_builder, Mode::Dev);
|
let dev_bundle = source_builder.generate_axum_source();
|
||||||
|
|
||||||
assert!(dev_bundle.contains("use tuono_lib::axum::routing::get;"));
|
assert!(dev_bundle.contains("use tuono_lib::axum::routing::get;"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use assert_cmd::Command;
|
use assert_cmd::Command;
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use tracing::Level;
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
use utils::temp_tuono_project::TempTuonoProject;
|
use utils::temp_tuono_project::TempTuonoProject;
|
||||||
@@ -8,6 +9,10 @@ use utils::temp_tuono_project::TempTuonoProject;
|
|||||||
const POST_API_FILE: &str = r"#[tuono_lib::api(POST)]";
|
const POST_API_FILE: &str = r"#[tuono_lib::api(POST)]";
|
||||||
const GET_API_FILE: &str = r"#[tuono_lib::api(GET)]";
|
const GET_API_FILE: &str = r"#[tuono_lib::api(GET)]";
|
||||||
|
|
||||||
|
fn tracing_message(level: Level, module: &str, message: &str) -> String {
|
||||||
|
format!("\x1b[31m{level}\x1b[0m \x1b[2mtuono::{module}\x1b[0m\x1b[2m:\x1b[0m {message}\n")
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
const BUILD_TUONO_CONFIG: &str = ".\\node_modules\\.bin\\tuono-build-config.cmd";
|
const BUILD_TUONO_CONFIG: &str = ".\\node_modules\\.bin\\tuono-build-config.cmd";
|
||||||
|
|
||||||
@@ -185,7 +190,11 @@ fn dev_fails_with_no_config() {
|
|||||||
.arg("dev")
|
.arg("dev")
|
||||||
.assert()
|
.assert()
|
||||||
.failure()
|
.failure()
|
||||||
.stderr("Cannot find tuono.config.ts - is this a tuono project?\n");
|
.stdout(tracing_message(
|
||||||
|
Level::ERROR,
|
||||||
|
"source_builder",
|
||||||
|
"Cannot find tuono.config.ts - is this a tuono project?",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -198,5 +207,9 @@ fn build_fails_with_no_config() {
|
|||||||
.arg("dev")
|
.arg("dev")
|
||||||
.assert()
|
.assert()
|
||||||
.failure()
|
.failure()
|
||||||
.stderr("Cannot find tuono.config.ts - is this a tuono project?\n");
|
.stdout(tracing_message(
|
||||||
|
Level::ERROR,
|
||||||
|
"source_builder",
|
||||||
|
"Cannot find tuono.config.ts - is this a tuono project?",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user