private static Context ParseArgs(string[] args) { var context = new Context(); var resolvedArgs = args .SelectMany(ResolveOptionsFromFile) .ToArray(); var options = new[] { new Option { Description = "AQSamples connection options:" }, new Option { Key = nameof(context.ServerUrl), Setter = value => context.ServerUrl = value, Getter = () => context.ServerUrl, Description = "AQS server URL" }, new Option { Key = nameof(context.ApiToken), Setter = value => context.ApiToken = value, Getter = () => context.ApiToken, Description = "AQS API Token" }, new Option(), new Option { Description = "Output options:" }, new Option { Key = nameof(context.CsvOutputPath), Setter = value => context.CsvOutputPath = value, Getter = () => context.CsvOutputPath, Description = $"Path to output file [default: ExportedObservations-yyyyMMddHHmmss.csv in the same folder as the EXE]" }, new Option { Key = nameof(context.Overwrite), Setter = value => context.Overwrite = ParseBoolean(value), Getter = () => $"{context.Overwrite}", Description = "Overwrite existing files?" }, new Option { Key = nameof(context.UtcOffset), Setter = value => context.UtcOffset = ParseOffset(value), Getter = () => string.Empty, Description = $"UTC offset for output times [default: Use system timezone, currently {context.UtcOffset:m}]" }, new Option(), new Option { Description = "Cumulative filter options: (ie. AND-ed together). Can be set multiple times." }, new Option { Key = nameof(context.StartTime), Setter = value => context.StartTime = ParseDateTimeOffset(value), Getter = () => string.Empty, Description = "Include observations after this time." }, new Option { Key = nameof(context.EndTime), Setter = value => context.EndTime = ParseDateTimeOffset(value), Getter = () => string.Empty, Description = "Include observations before this time." }, new Option { Key = nameof(context.LocationIds).Singularize(), Setter = value => context.LocationIds.Add(value), Getter = () => string.Empty, Description = "Observations matching these locations." }, new Option { Key = nameof(context.AnalyticalGroupIds).Singularize(), Setter = value => context.AnalyticalGroupIds.Add(value), Getter = () => string.Empty, Description = "Observations matching these analytical groups." }, new Option { Key = nameof(context.ObservedPropertyIds).Singularize(), Setter = value => context.ObservedPropertyIds.Add(value), Getter = () => string.Empty, Description = "Observations matching these observed properties." }, new Option { Key = nameof(context.ProjectIds).Singularize(), Setter = value => context.ProjectIds.Add(value), Getter = () => string.Empty, Description = "Observations matching these projects." }, }; var usageMessage = $"Export observations from an AQUARIUS Samples server." + $"\n" + $"\nusage: {ExeHelper.ExeName} [-option=value] [@optionsFile] ..." + $"\n" + $"\nSupported -option=value settings (/option=value works too):\n\n {string.Join("\n ", options.Select(o => o.UsageText()))}" + $"\n" + $"\nUse the @optionsFile syntax to read more options from a file." + $"\n" + $"\n Each line in the file is treated as a command line option." + $"\n Blank lines and leading/trailing whitespace is ignored." + $"\n Comment lines begin with a # or // marker." ; var helpGuidance = "See /help screen for details."; foreach (var arg in resolvedArgs) { var match = ArgRegex.Match(arg); if (!match.Success) { if (HelpKeyWords.Contains(arg)) { throw new ExpectedException(usageMessage); } throw new ExpectedException($"Unknown argument: {arg}\n\n{helpGuidance}"); } var key = match.Groups["key"].Value.ToLower(); var value = match.Groups["value"].Value; var option = options.FirstOrDefault(o => o.Key != null && o.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)); if (option == null) { throw new ExpectedException($"Unknown -option=value: {arg}\n\n{helpGuidance}"); } option.Setter(value); } return(context); }
private static Context ParseArgs(string[] args) { var context = new Context(); var resolvedArgs = InjectOptionsFileByDefault(args) .SelectMany(ResolveOptionsFromFile) .ToArray(); var options = new[] { new Option { Key = nameof(context.Server), Setter = value => context.Server = value, Getter = () => context.Server, Description = "AQTS server name" }, new Option { Key = nameof(context.Username), Setter = value => context.Username = value, Getter = () => context.Username, Description = "AQTS username" }, new Option { Key = nameof(context.Password), Setter = value => context.Password = value, Getter = () => context.Password, Description = "AQTS password" }, new Option { Key = nameof(context.ConfigPath), Setter = value => context.ConfigPath = value, Getter = () => context.ConfigPath, Description = $"Path to the JSON configuration file. [default: '{nameof(Config)}.json' in the same folder as the EXE]" }, new Option { Key = nameof(context.CreateMissingTimeSeries), Setter = value => context.CreateMissingTimeSeries = bool.Parse(value), Getter = () => $"{context.CreateMissingTimeSeries}", Description = "When true, any missing time-series will be created." }, }; var usageMessage = $"An external processor for calculating total discharge for arbitrary-length events." + $"\n" + $"\nusage: {ExeHelper.ExeName} [-option=value] [@optionsFile] ..." + $"\n" + $"\nSupported -option=value settings (/option=value works too):\n\n {string.Join("\n ", options.Select(o => o.UsageText()))}" + $"\n" + $"\nWhen no other command line options are given, the Options.txt file in" + $"\nsame folder as the EXE will be used if it exists." + $"\n" + $"\nUse the @optionsFile syntax to read more options from a file." + $"\n" + $"\n Each line in the file is treated as a command line option." + $"\n Blank lines and leading/trailing whitespace is ignored." + $"\n Comment lines begin with a # or // marker." ; var helpGuidance = "See /help screen for details."; foreach (var arg in resolvedArgs) { var match = ArgRegex.Match(arg); if (!match.Success) { if (HelpKeyWords.Contains(arg)) { throw new ExpectedException(usageMessage); } throw new ExpectedException($"Unknown argument: {arg}\n\n{helpGuidance}"); } var key = match.Groups["key"].Value.ToLower(); var value = match.Groups["value"].Value; var option = options.FirstOrDefault(o => o.Key != null && o.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)); if (option == null) { throw new ExpectedException($"Unknown -option=value: {arg}\n\n{helpGuidance}"); } option.Setter(value); } return(context); }
private static Context ParseArgs(string[] args) { var context = new Context(); var resolvedArgs = args .SelectMany(ResolveOptionsFromFile) .ToArray(); var options = new[] { new Option { Description = "AQUARIUS Samples connection options:" }, new Option { Key = nameof(context.SamplesServer), Setter = value => context.SamplesServer = value, Getter = () => context.SamplesServer, Description = "AQS server URL" }, new Option { Key = nameof(context.SamplesApiToken), Setter = value => context.SamplesApiToken = value, Getter = () => context.SamplesApiToken, Description = "AQS API Token" }, new Option(), new Option { Description = "AQUARIUS Time-Series connection options:" }, new Option { Key = nameof(context.TimeSeriesServer), Setter = value => context.TimeSeriesServer = value, Getter = () => context.TimeSeriesServer, Description = "AQTS server" }, new Option { Key = nameof(context.TimeSeriesUsername), Setter = value => context.TimeSeriesUsername = value, Getter = () => context.TimeSeriesUsername, Description = "AQTS username" }, new Option { Key = nameof(context.TimeSeriesPassword), Setter = value => context.TimeSeriesPassword = value, Getter = () => context.TimeSeriesPassword, Description = "AQTS password" }, new Option(), new Option { Description = "Export options:" }, new Option { Key = nameof(context.DryRun), Setter = value => context.DryRun = ParseBoolean(value), Getter = () => $"{context.DryRun}", Description = "When true, don't export and upload reports, just validate what would be done." }, new Option { Key = nameof(context.ExportTemplateName), Setter = value => context.ExportTemplateName = value, Getter = () => context.ExportTemplateName, Description = "The Observation Export Spreadsheet Template to use for all exports." }, new Option { Key = nameof(context.AttachmentFilename), Setter = value => context.AttachmentFilename = value, Getter = () => context.AttachmentFilename, Description = $"Filename of the exported attachment." }, new Option { Key = nameof(context.AttachmentTags), Setter = value => ParseAttachmentTagValue(context, value), Getter = () => string.Empty, Description = "Uploaded attachments will have these tag values applies, in key:value format." }, new Option { Key = nameof(context.DeleteExistingAttachments), Setter = value => context.DeleteExistingAttachments = ParseBoolean(value), Getter = () => $"{context.DeleteExistingAttachments}", Description = "Delete any existing location attachments with the same name." }, new Option { Key = nameof(context.ExportTime), Setter = value => context.ExportTime = ParseDateTimeOffset(value), Getter = () => string.Empty, Description = $"The timestamp used for all {{{FilenameGenerator.TimePattern}}} pattern substitutions. [default: The current time]" }, new Option(), new Option { Description = "Cumulative filter options: (ie. AND-ed together). Can be set multiple times." }, new Option { Key = nameof(context.StartTime), Setter = value => context.StartTime = ParseDateTimeOffset(value), Getter = () => string.Empty, Description = "Include observations after this time. [default: Start of record]" }, new Option { Key = nameof(context.EndTime), Setter = value => context.EndTime = ParseDateTimeOffset(value), Getter = () => string.Empty, Description = "Include observations before this time. [default: End of record]" }, new Option { Key = nameof(context.LocationIds).Singularize(), Setter = value => ParseListItem(context.LocationIds, value), Getter = () => string.Empty, Description = "Observations matching these sampling locations." }, new Option { Key = nameof(context.LocationGroupIds).Singularize(), Setter = value => ParseListItem(context.LocationGroupIds, value), Getter = () => string.Empty, Description = "Observations matching these sampling location groups." }, new Option { Key = nameof(context.AnalyticalGroupIds).Singularize(), Setter = value => ParseListItem(context.AnalyticalGroupIds, value), Getter = () => string.Empty, Description = "Observations matching these analytical groups." }, new Option { Key = nameof(context.ObservedPropertyIds).Singularize(), Setter = value => ParseListItem(context.ObservedPropertyIds, value), Getter = () => string.Empty, Description = "Observations matching these observed properties." }, }; var usageMessage = $"Export observations from AQUARIUS Samples using a spreadsheet template into AQUARIUS Time-Series locations as attachments." + $"\n" + $"\nusage: {ExeHelper.ExeName} [-option=value] [@optionsFile] ..." + $"\n" + $"\nSupported -option=value settings (/option=value works too):\n\n {string.Join("\n ", options.Select(o => o.UsageText()))}" + $"\n" + $"\nUse the @optionsFile syntax to read more options from a file." + $"\n" + $"\n Each line in the file is treated as a command line option." + $"\n Blank lines and leading/trailing whitespace is ignored." + $"\n Comment lines begin with a # or // marker." ; var helpGuidance = "See /help screen for details."; foreach (var arg in resolvedArgs) { var match = ArgRegex.Match(arg); if (!match.Success) { if (HelpKeyWords.Contains(arg)) { throw new ExpectedException(usageMessage); } throw new ExpectedException($"Unknown argument: {arg}\n\n{helpGuidance}"); } var key = match.Groups["key"].Value.ToLower(); var value = match.Groups["value"].Value; var option = options.FirstOrDefault(o => o.Key != null && o.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)); if (option == null) { throw new ExpectedException($"Unknown -option=value: {arg}\n\n{helpGuidance}"); } option.Setter(value); } return(context); }