Skip to content

Commit 4edb69f

Browse files
authored
feat: add blazor template (#656)
1 parent 14b6042 commit 4edb69f

20 files changed

Lines changed: 691 additions & 3 deletions

.changes/blazor.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"create-tauri-app": minor
3+
"create-tauri-app-js": minor
4+
---
5+
6+
Add Blazor template

.github/workflows/templates-test.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,19 @@ jobs:
9090
with:
9191
node-version: 18
9292

93+
- name: Install .NET@8.0.x
94+
if: matrix.settings.manager == 'dotnet'
95+
uses: actions/setup-dotnet@v4
96+
with:
97+
dotnet-version: 8.0.x
98+
9399
- uses: dtolnay/rust-toolchain@stable
94100

95101
- run: cargo install tauri-cli
96-
if: matrix.settings.manager == 'cargo' && matrix.settings.beta != true
102+
if: (matrix.settings.manager == 'cargo' || matrix.settings.manager == 'dotnet') && matrix.settings.beta != true
97103

98104
- run: cargo install tauri-cli --version '^2.0.0-beta'
99-
if: matrix.settings.manager == 'cargo' && matrix.settings.beta == true
105+
if: (matrix.settings.manager == 'cargo' || matrix.settings.manager == 'dotnet') && matrix.settings.beta == true
100106

101107
- run: |
102108
rustup target add wasm32-unknown-unknown

.scripts/generate-templates-matrix.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ const matrixConfig = [
5050
run_cmd: "bun run",
5151
templates: nodeJsTemplates,
5252
},
53+
{
54+
manager: "dotnet",
55+
install_cmd: "",
56+
run_cmd: "cargo",
57+
templates: ["blazor"],
58+
},
5359
];
5460

5561
const outMatrix = [];

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ Currently supported template presets include:
101101
- `yew`
102102
- `leptos`
103103
- `sycamore`
104+
- `blazor`
104105

105106
You can use `.` for the project name to scaffold in the current directory.
106107

node/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ Currently supported template presets include:
6868
- `yew`
6969
- `leptos`
7070
- `sycamore`
71+
- `blazor`
7172

7273
You can use `.` for the project name to scaffold in the current directory.
7374

src/category.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::package_manager::PackageManager;
77
pub enum Category {
88
Rust,
99
JsTs,
10+
Dotnet,
1011
}
1112
impl Default for Category {
1213
fn default() -> Self {
@@ -15,7 +16,7 @@ impl Default for Category {
1516
}
1617

1718
impl<'a> Category {
18-
pub const ALL: &'a [Self] = &[Category::JsTs, Category::Rust];
19+
pub const ALL: &'a [Self] = &[Category::JsTs, Category::Rust, Category::Dotnet];
1920

2021
pub const fn package_managers(&self) -> &[PackageManager] {
2122
match self {
@@ -26,6 +27,7 @@ impl<'a> Category {
2627
PackageManager::Npm,
2728
PackageManager::Bun,
2829
],
30+
Category::Dotnet => &[PackageManager::Dotnet],
2931
}
3032
}
3133
}
@@ -42,6 +44,7 @@ impl Display for Category {
4244
match self {
4345
Category::Rust => write!(f, "Rust - ({managers})"),
4446
Category::JsTs => write!(f, "TypeScript / JavaScript - ({managers})"),
47+
Category::Dotnet => write!(f, ".NET - ({managers})"),
4548
}
4649
}
4750
}

src/deps.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,14 @@ fn is_xcode_command_line_tools_installed() -> bool {
147147
.unwrap_or(false)
148148
}
149149

