add run
command
This commit is contained in:
parent
af46e2a811
commit
a11529717c
27
Cargo.lock
generated
27
Cargo.lock
generated
@ -163,6 +163,8 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
|
"strum",
|
||||||
|
"strum_macros",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
@ -340,6 +342,12 @@ version = "0.1.24"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -386,6 +394,25 @@ version = "0.11.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.26.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum_macros"
|
||||||
|
version = "0.26.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustversion",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.87"
|
version = "2.0.87"
|
||||||
|
@ -9,3 +9,5 @@ anyhow = "1.0.93"
|
|||||||
tokio = { version = "1.10.0", features = ["full"] }
|
tokio = { version = "1.10.0", features = ["full"] }
|
||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
tracing-subscriber = "0.3.18"
|
tracing-subscriber = "0.3.18"
|
||||||
|
strum = "0.26.3"
|
||||||
|
strum_macros = "0.26.4"
|
||||||
|
26
src/cpgen/commands.rs
Normal file
26
src/cpgen/commands.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
use crate::lang::Language;
|
||||||
|
use clap::{Parser, Subcommand};
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
pub struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
|
pub command: Command,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand, Clone)]
|
||||||
|
pub enum Command {
|
||||||
|
Init {
|
||||||
|
#[arg(required = true)]
|
||||||
|
contest_urls: Vec<String>,
|
||||||
|
},
|
||||||
|
Gen {
|
||||||
|
#[arg(required = true)]
|
||||||
|
file_dirs: Vec<String>,
|
||||||
|
|
||||||
|
#[arg(short, long)]
|
||||||
|
language: Option<Language>,
|
||||||
|
},
|
||||||
|
Run {
|
||||||
|
file: String,
|
||||||
|
},
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
|
use crate::lang::Language;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use crate::lang::Language;
|
|
||||||
|
|
||||||
pub struct Generator {
|
pub struct Generator {
|
||||||
pub file_dirs: Vec<String>,
|
pub file_dirs: Vec<String>,
|
||||||
@ -18,11 +18,11 @@ impl Generator {
|
|||||||
for file_dir in &self.file_dirs {
|
for file_dir in &self.file_dirs {
|
||||||
tracing::info!("Generating files in {}", file_dir);
|
tracing::info!("Generating files in {}", file_dir);
|
||||||
|
|
||||||
let path = PathBuf::try_from(file_dir);
|
#[allow(clippy::unnecessary_fallible_conversions)]
|
||||||
match path {
|
match PathBuf::try_from(file_dir) {
|
||||||
Ok(file_dir) => {
|
Ok(file_dir) => {
|
||||||
generate(file_dir.to_str().unwrap(), &self.language)?;
|
generate(file_dir.to_str().unwrap(), &self.language)?;
|
||||||
},
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return Err(anyhow::anyhow!("Invalid path: {}", file_dir));
|
return Err(anyhow::anyhow!("Invalid path: {}", file_dir));
|
||||||
}
|
}
|
||||||
@ -39,14 +39,21 @@ struct InnerGenerator {
|
|||||||
impl InnerGenerator {
|
impl InnerGenerator {
|
||||||
fn new<T: AsRef<str>, S: AsRef<str>>(files: Vec<(T, S)>) -> Self {
|
fn new<T: AsRef<str>, S: AsRef<str>>(files: Vec<(T, S)>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
files: files.into_iter().map(|(t, s)| (t.as_ref().to_string(), s.as_ref().to_string())).collect(),
|
files: files
|
||||||
|
.into_iter()
|
||||||
|
.map(|(t, s)| (t.as_ref().to_string(), s.as_ref().to_string()))
|
||||||
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn run(self, dir_path: &str) -> anyhow::Result<()> {
|
fn run(self, dir_path: &str) -> anyhow::Result<()> {
|
||||||
for (file_name, content) in self.files {
|
for (file_name, content) in self.files {
|
||||||
let file_path = PathBuf::from(format!("{}/{}", dir_path, file_name));
|
let file_path = PathBuf::from(format!("{}/{}", dir_path, file_name));
|
||||||
|
|
||||||
std::fs::create_dir_all(file_path.parent().ok_or(anyhow::anyhow!("Invalid parent dir"))?)?;
|
std::fs::create_dir_all(
|
||||||
|
file_path
|
||||||
|
.parent()
|
||||||
|
.ok_or(anyhow::anyhow!("Invalid parent dir"))?,
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut file = std::fs::File::create(file_path)?;
|
let mut file = std::fs::File::create(file_path)?;
|
||||||
file.write_all(content.as_bytes())?;
|
file.write_all(content.as_bytes())?;
|
||||||
@ -56,11 +63,14 @@ impl InnerGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn generate(dir_path: &str, lang: &Language) -> anyhow::Result<()> {
|
fn generate(dir_path: &str, lang: &Language) -> anyhow::Result<()> {
|
||||||
let inner_gen = match lang {
|
let inner_gen = match lang {
|
||||||
Language::Cpp => {
|
Language::Cpp => {
|
||||||
let cpp_files = vec![crate::r#static::MAIN_CPP, crate::r#static::BITS, crate::r#static::DBG_H];
|
let cpp_files = vec![
|
||||||
|
crate::r#static::MAIN_CPP,
|
||||||
|
crate::r#static::BITS,
|
||||||
|
crate::r#static::DBG_H,
|
||||||
|
];
|
||||||
InnerGenerator::new(cpp_files)
|
InnerGenerator::new(cpp_files)
|
||||||
}
|
}
|
||||||
Language::Rust => {
|
Language::Rust => {
|
||||||
@ -70,4 +80,4 @@ fn generate(dir_path: &str, lang: &Language) -> anyhow::Result<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inner_gen.run(dir_path)
|
inner_gen.run(dir_path)
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
mod run;
|
|
||||||
mod commands;
|
mod commands;
|
||||||
mod gen;
|
mod gen;
|
||||||
|
mod run;
|
||||||
|
|
||||||
pub use run::*;
|
pub use run::*;
|
@ -1,16 +1,24 @@
|
|||||||
use crate::runner::commands::{Cli, Command};
|
use crate::cpgen::commands::{Cli, Command};
|
||||||
|
use crate::cpgen::gen::Generator;
|
||||||
|
use crate::runner::Runner;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use crate::runner::gen::Generator;
|
|
||||||
|
|
||||||
pub async fn run() -> anyhow::Result<()> {
|
pub async fn run() -> anyhow::Result<()> {
|
||||||
let cli: Cli = Cli::parse();
|
let cli: Cli = Cli::parse();
|
||||||
let command = cli.command;
|
let command = cli.command;
|
||||||
match command {
|
match command {
|
||||||
Command::Init { .. } => todo!(),
|
Command::Init { .. } => todo!(),
|
||||||
Command::Gen { file_dirs, language } => {
|
Command::Gen {
|
||||||
|
file_dirs,
|
||||||
|
language,
|
||||||
|
} => {
|
||||||
let generator = Generator::new(file_dirs, language);
|
let generator = Generator::new(file_dirs, language);
|
||||||
generator.generate()?;
|
generator.generate()?;
|
||||||
}
|
}
|
||||||
|
Command::Run { file } => {
|
||||||
|
let runner = Runner::new(file);
|
||||||
|
runner.run()?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
@ -1,8 +1,14 @@
|
|||||||
use clap::ValueEnum;
|
use clap::ValueEnum;
|
||||||
|
|
||||||
#[derive(ValueEnum, Default, Clone)]
|
#[derive(ValueEnum, Default, Clone, strum_macros::EnumIter, strum_macros::Display)]
|
||||||
pub enum Language {
|
pub enum Language {
|
||||||
#[default]
|
#[default]
|
||||||
Cpp,
|
Cpp,
|
||||||
Rust,
|
Rust,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Language {
|
||||||
|
pub fn extension(&self) -> String {
|
||||||
|
self.to_string().to_lowercase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
pub mod runner;
|
pub mod cpgen;
|
||||||
pub mod lang;
|
pub mod lang;
|
||||||
pub mod r#static;
|
pub mod r#static;
|
||||||
|
|
||||||
|
pub mod runner;
|
||||||
|
@ -11,7 +11,7 @@ fn init() -> anyhow::Result<()> {
|
|||||||
.enable_all()
|
.enable_all()
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
rt.block_on(cpgen::runner::run())
|
rt.block_on(cpgen::cpgen::run())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
54
src/runner.rs
Normal file
54
src/runner.rs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
use crate::lang::Language;
|
||||||
|
use std::process::Command;
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
|
pub struct Runner {
|
||||||
|
file_path: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Runner {
|
||||||
|
pub fn new(file: String) -> Self {
|
||||||
|
Self { file_path: file }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(self) -> anyhow::Result<()> {
|
||||||
|
let ext = self
|
||||||
|
.file_path
|
||||||
|
.split(".")
|
||||||
|
.last()
|
||||||
|
.ok_or(anyhow::anyhow!("No file extension"))?
|
||||||
|
.to_string();
|
||||||
|
let lang: Language = Language::iter()
|
||||||
|
.find(|lang| lang.extension() == ext)
|
||||||
|
.ok_or(anyhow::anyhow!("Unsupported file extension"))?;
|
||||||
|
|
||||||
|
let file_name = self
|
||||||
|
.file_path
|
||||||
|
.split("/")
|
||||||
|
.last()
|
||||||
|
.ok_or(anyhow::anyhow!("No file name"))?;
|
||||||
|
|
||||||
|
match lang {
|
||||||
|
Language::Cpp => {
|
||||||
|
Command::new("g++")
|
||||||
|
.arg(file_name)
|
||||||
|
.arg("-o")
|
||||||
|
.arg("main")
|
||||||
|
.arg("-DLOCAL")
|
||||||
|
.arg(&self.file_path)
|
||||||
|
.output()?;
|
||||||
|
}
|
||||||
|
Language::Rust => {
|
||||||
|
Command::new("rustc")
|
||||||
|
.arg(file_name)
|
||||||
|
.arg("--cfg")
|
||||||
|
.arg(r#"'feature="local"'"#)
|
||||||
|
.arg("-o")
|
||||||
|
.arg("main")
|
||||||
|
.output()?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -1,23 +0,0 @@
|
|||||||
use clap::{Parser, Subcommand};
|
|
||||||
use crate::lang::Language;
|
|
||||||
|
|
||||||
#[derive(Parser)]
|
|
||||||
pub struct Cli {
|
|
||||||
#[command(subcommand)]
|
|
||||||
pub command: Command,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Subcommand, Clone)]
|
|
||||||
pub enum Command {
|
|
||||||
Init {
|
|
||||||
#[arg(required = true)]
|
|
||||||
contest_urls: Vec<String>,
|
|
||||||
},
|
|
||||||
Gen {
|
|
||||||
#[arg(required = true)]
|
|
||||||
file_dirs: Vec<String>,
|
|
||||||
|
|
||||||
#[arg(short, long)]
|
|
||||||
language: Option<Language>,
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,10 +1,7 @@
|
|||||||
/// CPP
|
/// CPP
|
||||||
pub const MAIN_CPP: (&'static str, &'static str) = ("main.cpp", include_str!("../cpp/main.cpp"));
|
pub const MAIN_CPP: (&str, &str) = ("main.cpp", include_str!("../cpp/main.cpp"));
|
||||||
pub const DBG_H: (&'static str, &'static str) = ("debug.h", include_str!("../cpp/dbg.h"));
|
pub const DBG_H: (&str, &str) = ("debug.h", include_str!("../cpp/dbg.h"));
|
||||||
pub const BITS: (&'static str, &'static str) = ("bits/stdc++.h", include_str!("../cpp/bits/stdc++.h"));
|
pub const BITS: (&str, &str) = ("bits/stdc++.h", include_str!("../cpp/bits/stdc++.h"));
|
||||||
pub const CPP_CMD: &'static str = r#"g++ main.cpp -o main -DLOCAL"#;
|
|
||||||
|
|
||||||
|
|
||||||
/// Rust
|
/// Rust
|
||||||
pub const MAIN_RS: (&'static str, &'static str) = ("main.rs", include_str!("../rust/main.rs"));
|
pub const MAIN_RS: (&str, &str) = ("main.rs", include_str!("../rust/main.rs"));
|
||||||
pub const RS_CMD: &'static str = r#"rustc main.rs --cfg 'feature="local"'"#;
|
|
||||||
|
Loading…
Reference in New Issue
Block a user