From 048088ac2098c793b733a6e3fb883f9c92df888e Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Thu, 1 Feb 2024 16:20:06 -0500 Subject: [PATCH 01/23] refactor input and input file commands as subcommands --- dsc/src/args.rs | 59 ++++++++++++++++++++++++++++-------- dsc/tests/dsc_args.tests.ps1 | 6 ++-- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/dsc/src/args.rs b/dsc/src/args.rs index c3920d14a..1dc48e111 100644 --- a/dsc/src/args.rs +++ b/dsc/src/args.rs @@ -36,14 +36,10 @@ pub struct Args { /// The output format to use #[clap(short = 'o', long)] pub format: Option, - #[clap(short = 'i', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] - pub input: Option, - #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] - pub input_file: Option, #[clap(short = 'l', long, help = "Trace level to use", value_enum, default_value = "warning")] pub trace_level: TraceLevel, #[clap(short = 'f', long, help = "Trace format to use", value_enum, default_value = "default")] - pub trace_format: TraceFormat, + pub trace_format: TraceFormat } #[derive(Debug, PartialEq, Eq, Subcommand)] @@ -77,15 +73,40 @@ pub enum SubCommand { #[derive(Debug, PartialEq, Eq, Subcommand)] pub enum ConfigSubCommand { #[clap(name = "get", about = "Retrieve the current configuration")] - Get, + Get { + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + document: Option, + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + path: Option, + }, #[clap(name = "set", about = "Set the current configuration")] - Set, + Set { + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + document: Option, + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + path: Option, + }, #[clap(name = "test", about = "Test the current configuration")] - Test, + Test { + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + document: Option, + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + path: Option, + }, #[clap(name = "validate", about = "Validate the current configuration", hide = true)] - Validate, + Validate { + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + document: Option, + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + path: Option, + }, #[clap(name = "export", about = "Export the current configuration")] - Export + Export { + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + document: Option, + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + path: Option, + } } #[derive(Debug, PartialEq, Eq, Subcommand)] @@ -106,21 +127,33 @@ pub enum ResourceSubCommand { #[clap(short, long, help = "The name or DscResource JSON of the resource to invoke `get` on")] resource: String, #[clap(short, long, help = "The input to pass to the resource as JSON")] - input: Option, + json: Option, + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + data: Option, + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + path: Option, }, #[clap(name = "set", about = "Invoke the set operation to a resource", arg_required_else_help = true)] Set { #[clap(short, long, help = "The name or DscResource JSON of the resource to invoke `set` on")] resource: String, #[clap(short, long, help = "The input to pass to the resource as JSON")] - input: Option, + json: Option, + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + data: Option, + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + path: Option, }, #[clap(name = "test", about = "Invoke the test operation to a resource", arg_required_else_help = true)] Test { #[clap(short, long, help = "The name or DscResource JSON of the resource to invoke `test` on")] resource: String, #[clap(short, long, help = "The input to pass to the resource as JSON")] - input: Option, + json: Option, + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + data: Option, + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + path: Option, }, #[clap(name = "schema", about = "Get the JSON schema for a resource", arg_required_else_help = true)] Schema { diff --git a/dsc/tests/dsc_args.tests.ps1 b/dsc/tests/dsc_args.tests.ps1 index 339191d42..3881d0949 100644 --- a/dsc/tests/dsc_args.tests.ps1 +++ b/dsc/tests/dsc_args.tests.ps1 @@ -114,7 +114,7 @@ resources: family: Windows '@ - $out = dsc $parameter "$yaml" config get | ConvertFrom-Json + $out = dsc config get $parameter "$yaml" | ConvertFrom-Json $LASTEXITCODE | Should -Be 0 $out.results[0].type | Should -BeExactly 'Microsoft/OSInfo' } @@ -135,13 +135,13 @@ resources: '@ Set-Content -Path $TestDrive/foo.yaml -Value $yaml - $out = dsc $parameter "$TestDrive/foo.yaml" config get | ConvertFrom-Json + $out = dsc config get $parameter "$TestDrive/foo.yaml" | ConvertFrom-Json $LASTEXITCODE | Should -Be 0 $out.results[0].type | Should -BeExactly 'Microsoft/OSInfo' } It '--input and --input-file cannot be used together' { - dsc --input 1 --input-file foo.json config get 2> $TestDrive/error.txt + dsc config get 2 --input 1 --input-file foo.json > $TestDrive/error.txt $err = Get-Content $testdrive/error.txt -Raw $err.Length | Should -Not -Be 0 $LASTEXITCODE | Should -Be 2 From a0aa9e815fa809c9b7ecb49ab391028ea6aef244 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Thu, 1 Feb 2024 16:22:26 -0500 Subject: [PATCH 02/23] refactor config and resource methods with input subcommands --- dsc/src/args.rs | 44 ++++++++++++-------------- dsc/src/main.rs | 14 +-------- dsc/src/resource_command.rs | 60 +++++------------------------------- dsc/src/subcommand.rs | 58 +++++++++++++---------------------- dsc/src/util.rs | 61 ++++++++++++++++++++++++++++++++++++- 5 files changed, 109 insertions(+), 128 deletions(-) diff --git a/dsc/src/args.rs b/dsc/src/args.rs index 1dc48e111..f43c7dad1 100644 --- a/dsc/src/args.rs +++ b/dsc/src/args.rs @@ -74,37 +74,37 @@ pub enum SubCommand { pub enum ConfigSubCommand { #[clap(name = "get", about = "Retrieve the current configuration")] Get { - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "path")] document: Option, - #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource", conflicts_with = "document")] path: Option, }, #[clap(name = "set", about = "Set the current configuration")] Set { - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "path")] document: Option, - #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource", conflicts_with = "document")] path: Option, }, #[clap(name = "test", about = "Test the current configuration")] Test { - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "path")] document: Option, - #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource", conflicts_with = "document")] path: Option, }, #[clap(name = "validate", about = "Validate the current configuration", hide = true)] Validate { - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "path")] document: Option, - #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource", conflicts_with = "document")] path: Option, }, #[clap(name = "export", about = "Export the current configuration")] Export { - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] + #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "path")] document: Option, - #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource", conflicts_with = "document")] path: Option, } } @@ -126,33 +126,27 @@ pub enum ResourceSubCommand { all: bool, #[clap(short, long, help = "The name or DscResource JSON of the resource to invoke `get` on")] resource: String, - #[clap(short, long, help = "The input to pass to the resource as JSON")] - json: Option, - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] - data: Option, - #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + #[clap(short, long, help = "The input to pass to the resource as JSON or YAML", conflicts_with = "path")] + input: Option, + #[clap(short = 'p', long, help = "The path to a JSON or YAML file used as input to the configuration or resource", conflicts_with = "input")] path: Option, }, #[clap(name = "set", about = "Invoke the set operation to a resource", arg_required_else_help = true)] Set { #[clap(short, long, help = "The name or DscResource JSON of the resource to invoke `set` on")] resource: String, - #[clap(short, long, help = "The input to pass to the resource as JSON")] - json: Option, - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] - data: Option, - #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + #[clap(short, long, help = "The input to pass to the resource as JSON or YAML", conflicts_with = "path")] + input: Option, + #[clap(short = 'p', long, help = "The path to a JSON or YAML file used as input to the configuration or resource", conflicts_with = "input")] path: Option, }, #[clap(name = "test", about = "Invoke the test operation to a resource", arg_required_else_help = true)] Test { #[clap(short, long, help = "The name or DscResource JSON of the resource to invoke `test` on")] resource: String, - #[clap(short, long, help = "The input to pass to the resource as JSON")] - json: Option, - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "input_file")] - data: Option, - #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource")] + #[clap(short, long, help = "The input to pass to the resource as JSON or YAML", conflicts_with = "path")] + input: Option, + #[clap(short = 'p', long, help = "The path to a JSON or YAML file used as input to the configuration or resource", conflicts_with = "input")] path: Option, }, #[clap(name = "schema", about = "Get the JSON schema for a resource", arg_required_else_help = true)] diff --git a/dsc/src/main.rs b/dsc/src/main.rs index 5eafb4e24..24dee9162 100644 --- a/dsc/src/main.rs +++ b/dsc/src/main.rs @@ -35,19 +35,7 @@ fn main() { debug!("Running dsc {}", env!("CARGO_PKG_VERSION")); - let input = if args.input.is_some() { - args.input - } else if args.input_file.is_some() { - info!("Reading input from file {}", args.input_file.as_ref().unwrap()); - let input_file = args.input_file.unwrap(); - match std::fs::read_to_string(input_file) { - Ok(input) => Some(input), - Err(err) => { - error!("Error: Failed to read input file: {err}"); - exit(util::EXIT_INVALID_INPUT); - } - } - } else if atty::is(Stream::Stdin) { + let input = if atty::is(Stream::Stdin) { None } else { info!("Reading input from STDIN"); diff --git a/dsc/src/resource_command.rs b/dsc/src/resource_command.rs index bb18008c9..d0da3a7bd 100644 --- a/dsc/src/resource_command.rs +++ b/dsc/src/resource_command.rs @@ -2,7 +2,7 @@ // Licensed under the MIT License. use crate::args::OutputFormat; -use crate::util::{EXIT_DSC_ERROR, EXIT_INVALID_ARGS, EXIT_JSON_ERROR, add_type_name_to_json, write_output}; +use crate::util::{add_type_name_to_json, write_output, EXIT_DSC_ERROR, EXIT_INVALID_ARGS, EXIT_JSON_ERROR, get_input}; use dsc_lib::configure::config_doc::Configuration; use dsc_lib::configure::add_resource_export_results_to_configuration; use dsc_lib::dscresources::invoke_result::GetResult; @@ -15,9 +15,9 @@ use dsc_lib::{ }; use std::process::exit; -pub fn get(dsc: &DscManager, resource_type: &str, input: &Option, stdin: &Option, format: &Option) { +pub fn get(dsc: &DscManager, resource_type: &str, input: &Option, stdin: &Option, path: &Option, format: &Option) { // TODO: support streaming stdin which includes resource and input - let mut input = get_input(input, stdin); + let mut input = get_input(input, stdin, path).to_string(); let Some(mut resource) = get_resource(dsc, resource_type) else { error!("{}", DscError::ResourceNotFound(resource_type.to_string()).to_string()); @@ -54,7 +54,7 @@ pub fn get(dsc: &DscManager, resource_type: &str, input: &Option, stdin: } } -pub fn get_all(dsc: &DscManager, resource_type: &str, _input: &Option, _stdin: &Option, format: &Option) { +pub fn get_all(dsc: &DscManager, resource_type: &str, _input: &Option, _stdin: &Option, _path: &Option, format: &Option) { let Some(resource) = get_resource(dsc, resource_type) else { error!("{}", DscError::ResourceNotFound(resource_type.to_string()).to_string()); return @@ -91,8 +91,8 @@ pub fn get_all(dsc: &DscManager, resource_type: &str, _input: &Option, _ /// /// Will panic if provider-based resource is not found. /// -pub fn set(dsc: &DscManager, resource_type: &str, input: &Option, stdin: &Option, format: &Option) { - let mut input = get_input(input, stdin); +pub fn set(dsc: &DscManager, resource_type: &str, input: &Option, stdin: &Option, path: &Option, format: &Option) { + let mut input = get_input(input, stdin, path).to_string(); if input.is_empty() { error!("Error: Input is empty"); exit(EXIT_INVALID_ARGS); @@ -140,8 +140,8 @@ pub fn set(dsc: &DscManager, resource_type: &str, input: &Option, stdin: /// /// Will panic if provider-based resource is not found. /// -pub fn test(dsc: &DscManager, resource_type: &str, input: &Option, stdin: &Option, format: &Option) { - let mut input = get_input(input, stdin); +pub fn test(dsc: &DscManager, resource_type: &str, input: &Option, stdin: &Option, path: &Option, format: &Option) { + let mut input = get_input(input, stdin, path).to_string(); let Some(mut resource) = get_resource(dsc, resource_type) else { error!("{}", DscError::ResourceNotFound(resource_type.to_string()).to_string()); return @@ -230,47 +230,3 @@ pub fn get_resource<'a>(dsc: &'a DscManager, resource: &str) -> Option<&'a DscRe //TODO: add dinamically generated resource to dsc dsc.find_resource(String::from(resource).to_lowercase().as_str()) } - -fn get_input(input: &Option, stdin: &Option) -> String { - let input = match (input, stdin) { - (Some(_input), Some(_stdin)) => { - error!("Error: Cannot specify both --input and stdin"); - exit(EXIT_INVALID_ARGS); - } - (Some(input), None) => input.clone(), - (None, Some(stdin)) => stdin.clone(), - (None, None) => { - return String::new(); - }, - }; - - if input.is_empty() { - return String::new(); - } - - match serde_json::from_str::(&input) { - Ok(_) => input, - Err(json_err) => { - match serde_yaml::from_str::(&input) { - Ok(yaml) => { - match serde_json::to_string(&yaml) { - Ok(json) => json, - Err(err) => { - error!("Error: Cannot convert YAML to JSON: {err}"); - exit(EXIT_INVALID_ARGS); - } - } - }, - Err(err) => { - if input.contains('{') { - error!("Error: Input is not valid JSON: {json_err}"); - } - else { - error!("Error: Input is not valid YAML: {err}"); - } - exit(EXIT_INVALID_ARGS); - } - } - } - } -} diff --git a/dsc/src/subcommand.rs b/dsc/src/subcommand.rs index a269ebca5..4068b8fd7 100644 --- a/dsc/src/subcommand.rs +++ b/dsc/src/subcommand.rs @@ -4,7 +4,7 @@ use crate::args::{ConfigSubCommand, DscType, OutputFormat, ResourceSubCommand}; use crate::resource_command::{get_resource, self}; use crate::tablewriter::Table; -use crate::util::{EXIT_DSC_ERROR, EXIT_INVALID_ARGS, EXIT_INVALID_INPUT, EXIT_JSON_ERROR, EXIT_SUCCESS, EXIT_VALIDATION_FAILED, get_schema, serde_json_value_to_string, write_output}; +use crate::util::{EXIT_DSC_ERROR, EXIT_INVALID_INPUT, EXIT_JSON_ERROR, EXIT_SUCCESS, EXIT_VALIDATION_FAILED, get_schema, serde_json_value_to_string, write_output, get_input}; use tracing::error; use atty::Stream; @@ -117,33 +117,17 @@ pub fn config_export(configurator: &mut Configurator, format: &Option, format: &Option, stdin: &Option) { - let Some(stdin) = stdin else { - error!("Configuration must be piped to STDIN"); - exit(EXIT_INVALID_ARGS); - }; - - let json: serde_json::Value = match serde_json::from_str(stdin.as_ref()) { - Ok(json) => json, - Err(_) => { - match serde_yaml::from_str::(stdin.as_ref()) { - Ok(yaml) => { - match serde_json::to_value(yaml) { - Ok(json) => json, - Err(err) => { - error!("Error: Failed to convert YAML to JSON: {err}"); - exit(EXIT_DSC_ERROR); - } - } - }, - Err(err) => { - error!("Error: Input is not valid JSON or YAML: {err}"); - exit(EXIT_INVALID_INPUT); - } - } + let json_string = match subcommand { + ConfigSubCommand::Get { document, path } | + ConfigSubCommand::Set { document, path } | + ConfigSubCommand::Test { document, path } | + ConfigSubCommand::Validate { document, path } | + ConfigSubCommand::Export { document, path } => { + let json = get_input(document, stdin, path); + serde_json_value_to_string(&json) } }; - let json_string = serde_json_value_to_string(&json); let mut configurator = match Configurator::new(&json_string) { Ok(configurator) => configurator, Err(err) => { @@ -184,19 +168,19 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option, format } match subcommand { - ConfigSubCommand::Get => { + ConfigSubCommand::Get { .. } => { config_get(&mut configurator, format); }, - ConfigSubCommand::Set => { + ConfigSubCommand::Set { ..} => { config_set(&mut configurator, format); }, - ConfigSubCommand::Test => { + ConfigSubCommand::Test { .. } => { config_test(&mut configurator, format); }, - ConfigSubCommand::Validate => { + ConfigSubCommand::Validate { .. } => { validate_config(&json_string); }, - ConfigSubCommand::Export => { + ConfigSubCommand::Export { .. }=> { config_export(&mut configurator, format); } } @@ -411,20 +395,20 @@ pub fn resource(subcommand: &ResourceSubCommand, format: &Option, table.print(); } }, - ResourceSubCommand::Get { resource, input, all } => { + ResourceSubCommand::Get { resource, input, path, all } => { dsc.discover_resources(&[resource.to_lowercase().to_string()]); - if *all { resource_command::get_all(&dsc, resource, input, stdin, format); } + if *all { resource_command::get_all(&dsc, resource, input, stdin, path, format); } else { - resource_command::get(&dsc, resource, input, stdin, format); + resource_command::get(&dsc, resource, input, stdin, path, format); }; }, - ResourceSubCommand::Set { resource, input } => { + ResourceSubCommand::Set { resource, input, path } => { dsc.discover_resources(&[resource.to_lowercase().to_string()]); - resource_command::set(&dsc, resource, input, stdin, format); + resource_command::set(&dsc, resource, input, stdin, path, format); }, - ResourceSubCommand::Test { resource, input } => { + ResourceSubCommand::Test { resource, input, path } => { dsc.discover_resources(&[resource.to_lowercase().to_string()]); - resource_command::test(&dsc, resource, input, stdin, format); + resource_command::test(&dsc, resource, input, stdin, path, format); }, ResourceSubCommand::Schema { resource } => { dsc.discover_resources(&[resource.to_lowercase().to_string()]); diff --git a/dsc/src/util.rs b/dsc/src/util.rs index be9106df2..acf216f21 100644 --- a/dsc/src/util.rs +++ b/dsc/src/util.rs @@ -17,6 +17,7 @@ use dsc_lib::{ } }; use schemars::{schema_for, schema::RootSchema}; +use serde_yaml::Value; use std::collections::HashMap; use std::process::exit; use syntect::{ @@ -25,7 +26,7 @@ use syntect::{ parsing::SyntaxSet, util::{as_24_bit_terminal_escaped, LinesWithEndings} }; -use tracing::{Level, error}; +use tracing::{Level, error, info}; use tracing_subscriber::{filter::EnvFilter, layer::SubscriberExt, Layer}; pub const EXIT_SUCCESS: i32 = 0; @@ -288,3 +289,61 @@ pub fn enable_tracing(trace_level: &TraceLevel, trace_format: &TraceFormat) { eprintln!("Unable to set global default tracing subscriber. Tracing is diabled."); } } + +pub fn parse_input_to_json(value: &str) -> serde_json::Value { + match serde_json::from_str(value) { + Ok(json) => json, + Err(_) => { + match serde_yaml::from_str::(value) { + Ok(yaml) => { + match serde_json::to_value(yaml) { + Ok(json) => json, + Err(err) => { + error!("Error: Failed to convert YAML to JSON: {err}"); + exit(EXIT_DSC_ERROR); + } + } + }, + Err(err) => { + error!("Error: Input is not valid JSON or YAML: {err}"); + exit(EXIT_INVALID_INPUT); + } + } + } + } +} + +pub fn get_input(input: &Option, stdin: &Option, path: &Option) -> serde_json::Value { + let value = match (input, stdin, path) { + (None, Some(_), Some(_)) | (Some(_), Some(_), None) => { + error!("Error: Cannot specify both stdin and --input or --path"); + exit(EXIT_INVALID_ARGS); + } + (Some(input), None, None) => input.clone(), + (None, Some(stdin), None) => stdin.clone(), + (None, None, Some(path)) => { + info!("Reading input from file {}", path); + match std::fs::read_to_string(path) { + Ok(input) => input.clone(), + Err(err) => { + error!("Error: Failed to read input file: {err}"); + exit(EXIT_INVALID_INPUT); + } + } + }, + (None, None, None) => { + return serde_json::Value::String(String::new()); + }, + _default => { + /* clap should handle these cases via conflicts_with so this should not get reached */ + error!("Error: Invalid input"); + exit(EXIT_INVALID_ARGS); + } + }; + + if value.is_empty() { + return serde_json::Value::String(String::new()); + } + + parse_input_to_json(&value) +} \ No newline at end of file From 2387e5507dc9a979caa6aa685885ed36d03adcf6 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Thu, 1 Feb 2024 16:22:58 -0500 Subject: [PATCH 03/23] fix typo --- dsc/src/args.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsc/src/args.rs b/dsc/src/args.rs index f43c7dad1..3acc7f933 100644 --- a/dsc/src/args.rs +++ b/dsc/src/args.rs @@ -39,7 +39,7 @@ pub struct Args { #[clap(short = 'l', long, help = "Trace level to use", value_enum, default_value = "warning")] pub trace_level: TraceLevel, #[clap(short = 'f', long, help = "Trace format to use", value_enum, default_value = "default")] - pub trace_format: TraceFormat + pub trace_format: TraceFormat, } #[derive(Debug, PartialEq, Eq, Subcommand)] From bb889966410e379e7fd34a99aa72498d02c5183f Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Thu, 1 Feb 2024 16:26:06 -0500 Subject: [PATCH 04/23] fix formatting --- dsc/src/resource_command.rs | 2 +- dsc/src/util.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dsc/src/resource_command.rs b/dsc/src/resource_command.rs index d0da3a7bd..4aa6a80e0 100644 --- a/dsc/src/resource_command.rs +++ b/dsc/src/resource_command.rs @@ -2,7 +2,7 @@ // Licensed under the MIT License. use crate::args::OutputFormat; -use crate::util::{add_type_name_to_json, write_output, EXIT_DSC_ERROR, EXIT_INVALID_ARGS, EXIT_JSON_ERROR, get_input}; +use crate::util::{EXIT_DSC_ERROR, EXIT_INVALID_ARGS, EXIT_JSON_ERROR, add_type_name_to_json, write_output, get_input}; use dsc_lib::configure::config_doc::Configuration; use dsc_lib::configure::add_resource_export_results_to_configuration; use dsc_lib::dscresources::invoke_result::GetResult; diff --git a/dsc/src/util.rs b/dsc/src/util.rs index acf216f21..e10f0eb4c 100644 --- a/dsc/src/util.rs +++ b/dsc/src/util.rs @@ -346,4 +346,4 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option Date: Fri, 2 Feb 2024 12:48:32 -0500 Subject: [PATCH 05/23] fix tests --- dsc/tests/dsc_args.tests.ps1 | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/dsc/tests/dsc_args.tests.ps1 b/dsc/tests/dsc_args.tests.ps1 index 3881d0949..3445f656f 100644 --- a/dsc/tests/dsc_args.tests.ps1 +++ b/dsc/tests/dsc_args.tests.ps1 @@ -85,7 +85,7 @@ actualState: ) { param($format, $expected) - $out = dsc --format $format resource get -r Test/Hello | Out-String + $out = dsc --format $format -l debug resource get -r Test/Hello | Out-String $LASTEXITCODE | Should -Be 0 $out.Trim() | Should -BeExactly $expected } @@ -100,8 +100,8 @@ actualState: } It 'input can be passed using ' -TestCases @( - @{ parameter = '-i' } - @{ parameter = '--input' } + @{ parameter = '-d' } + @{ parameter = '--document' } ) { param($parameter) @@ -121,7 +121,7 @@ resources: It 'input can be passed using ' -TestCases @( @{ parameter = '-p' } - @{ parameter = '--input-file' } + @{ parameter = '--path' } ) { param($parameter) @@ -140,16 +140,17 @@ resources: $out.results[0].type | Should -BeExactly 'Microsoft/OSInfo' } - It '--input and --input-file cannot be used together' { - dsc config get 2 --input 1 --input-file foo.json > $TestDrive/error.txt + It '--document and --path cannot be used together' { + dsc config get 2 --document 1 --path foo.json > $TestDrive/error.txt $err = Get-Content $testdrive/error.txt -Raw $err.Length | Should -Not -Be 0 $LASTEXITCODE | Should -Be 2 } - It '--logging-level has effect' { - dsc -l debug resource get -r Microsoft/OSInfo 2> $TestDrive/tracing.txt - "$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'DEBUG' + It '--trace-level has effect' { + # 2> $TestDrive/tracing.txt + dsc -l debug resource get -r Microsoft/OSInfo + #"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'DEBUG' $LASTEXITCODE | Should -Be 0 } } From efff8dcbf9ee26119f478803e161a23896f432d9 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Fri, 2 Feb 2024 13:53:09 -0500 Subject: [PATCH 06/23] fix tests --- dsc/src/resource_command.rs | 6 +++--- dsc/src/subcommand.rs | 5 ++--- dsc/src/util.rs | 11 ++++++----- dsc/tests/dsc_args.tests.ps1 | 9 ++++----- dsc/tests/dsc_parameters.tests.ps1 | 2 +- 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/dsc/src/resource_command.rs b/dsc/src/resource_command.rs index 4aa6a80e0..2ea6186a6 100644 --- a/dsc/src/resource_command.rs +++ b/dsc/src/resource_command.rs @@ -17,7 +17,7 @@ use std::process::exit; pub fn get(dsc: &DscManager, resource_type: &str, input: &Option, stdin: &Option, path: &Option, format: &Option) { // TODO: support streaming stdin which includes resource and input - let mut input = get_input(input, stdin, path).to_string(); + let mut input = get_input(input, stdin, path); let Some(mut resource) = get_resource(dsc, resource_type) else { error!("{}", DscError::ResourceNotFound(resource_type.to_string()).to_string()); @@ -92,7 +92,7 @@ pub fn get_all(dsc: &DscManager, resource_type: &str, _input: &Option, _ /// Will panic if provider-based resource is not found. /// pub fn set(dsc: &DscManager, resource_type: &str, input: &Option, stdin: &Option, path: &Option, format: &Option) { - let mut input = get_input(input, stdin, path).to_string(); + let mut input = get_input(input, stdin, path); if input.is_empty() { error!("Error: Input is empty"); exit(EXIT_INVALID_ARGS); @@ -141,7 +141,7 @@ pub fn set(dsc: &DscManager, resource_type: &str, input: &Option, stdin: /// Will panic if provider-based resource is not found. /// pub fn test(dsc: &DscManager, resource_type: &str, input: &Option, stdin: &Option, path: &Option, format: &Option) { - let mut input = get_input(input, stdin, path).to_string(); + let mut input = get_input(input, stdin, path); let Some(mut resource) = get_resource(dsc, resource_type) else { error!("{}", DscError::ResourceNotFound(resource_type.to_string()).to_string()); return diff --git a/dsc/src/subcommand.rs b/dsc/src/subcommand.rs index 4068b8fd7..d9e222c88 100644 --- a/dsc/src/subcommand.rs +++ b/dsc/src/subcommand.rs @@ -4,7 +4,7 @@ use crate::args::{ConfigSubCommand, DscType, OutputFormat, ResourceSubCommand}; use crate::resource_command::{get_resource, self}; use crate::tablewriter::Table; -use crate::util::{EXIT_DSC_ERROR, EXIT_INVALID_INPUT, EXIT_JSON_ERROR, EXIT_SUCCESS, EXIT_VALIDATION_FAILED, get_schema, serde_json_value_to_string, write_output, get_input}; +use crate::util::{EXIT_DSC_ERROR, EXIT_INVALID_INPUT, EXIT_JSON_ERROR, EXIT_SUCCESS, EXIT_VALIDATION_FAILED, get_schema, write_output, get_input}; use tracing::error; use atty::Stream; @@ -123,8 +123,7 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option, format ConfigSubCommand::Test { document, path } | ConfigSubCommand::Validate { document, path } | ConfigSubCommand::Export { document, path } => { - let json = get_input(document, stdin, path); - serde_json_value_to_string(&json) + get_input(document, stdin, path) } }; diff --git a/dsc/src/util.rs b/dsc/src/util.rs index e10f0eb4c..d4c8c6fa4 100644 --- a/dsc/src/util.rs +++ b/dsc/src/util.rs @@ -290,14 +290,14 @@ pub fn enable_tracing(trace_level: &TraceLevel, trace_format: &TraceFormat) { } } -pub fn parse_input_to_json(value: &str) -> serde_json::Value { +pub fn parse_input_to_json(value: &str) -> String { match serde_json::from_str(value) { Ok(json) => json, Err(_) => { match serde_yaml::from_str::(value) { Ok(yaml) => { match serde_json::to_value(yaml) { - Ok(json) => json, + Ok(json) => json.to_string(), Err(err) => { error!("Error: Failed to convert YAML to JSON: {err}"); exit(EXIT_DSC_ERROR); @@ -313,7 +313,7 @@ pub fn parse_input_to_json(value: &str) -> serde_json::Value { } } -pub fn get_input(input: &Option, stdin: &Option, path: &Option) -> serde_json::Value { +pub fn get_input(input: &Option, stdin: &Option, path: &Option) -> String { let value = match (input, stdin, path) { (None, Some(_), Some(_)) | (Some(_), Some(_), None) => { error!("Error: Cannot specify both stdin and --input or --path"); @@ -332,7 +332,8 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option { - return serde_json::Value::String(String::new()); + info!("returning from here in get_input"); + return String::new(); }, _default => { /* clap should handle these cases via conflicts_with so this should not get reached */ @@ -342,7 +343,7 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option $TestDrive/error.txt + dsc config get --document 1 --path foo.json 2> $TestDrive/error.txt $err = Get-Content $testdrive/error.txt -Raw $err.Length | Should -Not -Be 0 $LASTEXITCODE | Should -Be 2 } It '--trace-level has effect' { - # 2> $TestDrive/tracing.txt - dsc -l debug resource get -r Microsoft/OSInfo - #"$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'DEBUG' + dsc -l debug resource get -r Microsoft/OSInfo 2> $TestDrive/tracing.txt + "$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'DEBUG' $LASTEXITCODE | Should -Be 0 } } diff --git a/dsc/tests/dsc_parameters.tests.ps1 b/dsc/tests/dsc_parameters.tests.ps1 index 7a77866d2..29829aac5 100644 --- a/dsc/tests/dsc_parameters.tests.ps1 +++ b/dsc/tests/dsc_parameters.tests.ps1 @@ -248,7 +248,7 @@ Describe 'Parameters tests' { family: '[parameters(''osFamily'')]' '@ - $out = dsc -i $config_yaml config -p $params test | ConvertFrom-Json + $out = dsc config -p $params test -d $config_yaml | ConvertFrom-Json $LASTEXITCODE | Should -Be 0 $out.results[0].result.actualState.family | Should -BeExactly $os $out.results[0].result.inDesiredState | Should -BeTrue From 2e5e1bd56e0eb28b6638f871e35a30372031b4b1 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Fri, 2 Feb 2024 14:00:57 -0500 Subject: [PATCH 07/23] add tests for multiple input sources --- dsc/tests/dsc_args.tests.ps1 | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/dsc/tests/dsc_args.tests.ps1 b/dsc/tests/dsc_args.tests.ps1 index e0081d4cf..86acc5c42 100644 --- a/dsc/tests/dsc_args.tests.ps1 +++ b/dsc/tests/dsc_args.tests.ps1 @@ -147,6 +147,27 @@ resources: $LASTEXITCODE | Should -Be 2 } + It 'stdin and --document cannot be used together' { + '{ "foo": true }' | dsc config get --document 1 2> $TestDrive/error.txt + $err = Get-Content $testdrive/error.txt -Raw + $err.Length | Should -Not -Be 0 + $LASTEXITCODE | Should -Be 1 + } + + It 'stdin and --path cannot be used together' { + '{ "foo": true }' | dsc config get --path foo.json 2> $TestDrive/error.txt + $err = Get-Content $testdrive/error.txt -Raw + $err.Length | Should -Not -Be 0 + $LASTEXITCODE | Should -Be 1 + } + + It 'stdin, --document and --path cannot be used together' { + '{ "foo": true }' | dsc config get --document 1 --path foo.json 2> $TestDrive/error.txt + $err = Get-Content $testdrive/error.txt -Raw + $err.Length | Should -Not -Be 0 + $LASTEXITCODE | Should -Be 2 + } + It '--trace-level has effect' { dsc -l debug resource get -r Microsoft/OSInfo 2> $TestDrive/tracing.txt "$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'DEBUG' From cff852506d59433fa75e408e172332b248d21daf Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Fri, 2 Feb 2024 14:58:53 -0500 Subject: [PATCH 08/23] fix typo --- dsc/src/util.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dsc/src/util.rs b/dsc/src/util.rs index d4c8c6fa4..afab1a39b 100644 --- a/dsc/src/util.rs +++ b/dsc/src/util.rs @@ -318,7 +318,7 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option { error!("Error: Cannot specify both stdin and --input or --path"); exit(EXIT_INVALID_ARGS); - } + }, (Some(input), None, None) => input.clone(), (None, Some(stdin), None) => stdin.clone(), (None, None, Some(path)) => { @@ -333,6 +333,7 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option { info!("returning from here in get_input"); + return String::new(); }, _default => { From 73a90863cde256624eb066436ee24d3f58597af4 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Fri, 2 Feb 2024 15:30:22 -0500 Subject: [PATCH 09/23] add debug statements for CI test, not reproing locally --- dsc/tests/dsc_args.tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsc/tests/dsc_args.tests.ps1 b/dsc/tests/dsc_args.tests.ps1 index 86acc5c42..458dc8d84 100644 --- a/dsc/tests/dsc_args.tests.ps1 +++ b/dsc/tests/dsc_args.tests.ps1 @@ -135,7 +135,7 @@ resources: '@ Set-Content -Path $TestDrive/foo.yaml -Value $yaml - $out = dsc config get $parameter "$TestDrive/foo.yaml" | ConvertFrom-Json + $out = dsc -l info config get $parameter "$TestDrive/foo.yaml" | ConvertFrom-Json $LASTEXITCODE | Should -Be 0 $out.results[0].type | Should -BeExactly 'Microsoft/OSInfo' } From ac410ac004137ab9c19c77177483d27ddaa496c3 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Fri, 2 Feb 2024 15:45:15 -0500 Subject: [PATCH 10/23] more debug statements --- dsc/src/main.rs | 7 ++++++- dsc/src/util.rs | 28 +++++++++++++++++++++++----- dsc/tests/dsc_args.tests.ps1 | 2 +- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/dsc/src/main.rs b/dsc/src/main.rs index 24dee9162..2f10e636d 100644 --- a/dsc/src/main.rs +++ b/dsc/src/main.rs @@ -48,7 +48,12 @@ fn main() { exit(util::EXIT_INVALID_ARGS); }, }; - Some(input) + if input.is_empty() { + None + } + else { + Some(input) + } }; match args.subcommand { diff --git a/dsc/src/util.rs b/dsc/src/util.rs index afab1a39b..2a2fd99fd 100644 --- a/dsc/src/util.rs +++ b/dsc/src/util.rs @@ -315,9 +315,29 @@ pub fn parse_input_to_json(value: &str) -> String { pub fn get_input(input: &Option, stdin: &Option, path: &Option) -> String { let value = match (input, stdin, path) { - (None, Some(_), Some(_)) | (Some(_), Some(_), None) => { - error!("Error: Cannot specify both stdin and --input or --path"); - exit(EXIT_INVALID_ARGS); + (Some(input), Some(stdin), None) => { + info!("value of stdin is: {}", stdin); + if !stdin.is_empty() { + error!("Error: Cannot specify both stdin and --input or --path"); + exit(EXIT_INVALID_ARGS); + } + info!("stdin is empty"); + input.clone() + }, + (None, Some(stdin), Some(path)) => { + info!("value of stdin is: {}", stdin); + if !stdin.is_empty() { + error!("Error: Cannot specify both stdin and --input or --path"); + exit(EXIT_INVALID_ARGS); + } + info!("stdin is empty"); + match std::fs::read_to_string(path) { + Ok(input) => input.clone(), + Err(err) => { + error!("Error: Failed to read input file: {err}"); + exit(EXIT_INVALID_INPUT); + } + } }, (Some(input), None, None) => input.clone(), (None, Some(stdin), None) => stdin.clone(), @@ -332,8 +352,6 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option { - info!("returning from here in get_input"); - return String::new(); }, _default => { diff --git a/dsc/tests/dsc_args.tests.ps1 b/dsc/tests/dsc_args.tests.ps1 index 458dc8d84..ee04f021e 100644 --- a/dsc/tests/dsc_args.tests.ps1 +++ b/dsc/tests/dsc_args.tests.ps1 @@ -114,7 +114,7 @@ resources: family: Windows '@ - $out = dsc config get $parameter "$yaml" | ConvertFrom-Json + $out = dsc -l info config get $parameter "$yaml" | ConvertFrom-Json $LASTEXITCODE | Should -Be 0 $out.results[0].type | Should -BeExactly 'Microsoft/OSInfo' } From f506368a53d4cc55a56f0062b0dcbbd413574cf7 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Fri, 2 Feb 2024 16:02:37 -0500 Subject: [PATCH 11/23] remove debug statements from pester tests --- dsc/src/util.rs | 26 +++----------------------- dsc/tests/dsc_args.tests.ps1 | 4 ++-- 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/dsc/src/util.rs b/dsc/src/util.rs index 2a2fd99fd..119d50c3b 100644 --- a/dsc/src/util.rs +++ b/dsc/src/util.rs @@ -315,29 +315,9 @@ pub fn parse_input_to_json(value: &str) -> String { pub fn get_input(input: &Option, stdin: &Option, path: &Option) -> String { let value = match (input, stdin, path) { - (Some(input), Some(stdin), None) => { - info!("value of stdin is: {}", stdin); - if !stdin.is_empty() { - error!("Error: Cannot specify both stdin and --input or --path"); - exit(EXIT_INVALID_ARGS); - } - info!("stdin is empty"); - input.clone() - }, - (None, Some(stdin), Some(path)) => { - info!("value of stdin is: {}", stdin); - if !stdin.is_empty() { - error!("Error: Cannot specify both stdin and --input or --path"); - exit(EXIT_INVALID_ARGS); - } - info!("stdin is empty"); - match std::fs::read_to_string(path) { - Ok(input) => input.clone(), - Err(err) => { - error!("Error: Failed to read input file: {err}"); - exit(EXIT_INVALID_INPUT); - } - } + (Some(_), Some(_), None) | (None, Some(_), Some(_)) => { + error!("Error: Cannot specify both stdin and --input or --path"); + exit(EXIT_INVALID_ARGS); }, (Some(input), None, None) => input.clone(), (None, Some(stdin), None) => stdin.clone(), diff --git a/dsc/tests/dsc_args.tests.ps1 b/dsc/tests/dsc_args.tests.ps1 index ee04f021e..86acc5c42 100644 --- a/dsc/tests/dsc_args.tests.ps1 +++ b/dsc/tests/dsc_args.tests.ps1 @@ -114,7 +114,7 @@ resources: family: Windows '@ - $out = dsc -l info config get $parameter "$yaml" | ConvertFrom-Json + $out = dsc config get $parameter "$yaml" | ConvertFrom-Json $LASTEXITCODE | Should -Be 0 $out.results[0].type | Should -BeExactly 'Microsoft/OSInfo' } @@ -135,7 +135,7 @@ resources: '@ Set-Content -Path $TestDrive/foo.yaml -Value $yaml - $out = dsc -l info config get $parameter "$TestDrive/foo.yaml" | ConvertFrom-Json + $out = dsc config get $parameter "$TestDrive/foo.yaml" | ConvertFrom-Json $LASTEXITCODE | Should -Be 0 $out.results[0].type | Should -BeExactly 'Microsoft/OSInfo' } From bf81de0bf09278a53a62ff701e10f3255313b6e0 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Tue, 6 Feb 2024 14:31:16 -0500 Subject: [PATCH 12/23] update document help description --- dsc/src/args.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dsc/src/args.rs b/dsc/src/args.rs index 3acc7f933..a60866911 100644 --- a/dsc/src/args.rs +++ b/dsc/src/args.rs @@ -74,35 +74,35 @@ pub enum SubCommand { pub enum ConfigSubCommand { #[clap(name = "get", about = "Retrieve the current configuration")] Get { - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "path")] + #[clap(short = 'd', long, help = "The document to pass to the configuration or resource", conflicts_with = "path")] document: Option, #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource", conflicts_with = "document")] path: Option, }, #[clap(name = "set", about = "Set the current configuration")] Set { - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "path")] + #[clap(short = 'd', long, help = "The document to pass to the configuration or resource", conflicts_with = "path")] document: Option, #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource", conflicts_with = "document")] path: Option, }, #[clap(name = "test", about = "Test the current configuration")] Test { - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "path")] + #[clap(short = 'd', long, help = "The document to pass to the configuration or resource", conflicts_with = "path")] document: Option, #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource", conflicts_with = "document")] path: Option, }, #[clap(name = "validate", about = "Validate the current configuration", hide = true)] Validate { - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "path")] + #[clap(short = 'd', long, help = "The document to pass to the configuration or resource", conflicts_with = "path")] document: Option, #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource", conflicts_with = "document")] path: Option, }, #[clap(name = "export", about = "Export the current configuration")] Export { - #[clap(short = 'd', long, help = "The input to pass to the configuration or resource", conflicts_with = "path")] + #[clap(short = 'd', long, help = "The document to pass to the configuration or resource", conflicts_with = "path")] document: Option, #[clap(short = 'p', long, help = "The path to a file used as input to the configuration or resource", conflicts_with = "document")] path: Option, From a8f46f0f5352e6d741bf988b7c5060b215ac45e4 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Tue, 6 Feb 2024 15:18:25 -0500 Subject: [PATCH 13/23] call get_inputs earlier from get/set/test --- dsc/src/resource_command.rs | 15 +++++---------- dsc/src/subcommand.rs | 31 ++++++++++++++++--------------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/dsc/src/resource_command.rs b/dsc/src/resource_command.rs index 2ea6186a6..ba15348d4 100644 --- a/dsc/src/resource_command.rs +++ b/dsc/src/resource_command.rs @@ -2,7 +2,7 @@ // Licensed under the MIT License. use crate::args::OutputFormat; -use crate::util::{EXIT_DSC_ERROR, EXIT_INVALID_ARGS, EXIT_JSON_ERROR, add_type_name_to_json, write_output, get_input}; +use crate::util::{EXIT_DSC_ERROR, EXIT_INVALID_ARGS, EXIT_JSON_ERROR, add_type_name_to_json, write_output}; use dsc_lib::configure::config_doc::Configuration; use dsc_lib::configure::add_resource_export_results_to_configuration; use dsc_lib::dscresources::invoke_result::GetResult; @@ -15,10 +15,7 @@ use dsc_lib::{ }; use std::process::exit; -pub fn get(dsc: &DscManager, resource_type: &str, input: &Option, stdin: &Option, path: &Option, format: &Option) { - // TODO: support streaming stdin which includes resource and input - let mut input = get_input(input, stdin, path); - +pub fn get(dsc: &DscManager, resource_type: &str, mut input: String, format: &Option) { let Some(mut resource) = get_resource(dsc, resource_type) else { error!("{}", DscError::ResourceNotFound(resource_type.to_string()).to_string()); return @@ -54,7 +51,7 @@ pub fn get(dsc: &DscManager, resource_type: &str, input: &Option, stdin: } } -pub fn get_all(dsc: &DscManager, resource_type: &str, _input: &Option, _stdin: &Option, _path: &Option, format: &Option) { +pub fn get_all(dsc: &DscManager, resource_type: &str, format: &Option) { let Some(resource) = get_resource(dsc, resource_type) else { error!("{}", DscError::ResourceNotFound(resource_type.to_string()).to_string()); return @@ -91,8 +88,7 @@ pub fn get_all(dsc: &DscManager, resource_type: &str, _input: &Option, _ /// /// Will panic if provider-based resource is not found. /// -pub fn set(dsc: &DscManager, resource_type: &str, input: &Option, stdin: &Option, path: &Option, format: &Option) { - let mut input = get_input(input, stdin, path); +pub fn set(dsc: &DscManager, resource_type: &str, mut input: String, format: &Option) { if input.is_empty() { error!("Error: Input is empty"); exit(EXIT_INVALID_ARGS); @@ -140,8 +136,7 @@ pub fn set(dsc: &DscManager, resource_type: &str, input: &Option, stdin: /// /// Will panic if provider-based resource is not found. /// -pub fn test(dsc: &DscManager, resource_type: &str, input: &Option, stdin: &Option, path: &Option, format: &Option) { - let mut input = get_input(input, stdin, path); +pub fn test(dsc: &DscManager, resource_type: &str, mut input: String, format: &Option) { let Some(mut resource) = get_resource(dsc, resource_type) else { error!("{}", DscError::ResourceNotFound(resource_type.to_string()).to_string()); return diff --git a/dsc/src/subcommand.rs b/dsc/src/subcommand.rs index d9e222c88..f0223bfe9 100644 --- a/dsc/src/subcommand.rs +++ b/dsc/src/subcommand.rs @@ -390,32 +390,33 @@ pub fn resource(subcommand: &ResourceSubCommand, format: &Option, } } - if write_table { - table.print(); - } + if write_table { table.print(); } + }, + ResourceSubCommand::Schema { resource } => { + dsc.discover_resources(&[resource.to_lowercase().to_string()]); + resource_command::schema(&dsc, resource, format); + }, + ResourceSubCommand::Export { resource} => { + dsc.discover_resources(&[resource.to_lowercase().to_string()]); + resource_command::export(&mut dsc, resource, format); }, ResourceSubCommand::Get { resource, input, path, all } => { dsc.discover_resources(&[resource.to_lowercase().to_string()]); - if *all { resource_command::get_all(&dsc, resource, input, stdin, path, format); } + if *all { resource_command::get_all(&dsc, resource, format); } else { - resource_command::get(&dsc, resource, input, stdin, path, format); + let parsed_input = get_input(input, stdin, path); + resource_command::get(&dsc, resource, parsed_input, format); }; }, ResourceSubCommand::Set { resource, input, path } => { dsc.discover_resources(&[resource.to_lowercase().to_string()]); - resource_command::set(&dsc, resource, input, stdin, path, format); + let parsed_input = get_input(input, stdin, path); + resource_command::set(&dsc, resource, parsed_input, format); }, ResourceSubCommand::Test { resource, input, path } => { dsc.discover_resources(&[resource.to_lowercase().to_string()]); - resource_command::test(&dsc, resource, input, stdin, path, format); - }, - ResourceSubCommand::Schema { resource } => { - dsc.discover_resources(&[resource.to_lowercase().to_string()]); - resource_command::schema(&dsc, resource, format); - }, - ResourceSubCommand::Export { resource} => { - dsc.discover_resources(&[resource.to_lowercase().to_string()]); - resource_command::export(&mut dsc, resource, format); + let parsed_input = get_input(input, stdin, path); + resource_command::test(&dsc, resource, parsed_input, format); }, } } From 96059722c1b244f52ec1d121030b4753a2f86f60 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Tue, 6 Feb 2024 15:18:41 -0500 Subject: [PATCH 14/23] add comment around stdin empty input --- dsc/src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dsc/src/main.rs b/dsc/src/main.rs index 2f10e636d..696c78ed4 100644 --- a/dsc/src/main.rs +++ b/dsc/src/main.rs @@ -48,6 +48,8 @@ fn main() { exit(util::EXIT_INVALID_ARGS); }, }; + // get_input call expects at most 1 input, so wrapping Some(empty input) would throw it off + // have only seen this happen with dsc_args.test.ps1 running on the CI pipeline if input.is_empty() { None } From cfdc2290f8b236ce7b61b2cd0df0c81d93de58b4 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Tue, 6 Feb 2024 15:19:03 -0500 Subject: [PATCH 15/23] add tests for empty input for set --- dsc/tests/dsc_args.tests.ps1 | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/dsc/tests/dsc_args.tests.ps1 b/dsc/tests/dsc_args.tests.ps1 index 86acc5c42..16bbc9c60 100644 --- a/dsc/tests/dsc_args.tests.ps1 +++ b/dsc/tests/dsc_args.tests.ps1 @@ -173,4 +173,26 @@ resources: "$TestDrive/tracing.txt" | Should -FileContentMatchExactly 'DEBUG' $LASTEXITCODE | Should -Be 0 } + + It 'stdin cannot be empty if neither document or path is provided' { + '' | dsc config set 2> $TestDrive/error.txt + $err = Get-Content $testdrive/error.txt -Raw + $err.Length | Should -Not -Be 0 + $LASTEXITCODE | Should -Be 4 + } + + It 'document cannot be empty if neither stdin or path is provided' { + dsc config set --document '' 2> $TestDrive/error.txt + $err = Get-Content $testdrive/error.txt -Raw + $err.Length | Should -Not -Be 0 + $LASTEXITCODE | Should -Be 4 + } + + It 'path contents cannot be empty if neither stdin or document is provided' { + Set-Content -Path $TestDrive/empty.yaml -Value '' + dsc config set --path $TestDrive/empty.yaml 2> $TestDrive/error.txt + $err = Get-Content $testdrive/error.txt -Raw + $err.Length | Should -Not -Be 0 + $LASTEXITCODE | Should -Be 4 + } } From 62be5923f5d56251711f54c3ab89725ac81c76f1 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Tue, 6 Feb 2024 16:47:18 -0500 Subject: [PATCH 16/23] fix merge conflicts --- dsc/src/subcommand.rs | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/dsc/src/subcommand.rs b/dsc/src/subcommand.rs index bd5bfbb25..74ec29a2a 100644 --- a/dsc/src/subcommand.rs +++ b/dsc/src/subcommand.rs @@ -116,13 +116,13 @@ pub fn config_export(configurator: &mut Configurator, format: &Option, format: &Option, stdin: &Option) { +pub fn config(subcommand: &ConfigSubCommand, parameters: &Option, stdin: &Option) { let json_string = match subcommand { - ConfigSubCommand::Get { document, path } | - ConfigSubCommand::Set { document, path } | - ConfigSubCommand::Test { document, path } | - ConfigSubCommand::Validate { document, path } | - ConfigSubCommand::Export { document, path } => { + ConfigSubCommand::Get { document, path, .. } | + ConfigSubCommand::Set { document, path, .. } | + ConfigSubCommand::Test { document, path, .. } | + ConfigSubCommand::Validate { document, path, .. } | + ConfigSubCommand::Export { document, path, .. } => { get_input(document, stdin, path) } }; @@ -167,19 +167,19 @@ pub fn config(subcommand: &ConfigSubCommand, parameters: &Option, format } match subcommand { - ConfigSubCommand::Get { format } => { + ConfigSubCommand::Get { format, .. } => { config_get(&mut configurator, format); }, - ConfigSubCommand::Set { format } => { + ConfigSubCommand::Set { format, .. } => { config_set(&mut configurator, format); }, - ConfigSubCommand::Test { format } => { + ConfigSubCommand::Test { format, .. } => { config_test(&mut configurator, format); }, ConfigSubCommand::Validate { .. } => { validate_config(&json_string); }, - ConfigSubCommand::Export { format } => { + ConfigSubCommand::Export { format, .. } => { config_export(&mut configurator, format); } } @@ -393,17 +393,20 @@ pub fn resource(subcommand: &ResourceSubCommand, stdin: &Option) { if write_table { table.print(); } }, - ResourceSubCommand::Get { resource, input, all, format } => { + ResourceSubCommand::Get { resource, input, path, all, format } => { dsc.discover_resources(&[resource.to_lowercase().to_string()]); - let parsed_input = get_input(input, stdin, path); - resource_command::get(&dsc, resource, parsed_input, format); + if *all { resource_command::get_all(&dsc, resource, format); } + else { + let parsed_input = get_input(input, stdin, path); + resource_command::get(&dsc, resource, parsed_input, format); + } }, - ResourceSubCommand::Set { resource, input, format } => { + ResourceSubCommand::Set { resource, input, path, format } => { dsc.discover_resources(&[resource.to_lowercase().to_string()]); let parsed_input = get_input(input, stdin, path); resource_command::set(&dsc, resource, parsed_input, format); }, - ResourceSubCommand::Test { resource, input, format } => { + ResourceSubCommand::Test { resource, input, path, format } => { dsc.discover_resources(&[resource.to_lowercase().to_string()]); let parsed_input = get_input(input, stdin, path); resource_command::test(&dsc, resource, parsed_input, format); From 038e268ec1f91311f3e3a724be59ba7eb360fece Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Tue, 6 Feb 2024 16:56:37 -0500 Subject: [PATCH 17/23] add logging around inputs --- dsc/src/main.rs | 1 + dsc/src/util.rs | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/dsc/src/main.rs b/dsc/src/main.rs index 322e5af74..50b5b96cd 100644 --- a/dsc/src/main.rs +++ b/dsc/src/main.rs @@ -51,6 +51,7 @@ fn main() { // get_input call expects at most 1 input, so wrapping Some(empty input) would throw it off // have only seen this happen with dsc_args.test.ps1 running on the CI pipeline if input.is_empty() { + info!("Input from STDIN is empty"); None } else { diff --git a/dsc/src/util.rs b/dsc/src/util.rs index 119d50c3b..7c4ef3b7f 100644 --- a/dsc/src/util.rs +++ b/dsc/src/util.rs @@ -319,8 +319,14 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option input.clone(), - (None, Some(stdin), None) => stdin.clone(), + (Some(input), None, None) => { + info!("Reading input from command line parameter"); + input.clone() + }, + (None, Some(stdin), None) => { + info!("Reading input from stdin"); + stdin.clone() + }, (None, None, Some(path)) => { info!("Reading input from file {}", path); match std::fs::read_to_string(path) { @@ -332,6 +338,7 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option { + info!("No input provided via stdin, file, or command line"); return String::new(); }, _default => { @@ -342,6 +349,7 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option Date: Wed, 7 Feb 2024 11:20:07 -0500 Subject: [PATCH 18/23] refactor empty input tests and debug mac ci failure --- dsc/src/resource_command.rs | 2 +- dsc/src/subcommand.rs | 19 +++++++++---------- dsc/src/util.rs | 6 ++++-- dsc/tests/dsc_args.tests.ps1 | 24 ++++++++++++++++-------- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/dsc/src/resource_command.rs b/dsc/src/resource_command.rs index 727ff0ed4..2b75a09ee 100644 --- a/dsc/src/resource_command.rs +++ b/dsc/src/resource_command.rs @@ -52,7 +52,7 @@ pub fn get(dsc: &DscManager, resource_type: &str, mut input: String, format: &Op } pub fn get_all(dsc: &DscManager, resource_type: &str, format: &Option) { - let mut input = String::new() ; + let mut input = String::new(); let Some(mut resource) = get_resource(dsc, resource_type) else { error!("{}", DscError::ResourceNotFound(resource_type.to_string()).to_string()); return diff --git a/dsc/src/subcommand.rs b/dsc/src/subcommand.rs index 74ec29a2a..c4fe82b15 100644 --- a/dsc/src/subcommand.rs +++ b/dsc/src/subcommand.rs @@ -118,7 +118,7 @@ pub fn config_export(configurator: &mut Configurator, format: &Option, stdin: &Option) { let json_string = match subcommand { - ConfigSubCommand::Get { document, path, .. } | + ConfigSubCommand::Get { document, path, .. } | ConfigSubCommand::Set { document, path, .. } | ConfigSubCommand::Test { document, path, .. } | ConfigSubCommand::Validate { document, path, .. } | @@ -392,7 +392,14 @@ pub fn resource(subcommand: &ResourceSubCommand, stdin: &Option) { if write_table { table.print(); } }, - + ResourceSubCommand::Schema { resource , format } => { + dsc.discover_resources(&[resource.to_lowercase().to_string()]); + resource_command::schema(&dsc, resource, format); + }, + ResourceSubCommand::Export { resource, format } => { + dsc.discover_resources(&[resource.to_lowercase().to_string()]); + resource_command::export(&mut dsc, resource, format); + }, ResourceSubCommand::Get { resource, input, path, all, format } => { dsc.discover_resources(&[resource.to_lowercase().to_string()]); if *all { resource_command::get_all(&dsc, resource, format); } @@ -411,13 +418,5 @@ pub fn resource(subcommand: &ResourceSubCommand, stdin: &Option) { let parsed_input = get_input(input, stdin, path); resource_command::test(&dsc, resource, parsed_input, format); }, - ResourceSubCommand::Schema { resource , format } => { - dsc.discover_resources(&[resource.to_lowercase().to_string()]); - resource_command::schema(&dsc, resource, format); - }, - ResourceSubCommand::Export { resource, format } => { - dsc.discover_resources(&[resource.to_lowercase().to_string()]); - resource_command::export(&mut dsc, resource, format); - }, } } diff --git a/dsc/src/util.rs b/dsc/src/util.rs index 7c4ef3b7f..281c78164 100644 --- a/dsc/src/util.rs +++ b/dsc/src/util.rs @@ -330,7 +330,9 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option { info!("Reading input from file {}", path); match std::fs::read_to_string(path) { - Ok(input) => input.clone(), + Ok(input) => { + input.clone() + }, Err(err) => { error!("Error: Failed to read input file: {err}"); exit(EXIT_INVALID_INPUT); @@ -348,7 +350,7 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option $TestDrive/error.txt + It 'stdin cannot be empty if neither input or path is provided' { + '' | dsc -l info resource set -r Microsoft/OSInfo 2> $TestDrive/error.txt $err = Get-Content $testdrive/error.txt -Raw $err.Length | Should -Not -Be 0 - $LASTEXITCODE | Should -Be 4 + $LASTEXITCODE | Should -Be 1 } - It 'document cannot be empty if neither stdin or path is provided' { - dsc config set --document '' 2> $TestDrive/error.txt + It 'input cannot be empty if neither stdin or path is provided' { + dsc resource set -r Microsoft/OSInfo --input '' 2> $TestDrive/error.txt $err = Get-Content $testdrive/error.txt -Raw $err.Length | Should -Not -Be 0 - $LASTEXITCODE | Should -Be 4 + $LASTEXITCODE | Should -Be 1 } - It 'path contents cannot be empty if neither stdin or document is provided' { + It 'path contents cannot be empty if neither stdin or input is provided' { Set-Content -Path $TestDrive/empty.yaml -Value '' - dsc config set --path $TestDrive/empty.yaml 2> $TestDrive/error.txt + dsc -l info resource set -r Microsoft/OSInfo --path $TestDrive/empty.yaml 2> $TestDrive/error.txt $err = Get-Content $testdrive/error.txt -Raw $err.Length | Should -Not -Be 0 + $LASTEXITCODE | Should -Be 1 + } + + It 'document cannot be empty if neither stdin or path is provided' { + dsc -l info config set --document '' + #2> $TestDrive/error.txt + #$err = Get-Content $testdrive/error.txt -Raw + #$err.Length | Should -Not -Be 0 $LASTEXITCODE | Should -Be 4 } } From 9b21daad179eae9471e2481f31bb0701f6c85f0f Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Wed, 7 Feb 2024 11:33:31 -0500 Subject: [PATCH 19/23] remove debug statements from pester tests --- dsc/src/util.rs | 4 +--- dsc/tests/dsc_args.tests.ps1 | 11 +++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/dsc/src/util.rs b/dsc/src/util.rs index 281c78164..2f3b91990 100644 --- a/dsc/src/util.rs +++ b/dsc/src/util.rs @@ -330,9 +330,7 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option { info!("Reading input from file {}", path); match std::fs::read_to_string(path) { - Ok(input) => { - input.clone() - }, + Ok(input) => input.clone(), Err(err) => { error!("Error: Failed to read input file: {err}"); exit(EXIT_INVALID_INPUT); diff --git a/dsc/tests/dsc_args.tests.ps1 b/dsc/tests/dsc_args.tests.ps1 index aa42c2738..7de985180 100644 --- a/dsc/tests/dsc_args.tests.ps1 +++ b/dsc/tests/dsc_args.tests.ps1 @@ -175,7 +175,7 @@ resources: } It 'stdin cannot be empty if neither input or path is provided' { - '' | dsc -l info resource set -r Microsoft/OSInfo 2> $TestDrive/error.txt + '' | dsc resource set -r Microsoft/OSInfo 2> $TestDrive/error.txt $err = Get-Content $testdrive/error.txt -Raw $err.Length | Should -Not -Be 0 $LASTEXITCODE | Should -Be 1 @@ -190,17 +190,16 @@ resources: It 'path contents cannot be empty if neither stdin or input is provided' { Set-Content -Path $TestDrive/empty.yaml -Value '' - dsc -l info resource set -r Microsoft/OSInfo --path $TestDrive/empty.yaml 2> $TestDrive/error.txt + dsc resource set -r Microsoft/OSInfo --path $TestDrive/empty.yaml 2> $TestDrive/error.txt $err = Get-Content $testdrive/error.txt -Raw $err.Length | Should -Not -Be 0 $LASTEXITCODE | Should -Be 1 } It 'document cannot be empty if neither stdin or path is provided' { - dsc -l info config set --document '' - #2> $TestDrive/error.txt - #$err = Get-Content $testdrive/error.txt -Raw - #$err.Length | Should -Not -Be 0 + dsc config set --document '' 2> $TestDrive/error.txt + $err = Get-Content $testdrive/error.txt -Raw + $err.Length | Should -Not -Be 0 $LASTEXITCODE | Should -Be 4 } } From 3922c471d7082e31470c07cb4f31ba320c8f8ed5 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Wed, 7 Feb 2024 12:02:04 -0500 Subject: [PATCH 20/23] much confusion --- dsc/src/util.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dsc/src/util.rs b/dsc/src/util.rs index 2f3b91990..281c78164 100644 --- a/dsc/src/util.rs +++ b/dsc/src/util.rs @@ -330,7 +330,9 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option { info!("Reading input from file {}", path); match std::fs::read_to_string(path) { - Ok(input) => input.clone(), + Ok(input) => { + input.clone() + }, Err(err) => { error!("Error: Failed to read input file: {err}"); exit(EXIT_INVALID_INPUT); From 89ad1c9e59b86eb29d86c2291fdbc6088b422322 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Wed, 7 Feb 2024 13:06:14 -0500 Subject: [PATCH 21/23] try removing log file after each test --- dsc/tests/dsc_args.tests.ps1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dsc/tests/dsc_args.tests.ps1 b/dsc/tests/dsc_args.tests.ps1 index 7de985180..e06aeb522 100644 --- a/dsc/tests/dsc_args.tests.ps1 +++ b/dsc/tests/dsc_args.tests.ps1 @@ -44,6 +44,12 @@ Describe 'config argument tests' { $env:DSC_RESOURCE_PATH = $env:PATH + $sep + $TestDrive } + AfterEach { + if (Test-Path $TestDrive/error.txt) { + Remove-Item -Path $TestDrive/error.txt + } + } + AfterAll { $env:DSC_RESOURCE_PATH = $oldPath } From bc7f14ecac9155555bb543d233662b3f6ade36f0 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Wed, 7 Feb 2024 13:24:09 -0500 Subject: [PATCH 22/23] try using explicit whitespace in test --- dsc/tests/dsc_args.tests.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dsc/tests/dsc_args.tests.ps1 b/dsc/tests/dsc_args.tests.ps1 index e06aeb522..25bfd24ec 100644 --- a/dsc/tests/dsc_args.tests.ps1 +++ b/dsc/tests/dsc_args.tests.ps1 @@ -49,7 +49,7 @@ Describe 'config argument tests' { Remove-Item -Path $TestDrive/error.txt } } - + AfterAll { $env:DSC_RESOURCE_PATH = $oldPath } @@ -188,14 +188,14 @@ resources: } It 'input cannot be empty if neither stdin or path is provided' { - dsc resource set -r Microsoft/OSInfo --input '' 2> $TestDrive/error.txt + dsc resource set -r Microsoft/OSInfo --input " " 2> $TestDrive/error.txt $err = Get-Content $testdrive/error.txt -Raw $err.Length | Should -Not -Be 0 $LASTEXITCODE | Should -Be 1 } It 'path contents cannot be empty if neither stdin or input is provided' { - Set-Content -Path $TestDrive/empty.yaml -Value '' + Set-Content -Path $TestDrive/empty.yaml -Value " " dsc resource set -r Microsoft/OSInfo --path $TestDrive/empty.yaml 2> $TestDrive/error.txt $err = Get-Content $testdrive/error.txt -Raw $err.Length | Should -Not -Be 0 @@ -203,7 +203,7 @@ resources: } It 'document cannot be empty if neither stdin or path is provided' { - dsc config set --document '' 2> $TestDrive/error.txt + dsc config set --document " " 2> $TestDrive/error.txt $err = Get-Content $testdrive/error.txt -Raw $err.Length | Should -Not -Be 0 $LASTEXITCODE | Should -Be 4 From f188b406c3c38664c42f3ab38b8ac915f9397127 Mon Sep 17 00:00:00 2001 From: "tgauth@bu.edu" Date: Wed, 7 Feb 2024 17:04:17 -0500 Subject: [PATCH 23/23] change from info to debug logging level --- dsc/src/main.rs | 2 +- dsc/src/util.rs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dsc/src/main.rs b/dsc/src/main.rs index 50b5b96cd..4e3a5e019 100644 --- a/dsc/src/main.rs +++ b/dsc/src/main.rs @@ -51,7 +51,7 @@ fn main() { // get_input call expects at most 1 input, so wrapping Some(empty input) would throw it off // have only seen this happen with dsc_args.test.ps1 running on the CI pipeline if input.is_empty() { - info!("Input from STDIN is empty"); + debug!("Input from STDIN is empty"); None } else { diff --git a/dsc/src/util.rs b/dsc/src/util.rs index 281c78164..fbaa15ea4 100644 --- a/dsc/src/util.rs +++ b/dsc/src/util.rs @@ -26,7 +26,7 @@ use syntect::{ parsing::SyntaxSet, util::{as_24_bit_terminal_escaped, LinesWithEndings} }; -use tracing::{Level, error, info}; +use tracing::{Level, debug, error}; use tracing_subscriber::{filter::EnvFilter, layer::SubscriberExt, Layer}; pub const EXIT_SUCCESS: i32 = 0; @@ -320,15 +320,15 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option { - info!("Reading input from command line parameter"); + debug!("Reading input from command line parameter"); input.clone() }, (None, Some(stdin), None) => { - info!("Reading input from stdin"); + debug!("Reading input from stdin"); stdin.clone() }, (None, None, Some(path)) => { - info!("Reading input from file {}", path); + debug!("Reading input from file {}", path); match std::fs::read_to_string(path) { Ok(input) => { input.clone() @@ -340,7 +340,7 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option { - info!("No input provided via stdin, file, or command line"); + debug!("No input provided via stdin, file, or command line"); return String::new(); }, _default => { @@ -351,7 +351,7 @@ pub fn get_input(input: &Option, stdin: &Option, path: &Option