150+
fn is_dotnet_installed() -> bool {
151+
Command::new("dotnet")
152+
.arg("--version")
153+
.output()
154+
.map(|o| o.status.success())
155+
.unwrap_or(false)
156+
}
157+
150158
struct Dep<'a> {
151159
name: &'a str,
152160
instruction: String,
@@ -281,6 +289,12 @@ pub fn print_missing_deps(pkg_manager: PackageManager, template: Template, beta:
281289
exists: &is_xcode_command_line_tools_installed,
282290
skip: false,
283291
},
292+
Dep {
293+
name: ".NET",
294+
instruction: format!("Visit {BLUE}{BOLD}https://dotnet.microsoft.com/download{RESET}"),
295+
exists: &is_dotnet_installed,
296+
skip: !template.needs_dotnet() || pkg_manager.is_node(),
297+
}
284298
];
285299

286300
let missing_deps: Vec<(&str, &str)> = deps

src/package_manager.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub enum PackageManager {
1414
Yarn,
1515
Npm,
1616
Bun,
17+
Dotnet,
1718
}
1819

1920
impl Default for PackageManager {
@@ -30,6 +31,7 @@ impl Display for PackageManager {
3031
PackageManager::Yarn => write!(f, "yarn"),
3132
PackageManager::Npm => write!(f, "npm"),
3233
PackageManager::Bun => write!(f, "bun"),
34+
PackageManager::Dotnet => write!(f, "dotnet"),
3335
}
3436
}
3537
}
@@ -43,6 +45,7 @@ impl FromStr for PackageManager {
4345
"yarn" => Ok(PackageManager::Yarn),
4446
"npm" => Ok(PackageManager::Npm),
4547
"bun" => Ok(PackageManager::Bun),
48+
"dotnet" => Ok(PackageManager::Dotnet),
4649
_ => Err(format!(
4750
"{YELLOW}{s}{RESET} is not a valid package manager. Valid package mangers are [{}]",
4851
PackageManager::ALL
@@ -62,6 +65,7 @@ impl<'a> PackageManager {
6265
PackageManager::Yarn,
6366
PackageManager::Npm,
6467
PackageManager::Bun,
68+
PackageManager::Dotnet,
6569
];
6670

6771
/// Node.js managers
@@ -94,6 +98,7 @@ impl PackageManager {
9498
Template::Angular,
9599
Template::Preact,
96100
],
101+
PackageManager::Dotnet => &[Template::Blazor],
97102
}
98103
}
99104

@@ -123,6 +128,7 @@ impl PackageManager {
123128
Template::Preact,
124129
Template::PreactTs,
125130
],
131+
PackageManager::Dotnet => &[Template::Blazor],
126132
}
127133
}
128134

@@ -143,6 +149,7 @@ impl PackageManager {
143149
PackageManager::Yarn => "yarn",
144150
PackageManager::Npm => "npm run",
145151
PackageManager::Bun => "bun run",
152+
PackageManager::Dotnet => "cargo",
146153
}
147154
}
148155

src/template.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pub enum Template {
5555
Angular,
5656
Preact,
5757
PreactTs,
58+
Blazor,
5859
}
5960

6061
impl Default for Template {
@@ -82,6 +83,7 @@ impl Display for Template {
8283
Template::Angular => write!(f, "angular"),
8384
Template::Preact => write!(f, "preact"),
8485
Template::PreactTs => write!(f, "preact-ts"),
86+
Template::Blazor => write!(f, "blazor"),
8587
}
8688
}
8789
}
@@ -106,6 +108,7 @@ impl FromStr for Template {
106108
"angular" => Ok(Template::Angular),
107109
"preact" => Ok(Template::Preact),
108110
"preact-ts" => Ok(Template::PreactTs),
111+
"blazor" => Ok(Template::Blazor),
109112
_ => Err(format!(
110113
"{YELLOW}{s}{RESET} is not a valid template. Valid templates are [{}]",
111114
Template::ALL
@@ -131,6 +134,9 @@ impl Template {
131134
Template::Sycamore => "Sycamore - (https://sycamore-rs.netlify.app/)",
132135
Template::Angular => "Angular - (https://angular.dev/)",
133136
Template::Preact => "Preact - (https://preactjs.com/)",
137+
Template::Blazor => {
138+
"Blazor - (https://dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor/)"
139+
}
134140
_ => unreachable!(),
135141
}
136142
}
@@ -154,6 +160,7 @@ impl<'a> Template {
154160
Template::Angular,
155161
Template::Preact,
156162
Template::PreactTs,
163+
Template::Blazor,
157164
];
158165

159166
pub fn flavors<'b>(&self, pkg_manager: PackageManager) -> Option<&'b [Flavor]> {
@@ -220,6 +227,7 @@ impl<'a> Template {
220227
| Template::Preact
221228
| Template::PreactTs => PackageManager::NODE,
222229
Template::Yew | Template::Leptos | Template::Sycamore => &[PackageManager::Cargo],
230+
Template::Blazor => &[PackageManager::Dotnet],
223231
}
224232
}
225233

