Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat: init new git repo for new projects #558

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
6 changes: 5 additions & 1 deletion crates/tuono/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ enum Actions {
/// Load the latest commit available on the main branch
#[arg(long)]
head: Option<bool>,
/// Initialize a new Git repository in the specified directory
#[arg(short, long)]
git_init: Option<bool>,
},
}

Expand Down Expand Up @@ -154,8 +157,9 @@ pub fn app() -> std::io::Result<()> {
folder_name,
template,
head,
git_init,
} => {
scaffold_project::create_new_project(folder_name, template, head);
scaffold_project::create_new_project(folder_name, template, head, git_init);
}
}

Expand Down
40 changes: 40 additions & 0 deletions crates/tuono/src/scaffold_project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::env;
use std::fs::{self, create_dir, File, OpenOptions};
use std::io::{self, prelude::*};
use std::path::{Path, PathBuf};
use std::process::Command;

const GITHUB_TUONO_TAGS_URL: &str = "https://api.github.com/repos/tuono-labs/tuono/git/ref/tags/";

Expand Down Expand Up @@ -66,9 +67,20 @@ pub fn create_new_project(
folder_name: Option<String>,
template: Option<String>,
select_head: Option<bool>,
git_init: Option<bool>,
) {
let folder = folder_name.unwrap_or(".".to_string());

let is_git_installed = is_git_installed();

// Check if Git is installed when the user requests to use it; otherwise, continue
if git_init.unwrap_or(false) && !is_git_installed {
exit_with_error("You requested to use Git, but it is not installed.")
}

// Use git by default
let git = git_init.unwrap_or(true) && is_git_installed;

// In case of missing select the tuono example
let template = template.unwrap_or("tuono-app".to_string());
let client = blocking::Client::builder()
Expand Down Expand Up @@ -151,6 +163,12 @@ pub fn create_new_project(

update_package_json_version(&folder_path).expect("Failed to update package.json version");
update_cargo_toml_version(&folder_path).expect("Failed to update Cargo.toml version");

if git {
init_new_git_repo(&folder_path)
.unwrap_or_else(|_| exit_with_error("Failed to initialise a new git repo"));
}

outro(folder);
}

Expand Down Expand Up @@ -245,6 +263,28 @@ fn update_cargo_toml_version(folder_path: &Path) -> io::Result<()> {
Ok(())
}

fn is_git_installed() -> bool {
let output = Command::new("git").arg("--version").output();

output.is_ok()
}

fn init_new_git_repo(folder_path: &Path) -> Result<(), io::Error> {
let output = Command::new("git").arg("init").arg(folder_path).output()?;

if output.status.success() {
Ok(())
} else {
Err(io::Error::new(
io::ErrorKind::Other,
format!(
"Git init failed: {}",
String::from_utf8_lossy(&output.stderr)
),
))
}
}

fn outro(folder_name: String) {
println!("Success! 🎉");

Expand Down
73 changes: 73 additions & 0 deletions crates/tuono/tests/cli_new.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
mod utils;
use assert_cmd::Command;
use serial_test::serial;
use utils::TempTuonoProject;

#[test]
#[serial]
fn it_inits_new_git_repo_by_default_with_git_installed() {
let temp_tuono_project = TempTuonoProject::new();

std::env::set_current_dir(temp_tuono_project.path()).unwrap();

let mut test_tuono_new = Command::cargo_bin("tuono").unwrap();
test_tuono_new.arg("new").arg(".").assert().success();

// Ensure the `.git` directory exists
assert!(temp_tuono_project.path().join(".git").exists());
}

#[test]
#[serial]
fn it_does_not_init_new_git_repo_with_git_false() {
let temp_tuono_project = TempTuonoProject::new();

std::env::set_current_dir(temp_tuono_project.path()).unwrap();

let mut test_tuono_new = Command::cargo_bin("tuono").unwrap();
test_tuono_new
.arg("new")
.arg(".")
.arg("--git-init=false")
.assert()
.success();

// Ensure the `.git` directory does not exist
assert!(!temp_tuono_project.path().join(".git").exists());
}

#[test]
#[serial]
fn it_creates_project_without_git_if_not_installed() {
let temp_tuono_project = TempTuonoProject::new();

std::env::set_current_dir(temp_tuono_project.path()).unwrap();

let mut test_tuono_new = Command::cargo_bin("tuono").unwrap();
test_tuono_new
.arg("new")
.arg(".")
.env("PATH", "") // Simulate git not being installed
.assert()
.success();

assert!(!temp_tuono_project.path().join(".git").exists());
}

#[test]
#[serial]
fn it_errors_if_git_not_installed_and_flag_set() {
let temp_tuono_project = TempTuonoProject::new();

std::env::set_current_dir(temp_tuono_project.path()).unwrap();

let mut test_tuono_new = Command::cargo_bin("tuono").unwrap();
test_tuono_new
.arg("new")
.arg(".")
.arg("--git-init=true")
.env("PATH", "") // Simulate git not being installed
.assert()
.failure()
.stderr("You requested to use Git, but it is not installed.\n");
}
Loading