mirror of
https://github.com/tuono-labs/tuono
synced 2026-07-29 13:52:46 -07:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3de9d1be66 | |||
| 00916f188d | |||
| fff5f92893 | |||
| 8b796fc1f4 | |||
| 5ac679785b | |||
| 38b6cc8c65 |
@@ -61,14 +61,14 @@ tuono dev
|
|||||||
## Folder structure
|
## Folder structure
|
||||||
|
|
||||||
```
|
```
|
||||||
├── package.json
|
├── package.json
|
||||||
├── public
|
├── public
|
||||||
├── src
|
├── src
|
||||||
│ ├── routes
|
│ ├── routes
|
||||||
│ └── styles
|
│ └── styles
|
||||||
├── Cargo.toml
|
├── Cargo.toml
|
||||||
├── README.md
|
├── README.md
|
||||||
└── tsconfig.json
|
└── tsconfig.json
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tuono"
|
name = "tuono"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["V. Ageno <valerioageno@yahoo.it>"]
|
authors = ["V. Ageno <valerioageno@yahoo.it>"]
|
||||||
description = "The react/rust fullstack framework"
|
description = "The react/rust fullstack framework"
|
||||||
|
|||||||
+13
-3
@@ -15,7 +15,14 @@ enum Actions {
|
|||||||
/// Build the production assets
|
/// Build the production assets
|
||||||
Build,
|
Build,
|
||||||
/// Scaffold a new project
|
/// Scaffold a new project
|
||||||
New { folder_name: Option<String> },
|
New {
|
||||||
|
/// The folder in which load the project. Default is the current directory.
|
||||||
|
folder_name: Option<String>,
|
||||||
|
/// The template to use to scaffold the project. The template should match one of the tuono
|
||||||
|
/// examples
|
||||||
|
#[arg(short, long)]
|
||||||
|
template: Option<String>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
@@ -46,8 +53,11 @@ pub fn cli() -> std::io::Result<()> {
|
|||||||
let mut vite_build = Command::new("./node_modules/.bin/tuono-build-prod");
|
let mut vite_build = Command::new("./node_modules/.bin/tuono-build-prod");
|
||||||
let _ = &vite_build.output()?;
|
let _ = &vite_build.output()?;
|
||||||
}
|
}
|
||||||
Actions::New { folder_name } => {
|
Actions::New {
|
||||||
scaffold_project::create_new_project(folder_name);
|
folder_name,
|
||||||
|
template,
|
||||||
|
} => {
|
||||||
|
scaffold_project::create_new_project(folder_name, template);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,12 +38,11 @@ fn create_file(path: PathBuf, content: String) -> std::io::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_new_project(folder_name: Option<String>) {
|
pub fn create_new_project(folder_name: Option<String>, template: Option<String>) {
|
||||||
let folder = folder_name.unwrap_or(".".to_string());
|
let folder = folder_name.unwrap_or(".".to_string());
|
||||||
|
|
||||||
if folder != "." {
|
// In case of missing select the tuono example
|
||||||
create_dir(&folder).unwrap();
|
let template = template.unwrap_or("tuono".to_string());
|
||||||
}
|
|
||||||
|
|
||||||
let client = blocking::Client::builder()
|
let client = blocking::Client::builder()
|
||||||
.user_agent("")
|
.user_agent("")
|
||||||
@@ -60,21 +59,25 @@ pub fn create_new_project(folder_name: Option<String>) {
|
|||||||
let new_project_files = res
|
let new_project_files = res
|
||||||
.tree
|
.tree
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|GithubFile { path, .. }| {
|
.filter(|GithubFile { path, .. }| path.starts_with(&format!("examples/{template}/")))
|
||||||
// TODO: Handle custom example download by CLI argument --template
|
|
||||||
if path.starts_with("examples/tuono/") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
})
|
|
||||||
.collect::<Vec<&GithubFile>>();
|
.collect::<Vec<&GithubFile>>();
|
||||||
|
|
||||||
|
if new_project_files.is_empty() {
|
||||||
|
println!("Template not found: {template}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if folder != "." {
|
||||||
|
create_dir(&folder).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let folder_name = PathBuf::from(&folder);
|
let folder_name = PathBuf::from(&folder);
|
||||||
let current_dir = env::current_dir().expect("Failed to get current working directory");
|
let current_dir = env::current_dir().expect("Failed to get current working directory");
|
||||||
|
|
||||||
let folder_path = current_dir.join(folder_name);
|
let folder_path = current_dir.join(folder_name);
|
||||||
|
|
||||||
create_directories(&new_project_files, &folder_path).expect("Failed to create directories");
|
create_directories(&new_project_files, &folder_path, &template)
|
||||||
|
.expect("Failed to create directories");
|
||||||
|
|
||||||
for GithubFile {
|
for GithubFile {
|
||||||
element_type, path, ..
|
element_type, path, ..
|
||||||
@@ -88,7 +91,7 @@ pub fn create_new_project(folder_name: Option<String>) {
|
|||||||
.text()
|
.text()
|
||||||
.expect("Failed to parse the repo structure");
|
.expect("Failed to parse the repo structure");
|
||||||
|
|
||||||
let path = PathBuf::from(&path.replace("examples/tuono/", ""));
|
let path = PathBuf::from(&path.replace(&format!("examples/{template}/"), ""));
|
||||||
|
|
||||||
let file_path = folder_path.join(&path);
|
let file_path = folder_path.join(&path);
|
||||||
|
|
||||||
@@ -101,13 +104,17 @@ pub fn create_new_project(folder_name: Option<String>) {
|
|||||||
outro(folder);
|
outro(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_directories(new_project_files: &Vec<&GithubFile>, folder_path: &Path) -> io::Result<()> {
|
fn create_directories(
|
||||||
|
new_project_files: &[&GithubFile],
|
||||||
|
folder_path: &Path,
|
||||||
|
template: &String,
|
||||||
|
) -> io::Result<()> {
|
||||||
for GithubFile {
|
for GithubFile {
|
||||||
element_type, path, ..
|
element_type, path, ..
|
||||||
} in new_project_files.iter()
|
} in new_project_files.iter()
|
||||||
{
|
{
|
||||||
if let GithubFileType::Tree = element_type {
|
if let GithubFileType::Tree = element_type {
|
||||||
let path = PathBuf::from(&path.replace("examples/tuono/", ""));
|
let path = PathBuf::from(&path.replace(&format!("examples/{template}/"), ""));
|
||||||
|
|
||||||
let dir_path = folder_path.join(&path);
|
let dir_path = folder_path.join(&path);
|
||||||
create_dir(&dir_path).unwrap();
|
create_dir(&dir_path).unwrap();
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ async fn main() {
|
|||||||
.with_state(fetch);
|
.with_state(fetch);
|
||||||
|
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||||
|
|
||||||
|
println!("\nDevelopment app ready at http://localhost:3000/");
|
||||||
axum::serve(listener, app).await.unwrap();
|
axum::serve(listener, app).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +242,6 @@ pub fn bundle_axum_source() -> io::Result<()> {
|
|||||||
pub fn check_tuono_folder() -> io::Result<()> {
|
pub fn check_tuono_folder() -> io::Result<()> {
|
||||||
let dev_folder = Path::new(DEV_FOLDER);
|
let dev_folder = Path::new(DEV_FOLDER);
|
||||||
if !&dev_folder.is_dir() {
|
if !&dev_folder.is_dir() {
|
||||||
println!("exists");
|
|
||||||
fs::create_dir(dev_folder)?;
|
fs::create_dir(dev_folder)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ pub async fn watch() -> Result<()> {
|
|||||||
|
|
||||||
run_server.start().await;
|
run_server.start().await;
|
||||||
|
|
||||||
println!("\nDevelopment app ready at http://localhost:3000/");
|
build_ssr_bundle.to_wait().await;
|
||||||
|
|
||||||
let wx = Watchexec::new(move |mut action| {
|
let wx = Watchexec::new(move |mut action| {
|
||||||
let mut should_reload = false;
|
let mut should_reload = false;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tuono_lib"
|
name = "tuono_lib"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["V. Ageno <valerioageno@yahoo.it>"]
|
authors = ["V. Ageno <valerioageno@yahoo.it>"]
|
||||||
description = "The react/rust fullstack framework"
|
description = "The react/rust fullstack framework"
|
||||||
@@ -24,5 +24,5 @@ serde = { version = "1.0.202", features = ["derive"] }
|
|||||||
erased-serde = "0.4.5"
|
erased-serde = "0.4.5"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
||||||
tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.1.3"}
|
tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.1.4"}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tuono_lib_macros"
|
name = "tuono_lib_macros"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "The react/rust fullstack framework"
|
description = "The react/rust fullstack framework"
|
||||||
homepage = "https://github.com/Valerioageno/tuono"
|
homepage = "https://github.com/Valerioageno/tuono"
|
||||||
|
|||||||
+14
-13
@@ -4,12 +4,11 @@ This tutorial is meant for giving you a sneak peek of the framework and is inten
|
|||||||
|
|
||||||
The first part is about the project setup and the base knowledge needed to work with tuono. The actual tutorial starts at [Tutorial introduction](#tutorial-introduction).
|
The first part is about the project setup and the base knowledge needed to work with tuono. The actual tutorial starts at [Tutorial introduction](#tutorial-introduction).
|
||||||
|
|
||||||
> If you prefer to see directly the final outcome check out the [tutorial source](https://github.com/Valerioageno/tuono/tree/main/examples/tutorial).
|
> If you have already installed the tuono CLI you can download the tutorial source with `tuono new tuono-tutorial --template tutorial`
|
||||||
|
|
||||||
## Table of Content
|
## Table of Content
|
||||||
|
|
||||||
* [Tuono tutorial](#tuono-tutorial)
|
* [CLI Installation](#cli-installation)
|
||||||
* [Installation](#installation)
|
|
||||||
* [Project scaffold](#project-scaffold)
|
* [Project scaffold](#project-scaffold)
|
||||||
* [Start the dev environment](#start-the-dev-environment)
|
* [Start the dev environment](#start-the-dev-environment)
|
||||||
* [The “/” route](#the--route)
|
* [The “/” route](#the--route)
|
||||||
@@ -20,7 +19,7 @@ The first part is about the project setup and the base knowledge needed to work
|
|||||||
* [Error handling](#error-handling)
|
* [Error handling](#error-handling)
|
||||||
* [Conclusion](#conclusion)
|
* [Conclusion](#conclusion)
|
||||||
|
|
||||||
## Installation
|
## CLI Installation
|
||||||
|
|
||||||
The tuono CLI is hosted on [crates.io](https://crates.io/crates/tuono); to download and install it just run on a terminal:
|
The tuono CLI is hosted on [crates.io](https://crates.io/crates/tuono); to download and install it just run on a terminal:
|
||||||
|
|
||||||
@@ -34,9 +33,11 @@ To check that is correctly installed run:
|
|||||||
$ tuono --version
|
$ tuono --version
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Run `tuono -h` to see all the available commands.
|
||||||
|
|
||||||
## Project scaffold
|
## Project scaffold
|
||||||
|
|
||||||
To setup a new project you just need to run the following command:
|
To setup a new fresh project you just need to run the following command:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ tuono new tuono-tutorial
|
$ tuono new tuono-tutorial
|
||||||
@@ -53,14 +54,14 @@ Open it with your favourite code editor.
|
|||||||
The project will have the following structure:
|
The project will have the following structure:
|
||||||
|
|
||||||
```
|
```
|
||||||
├── package.json
|
├── package.json
|
||||||
├── public
|
├── public
|
||||||
├── src
|
├── src
|
||||||
│ ├── routes
|
│ ├── routes
|
||||||
│ └── styles
|
│ └── styles
|
||||||
├── Cargo.toml
|
├── Cargo.toml
|
||||||
├── README.md
|
├── README.md
|
||||||
└── tsconfig.json
|
└── tsconfig.json
|
||||||
```
|
```
|
||||||
|
|
||||||
**public/**: put here all the files you want to be public
|
**public/**: put here all the files you want to be public
|
||||||
|
|||||||
@@ -7,3 +7,13 @@ To simply scaffold the base project run in your terminal:
|
|||||||
```shell
|
```shell
|
||||||
$ tuono new [NAME]
|
$ tuono new [NAME]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can install any example included in this folder by just using the `--template` flag:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ tuono new [NAME] --template [TEMPLATE]
|
||||||
|
```
|
||||||
|
|
||||||
|
`[TEMPLATE]` is the folder name.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
# Tuono tutorial
|
# Tuono tutorial
|
||||||
|
|
||||||
This project is the outcome of the [tuono tutorial](https://github.com/Valerioageno/tuono/blob/main/docs/tutorial.md)
|
This project is the outcome of the [tuono tutorial](https://github.com/Valerioageno/tuono/blob/main/docs/tutorial.md)
|
||||||
|
|
||||||
|
If you want to directly install it you can run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ tuono new my-project -t tutorial
|
||||||
|
```
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tuono",
|
"name": "tuono",
|
||||||
"version": "0.1.3",
|
"version": "0.1.4",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"packageManager": "pnpm@9.1.1",
|
"packageManager": "pnpm@9.1.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tuono",
|
"name": "tuono",
|
||||||
"version": "0.1.3",
|
"version": "0.1.4",
|
||||||
"description": "The react/rust fullstack framework",
|
"description": "The react/rust fullstack framework",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite build --watch",
|
"dev": "vite build --watch",
|
||||||
|
|||||||
Reference in New Issue
Block a user