@@ -234,6 +242,10 @@ impl<'a> Template {
234242
)
235243
}
236244

245+
pub const fn needs_dotnet(&self) -> bool {
246+
matches!(self, Template::Blazor)
247+
}
248+
237249
pub const fn needs_wasm32_target(&self) -> bool {
238250
matches!(self, Template::Sycamore | Template::Yew | Template::Leptos)
239251
}
@@ -256,13 +268,16 @@ impl<'a> Template {
256268
let manifest = Manifest::parse(&manifest_str, mobile)?;
257269

258270
let lib_name = format!("{}_lib", package_name.replace('-', "_"));
271+
let project_name_pascal_case = Self::transform_to_pascal_case(project_name.to_string());
259272

260273
let beta_str = beta.to_string();
261274
let manifest_template_data: HashMap<&str, &str> = [
262275
("beta", beta_str.as_str()),
263276
("pkg_manager_run_command", pkg_manager.run_cmd()),
264277
("lib_name", &lib_name),
265278
("package_name", package_name),
279+
("project_name", project_name),
280+
("project_name_pascal_case", &project_name_pascal_case),
266281
(
267282
"double_dash_with_space",
268283
if pkg_manager == PackageManager::Npm {
@@ -279,6 +294,10 @@ impl<'a> Template {
279294
("beta", beta_str.clone()),
280295
("mobile", mobile.to_string()),
281296
("project_name", project_name.to_string()),
297+
(
298+
"project_name_pascal_case",
299+
project_name_pascal_case.to_string(),
300+
),
282301
("package_name", package_name.to_string()),
283302
(
284303
"before_dev_command",
@@ -376,6 +395,8 @@ impl<'a> Template {
376395
(data, file_name)
377396
};
378397

398+
let file_name = lte::render(file_name, template_data)?;
399+
379400
let parent = p.parent().unwrap();
380401
fs::create_dir_all(parent)?;
381402
fs::write(parent.join(file_name), file_data)?;
@@ -423,4 +444,22 @@ impl<'a> Template {
423444

424445
Ok(())
425446
}
447+
448+
fn transform_to_pascal_case(s: String) -> String {
449+
let mut result = String::new();
450+
let mut capitalize_next = false;
451+
for (s, c) in s.chars().enumerate() {
452+
if s == 0 {
453+
result.push(c.to_ascii_uppercase());
454+
} else if capitalize_next {
455+
result.push(c.to_ascii_uppercase());
456+
capitalize_next = false;
457+
} else if ['_', '-'].contains(&c) {
458+
capitalize_next = true;
459+
} else {
460+
result.push(c);
461+
}
462+
}
463+
result
464+
}
426465
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
beforeDevCommand = dotnet watch run --project src/{% project_name_pascal_case %}.csproj
2+
beforeBuildCommand = dotnet publish -c release src/{% project_name_pascal_case %}.csproj -o dist
3+
devPath = http://localhost:1420
4+
distDir = ../dist/wwwroot
5+
withGlobalTauri = true
6+
7+
[files]
8+
styles.css = src/wwwroot/css/app.css
9+
tauri.svg = src/wwwroot/img/tauri.svg

0 commit comments

Comments
 (0)