Skip to content

Commit ec6f082

Browse files
committed
fixed python install
1 parent 3628924 commit ec6f082

6 files changed

Lines changed: 86 additions & 66 deletions

File tree

crates/dev/src/cli.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ pub enum LanguageCommand {
325325
pub struct InstallArgs {
326326
#[arg()]
327327
pub language: Option<String>,
328+
/// Overwrite existing scaffold files instead of skipping them.
329+
#[arg(long = "force", default_value_t = false)]
330+
pub force: bool,
328331
}
329332

330333
#[derive(Args, Debug)]

crates/dev/src/runner.rs

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,7 @@ fn config_root_dir(config_path: &Utf8PathBuf) -> PathBuf {
4646
parent.to_path_buf()
4747
}
4848

49-
fn should_scaffold_in_cwd(language: &str) -> bool {
50-
// `dev install` is used both for bootstrapping a brand new project and for provisioning
51-
// dependencies in an existing one. When we detect common manifests in the current
52-
// directory, we skip template scaffolding to avoid overwriting/adding unrelated files.
53-
match language {
54-
"typescript" | "ts" => !Path::new("package.json").exists(),
55-
"python" => !Path::new("pyproject.toml").exists(),
56-
"rust" => !Path::new("Cargo.toml").exists(),
57-
_ => true,
58-
}
59-
}
60-
61-
fn handle_kube(state: &AppState, command: KubeCommand) -> Result<()> {
49+
fn handle_kube(state: &AppState, command: KubeCommand) -> Result<()> {
6250
match command {
6351
KubeCommand::Help => {
6452
println!(
@@ -723,12 +711,8 @@ fn handle_install(state: &AppState, args: InstallArgs) -> Result<()> {
723711
return Ok(());
724712
}
725713

726-
if should_scaffold_in_cwd(&language) {
727-
println!("Installing scaffolds for `{}`...", language);
728-
scaffold::install(&language)?;
729-
} else {
730-
println!("Skipping scaffolds for `{}` (project already initialized)", language);
731-
}
714+
println!("Installing scaffolds for `{}`...", language);
715+
scaffold::install(&language, args.force)?;
732716

733717
match install_commands(&state.config, &language) {
734718
Some(commands) if !commands.is_empty() => {

crates/dev/src/scaffold/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ use crate::templates;
66
use anyhow::{Result, bail};
77
use camino::Utf8Path;
88

9-
pub fn install(language: &str) -> Result<()> {
9+
pub fn install(language: &str, force: bool) -> Result<()> {
1010
match language {
11-
"rust" => rust::install(),
12-
"python" => python::install(),
13-
"typescript" | "ts" => typescript::install(),
11+
"rust" => rust::install(force),
12+
"python" => python::install(force),
13+
"typescript" | "ts" => typescript::install(force),
1414
other => bail!("unsupported language scaffold: {other}"),
1515
}
1616
}

crates/dev/src/scaffold/python.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,29 @@ const PRECOMMIT: &str = ".pre-commit-config.yaml";
1212
const CI_WORKFLOW: &str = ".github/workflows/ci.yml";
1313
const GITIGNORE: &str = ".gitignore";
1414

15-
pub fn install() -> Result<()> {
15+
pub fn install(force: bool) -> Result<()> {
1616
ensure_uv()?; // installs uv if necessary
1717
ensure_uv_tool("ruff")?;
1818
ensure_uv_tool("mypy")?;
19-
ensure_file(GITIGNORE, "python/.gitignore")?;
20-
ensure_file(RUFF, "python/ruff.toml")?;
21-
ensure_file(MYPY, "python/mypy.ini")?;
22-
ensure_file(PRECOMMIT, "python/pre-commit-config.yaml")?;
23-
ensure_ci_workflow()?;
19+
ensure_file(GITIGNORE, "python/.gitignore", force)?;
20+
ensure_file(RUFF, "python/ruff.toml", force)?;
21+
ensure_file(MYPY, "python/mypy.ini", force)?;
22+
ensure_file(PRECOMMIT, "python/pre-commit-config.yaml", force)?;
23+
ensure_ci_workflow(force)?;
2424

2525
println!("Python scaffolding complete");
2626
Ok(())
2727
}
2828

29-
30-
fn ensure_file(target: &str, template: &str) -> Result<()> {
29+
fn ensure_file(target: &str, template: &str, force: bool) -> Result<()> {
3130
let destination = Utf8Path::new(target);
3231
if destination.exists() {
32+
if force {
33+
write_template(destination, template)?;
34+
println!(" overwritten {}", destination);
35+
} else {
36+
println!(" skipped {}", destination);
37+
}
3338
return Ok(());
3439
}
3540

@@ -38,9 +43,15 @@ fn ensure_file(target: &str, template: &str) -> Result<()> {
3843
Ok(())
3944
}
4045

41-
fn ensure_ci_workflow() -> Result<()> {
46+
fn ensure_ci_workflow(force: bool) -> Result<()> {
4247
let destination = Utf8Path::new(CI_WORKFLOW);
4348
if destination.exists() {
49+
if force {
50+
write_template(destination, "python/.github/workflows/ci.yml")?;
51+
println!(" overwritten {}", destination);
52+
} else {
53+
println!(" skipped {}", destination);
54+
}
4455
return Ok(());
4556
}
4657

@@ -101,5 +112,3 @@ fn ensure_uv_tool(tool: &str) -> Result<()> {
101112
}
102113
Ok(())
103114
}
104-
105-

crates/dev/src/scaffold/rust.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,27 @@ const DENY_FILE: &str = "deny.toml";
99
const CI_WORKFLOW: &str = ".github/workflows/ci.yml";
1010
const GITIGNORE: &str = ".gitignore";
1111

12-
pub fn install() -> Result<()> {
13-
ensure_file(GITIGNORE, "rust/.gitignore")?;
14-
ensure_file(CARGO_CONFIG, "rust/cargo-config.toml")?;
15-
ensure_file(DENY_FILE, "rust/deny.toml")?;
16-
ensure_ci_workflow()?;
12+
pub fn install(force: bool) -> Result<()> {
13+
ensure_file(GITIGNORE, "rust/.gitignore", force)?;
14+
ensure_file(CARGO_CONFIG, "rust/cargo-config.toml", force)?;
15+
ensure_file(DENY_FILE, "rust/deny.toml", force)?;
16+
ensure_ci_workflow(force)?;
1717

1818
println!("Rust scaffolding complete");
1919
Ok(())
2020
}
2121

22-
fn ensure_ci_workflow() -> Result<()> {
23-
let destination = Utf8Path::new(CI_WORKFLOW);
24-
if destination.exists() {
25-
return Ok(());
26-
}
22+
fn ensure_ci_workflow(force: bool) -> Result<()> {
23+
let destination = Utf8Path::new(CI_WORKFLOW);
24+
if destination.exists() {
25+
if force {
26+
write_template(destination, "rust/.github/workflows/ci.yml")?;
27+
println!(" overwritten {}", destination);
28+
} else {
29+
println!(" skipped {}", destination);
30+
}
31+
return Ok(());
32+
}
2733

2834
if let Some(parent) = destination.parent() {
2935
fs::create_dir_all(parent)?;
@@ -34,11 +40,17 @@ fn ensure_ci_workflow() -> Result<()> {
3440
Ok(())
3541
}
3642

37-
fn ensure_file(target: &str, template: &str) -> Result<()> {
38-
let destination = Utf8Path::new(target);
39-
if destination.exists() {
40-
return Ok(());
41-
}
43+
fn ensure_file(target: &str, template: &str, force: bool) -> Result<()> {
44+
let destination = Utf8Path::new(target);
45+
if destination.exists() {
46+
if force {
47+
write_template(destination, template)?;
48+
println!(" overwritten {}", destination);
49+
} else {
50+
println!(" skipped {}", destination);
51+
}
52+
return Ok(());
53+
}
4254

4355
write_template(destination, template)?;
4456
println!(" created {}", destination);

crates/dev/src/scaffold/typescript.rs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,29 @@ const PRETTIER: &str = ".prettierrc.json";
1111
const CI_WORKFLOW: &str = ".github/workflows/ci.yml";
1212
const GITIGNORE: &str = ".gitignore";
1313

14-
pub fn install() -> Result<()> {
15-
ensure_file(GITIGNORE, "typescript/.gitignore")?;
16-
ensure_file(ESLINT, "typescript/eslint.config.ts")?;
17-
ensure_file(TSCONFIG, "typescript/tsconfig.json")?;
18-
ensure_file(VITEST, "typescript/vitest.config.ts")?;
19-
ensure_file(PRETTIER, "typescript/prettierrc.json")?;
20-
ensure_ci_workflow()?;
14+
pub fn install(force: bool) -> Result<()> {
15+
ensure_file(GITIGNORE, "typescript/.gitignore", force)?;
16+
ensure_file(ESLINT, "typescript/eslint.config.ts", force)?;
17+
ensure_file(TSCONFIG, "typescript/tsconfig.json", force)?;
18+
ensure_file(VITEST, "typescript/vitest.config.ts", force)?;
19+
ensure_file(PRETTIER, "typescript/prettierrc.json", force)?;
20+
ensure_ci_workflow(force)?;
2121

2222
println!("TypeScript scaffolding complete");
2323
Ok(())
2424
}
2525

26-
fn ensure_ci_workflow() -> Result<()> {
27-
let destination = Utf8Path::new(CI_WORKFLOW);
28-
if destination.exists() {
29-
return Ok(());
30-
}
26+
fn ensure_ci_workflow(force: bool) -> Result<()> {
27+
let destination = Utf8Path::new(CI_WORKFLOW);
28+
if destination.exists() {
29+
if force {
30+
write_template(destination, "typescript/.github/workflows/ci.yml")?;
31+
println!(" overwritten {}", destination);
32+
} else {
33+
println!(" skipped {}", destination);
34+
}
35+
return Ok(());
36+
}
3137

3238
if let Some(parent) = destination.parent() {
3339
fs::create_dir_all(parent)?;
@@ -38,11 +44,17 @@ fn ensure_ci_workflow() -> Result<()> {
3844
Ok(())
3945
}
4046

41-
fn ensure_file(target: &str, template: &str) -> Result<()> {
42-
let destination = Utf8Path::new(target);
43-
if destination.exists() {
44-
return Ok(());
45-
}
47+
fn ensure_file(target: &str, template: &str, force: bool) -> Result<()> {
48+
let destination = Utf8Path::new(target);
49+
if destination.exists() {
50+
if force {
51+
write_template(destination, template)?;
52+
println!(" overwritten {}", destination);
53+
} else {
54+
println!(" skipped {}", destination);
55+
}
56+
return Ok(());
57+
}
4658

4759
write_template(destination, template)?;
4860
println!(" created {}", destination);

0 commit comments

Comments
 (0)