Skip to content
This repository has been archived by the owner on Aug 3, 2023. It is now read-only.

Fixes #58 - Auto increment for default name #469

Merged
merged 5 commits into from
May 1, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 62 additions & 4 deletions src/commands/generate/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::ffi::OsString;
use std::path::PathBuf;
use std::process::Command;
use std::{env, fs};

use crate::commands::validate_worker_name;
use crate::settings::toml::{Manifest, Site, TargetType};
Expand All @@ -13,8 +15,30 @@ pub fn generate(
) -> Result<(), failure::Error> {
validate_worker_name(name)?;

log::info!("Generating a new worker project with name '{}'", name);
run_generate(name, template)?;
let dirname_exists = match directory_exists(name) {
Ok(val) => val,
Err(_) => true,
};

let new_name: String;

if dirname_exists {
new_name = match generate_name(name) {
Ok(val) => val,
Err(_) => {
log::debug!(
"Failed to auto-increment name for a new worker project, using '{}'",
name
);
String::from(name)
}
};
} else {
new_name = String::from(name);
}

log::info!("Generating a new worker project with name '{}'", new_name);
run_generate(&new_name, template)?;

let config_path = PathBuf::from("./").join(&name);
// TODO: this is tightly coupled to our site template. Need to remove once
Expand All @@ -24,7 +48,7 @@ pub fn generate(
} else {
None
};
Manifest::generate(name.to_string(), target_type, &config_path, generated_site)?;
Manifest::generate(new_name, target_type, &config_path, generated_site)?;

Ok(())
}
Expand All @@ -37,10 +61,44 @@ pub fn run_generate(name: &str, template: &str) -> Result<(), failure::Error> {

let command = command(binary_path, &args);
let command_name = format!("{:?}", command);

commands::run(command, &command_name)
}

fn generate_name(name: &str) -> Result<String, failure::Error> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it is worth adding some comments here to establish the convention.

let mut num = 1;
let entry_names = read_current_dir()?;
let mut new_name = construct_name(&name, num);

while entry_names.contains(&OsString::from(&new_name)) {
num = num + 1;
new_name = construct_name(&name, num);
}
Ok(new_name)
}

fn read_current_dir() -> Result<Vec<OsString>, failure::Error> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would also suggest passing the name in and only returning colliding directories.

let current_dir = env::current_dir()?;
let mut entry_names = Vec::new();

for entry in fs::read_dir(current_dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
entry_names.push(entry.file_name());
}
}
Ok(entry_names)
}

fn directory_exists(dirname: &str) -> Result<bool, failure::Error> {
let entry_names = read_current_dir()?;
Ok(entry_names.contains(&OsString::from(dirname)))
}

fn construct_name(name: &str, num: i32) -> String {
format!("{}-{}", name, num)
}

fn command(binary_path: PathBuf, args: &[&str]) -> Command {
let mut c = if cfg!(target_os = "windows") {
let mut c = Command::new("cmd");
Expand Down