From b9b35f3f0f9f5d627e7ad69e4fb62fc02b5b8f43 Mon Sep 17 00:00:00 2001 From: Shea Frembling Date: Sun, 22 Mar 2026 11:16:14 -0500 Subject: [PATCH] initial commit --- .gitignore | 1 + Cargo.lock | 301 +++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 10 ++ README.md | 20 +++ src/app.rs | 112 ++++++++++++++++ src/config.rs | 49 +++++++ src/main.rs | 9 ++ src/templates/main.c | 7 + 8 files changed, 509 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 src/app.rs create mode 100644 src/config.rs create mode 100644 src/main.rs create mode 100644 src/templates/main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..822128f --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,301 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", +] + +[[package]] +name = "clap" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "pallet" +version = "0.1.0" +dependencies = [ + "clap", + "glob", + "serde", + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +dependencies = [ + "serde_core", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "toml" +version = "1.0.7+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd28d57d8a6f6e458bc0b8784f8fdcc4b99a437936056fa122cb234f18656a96" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.0.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b320e741db58cac564e26c607d3cc1fdc4a88fd36c879568c07856ed83ff3e9" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.0.10+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.0.7+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17aaa1c6e3dc22b1da4b6bba97d066e354c7945cac2f7852d4e4e7ca7a6b56d" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..7751c89 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "pallet" +version = "0.1.0" +edition = "2024" + +[dependencies] +clap = { version = "4.6.0", features = ["derive"] } +glob = "0.3.3" +serde = { version = "1.0.228", features = ["derive"] } +toml = "1.0.7" diff --git a/README.md b/README.md new file mode 100644 index 0000000..66ca656 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# Pallet + +Pallet is a project manager and build system for C inspired by Cargo for Rust. + +This is a toy project not meant to be taken very seriously. + +## Usage + +- `pallet new `: initializes a new project at `project` +- `pallet init`: initializes a new project in the current directory +- `pallet run`: runs the local project +- `pallet build`: builds the local project + +## Configuring + +You can configure options by editing `Pallet.toml` + +### Options + +TBD diff --git a/src/app.rs b/src/app.rs new file mode 100644 index 0000000..25e7227 --- /dev/null +++ b/src/app.rs @@ -0,0 +1,112 @@ +use std::{ + env::set_current_dir, + path::{Path, PathBuf}, +}; + +const MAIN_C: &str = include_str!("templates/main.c"); + +#[derive(clap::Parser)] +pub struct App { + #[clap(subcommand)] + command: Subcommand, +} + +#[derive(clap::Subcommand)] +enum Subcommand { + /// Create a new C project + New { + /// The name of the new project + name: String, + }, + /// Initialize a new C project + Init, + /// Run the local project + Run { + /// The build mode to use + mode: Option, + }, + /// Build the local project + Build { + /// The build mode to use + mode: Option, + }, +} + +impl App { + pub fn run(self) { + match self.command { + Subcommand::New { name } => match create_project(&name) { + Ok(_) => println!("Successfully created new project '{name}'."), + Err(e) => { + eprintln!("Error creating project '{name}': {e}"); + std::process::exit(1); + } + }, + Subcommand::Init => match create_project(".") { + Ok(_) => println!("Successfully initialized new project."), + Err(e) => { + eprintln!("Error initializing project: {e}"); + std::process::exit(1); + } + }, + Subcommand::Run { mode } => todo!(), + Subcommand::Build { mode } => todo!(), + } + } +} + +fn create_project>(directory: P) -> std::io::Result<()> { + let pathdir = directory.as_ref(); + + if pathdir.exists() && pathdir.to_string_lossy() != "." { + return Err(std::io::Error::new( + std::io::ErrorKind::AlreadyExists, + "specified directory already exists", + )); + } + + if !pathdir.exists() && pathdir.to_string_lossy() != "." { + std::fs::create_dir(pathdir)?; + } + + set_current_dir(pathdir)?; + + std::fs::create_dir("src")?; + + std::fs::write("src/main.c", MAIN_C)?; + + let config = crate::config::Config::new(&pathdir.to_string_lossy()); + + let serial = toml::to_string_pretty(&config).expect("a valid TOML structure"); + + std::fs::write("Pallet.toml", &serial)?; + + Ok(()) +} + +fn get_config() -> Option { + let p = PathBuf::from("Pallet.toml"); + if !p.exists() { + return None; + } + let raw = std::fs::read_to_string(&p).expect("A valid config file"); + + toml::from_str(&raw).ok() +} + +fn build(mode: Option) -> std::io::Result<()> { + let conf = match get_config() { + Some(conf) => conf, + None => { + eprintln!("Error opening config file. No Pallet.toml in current directory."); + std::process::exit(1); + } + }; + + let build_config = conf.get_or_default(mode).ok_or(std::io::Error::new( + std::io::ErrorKind::NotFound, + "build layout not found", + ))?; + + todo!() +} diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..b0534fc --- /dev/null +++ b/src/config.rs @@ -0,0 +1,49 @@ +#[derive(serde::Deserialize, serde::Serialize)] +pub struct Config { + /// The name of the output binary + pub name: String, + /// The default build to use + pub default_build: String, + /// Build configs + pub build: Vec, +} + +impl Config { + pub fn new(name: &str) -> Self { + Self { + name: name.to_owned(), + default_build: "debug".to_owned(), + build: vec![BuildConf::debug(), BuildConf::release()], + } + } + + pub fn get_or_default(&self, mode: Option) -> Option<&BuildConf> { + if let Some(mode) = mode { + self.build.iter().find(|bc| bc.name == mode) + } else { + self.build.iter().find(|bc| bc.name == self.default_build) + } + } +} + +#[derive(serde::Deserialize, serde::Serialize)] +pub struct BuildConf { + pub name: String, + pub args: Vec, +} + +impl BuildConf { + fn debug() -> Self { + Self { + name: "debug".to_owned(), + args: vec!["-g".to_owned(), "-O0".to_owned()], + } + } + + fn release() -> Self { + Self { + name: "release".to_owned(), + args: vec!["-DNDEBUG".to_owned(), "-O3".to_owned()], + } + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..4baf039 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,9 @@ +use clap::Parser; + +mod app; +mod config; + +fn main() { + let app = app::App::parse(); + app.run(); +} diff --git a/src/templates/main.c b/src/templates/main.c new file mode 100644 index 0000000..1089a12 --- /dev/null +++ b/src/templates/main.c @@ -0,0 +1,7 @@ +#include + +int main() { + printf("Hello, world!\n"); + + return 0; +}