From a57dc03660c6dcc8bcdd41fdcd773d14c42fe1f8 Mon Sep 17 00:00:00 2001 From: Kris Stasik Date: Thu, 6 Jan 2022 16:42:19 -0500 Subject: [PATCH] Ubercompiler binary --- lib/data-compiler/src/compiler_api.rs | 15 +++++-- lib/data-compiler/src/compiler_cmd.rs | 6 ++- server/ubercompiler/Cargo.toml | 6 +++ server/ubercompiler/src/main.rs | 64 +++++++++++++++++++++++++++ server/ubercompiler/tests/tests.rs | 49 ++++++++++++++++++++ 5 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 server/ubercompiler/src/main.rs create mode 100644 server/ubercompiler/tests/tests.rs diff --git a/lib/data-compiler/src/compiler_api.rs b/lib/data-compiler/src/compiler_api.rs index 49eee66d49..925aaf19fe 100644 --- a/lib/data-compiler/src/compiler_api.rs +++ b/lib/data-compiler/src/compiler_api.rs @@ -538,19 +538,26 @@ enum Commands { /// /// > **NOTE**: Data compiler must not write to stdout because this could break /// the specific output that is expected. -// TODO: remove the limitation above. pub fn compiler_main( args: env::Args, descriptor: &'static CompilerDescriptor, +) -> Result<(), CompilerError> { + let compilers = CompilerRegistryOptions::default().add_compiler(descriptor); + + multi_compiler_main(args, compilers) +} + +/// Same as `compiler_main` but supports many compilers in a single binary. +pub fn multi_compiler_main( + args: env::Args, + compilers: CompilerRegistryOptions, ) -> Result<(), CompilerError> { let args = Cli::try_parse_from(args).map_err(|err| { eprintln!("{}", err); CompilerError::InvalidArgs })?; - let compilers = CompilerRegistryOptions::default() - .add_compiler(descriptor) - .create(); + let compilers = compilers.create(); let result = run(args.command, &compilers); if let Err(error) = &result { diff --git a/lib/data-compiler/src/compiler_cmd.rs b/lib/data-compiler/src/compiler_cmd.rs index 00a0dd9fe8..c963cadd95 100644 --- a/lib/data-compiler/src/compiler_cmd.rs +++ b/lib/data-compiler/src/compiler_cmd.rs @@ -178,7 +178,7 @@ impl CommandBuilder { // /// Output of `compiler_info` command. -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug)] pub struct CompilerInfoCmdOutput(Vec); impl CompilerInfoCmdOutput { @@ -188,7 +188,9 @@ impl CompilerInfoCmdOutput { pub(crate) fn from_bytes(bytes: &[u8]) -> Option { serde_json::from_slice(bytes).ok()? } - pub(crate) fn take(self) -> Vec { + + /// Converts the the output to a list of `CompilerInfo`. + pub fn take(self) -> Vec { self.0 } } diff --git a/server/ubercompiler/Cargo.toml b/server/ubercompiler/Cargo.toml index 1233b0a682..5b689bc489 100644 --- a/server/ubercompiler/Cargo.toml +++ b/server/ubercompiler/Cargo.toml @@ -8,6 +8,12 @@ license = "MIT OR Apache-2.0" [lib] doc = false + +[[bin]] +name = "compiler-ubercompiler" +path = "src/main.rs" +doc = false + [dependencies] lgn-data-offline = { path = "../../lib/data-offline" } lgn-data-runtime = { path = "../../lib/data-runtime" } diff --git a/server/ubercompiler/src/main.rs b/server/ubercompiler/src/main.rs new file mode 100644 index 0000000000..c0b2f1bf7e --- /dev/null +++ b/server/ubercompiler/src/main.rs @@ -0,0 +1,64 @@ +// BEGIN - Legion Labs lints v0.6 +// do not change or add/remove here, but one can add exceptions after this +// section +#![deny(unsafe_code)] +#![warn(future_incompatible, nonstandard_style, rust_2018_idioms)] +// Rustdoc lints +#![warn( + rustdoc::broken_intra_doc_links, + rustdoc::missing_crate_level_docs, + rustdoc::private_intra_doc_links +)] +// Clippy pedantic lints, treat all as warnings by default, add exceptions in allow list +#![warn(clippy::pedantic)] +#![allow( + clippy::cast_possible_truncation, + clippy::cast_sign_loss, + clippy::if_not_else, + clippy::items_after_statements, + clippy::missing_panics_doc, + clippy::module_name_repetitions, + clippy::must_use_candidate, + clippy::similar_names, + clippy::shadow_unrelated, + clippy::unreadable_literal, + clippy::unseparated_literal_suffix +)] +// Clippy nursery lints, still under development +#![warn( + clippy::debug_assert_with_mut_call, + clippy::disallowed_method, + clippy::disallowed_type, + clippy::fallible_impl_from, + clippy::imprecise_flops, + clippy::mutex_integer, + clippy::path_buf_push_overwrite, + clippy::string_lit_as_bytes, + clippy::use_self, + clippy::useless_transmute +)] +// Clippy restriction lints, usually not considered bad, but useful in specific cases +#![warn( + clippy::dbg_macro, + clippy::exit, + clippy::float_cmp_const, + clippy::map_err_ignore, + clippy::mem_forget, + clippy::missing_enforced_import_renames, + clippy::rest_pat_in_fully_bound_structs, + clippy::string_to_string, + clippy::todo, + clippy::unimplemented, + clippy::verbose_file_reads +)] +// END - Legion Labs lints v0.6 +// crate-specific exceptions: +#![allow()] + +use std::env; + +use lgn_data_compiler::compiler_api::{multi_compiler_main, CompilerError}; + +fn main() -> Result<(), CompilerError> { + multi_compiler_main(env::args(), lgn_ubercompiler::create()) +} diff --git a/server/ubercompiler/tests/tests.rs b/server/ubercompiler/tests/tests.rs new file mode 100644 index 0000000000..711c4bf75a --- /dev/null +++ b/server/ubercompiler/tests/tests.rs @@ -0,0 +1,49 @@ +use lgn_data_compiler::{compiler_api::CompilationEnv, compiler_cmd, Locale, Platform, Target}; + +static UBERCOMPILER_EXE: &str = env!("CARGO_BIN_EXE_compiler-ubercompiler"); + +#[test] +fn test() { + // list all compiler info. + let info_output = { + let info_cmd = lgn_data_compiler::compiler_cmd::CompilerInfoCmd::default(); + let info_output = info_cmd + .execute(UBERCOMPILER_EXE) + .expect("valid output") + .take(); + + assert!(info_output.len() > 1); + info_output + }; + + let env = CompilationEnv { + target: Target::Game, + platform: Platform::Windows, + locale: Locale::new("en"), + }; + + // get hashes for all compilers + { + let all_hash_cmd = compiler_cmd::CompilerHashCmd::new(&env, None); + + let all_hash_output = all_hash_cmd + .execute(UBERCOMPILER_EXE) + .expect("valid output"); + + assert!(all_hash_output.compiler_hash_list.len() >= info_output.len()); + } + + // get hash of a single selected transform + { + let selected_transform = info_output[0].transform; + let single_hash_cmd = compiler_cmd::CompilerHashCmd::new(&env, Some(selected_transform)); + let single_hash_output = single_hash_cmd + .execute(UBERCOMPILER_EXE) + .expect("valid output"); + + assert!(!single_hash_output.compiler_hash_list.is_empty()); + for (transform, _) in single_hash_output.compiler_hash_list { + assert_eq!(transform, selected_transform); + } + } +}