private void FillCmdLineObjInfo(CmdLineParseResults <T> results) { // Get the app title. if (Application.Title.IsEmpty()) { results.Title = "Command-line options."; } else if (Application.Version == null) { results.Title = Application.Title; } else { results.Title = string.Format("{0} ver. {1}", Application.Title, Application.Version); } if (Application.Copyright.HasValue()) { results.Copyright = Application.Copyright; } // Get the app description. var att = this.GetAttribute <DescriptionAttribute>(true); if (att != null) { results.Description = att.Description; } else { results.Description = Application.Description; } // Get the file name. results.ApplicationFileName = Application.ExeName; }
/// <summary> /// Fills an existing command-line object from the command-line arguments. /// </summary> /// <param name="obj">The instance to fill.</param> /// <param name="args"></param> /// <returns></returns> public CmdLineParseResults <T> Fill(T obj, IEnumerable <string> args) { VerifyCmdLineOptions(); if (Options.ExitCodes == null) { Options.ExitCodes = FindExitCodes(); } if (Options.ExitCodes != null) { if (Options.InvalidArgsExitCode == null) { Options.InvalidArgsExitCode = FindExitCode(Options.ExitCodes, "InvalidArgs"); } if (Options.FatalErrorExitCode == null) { Options.FatalErrorExitCode = FindExitCode(Options.ExitCodes, "FatalError"); } } var results = new CmdLineParseResults <T>(Options); results.Args = obj; var props = results.Properties = GetCmdLineProperties(obj); var errors = new List <string>(); CmdLineProperty prop = null; List <string> arrayVals = null; var notSpecifiedRequiredProps = props.Where(p => p.Required).ToList(); // To keep the parsing logic as simple as possible, // normalize the argument list. // Normalize for assignment first so other transforms // can work with the same type of list. args = TransformAssignedArgs(args); args = TransformDefaultArgs(args); foreach (var arg in args) { try { if (arg.StartsWith(Options.ArgumentPrefix)) // Named value. { // We might be setting a flag or array value. SetPropertyValue(prop, null, arrayVals); arrayVals = null; var name = arg.Substring(Options.ArgumentPrefix.Length); var falseVal = false; if (name.EndsWith("-")) { name = name.Substring(0, name.Length - 1); falseVal = true; } prop = props[name]; if (prop != null) { if (prop.Required) { notSpecifiedRequiredProps.Remove(prop); } if (falseVal && prop.PropertyType == typeof(bool)) { SetPropertyValue(prop, "false", null); prop = null; } } } else if (prop != null) { // Either setting a value or adding to an array. if (prop.PropertyType.IsArray) { if (Options.ArraySeparator != null) { var values = Regex.Split(arg, Regex.Escape(Options.ArraySeparator)); SetPropertyValue(prop, null, values); prop = null; } else { if (arrayVals == null) { arrayVals = new List <string>(); } arrayVals.Add(arg); } } else { SetPropertyValue(prop, arg, null); prop = null; } } } catch (Exception ex) { if (prop == null || prop.Name.IsEmpty()) { errors.Add("ERR: " + ex.Message); } else if (arrayVals == null) { errors.Add("Unable to set {0}. Value <{1}> is not valid.".Fmt(prop.Name, arg)); } else { errors.Add("Unable to set {0}. Invalid value.".Fmt(prop.Name, arg)); } } } try { SetPropertyValue(prop, null, arrayVals); } catch (Exception ex) { if (prop == null || prop.Name.IsEmpty()) { errors.Add("ERR: " + ex.Message); } else { errors.Add("Unable to set {0}. Invalid value.".Fmt(prop.Name)); } } // Populate header-level information, such as the title. FillCmdLineObjInfo(results); // Set errors for any missing, required properties. // https://github.com/BizArk/BizArk3/issues/7 errors.AddRange(notSpecifiedRequiredProps.Select(p => { var reqAtt = p.Property.GetAttribute <RequiredAttribute>(); var msg = reqAtt?.ErrorMessage ?? $"{p.Name} is required."; return(msg); })); // Validate the object using validation attributes. errors.AddRange(ValidateCmdLineObject(obj)); results.Errors = errors.Distinct().ToArray(); // Required messages might show up twice. return(results); }