Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

finish build new template project #54

Merged
Show file tree
Hide file tree
Changes from 1 commit
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
23 changes: 22 additions & 1 deletion zork++/src/bin/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use std::{fs::File, io::Read, path::Path};

use clap::Parser;
use env_logger::Target;
use zork::{config_cli::CliArgs, utils::logger::config_logger};
use zork::{
config_cli::{CliArgs, CppCompiler},
config_file::ZorkConfigFile,
utils::{logger::config_logger, template::create_template_project},
};

fn main() {
let parser_cli = CliArgs::parse_from([""]);
Expand All @@ -10,4 +16,19 @@ fn main() {
log::warn!("warn");
log::info!("info");
log::error!("error");

create_template_project(&Some("proyect".to_owned()), true, &Some(CppCompiler::CLANG));
Copy link
Member

Choose a reason for hiding this comment

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

You are passing default useless values. Remove then from the call site (here) or explictly pass a valid reference to the parser_cli args


let path_file = Path::new("example").join("zork.conf");

let mut file_conf = File::open(path_file).unwrap();

let mut buffer: String = String::new();
file_conf
.read_to_string(&mut buffer)
.expect("Error read file");

let zork_config: Result<ZorkConfigFile, toml::de::Error> = toml::from_str(&buffer);

println!("{:?}", zork_config);
}
5 changes: 0 additions & 5 deletions zork++/src/lib/config_cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ pub struct CliArgs {

#[arg(short, long, group = "base_option", help = "Create Project template")]
pub new_template: Option<String>,
#[arg(
long,
help = "To generate a C++ modules project or a classical one with headers, can you use with template project"
)]
pub legacy: bool,
#[arg(
long,
help = "Initializes a new local git repo, can you use with template project"
Expand Down
2 changes: 1 addition & 1 deletion zork++/src/lib/config_file/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use self::{
/// ZorkConfigFile,
/// compiler::CppCompiler
/// };
///
///
/// const CONFIG_FILE_MOCK: &str = r#"
/// [project]
/// name = 'Zork++ serde tests'
Expand Down
1 change: 1 addition & 0 deletions zork++/src/lib/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod logger;
pub mod template;
199 changes: 199 additions & 0 deletions zork++/src/lib/utils/template.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
use crate::config_cli::CppCompiler;
use log::info;
use std::io::Write;
use std::path::PathBuf;
use std::process::Command;
use std::str::FromStr;
use std::{
fs::{DirBuilder, File},
path::Path,
};

/// Generates a new C++ standarized empty base project
/// with a pre-designed structure to organize the
/// user code in a modern fashion way.
/// Base design for create the project files and folders:
/// - ./ifc/<project_name>
/// - hello_zork.<mod_extension>
/// - ./src/<project_name>
/// - hello_zork.cpp
/// - test
/// - dependencies
pub fn create_template_project(
name_template: &Option<String>,
git: bool,
compiler: &Option<CppCompiler>,
) {
// TODO required validate or control optionals
info!("Create template project");
let name = name_template.as_deref().unwrap_or("calculator");
Copy link
Member

Choose a reason for hiding this comment

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

Review the lines 29-32. There's no need to dereference the option

Copy link
Member Author

Choose a reason for hiding this comment

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

Its solved

let resolved_compiler = compiler.clone().unwrap_or(CppCompiler::CLANG); // Deref ??? and not clone?
Copy link
Member

@TheRustifyer TheRustifyer Dec 31, 2022

Choose a reason for hiding this comment

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

There's no need to clone. Also, there's no need to pass the Optionals there as references. Move the values (ie, pass by value)

Copy link
Member Author

Choose a reason for hiding this comment

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

It is solved we required CppCompiler use Clone because ValueEnum hasnt implementarios Copy trait


let root_path = Path::new("example");
let path_ifc = root_path.join("ifc");
let path_src = root_path.join("src");
let path_test = root_path.join("test");
let path_dependencies = root_path.join("dependencies");

create_directory(root_path);
create_directory(&path_ifc);
create_directory(&path_src);
create_directory(&path_test);
create_directory(&path_dependencies);

let extension_ifcs = match resolved_compiler {
CppCompiler::CLANG => "cppm",
CppCompiler::MSVC => "ixx",
CppCompiler::GCC => "ixx",
};
create_file(
&path_ifc,
format!("{}.{}", "math", extension_ifcs).as_str(),
INTERFACE_MOD_FILE,
);
create_file(&path_src, "main.cpp", MAIN.as_bytes());
create_file(&path_src, "math.cpp", SRC_MOD_FILE.as_bytes());
create_file(&path_src, "math2.cpp", SRC_MOD_FILE_2.as_bytes());

let mut zork_conf = ZORK_CONF
.replace("<project_name>", name)
.replace("<autog_test>", name)
.replace("<autogenerated_executable>", name);

if cfg!(windows) {
zork_conf = zork_conf.replace("libcpp", "stdlib")
}
create_file(
&PathBuf::from_str(root_path.to_str().unwrap())
Copy link
Member

Choose a reason for hiding this comment

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

Replace raw .unwrap() for .expect(msg), or better use if let pattern in these situations

.expect("Not valid path to generate zork.conf"),
"zork.conf",
zork_conf.as_bytes(),
);

if git {
let result_git_init = Command::new("git")
.current_dir(&root_path)
.arg("init")
.spawn();

match result_git_init {
Ok(_children) => {
log::info!("Created git repository")
}
Err(_) => {
log::error!("Error create git respotory")
}
}
}
}

const INTERFACE_MOD_FILE: &'static [u8] = "
export module math;
export namespace math {
int sum(int num1, int num2);
int multiply(int num1, int num2);
int substract(int num1, int num2);
int divide(int num1, int num2);
}
"
.as_bytes();

const SRC_MOD_FILE: &'static str = "
Copy link
Member

Choose a reason for hiding this comment

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

It's usually a code smell anotate the lifetime of const or static string slices. They are always static, as they are stored directly in the generated binary. Remove the 'static lifetimes of those const declarations

module math;
// Implementation of the definitions on the module unit interface
// for the sum and multiply math operations
namespace math {
int sum(int num1, int num2) {
return num1 + num2;
}
int multiply(int num1, int num2) {
return num1 * num2;
}
}
";

const SRC_MOD_FILE_2: &'static str = "
Copy link
Member

Choose a reason for hiding this comment

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

MOVE all the str slices to it's own file, ie: constants.rs or simillar

module math;
// Implementation of the definitions on the module unit interface
// for the substract and divide math operations
namespace math {
int substract(int num1, int num2) {
return num1 - num2;
}
int divide(int num1, int num2) {
return num1 / num2;
}
}
";

const MAIN: &'static str = r#"
import std;
import math;
int main() {
std::cout << "Hello from an autogenerated Zork project!" << std::endl;
std::cout << "RESULT '+': " << math::sum(2, 8) << std::endl;
std::cout << "RESULT '-': " << math::substract(8, 2) << std::endl;
std::cout << "RESULT '*': " << math::multiply(2, 8) << std::endl;
std::cout << "RESULT '/': " << math::divide(2, 2) << std::endl;
return 0;
}
"#;

const ZORK_CONF: &'static str = r#"
#This file it's autogenerated as an example of a Zork config file
[project]
name = "calculator"
authors = [ "Zero Day Code" ] # Replace this for the real authors
[compiler]
cpp_compiler = "clang"
cpp_standard = "20"
std_lib = "libcpp"
[build]
output_dir = "./out"
[executable]
executable_name = "<autogenerated_executable>"
sources = [
"*.cpp"
]
auto_execute = true
[tests]
tests_executable_name = "zork_proj_tests"
sources = [
"*.cpp"
]
auto_run_tests = true
[modules]
base_ifcs_dir = "<project_name>/ifc/"
interfaces = [ "*.cppm" ]
base_impls_dir = "<project_name>/src/"
implementations = [
"math.cpp",
"math2.cpp=[math]"
]
"#;

fn create_file<'a>(path: &PathBuf, name_file: &'a str, buff_write: &'a [u8]) {
let mut file = File::create(path.join(name_file)).expect(
format!(
"Error create in directory: {}, file: {}",
path.to_str().unwrap(),
name_file
)
.as_str(),
);
file.write_all(buff_write).expect(
format!(
"Error write in directory: {}, file: {}",
path.to_str().unwrap(),
name_file
)
.as_str(),
);
}

fn create_directory(path_create: &Path) {
DirBuilder::new()
.recursive(true)
.create(path_create)
.expect(format!("Error create directory: {}", path_create.to_string_lossy()).as_str())
Copy link
Member

Choose a reason for hiding this comment

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

Error create directory => `Error create directory

Copy link
Member

Choose a reason for hiding this comment

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

.to_string_lossy(). Try to use one of the UTF-8 alternatives to mantain consistency across the whole API

}
Empty file added zork++/zork.conf
Empty file.