From 98b8d0378ff05ea5b9fe3d3d20507e99fb117ddb Mon Sep 17 00:00:00 2001 From: Janis Date: Thu, 29 Jun 2023 16:25:31 +0200 Subject: [PATCH] sdk-builder: main function does stuff --- sdk-builder/Cargo.toml | 3 +- sdk-builder/src/main.rs | 108 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 101 insertions(+), 10 deletions(-) diff --git a/sdk-builder/Cargo.toml b/sdk-builder/Cargo.toml index e3f387f..8489e11 100644 --- a/sdk-builder/Cargo.toml +++ b/sdk-builder/Cargo.toml @@ -14,4 +14,5 @@ itertools = "0.11.0" unreal-sdk = {path = "../unreal-sdk"} quote = "1.0.28" -proc-macro2 = "1.0.60" \ No newline at end of file +proc-macro2 = "1.0.60" +clap = { version = "4.3.9", features = ["derive"] } diff --git a/sdk-builder/src/main.rs b/sdk-builder/src/main.rs index 9a37561..5f6b0b4 100644 --- a/sdk-builder/src/main.rs +++ b/sdk-builder/src/main.rs @@ -1,9 +1,50 @@ -use std::{borrow::Cow, collections::BTreeMap}; +use std::{borrow::Cow, collections::BTreeMap, path::PathBuf}; -use unreal_sdk::sdk::repr::ObjectRef; +use clap::{Args, Parser, Subcommand}; +use unreal_sdk::sdk::repr::{ObjectRef, Sdk}; -fn main() { +use crate::rust::Builder; + +#[derive(Parser)] +#[command(author, version, about, long_about = None)] +pub struct Cli { + #[command(subcommand)] + commands: Option, +} + +#[derive(Args)] +pub struct Build { + #[arg(short, long)] + in_archive: PathBuf, + /// directory into which the sdk will be dumped. + #[arg(short, long)] + out: Option, + #[arg(short, long, default_value = "false")] + single_file: bool, + #[arg(short, long, default_value = "true")] + feature_gate: bool, +} + +#[derive(Subcommand)] +pub enum Commands { + Build(Build), +} + +fn main() -> anyhow::Result<()> { println!("Hello, world!"); + + let cli = Cli::parse(); + + if let Some(Commands::Build(build)) = &cli.commands { + let sdk = Sdk::from_path_ron(&build.in_archive)?; + let builder = Builder::new(sdk); + + let path = build.out.clone().unwrap_or(std::env::current_dir()?); + + builder.build_in_dir(path, build)?; + } + + Ok(()) } struct SplitResult<'a> { @@ -97,9 +138,10 @@ pub struct CanonicalNames { } pub mod rust { - use std::{borrow::Cow, collections::BTreeMap}; + use std::{borrow::Cow, collections::BTreeMap, path::Path}; use anyhow::Context; + use itertools::Itertools; use proc_macro2::TokenStream; use quote::{format_ident, quote}; use unreal_sdk::sdk::repr::{ @@ -170,11 +212,18 @@ pub mod rust { } /// returns the absolute path of a type with the assumption that all - /// packages are children of the path `::crate::sdk` + /// packages are children of the path `crate::sdk` + fn get_type_package_path(&self, key: &ObjectRef) -> Option { + let pkg = &self.sdk.packages.get(&key.package)?.name; + Some(format!("crate::sdk::{pkg}")) + } + + /// returns the absolute path of a type with the assumption that all + /// packages are children of the path `crate::sdk` fn get_type_path(&self, key: &ObjectRef) -> Option { let pkg = &self.sdk.packages.get(&key.package)?.name; self.get_type_name(key) - .map(|name| format!("::crate::sdk::{pkg}::{name}")) + .map(|name| format!("crate::sdk::{pkg}::{name}")) } /// returns the precached, prefixed and cannonicalized (for this @@ -201,11 +250,52 @@ pub mod rust { } } - pub fn build(self) -> anyhow::Result<()> { - for pkg in self.sdk.packages.values() { - self.generate_package(pkg)?; + pub fn build(self, args: &super::Build) -> anyhow::Result> { + let packages = self + .sdk + .packages + .values() + .map(|pkg| { + let name = pkg.name.clone(); + let tokens = self.generate_package(pkg, args.feature_gate)?; + + anyhow::Ok((name, tokens)) + }) + .collect::, _>>()?; + + Ok(packages) + } + + pub fn build_in_dir>( + self, + path: P, + args: &super::Build, + ) -> anyhow::Result<()> { + let packages = self.build(args)?; + + let path = path.as_ref(); + std::fs::create_dir_all(&path)?; + + let mut mod_rs = TokenStream::new(); + + for (name, tokens) in packages { + if args.single_file { + mod_rs.extend(quote! { + pub mod #name { + #tokens + } + }); + } else { + std::fs::write(path.join(format!("{name}.rs")), tokens.to_string())?; + + mod_rs.extend(quote! { + pub mod #name; + }); + } } + std::fs::write(path.join("mod.rs"), mod_rs.to_string())?; + Ok(()) }