private Result <List <CoverageFile>, string> BuildCoverageFiles(ConfigurationSettings args)
        {
            var pathProcessor = new PathProcessor(args.BasePath);

            var files = new List <CoverageFile>();

            foreach (var source in args.CoverageSources)
            {
                var mode          = source.Mode;
                var coverageFiles = LoadCoverageFiles(mode, pathProcessor, source.Input, args.UseRelativePaths);
                if (!coverageFiles.Successful)
                {
                    return(coverageFiles.Error);
                }

                files.AddRange(coverageFiles.Value);
            }

            Debug.Assert(files != null, "Files should always be returned.");
            return(files);
        }
        public Result <Unit, string> Run(
            ConfigurationSettings settings,
            Either <GitData, CommitSha>?gitData,
            CoverageMetadata metadata)
        {
            _ = settings ?? throw new ArgumentNullException(nameof(settings));
            _ = metadata ?? throw new ArgumentNullException(nameof(metadata));

            var outputFile = ResolveOutpuFile(settings);

            // Main Processing
            var files = BuildCoverageFiles(settings);

            if (!files.Successful)
            {
                return(files.Error);
            }

            var data = new CoverallData(
                repoToken: settings.RepoToken,
                serviceName: metadata.ServiceName,
                sourceFiles: files.Value.ToArray())
            {
                ServiceJobId  = metadata.ServiceJobId,
                ServiceNumber = metadata.ServiceBuildNumber,
                PullRequestId = metadata.PullRequestId,
                Parallel      = metadata.Parallel,
            };

            if (gitData.HasValue)
            {
                gitData.Value.Match(
                    git =>
                {
                    data.Git = git;
                },
                    sha =>
                {
                    data.CommitSha = sha.Value;
                });
            }

            var fileData = JsonConvert.SerializeObject(data);

            if (outputFile.IsNotNullOrWhitespace())
            {
                WriteFileData(_fileSystem, fileData, outputFile);
            }

            if (!settings.DryRun)
            {
                var uploadResult = UploadCoverage(fileData);
                if (!uploadResult.Successful)
                {
                    if (settings.TreatUploadErrorsAsWarnings)
                    {
                        _console.WriteLine(uploadResult.Error);
                    }
                    else
                    {
                        return(uploadResult.Error);
                    }
                }
            }

            return(Unit.Default);
        }