private static Context ParseArgs(string[] args) { var context = new Context(); var options = new[] { new CommandLineOption { Key = nameof(context.AssemblyFolder), Setter = value => context.AssemblyFolder = value, Getter = () => context.AssemblyFolder, Description = "Path to the folder containing the plugin." }, new CommandLineOption { Key = nameof(context.AssemblyPath), Setter = value => context.AssemblyPath = value, Getter = () => context.AssemblyPath, Description = "Path to the plugin assembly." }, new CommandLineOption { Key = nameof(context.OutputPath), Setter = value => context.OutputPath = value, Getter = () => context.OutputPath, Description = "Path to packaged output file." }, new CommandLineOption { Key = nameof(context.DeployedFolderName), Setter = value => context.DeployedFolderName = value, Getter = () => context.DeployedFolderName, Description = "Name of the deployed folder" }, new CommandLineOption { Key = nameof(context.Description), Setter = value => context.Description = value, Getter = () => context.Description, Description = "Description of the plugin" }, new CommandLineOption { Key = nameof(context.AssemblyQualifiedTypeName), Setter = value => context.AssemblyQualifiedTypeName = value, Getter = () => context.AssemblyQualifiedTypeName, Description = "Assembly-qualified type name of the plugin" }, new CommandLineOption { Key = nameof(context.Subfolders), Setter = value => context.Subfolders = bool.Parse(value), Getter = () => context.Subfolders.ToString(), Description = "Include all subfolders" }, new CommandLineOption { Key = nameof(context.Include), Setter = value => AddToList(value, context.Include), Getter = () => string.Join(", ", context.Include), Description = "Include file or DOS wildcard pattern" }, new CommandLineOption { Key = nameof(context.Exclude), Setter = value => AddToList(value, context.Exclude), Getter = () => string.Join(", ", context.Exclude), Description = "Exclude file or DOS wildcard pattern" }, }; var usageMessage = CommandLineUsage.ComposeUsageText( "Package a field data plugin into a deployable .plugin file.", options); var optionResolver = new CommandLineOptionResolver(); optionResolver.Resolve(args, options, usageMessage, arg => ResolvePositionalArgument(context, arg)); if (string.IsNullOrEmpty(context.AssemblyFolder) && string.IsNullOrEmpty(context.AssemblyPath)) { throw new ExpectedException($"You must specify at least one /{nameof(context.AssemblyPath)} or /{nameof(context.AssemblyFolder)} option."); } if (string.IsNullOrEmpty(context.OutputPath)) { throw new ExpectedException($"You must specify the /{nameof(context.OutputPath)} option."); } return(context); }
private void ParseArgs(string[] args) { var options = new[] { new CommandLineOption { Key = "Plugin", Setter = value => Context.PluginPath = value, Getter = () => Context.PluginPath, Description = "Path to the plugin assembly to debug" }, new CommandLineOption { Key = "Data", Setter = value => AddDataPath(Context, value), Getter = () => string.Empty, Description = "Path to the data file to be parsed. Can be set more than once." }, new CommandLineOption { Key = nameof(Context.RecursiveSearch), Setter = value => Context.RecursiveSearch = bool.Parse(value), Getter = () => $"{Context.RecursiveSearch}", Description = "Search /Data directories recursively. -R shortcut is also supported." }, new CommandLineOption { Key = "Location", Setter = value => Context.LocationIdentifier = value, Getter = () => Context.LocationIdentifier, Description = "Optional location identifier context" }, new CommandLineOption { Key = "UtcOffset", Setter = value => Context.LocationUtcOffset = TimeSpan.Parse(value), Getter = () => Context.LocationUtcOffset.ToString(), Description = "UTC offset in .NET TimeSpan format." }, new CommandLineOption { Key = "Json", Setter = value => Context.JsonPath = value, Getter = () => Context.JsonPath, Description = "Optional path to write the appended results as JSON" }, new CommandLineOption { Key = "Setting", Setter = value => AddSetting(Context, value), Getter = () => string.Empty, Description = "Supply plugin settings as 'key=text' or 'key=@pathToTextFile' values." }, new CommandLineOption { Key = "ExpectedError", Setter = value => Context.ExpectedError = value, Getter = () => Context.ExpectedError, Description = "Expected error message" }, new CommandLineOption { Key = "ExpectedStatus", Setter = value => Context.ExpectedStatus = (ParseFileStatus)Enum.Parse(typeof(ParseFileStatus), value, true), Getter = () => Context.ExpectedStatus.ToString(), Description = $"Expected parse status. One of {string.Join(", ", Enum.GetNames(typeof(ParseFileStatus)))}" }, }; var usageMessage = CommandLineUsage.ComposeUsageText( "Parse a file using a field data plugin, logging the results.", options); var optionResolver = new CommandLineOptionResolver(); optionResolver.Resolve(args, options, usageMessage, arg => PositionalArgumentResolver(Context, arg)); if (string.IsNullOrEmpty(Context.PluginPath)) { throw new ExpectedException("No plugin assembly specified."); } if (!Context.DataPaths.Any()) { throw new ExpectedException("No data file specified."); } }
private void ParseArgs(string[] args) { var options = new[] { new CommandLineOption { Description = "Specify the plugin to be tested" }, new CommandLineOption { Key = "Plugin", Setter = value => Context.PluginPath = value, Getter = () => Context.PluginPath, Description = "Path to the plugin assembly. Can be a folder, a DLL, or a packaged *.plugin file." }, new CommandLineOption { Key = nameof(Context.Verbose), Setter = value => Context.Verbose = bool.Parse(value), Getter = () => $"{Context.Verbose}", Description = "Enables verbose logging of assembly loading logic." }, new CommandLineOption { Key = nameof(Context.FrameworkAssemblyPath), Setter = value => Context.FrameworkAssemblyPath = value, Getter = () => Context.FrameworkAssemblyPath, Description = "Optional path to the FieldDataPluginFramework.dll assembly. [default: Test using the latest framework version]" }, new CommandLineOption(), new CommandLineOption { Description = "Test data settings" }, new CommandLineOption { Key = "Data", Setter = value => AddDataPath(Context, value), Getter = () => string.Empty, Description = "Path to the data file to be parsed. Can be set more than once." }, new CommandLineOption { Key = nameof(Context.RecursiveSearch), Setter = value => Context.RecursiveSearch = bool.Parse(value), Getter = () => $"{Context.RecursiveSearch}", Description = "Search /Data directories recursively. -R shortcut is also supported." }, new CommandLineOption { Key = "Setting", Setter = value => AddSetting(Context, value), Getter = () => string.Empty, Description = "Supply plugin settings as 'key=text' or 'key=@pathToTextFile' values." }, new CommandLineOption(), new CommandLineOption { Description = "Plugin context settings" }, new CommandLineOption { Key = "Location", Setter = value => Context.LocationIdentifier = value, Getter = () => Context.LocationIdentifier, Description = "Optional location identifier context" }, new CommandLineOption { Key = "UtcOffset", Setter = value => Context.LocationUtcOffset = TimeSpan.Parse(value), Getter = () => Context.LocationUtcOffset.ToString(), Description = "UTC offset in .NET TimeSpan format." }, new CommandLineOption(), new CommandLineOption { Description = "Output settings" }, new CommandLineOption { Key = "Json", Setter = value => Context.JsonPath = value, Getter = () => Context.JsonPath, Description = "Optional path (file or folder) to write the appended results as JSON." }, new CommandLineOption(), new CommandLineOption { Description = "Expected response settings" }, new CommandLineOption { Key = nameof(Context.ExpectedError), Setter = value => Context.ExpectedError = value, Getter = () => Context.ExpectedError, Description = "Expected error message" }, new CommandLineOption { Key = nameof(Context.ExpectedStatus), Setter = value => Context.ExpectedStatus = (StatusType)Enum.Parse(typeof(StatusType), value, true), Getter = () => Context.ExpectedStatus.ToString(), Description = $"Expected parse status. One of {string.Join(", ", Enum.GetNames(typeof(StatusType)))}" }, }; var usageMessage = CommandLineUsage.ComposeUsageText( "Parse a file using a field data plugin, logging the results.", options); var optionResolver = new CommandLineOptionResolver(); optionResolver.Resolve(args, options, usageMessage, arg => PositionalArgumentResolver(Context, arg)); if (string.IsNullOrEmpty(Context.PluginPath)) { throw new ExpectedException("No plugin assembly specified."); } if (!Context.DataPaths.Any()) { throw new ExpectedException("No data file specified."); } }
public static Context GetContext(Context context, string[] args) { context.LocationAliases.Clear(); var options = new[] { new CommandLineOption { Description = "AQTS connection settings" }, new CommandLineOption { Key = nameof(context.Server), Setter = value => context.Server = value, Getter = () => context.Server, Description = "The AQTS app server." }, new CommandLineOption { Key = nameof(context.Username), Setter = value => context.Username = value, Getter = () => context.Username, Description = "AQTS username." }, new CommandLineOption { Key = nameof(context.Password), Setter = value => context.Password = value, Getter = () => context.Password, Description = "AQTS credentials." }, new CommandLineOption { Key = nameof(context.MaximumConnectionAttempts), Setter = value => context.MaximumConnectionAttempts = int.Parse(value), Getter = () => context.MaximumConnectionAttempts.ToString(), Description = "The maximum number of connection attempts before exiting." }, new CommandLineOption { Key = nameof(context.ConnectionRetryDelay), Setter = value => context.ConnectionRetryDelay = TimeSpan.Parse(value), Getter = () => context.ConnectionRetryDelay.ToString(), Description = "The TimeSpan to wait in between AQTS connection attempts." }, new CommandLineOption { Key = nameof(context.MaximumConcurrentRequests), Setter = value => context.MaximumConcurrentRequests = int.Parse(value), Getter = () => context.MaximumConcurrentRequests.ToString(), Description = "Maximum concurrent requests during field visit import." }, new CommandLineOption(), new CommandLineOption { Description = "Visit merge settings" }, new CommandLineOption { Key = nameof(context.MergeMode), Setter = value => context.MergeMode = ParseEnum <MergeMode>(value), Getter = () => context.MergeMode.ToString(), Description = $"One of {DescribeEnumValues<MergeMode>()}." }, new CommandLineOption { Key = nameof(context.OverlapIncludesWholeDay), Setter = value => context.OverlapIncludesWholeDay = bool.Parse(value), Getter = () => context.OverlapIncludesWholeDay.ToString(), Description = $"True if a conflict includes any visit on same day. False can generate multiple visits on the same day." }, new CommandLineOption { Key = nameof(context.MaximumVisitDuration), Setter = value => context.MaximumVisitDuration = TimeSpan.Parse(value), Getter = () => context.MaximumVisitDuration.ToString(), Description = "Maximum visit duration. Visits exceeding this duration will not be imported." }, new CommandLineOption { Key = nameof(context.DryRun), Setter = value => context.DryRun = bool.Parse(value), Getter = () => context.DryRun.ToString(), Description = $"True if no visits will be imported. Use /N as a shortcut." }, new CommandLineOption(), new CommandLineOption { Description = "Location alias settings" }, new CommandLineOption { Key = nameof(context.LocationAliases), Setter = value => ParseLocationAliases(context, value), Getter = () => string.Empty, Description = $"A list of location aliases, in alias=locationIdentifier syntax." }, new CommandLineOption(), new CommandLineOption { Description = "Plugin configuration settings" }, new CommandLineOption { Key = nameof(context.PluginSettings), Setter = value => AddSetting(context, value), Getter = () => string.Empty, Description = $"Configure plugin settings as 'pluginFolderName=key=text' or 'pluginFolderName=key=@pathToTextFile' values." }, new CommandLineOption { Key = nameof(context.PluginPriority), Setter = value => AddPluginPriority(context, value), Getter = () => string.Empty, Description = $"Configure plugin priority as 'pluginFolderName=integerPriority' [defaults to the AQTS plugin priority]" }, new CommandLineOption { Key = nameof(context.Verbose), Setter = value => context.Verbose = bool.Parse(value), Getter = () => $"{context.Verbose}", Description = "Enables verbose logging of plugin assembly loading logic." }, new CommandLineOption(), new CommandLineOption { Description = "File monitoring settings" }, new CommandLineOption { Key = nameof(context.HotFolderPath), Setter = value => context.HotFolderPath = value, Getter = () => context.HotFolderPath, Description = "The root path to monitor for field visit files." }, new CommandLineOption { Key = nameof(context.FileMask), Setter = value => context.FileMask = value, Getter = () => context.FileMask, Description = "A comma-separated list of file patterns to monitor. [defaults to '*.*' if omitted]" }, new CommandLineOption { Key = nameof(context.FileQuietDelay), Setter = value => context.FileQuietDelay = TimeSpan.Parse(value), Getter = () => context.FileQuietDelay.ToString(), Description = "Timespan of no file activity before processing begins." }, new CommandLineOption { Key = nameof(context.FileScanInterval), Setter = value => context.FileScanInterval = TimeSpan.Parse(value), Getter = () => context.FileScanInterval.ToString(), Description = "Maximum timespan between scanning for new files." }, new CommandLineOption { Key = nameof(context.ProcessingFolder), Setter = value => context.ProcessingFolder = value, Getter = () => context.ProcessingFolder, Description = "Move files to this folder during processing." }, new CommandLineOption { Key = nameof(context.UploadedFolder), Setter = value => context.UploadedFolder = value, Getter = () => context.UploadedFolder, Description = "Move files to this folder after successful uploads." }, new CommandLineOption { Key = nameof(context.PartialFolder), Setter = value => context.PartialFolder = value, Getter = () => context.PartialFolder, Description = "Move files to this folder if when partial uploads are performed to avoid duplicates." }, new CommandLineOption { Key = nameof(context.ArchivedFolder), Setter = value => context.ArchivedFolder = value, Getter = () => context.ArchivedFolder, Description = $"Any visits replaced via /{nameof(context.MergeMode)}={MergeMode.ArchiveAndReplace} will be archived here before being replace with new visits." }, new CommandLineOption { Key = nameof(context.FailedFolder), Setter = value => context.FailedFolder = value, Getter = () => context.FailedFolder, Description = "Move files to this folder if an upload error occurs." }, new CommandLineOption { Key = nameof(context.MaximumFileCount), Setter = value => context.MaximumFileCount = int.Parse(value), Getter = () => $"{context.MaximumFileCount}", Description = "Maximum number of files to process before exiting. [default: Keep running forever]" }, new CommandLineOption { Key = nameof(context.MaximumFileWaitInterval), Setter = value => context.MaximumFileWaitInterval = TimeSpan.Parse(value), Getter = () => $"{context.MaximumFileWaitInterval}", Description = "Maximum TimeSpan to wait for new files before exiting. [default: Keep running forever]" }, new CommandLineOption { Key = nameof(context.MaximumDuplicateRetry), Setter = value => context.MaximumDuplicateRetry = int.Parse(value), Getter = () => $"{context.MaximumDuplicateRetry}", Description = "Maximum number of retries for duplicate visits." }, new CommandLineOption(), new CommandLineOption { Description = "Export settings" }, new CommandLineOption { Key = nameof(context.ExportFolder), Setter = value => context.ExportFolder = value, Getter = () => context.ExportFolder, Description = "Export visits to this root folder." }, new CommandLineOption { Key = nameof(context.ExportLocations), Setter = value => ParseExportLocations(context, value), Description = "Export only these locations [default: All locations]" }, new CommandLineOption { Key = nameof(context.ExportBefore), Setter = value => context.ExportBefore = ParseDateTimeOffset(value), Description = "Export existing visits before this time." }, new CommandLineOption { Key = nameof(context.ExportAfter), Setter = value => context.ExportAfter = ParseDateTimeOffset(value), Description = "Export existing visits after this time." }, new CommandLineOption { Key = nameof(context.ExportOverwrite), Setter = value => context.ExportOverwrite = bool.Parse(value), Getter = () => context.ExportOverwrite.ToString(), Description = $"When true, any already exported visits will be re-exported." }, new CommandLineOption { Key = nameof(context.ExportUtcOverride), Setter = value => context.ExportUtcOverride = ParseUtcOffset(value), Getter = () => context.ExportUtcOverride.ToString(), Description = $"When set, change all timestamps in exported visits to the specific UTC offset. Supported formats: ±HH, ±HHmm, ±HH:mm." }, }; var usageMessage = CommandLineUsage.ComposeUsageText( "Purpose: Monitors a folder for field visit files and appends them to an AQTS app server", options); var optionResolver = new CommandLineOptionResolver(); optionResolver.Resolve(InjectOptionsFileByDefault(args), options, usageMessage, arg => ResolvePositionalArgument(context, arg)); ValidateContext(context); return(context); }