示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
 }
示例#8
0
        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);
        }