diff --git a/compiler/plc_driver/src/cli.rs b/compiler/plc_driver/src/cli.rs index 9c6676bf68..8d2f31febb 100644 --- a/compiler/plc_driver/src/cli.rs +++ b/compiler/plc_driver/src/cli.rs @@ -196,11 +196,33 @@ pub enum SubCommands { )] build_config: Option, }, + + /// Prints out various configuration options + Config { + #[clap( + name = "config-format", + group = "config", + default_value = "json", + help = "Format of the configuration file, if supported" + )] + format: ConfigFormat, + + #[clap(subcommand)] + option: ConfigOption, + }, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Subcommand)] +pub enum ConfigOption { + #[clap(help = "Prints the plc.json schema used for validation")] + Schema, } impl SubCommands { pub fn get_build_configuration(&self) -> Option<&str> { - let (SubCommands::Build { build_config, .. } | SubCommands::Check { build_config }) = self; + let (SubCommands::Build { build_config, .. } | SubCommands::Check { build_config }) = self else { + return None; + }; build_config.as_deref() } } @@ -319,6 +341,13 @@ impl CompileParameters { _ => None, } } + + pub fn get_config_options(&self) -> Option<(ConfigOption, ConfigFormat)> { + let Some(SubCommands::Config { format, option }) = &self.commands else { + return None + }; + Some((*option, *format)) + } } #[cfg(test)] diff --git a/compiler/plc_driver/src/lib.rs b/compiler/plc_driver/src/lib.rs index 13914421eb..8d1ec68602 100644 --- a/compiler/plc_driver/src/lib.rs +++ b/compiler/plc_driver/src/lib.rs @@ -122,6 +122,9 @@ impl Display for CompileError { pub fn compile + AsRef + Debug>(args: &[T]) -> Result<()> { //Parse the arguments let compile_parameters = CompileParameters::parse(args)?; + if let Some((options, format)) = compile_parameters.get_config_options() { + return print_config_options(options, format); + } let project = get_project(&compile_parameters)?; let output_format = compile_parameters.output_format().unwrap_or_else(|| project.get_output_format()); let location = project.get_location().map(|it| it.to_path_buf()); @@ -205,6 +208,20 @@ pub fn compile + AsRef + Debug>(args: &[T]) -> Result<()> { Ok(()) } +fn print_config_options( + option: cli::ConfigOption, + _format: plc::ConfigFormat, +) -> std::result::Result<(), anyhow::Error> { + match option { + cli::ConfigOption::Schema => { + let schema = include_str!("../../plc_project/schema/plc-json.schema"); + println!("{schema}"); + } + }; + + Ok(()) +} + /// Parses and annotates a given project. Can be used in tests or api calls pub fn parse_and_annotate( name: &str, diff --git a/compiler/plc_project/src/build_config.rs b/compiler/plc_project/src/build_config.rs index 63c0a1ee9f..fd7a7dacf0 100644 --- a/compiler/plc_project/src/build_config.rs +++ b/compiler/plc_project/src/build_config.rs @@ -84,41 +84,9 @@ impl ProjectConfig { Ok(project) } - fn get_schema() -> Result { - let current_exe_dir = - std::env::current_exe()?.parent().map(|it| it.to_path_buf()).unwrap_or_default(); - let schema_dir = current_exe_dir.join("schema"); - #[cfg(feature = "integration")] - //Fallback to the build location - let schema_dir = if !&schema_dir.exists() { - let project_dir: PathBuf = env!("CARGO_MANIFEST_DIR").into(); - project_dir.join("schema") - } else { - schema_dir - }; - let path = schema_dir.join("plc-json.schema"); - if !path.exists() { - Err(std::io::Error::new( - std::io::ErrorKind::NotFound, - format!("{}: File not found", path.to_string_lossy()), - ) - .into()) - } else { - Ok(path) - } - } - fn validate(&self) -> Result<()> { - let schema_path = match Self::get_schema() { - Ok(path) => path, - Err(error) => { - eprintln!("Could not find schema, validation skipped. Original error: {error:?}"); - //Skip validation but do not fail - return Ok(()); - } - }; - let schema = fs::read_to_string(schema_path).map_err(Diagnostic::from)?; - let schema_obj = serde_json::from_str(&schema).expect("A valid schema"); + let schema = include_str!("../schema/plc-json.schema"); + let schema_obj = serde_json::from_str(schema).expect("A valid schema"); let compiled = JSONSchema::compile(&schema_obj).expect("A valid schema"); let instance = json!(self); compiled.validate(&instance).map_err(|errors| {