public int Run(FileWorkItemsOptions options, IFileSystem fileSystem) { var filingContext = new SarifWorkItemContext(); if (!string.IsNullOrEmpty(options.ConfigurationFilePath)) { filingContext.LoadFromXml(options.ConfigurationFilePath); } if (!ValidateOptions(options, filingContext, fileSystem)) { return(FAILURE); } // For unit tests: allow us to just validate the options and return. if (s_validateOptionsOnly) { return(SUCCESS); } string logFileContents = fileSystem.ReadAllText(options.InputFilePath); EnsureValidSarifLogFile(logFileContents, options.InputFilePath); if (options.SplittingStrategy != SplittingStrategy.None) { filingContext.SplittingStrategy = options.SplittingStrategy; } if (options.DataToRemove.ToFlags() != OptionallyEmittedData.None) { filingContext.DataToRemove = options.DataToRemove.ToFlags(); } if (options.DataToInsert.ToFlags() != OptionallyEmittedData.None) { filingContext.DataToInsert = options.DataToInsert.ToFlags(); } var filer = new SarifWorkItemFiler(filingContext); filer.FileWorkItems(logFileContents); // TODO: We need to process updated work item models to persist filing // details back to the input SARIF file, if that was specified. // The SarifWorkItemFiler should either return or persist the updated // models via a property, so that we can do this work. // // This information should be inlined to the input file, if configured, // or persisted to a new SARIF file, if configured. If neither of // those options is specified, there is no work to do. // // https://github.com/microsoft/sarif-sdk/issues/1774 return(SUCCESS); }
private bool ValidateOptions(FileWorkItemsOptions options, IFileSystem fileSystem) { bool valid = true; // The CommandLine package lets you declare an option of any type with a constructor // that accepts a string. We could have declared the property corresponding to the // "project-uri" option to be of type Uri, in which case CommandLine would have // populated it by invoking the Uri(string) ctor. This overload requires its argument // to be an absolute URI. This happens to be what we want; the problem is that if the // user supplies a relative URI, CommandLine produces this error: // // Option 'p, project-uri' is defined with a bad format. // Required option 'p, project-uri' is missing. // // That's not as helpful as a message like this: // // The value of the 'p, project-uri' option must be an absolute URI. // // Therefore we declare the property corresponding to "project-uri" as a string. // We convert it to a URI with the ctor Uri(string, UriKind.RelativeOrAbsolute). // If it succeeds, we can assign the result to a Uri-valued property; if it fails, // we can produce a helpful error message. options.ProjectUri = new Uri(options.ProjectUriString, UriKind.RelativeOrAbsolute); if (!options.ProjectUri.IsAbsoluteUri) { string optionDescription = DriverUtilities.GetOptionDescription <FileWorkItemsOptions>(nameof(options.ProjectUriString)); Console.Error.WriteLine( string.Format( CultureInfo.CurrentCulture, MultitoolResources.WorkItemFiling_ErrorUriIsNotAbsolute, options.ProjectUriString, optionDescription)); valid = false; } valid &= options.ValidateOutputOptions(); valid &= DriverUtilities.ReportWhetherOutputFileCanBeCreated(options.OutputFilePath, options.Force, fileSystem); return(valid); }
private static bool EnsurePersonalAccessToken(FileWorkItemsOptions options, SarifWorkItemContext workItemFilingConfiguration) { string pat = Environment.GetEnvironmentVariable("SarifWorkItemFilingPat"); if (!string.IsNullOrEmpty(pat)) { workItemFilingConfiguration.PersonalAccessToken = pat; } if (string.IsNullOrEmpty(workItemFilingConfiguration.PersonalAccessToken)) { // "No security token was provided. Populate the 'SarifWorkItemFilingPath' environment // variable with a valid personal access token or pass a token in a configuration file using // the --configuration arguement." Console.Error.WriteLine(MultitoolResources.WorkItemFiling_NoPatFound); return(false); } return(true); }
private bool ValidateOptions(FileWorkItemsOptions options, SarifWorkItemContext sarifWorkItemContext, IFileSystem fileSystem) { bool valid = true; // The CommandLine package lets you declare an option of any type with a constructor // that accepts a string. We could have declared the property corresponding to the // "project-uri" option to be of type Uri, in which case CommandLine would have // populated it by invoking the Uri(string) ctor. This overload requires its argument // to be an absolute URI. This happens to be what we want; the problem is that if the // user supplies a relative URI, CommandLine produces this error: // // Option 'p, project-uri' is defined with a bad format. // Required option 'p, project-uri' is missing. // // That's not as helpful as a message like this: // // The value of the 'p, project-uri' option must be an absolute URI. // // Therefore we declare the property corresponding to "project-uri" as a string. // We convert it to a URI with the ctor Uri(string, UriKind.RelativeOrAbsolute). // If it succeeds, we can assign the result to a Uri-valued property (persisted in the // context object); if it fails, we can produce a helpful error message. valid &= ValidateHostUri(options.HostUri, sarifWorkItemContext); valid &= options.Validate(); if (!string.IsNullOrEmpty(options.OutputFilePath)) { valid &= DriverUtilities.ReportWhetherOutputFileCanBeCreated(options.OutputFilePath, options.Force, fileSystem); } valid &= EnsurePersonalAccessToken(sarifWorkItemContext); return(valid); }
public int Run(FileWorkItemsOptions options, IFileSystem fileSystem) { using (var filingContext = new SarifWorkItemContext()) { if (!string.IsNullOrEmpty(options.ConfigurationFilePath)) { filingContext.LoadFromXml(options.ConfigurationFilePath); } if (!ValidateOptions(options, filingContext, fileSystem)) { return(FAILURE); } // For unit tests: allow us to just validate the options and return. if (s_validateOptionsOnly) { return(SUCCESS); } string logFileContents = fileSystem.FileReadAllText(options.InputFilePath); if (!options.DoNotValidate) { EnsureValidSarifLogFile(logFileContents, options.InputFilePath); } if (options.SplittingStrategy != SplittingStrategy.None) { filingContext.SplittingStrategy = options.SplittingStrategy; } if (options.SyncWorkItemMetadata != null) { filingContext.SyncWorkItemMetadata = options.SyncWorkItemMetadata.Value; } if (options.ShouldFileUnchanged != null) { filingContext.ShouldFileUnchanged = options.ShouldFileUnchanged.Value; } if (options.DataToRemove.ToFlags() != OptionallyEmittedData.None) { filingContext.DataToRemove = options.DataToRemove.ToFlags(); } if (options.DataToInsert.ToFlags() != OptionallyEmittedData.None) { filingContext.DataToInsert = options.DataToInsert.ToFlags(); } SarifLog sarifLog = null; using (var filer = new SarifWorkItemFiler(filingContext.HostUri, filingContext)) { sarifLog = filer.FileWorkItems(logFileContents); } // By the time we're here, we have updated options.OutputFilePath with the // options.InputFilePath argument (in the presence of --inline) and validated // that we can write to this location with one exception: we do not currently // handle inlining to a read-only location. string outputFilePath = options.OutputFilePath; if (!string.IsNullOrEmpty(outputFilePath)) { string sarifLogText = JsonConvert.SerializeObject(sarifLog, options.Formatting); fileSystem.FileWriteAllText(outputFilePath, sarifLogText); } } return(SUCCESS); }
public int Run(FileWorkItemsOptions options) => Run(options, new FileSystem());
public void ConsumeEnvVarsAndInterpretOptions(FileWorkItemsOptions fileWorkItemsOptions) { ConsumeEnvVarsAndInterpretOptions((SingleFileOptionsBase)fileWorkItemsOptions); }
public int Run(FileWorkItemsOptions options, IFileSystem fileSystem) { if (!ValidateOptions(options, fileSystem)) { return(FAILURE); } // For unit tests: allow us to just validate the options and return. if (s_validateOptionsOnly) { return(SUCCESS); } string projectName = options.ProjectUri.GetProjectName(); string logFileContents = fileSystem.ReadAllText(options.InputFilePath); EnsureValidSarifLogFile(logFileContents, options.InputFilePath); FilingTarget filingTarget = FilingTargetFactory.CreateFilingTarget(options.ProjectUriString); var filer = new WorkItemFiler(filingTarget); SarifLog sarifLog = JsonConvert.DeserializeObject <SarifLog>(logFileContents); if (options.DataToRemove != null) { var dataRemovingVisitor = new RemoveOptionalDataVisitor(options.DataToRemove.ToFlags()); dataRemovingVisitor.Visit(sarifLog); } for (int runIndex = 0; runIndex < sarifLog.Runs.Count; ++runIndex) { if (sarifLog.Runs[runIndex]?.Results?.Count > 0) { IList <SarifLog> logsToProcess = new List <SarifLog>(new SarifLog[] { sarifLog }); if (options.GroupingStrategy != GroupingStrategy.PerRun) { SplittingVisitor visitor = (options.GroupingStrategy == GroupingStrategy.PerRunPerRule ? (SplittingVisitor) new PerRunPerRuleSplittingVisitor() : new PerRunPerTargetPerRuleSplittingVisitor()); visitor.VisitRun(sarifLog.Runs[runIndex]); logsToProcess = visitor.SplitSarifLogs; } IList <WorkItemFilingMetadata> workItemMetadata = new List <WorkItemFilingMetadata>(logsToProcess.Count); for (int splitFileIndex = 0; splitFileIndex < logsToProcess.Count; splitFileIndex++) { SarifLog splitLog = logsToProcess[splitFileIndex]; workItemMetadata.Add(splitLog.CreateWorkItemFilingMetadata(projectName, options.TemplateFilePath)); } try { IEnumerable <WorkItemFilingMetadata> filedWorkItems = filer.FileWorkItems(options.ProjectUri, workItemMetadata, options.PersonalAccessToken).Result; Console.WriteLine($"Created {filedWorkItems.Count()} work items for run {runIndex}."); } catch (Exception ex) { Console.Error.WriteLine(ex); } } } Console.WriteLine($"Writing log with work item Ids to {options.OutputFilePath}."); WriteSarifFile <SarifLog>(fileSystem, sarifLog, options.OutputFilePath, (options.PrettyPrint ? Formatting.Indented : Formatting.None)); return(SUCCESS); }