コード例 #1
0
        private void AddConfigurationDefaults(XElement configuration, XNamespace xNameSpace, CodeCoverageEnablerInputs mavenCcParams, bool isPrepartAgentExecution = false)
        {
            var      excludesElement = CodeCoverageUtilities.GetClassDataForMaven(mavenCcParams.Exclude, "excludes", "exclude", true);
            XElement includesElement;

            if (!isPrepartAgentExecution)
            {
                includesElement = CodeCoverageUtilities.GetClassDataForMaven(mavenCcParams.Include, "includes", "include", true);
            }
            else
            {
                includesElement = new XElement("includes",
                                               new XElement("include", "**/*"));
            }

            configuration.SetElementValue(xNameSpace + "destFile", Path.Combine(mavenCcParams.ReportDirectory, _jacocoExecPrefix + ".exec"));
            configuration.SetElementValue(xNameSpace + "outputDirectory", mavenCcParams.ReportDirectory);
            configuration.SetElementValue(xNameSpace + "dataFile", Path.Combine(mavenCcParams.ReportDirectory, _jacocoExecPrefix + ".exec"));
            configuration.SetElementValue(xNameSpace + "append", "true");

            // remove any existing excludes and includes. We cannot directly set the values here as the value is not one single object but multiple xelements
            configuration.SetElementValue(xNameSpace + excludesElement.Name.ToString(), null);
            configuration.SetElementValue(xNameSpace + includesElement.Name.ToString(), null);

            // add includes and excludes from user inputs
            configuration.Add(includesElement);
            configuration.Add(excludesElement);
        }
コード例 #2
0
        private XmlNode GetInstrumentNode(CodeCoverageEnablerInputs antCCParams, string instrumentedClassesDirectory, string dataFile)
        {
            var inclusionExclusionSet = CodeCoverageUtilities.GetClassDataForAnt(antCCParams.Include, antCCParams.Exclude, antCCParams.ClassFilesDirectories);

            var targetXml = string.Format(CodeCoverageConstants.CoberturaInstrumentNode, instrumentedClassesDirectory, dataFile, inclusionExclusionSet);

            return(GetXmlNode(targetXml));
        }
コード例 #3
0
        public void VerifyInputsForCoberturaAnt(IExecutionContext context)
        {
            ClassFilesDirectories = CodeCoverageUtilities.TrimNonEmptyParam(ClassFilesDirectories, "ClassFilesDirectories");
            ReportDirectory       = CodeCoverageUtilities.TrimNonEmptyParam(ReportDirectory, "ReportDirectory");
            CCReportTask          = CodeCoverageUtilities.TrimNonEmptyParam(CCReportTask, "CodeCoverageReportTarget");
            ReportBuildFile       = CodeCoverageUtilities.TrimNonEmptyParam(ReportBuildFile, "CodeCoverageReportBuildFile");
            CodeCoverageUtilities.ThrowIfClassFilesDirectoriesIsInvalid(ClassFilesDirectories);

            SourceDirectories = CodeCoverageUtilities.SetCurrentDirectoryIfDirectoriesParameterIsEmpty(context, SourceDirectories, StringUtil.Loc("SourceDirectoriesNotSpecified"));
        }
コード例 #4
0
        private IEnumerable <CodeCoverageStatistics> ReadDataFromNodes(XmlDocument doc, string summaryXmlLocation)
        {
            var listCoverageStats = new List <CodeCoverageStatistics>();

            if (doc == null)
            {
                return(null);
            }

            //read data from report nodes
            XmlNode reportNode = doc.SelectSingleNode("report");

            if (reportNode != null)
            {
                XmlNodeList counterNodeList = doc.SelectNodes("/report/counter");
                if (counterNodeList != null)
                {
                    foreach (XmlNode counterNode in counterNodeList)
                    {
                        var coverageStatistics = new CodeCoverageStatistics();

                        if (counterNode.Attributes != null)
                        {
                            if (counterNode.Attributes["type"] != null)
                            {
                                coverageStatistics.Label    = ToTitleCase(counterNode.Attributes["type"].Value);
                                coverageStatistics.Position = CodeCoverageUtilities.GetPriorityOrder(coverageStatistics.Label);
                            }

                            if (counterNode.Attributes[_covered] != null)
                            {
                                float covered;
                                if (!float.TryParse(counterNode.Attributes[_covered].Value, out covered))
                                {
                                    throw new InvalidDataException(StringUtil.Loc("InvalidValueInXml", _covered, summaryXmlLocation));
                                }
                                coverageStatistics.Covered = (int)covered;
                                if (counterNode.Attributes[_missed] != null)
                                {
                                    float missed;
                                    if (!float.TryParse(counterNode.Attributes[_missed].Value, out missed))
                                    {
                                        throw new InvalidDataException(StringUtil.Loc("InvalidValueInXml", _missed, summaryXmlLocation));
                                    }
                                    coverageStatistics.Total = (int)missed + (int)covered;
                                }
                            }
                        }

                        listCoverageStats.Add(coverageStatistics);
                    }
                }
            }
            return(listCoverageStats.AsEnumerable());
        }
コード例 #5
0
        private string GetAntReport(CodeCoverageEnablerInputs antCCParams)
        {
            var executionData = string.Empty;

            executionData += @"             <file file='" + Path.Combine(antCCParams.ReportDirectory, _jacocoExecPrefix + ".exec") + @"'/>" + Environment.NewLine;


            var srcData   = CodeCoverageUtilities.GetSourceDataForJacoco(antCCParams.SourceDirectories);
            var classData = CodeCoverageUtilities.GetClassDataForAnt(antCCParams.Include, antCCParams.Exclude, antCCParams.ClassFilesDirectories);

            return(string.Format(CodeCoverageConstants.JacocoAntReport, antCCParams.CCReportTask, executionData, classData, srcData, antCCParams.ReportDirectory, Path.Combine(antCCParams.ReportDirectory, "report.csv"), Path.Combine(antCCParams.ReportDirectory, antCCParams.SummaryFile)));
        }
コード例 #6
0
        private CodeCoverageStatistics GetCCStats(string labelTag, string coveredTag, string validTag, string priorityTag, string summaryXmlLocation, XmlNode reportNode)
        {
            CodeCoverageStatistics coverageStatistics = null;

            if (reportNode.Attributes[coveredTag] != null && reportNode.Attributes[validTag] != null)
            {
                coverageStatistics          = new CodeCoverageStatistics();
                coverageStatistics.Label    = labelTag;
                coverageStatistics.Position = CodeCoverageUtilities.GetPriorityOrder(priorityTag);

                coverageStatistics.Covered = (int)ParseFromXML(coveredTag, summaryXmlLocation, reportNode);

                coverageStatistics.Total = (int)ParseFromXML(validTag, summaryXmlLocation, reportNode);
            }

            return(coverageStatistics);
        }
コード例 #7
0
        public void EnableCodeCoverage(IExecutionContext context, CodeCoverageEnablerInputs ccInputs)
        {
            Trace.Entering();

            ccInputs.VerifyInputsForCoberturaGradle();

            context.Debug(StringUtil.Format(CodeCoverageConstants.EnablingEditingTemplate, "cobertura", "gradle", ccInputs.BuildFile));
            var buildScript = new FileInfo(ccInputs.BuildFile);

            if (buildScript.Length == 0)
            {
                throw new InvalidOperationException(StringUtil.Loc("CodeCoverageBuildFileIsEmpty", ccInputs.BuildFile));
            }

            CodeCoverageUtilities.PrependDataToFile(ccInputs.BuildFile, GetCoberturaPluginDefination());
            File.AppendAllText(ccInputs.BuildFile, GetGradleCoberturaReport(ccInputs));
            context.Output(StringUtil.Loc("CodeCoverageEnabled", "cobertura", "gradle"));
        }
コード例 #8
0
        private void AddConfigurationDefaults(XElement configuration, XNamespace xNameSpace, CodeCoverageEnablerInputs mavenCcParams)
        {
            var excludesElement = CodeCoverageUtilities.GetClassDataForMaven(mavenCcParams.Exclude, "excludes", "exclude");
            var includesElement = CodeCoverageUtilities.GetClassDataForMaven(mavenCcParams.Include, "includes", "include");

            var formatElement = GetFormatsElement();

            var instrumentationNode = configuration.Element(xNameSpace + "instrumentation");

            if (instrumentationNode != null)
            {
                // remove any existing excludes and includes. We cannot directly set the values here as the value is not one single object but multiple xelements
                instrumentationNode.Remove();
            }

            var formatsNode = configuration.Element(xNameSpace + "formats");

            if (formatsNode != null)
            {
                formatsNode.Remove();
            }

            //Adding formats
            configuration.Add(formatElement);

            // add includes and excludes from user inputs
            configuration.Add(new XElement(xNameSpace + "instrumentation", includesElement, excludesElement));

            var aggregateNode = configuration.Element(xNameSpace + "aggregate");

            if (aggregateNode != null && _isMultiModule)
            {
                aggregateNode.Value = "true";
            }
            else if (_isMultiModule)
            {
                configuration.Add(new XElement(xNameSpace + "aggregate", "true"));
            }
        }
コード例 #9
0
        private string GetGradleCoberturaReport(CodeCoverageEnablerInputs gradleCCParams)
        {
            var coberturaExclude = CodeCoverageUtilities.TrimToEmptyString(gradleCCParams.Exclude);
            var coberturaInclude = CodeCoverageUtilities.TrimToEmptyString(gradleCCParams.Include);
            var exclude          = string.IsNullOrEmpty(coberturaExclude) ? string.Empty : string.Join(",", coberturaExclude.Split(':').Select(exclPackage => exclPackage.EndsWith("*") ? "'.*" + exclPackage.TrimEnd('*') + ".*'" : "'.*" + exclPackage + "'"));
            var include          = string.IsNullOrEmpty(coberturaInclude) ? string.Empty : string.Join(",", coberturaInclude.Split(':').Select(inclPackage => inclPackage.EndsWith("*") ? "'.*" + inclPackage.TrimEnd('*') + ".*'" : "'.*" + inclPackage + "'"));
            var classDirectories = string.Join(",", gradleCCParams.ClassFilesDirectories.Split(',').Select(exclPackage => "'" + exclPackage + "'"));
            var enableCobertura  = GetCoberturaPluginScriptForGradle(include, exclude);

            if (!gradleCCParams.IsMultiModule)
            {
                enableCobertura = string.Concat(enableCobertura, GetCoberturaReportingScriptForSingleModuleGradle(classDirectories, null,
                                                                                                                  gradleCCParams.ReportDirectory));
            }
            else
            {
                enableCobertura = string.Concat(enableCobertura, GetCoberturaReportingScriptForMultiModuleGradle(classDirectories, null,
                                                                                                                 gradleCCParams.ReportDirectory));
            }

            return(enableCobertura);
        }
コード例 #10
0
        public IEnumerable <CodeCoverageStatistics> GetCodeCoverageSummary(IExecutionContext context, string summaryXmlLocation)
        {
            var doc = CodeCoverageUtilities.ReadSummaryFile(context, summaryXmlLocation);

            return(ReadDataFromNodes(doc, summaryXmlLocation));
        }
コード例 #11
0
        private string GetReportPomXml(XNamespace xNameSpace, XElement pomXml, CodeCoverageEnablerInputs mavenCcParams)
        {
            string settings = string.Empty;

            settings += GetSettingsForPom(xNameSpace, pomXml);


            var srcDirectories        = CodeCoverageUtilities.SetCurrentDirectoryIfDirectoriesParameterIsEmpty(_executionContext, mavenCcParams.SourceDirectories, StringUtil.Loc("SourceDirectoriesNotSpecifiedForMultiModule"));
            var classFilesDirectories = CodeCoverageUtilities.SetCurrentDirectoryIfDirectoriesParameterIsEmpty(_executionContext, mavenCcParams.ClassFilesDirectories, StringUtil.Loc("ClassDirectoriesNotSpecifiedForMultiModule"));

            var srcData   = CodeCoverageUtilities.GetSourceDataForJacoco(srcDirectories);
            var classData = CodeCoverageUtilities.GetClassDataForAnt(mavenCcParams.Include, mavenCcParams.Exclude, classFilesDirectories);

            var execFile    = Path.Combine(mavenCcParams.ReportDirectory, _jacocoExecPrefix + ".exec");
            var csvFile     = Path.Combine(mavenCcParams.ReportDirectory, "report.csv");
            var summaryFile = Path.Combine(mavenCcParams.ReportDirectory, mavenCcParams.SummaryFile);

            // ref https://dzone.com/articles/jacoco-maven-multi-module

            return
                (@"<?xml version='1.0' encoding='UTF-8'?>" + Environment.NewLine +
                 @" <project xmlns='http://maven.apache.org/POM/4.0.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd'>" + Environment.NewLine +
                 settings +
                 @"   <build>" + Environment.NewLine +
                 @"      <plugins>" + Environment.NewLine +
                 @"         <plugin>" + Environment.NewLine +
                 @"            <groupId>org.apache.maven.plugins</groupId>" + Environment.NewLine +
                 @"            <artifactId>maven-antrun-plugin</artifactId>" + Environment.NewLine +
                 @"            <version>" + _mavenAntRunPluginVersion + @"</version>" + Environment.NewLine +
                 @"            <executions>" + Environment.NewLine +
                 @"               <execution>" + Environment.NewLine +
                 @"                  <phase>post-integration-test</phase>" + Environment.NewLine +
                 @"                  <goals>" + Environment.NewLine +
                 @"                     <goal>run</goal>" + Environment.NewLine +
                 @"                  </goals>" + Environment.NewLine +
                 @"                  <configuration>" + Environment.NewLine +
                 @"                     <target>" + Environment.NewLine +
                 @"                        <echo message='Generating JaCoCo Reports' />" + Environment.NewLine +
                 @"                        <taskdef name='report' classname='org.jacoco.ant.ReportTask'>" + Environment.NewLine +
                 @"                           <classpath path='{basedir}/target/jacoco-jars/org.jacoco.ant.jar' />" + Environment.NewLine +
                 @"                       </taskdef>" + Environment.NewLine +
                 @"                        <report>" + Environment.NewLine +
                 @"                           <executiondata>" + Environment.NewLine +
                 @"                              <file file='" + execFile + @"' />" + Environment.NewLine +
                 @"                           </executiondata>" + Environment.NewLine +
                 @"                           <structure name='Jacoco report'>" + Environment.NewLine +
                 @"                              <classfiles>" + Environment.NewLine +
                 classData +
                 @"                              </classfiles>" + Environment.NewLine +
                 @"                              <sourcefiles encoding = 'UTF-8'>" + Environment.NewLine +
                 srcData +
                 @"                              </sourcefiles>" + Environment.NewLine +
                 @"                           </structure>" + Environment.NewLine +
                 @"                           <html destdir='" + mavenCcParams.ReportDirectory + @"' />" + Environment.NewLine +
                 @"                           <xml destfile='" + summaryFile + @"' />" + Environment.NewLine +
                 @"                           <csv destfile='" + csvFile + @"' />" + Environment.NewLine +
                 @"                        </report>" + Environment.NewLine +
                 @"                     </target>" + Environment.NewLine +
                 @"                  </configuration>" + Environment.NewLine +
                 @"               </execution>" + Environment.NewLine +
                 @"            </executions>" + Environment.NewLine +
                 @"            <dependencies>" + Environment.NewLine +
                 @"               <dependency>" + Environment.NewLine +
                 @"                  <groupId>org.jacoco</groupId>" + Environment.NewLine +
                 @"                  <artifactId>org.jacoco.ant</artifactId>" + Environment.NewLine +
                 @"                  <version>" + _jacocoVersion + @"</version>" + Environment.NewLine +
                 @"               </dependency>" + Environment.NewLine +
                 @"            </dependencies>" + Environment.NewLine +
                 @"         </plugin>" + Environment.NewLine +
                 @"     </plugins>" + Environment.NewLine +
                 @"   </build>" + Environment.NewLine +
                 @" </project>");
        }
コード例 #12
0
 public void VerifyInputsForJacocoMaven()
 {
     SummaryFile     = CodeCoverageUtilities.TrimNonEmptyParam(SummaryFile, "SummaryFile");
     ReportDirectory = CodeCoverageUtilities.TrimNonEmptyParam(ReportDirectory, "ReportDirectory");
     CodeCoverageUtilities.ThrowIfClassFilesDirectoriesIsInvalid(ClassFilesDirectories);
 }
コード例 #13
0
 public void VerifyInputsForCoberturaGradle()
 {
     ClassFilesDirectories = CodeCoverageUtilities.TrimNonEmptyParam(ClassFilesDirectories, "ClassFilesDirectory");
     ReportDirectory       = CodeCoverageUtilities.TrimNonEmptyParam(ReportDirectory, "ReportDirectory");
 }
コード例 #14
0
 public void VerifyInputsForJacocoGradle()
 {
     ClassFilesDirectories = CodeCoverageUtilities.TrimNonEmptyParam(ClassFilesDirectories, "ClassFilesDirectory");
     SummaryFile           = CodeCoverageUtilities.TrimNonEmptyParam(SummaryFile, "SummaryFile");
     ReportDirectory       = CodeCoverageUtilities.TrimNonEmptyParam(ReportDirectory, "ReportDirectory");
 }
コード例 #15
0
        public CodeCoverageEnablerInputs(IExecutionContext context, string buildTool, Dictionary <string, string> eventProperties)
        {
            string classFilter;

            eventProperties.TryGetValue(EnableCodeCoverageEventProperties.ClassFilter, out classFilter);

            string buildFile;

            eventProperties.TryGetValue(EnableCodeCoverageEventProperties.BuildFile, out buildFile);

            string classFilesDirectories;

            eventProperties.TryGetValue(EnableCodeCoverageEventProperties.ClassFilesDirectories, out classFilesDirectories);

            string sourceDirectories;

            eventProperties.TryGetValue(EnableCodeCoverageEventProperties.SourceDirectories, out sourceDirectories);

            string summaryFile;

            eventProperties.TryGetValue(EnableCodeCoverageEventProperties.SummaryFile, out summaryFile);

            string cCReportTask;

            eventProperties.TryGetValue(EnableCodeCoverageEventProperties.CCReportTask, out cCReportTask);

            string reportBuildFile;

            eventProperties.TryGetValue(EnableCodeCoverageEventProperties.ReportBuildFile, out reportBuildFile);

            string isMultiModuleInput;
            var    isMultiModule = false;

            eventProperties.TryGetValue(EnableCodeCoverageEventProperties.IsMultiModule, out isMultiModuleInput);
            if (!bool.TryParse(isMultiModuleInput, out isMultiModule) && buildTool.Equals("gradle", StringComparison.OrdinalIgnoreCase))
            {
                context.Output(StringUtil.Loc("IsMultiModuleParameterNotAvailable"));
            }

            string reportDirectory;

            eventProperties.TryGetValue(EnableCodeCoverageEventProperties.ReportDirectory, out reportDirectory);

            string include, exclude;

            CodeCoverageUtilities.GetFilters(classFilter, out include, out exclude);

            BuildFile = CodeCoverageUtilities.TrimNonEmptyParam(buildFile, "BuildFile");

            //validatebuild file exists
            if (!File.Exists(BuildFile))
            {
                throw new FileNotFoundException(StringUtil.Loc("FileDoesNotExist", BuildFile));
            }

            ClassFilesDirectories = classFilesDirectories;
            Include           = include;
            Exclude           = exclude;
            SourceDirectories = sourceDirectories;
            SummaryFile       = summaryFile;
            ReportDirectory   = reportDirectory;
            CCReportTask      = cCReportTask;
            ReportBuildFile   = reportBuildFile;
            IsMultiModule     = isMultiModule;
        }
コード例 #16
0
        private async Task PublishCodeCoverageAsync(IExecutionContext executionContext, IAsyncCommandContext commandContext, ICodeCoveragePublisher codeCoveragePublisher, IEnumerable <CodeCoverageStatistics> coverageData,
                                                    string project, Guid projectId, long containerId, CancellationToken cancellationToken)
        {
            //step 2: publish code coverage summary to TFS
            if (coverageData != null && coverageData.Count() > 0)
            {
                commandContext.Output(StringUtil.Loc("PublishingCodeCoverage"));
                foreach (var coverage in coverageData)
                {
                    commandContext.Output(StringUtil.Format(" {0}- {1} of {2} covered.", coverage.Label, coverage.Covered, coverage.Total));
                }
                await codeCoveragePublisher.PublishCodeCoverageSummaryAsync(coverageData, project, cancellationToken);
            }

            // step 3: publish code coverage files as build artifacts

            string additionalCodeCoverageFilePath = null;
            string destinationSummaryFile         = null;
            var    newReportDirectory             = _reportDirectory;

            try
            {
                var filesToPublish = new List <Tuple <string, string> >();

                if (!Directory.Exists(newReportDirectory))
                {
                    if (!string.IsNullOrWhiteSpace(newReportDirectory))
                    {
                        // user gave a invalid report directory. Write warning and continue.
                        executionContext.Warning(StringUtil.Loc("DirectoryNotFound", newReportDirectory));
                    }
                    newReportDirectory = GetCoverageDirectory(_buildId.ToString(), CodeCoverageConstants.ReportDirectory);
                    Directory.CreateDirectory(newReportDirectory);
                }

                var summaryFileName = Path.GetFileName(_summaryFileLocation);
                destinationSummaryFile = Path.Combine(newReportDirectory, CodeCoverageConstants.SummaryFileDirectory + _buildId, summaryFileName);
                Directory.CreateDirectory(Path.GetDirectoryName(destinationSummaryFile));
                File.Copy(_summaryFileLocation, destinationSummaryFile, true);


                filesToPublish.Add(new Tuple <string, string>(newReportDirectory, GetCoverageDirectoryName(_buildId.ToString(), CodeCoverageConstants.ReportDirectory)));

                if (_additionalCodeCoverageFiles != null && _additionalCodeCoverageFiles.Count != 0)
                {
                    additionalCodeCoverageFilePath = GetCoverageDirectory(_buildId.ToString(), CodeCoverageConstants.RawFilesDirectory);
                    CodeCoverageUtilities.CopyFilesFromFileListWithDirStructure(_additionalCodeCoverageFiles, ref additionalCodeCoverageFilePath);
                    filesToPublish.Add(new Tuple <string, string>(additionalCodeCoverageFilePath, GetCoverageDirectoryName(_buildId.ToString(), CodeCoverageConstants.RawFilesDirectory)));
                }
                commandContext.Output(StringUtil.Loc("PublishingCodeCoverageFiles"));


                await codeCoveragePublisher.PublishCodeCoverageFilesAsync(commandContext, projectId, containerId, filesToPublish, File.Exists(Path.Combine(newReportDirectory, CodeCoverageConstants.DefaultIndexFile)), cancellationToken);
            }
            catch (IOException ex)
            {
                executionContext.Warning(StringUtil.Loc("ErrorOccuredWhilePublishingCCFiles", ex.Message));
            }
            finally
            {
                // clean temporary files.
                if (!string.IsNullOrEmpty(additionalCodeCoverageFilePath))
                {
                    if (Directory.Exists(additionalCodeCoverageFilePath))
                    {
                        Directory.Delete(path: additionalCodeCoverageFilePath, recursive: true);
                    }
                }

                if (!string.IsNullOrEmpty(destinationSummaryFile))
                {
                    var summaryFileDirectory = Path.GetDirectoryName(destinationSummaryFile);
                    if (Directory.Exists(summaryFileDirectory))
                    {
                        Directory.Delete(path: summaryFileDirectory, recursive: true);
                    }
                }

                if (!Directory.Exists(_reportDirectory))
                {
                    if (Directory.Exists(newReportDirectory))
                    {
                        //delete the generated report directory
                        Directory.Delete(path: newReportDirectory, recursive: true);
                    }
                }
            }
        }
コード例 #17
0
        public void EnableCodeCoverage(IExecutionContext context, CodeCoverageEnablerInputs ccInputs)
        {
            Trace.Entering();

            ccInputs.VerifyInputsForJacocoGradle();

            context.Debug(StringUtil.Format(CodeCoverageConstants.EnablingEditingTemplate, "jacoco", "gradle", ccInputs.BuildFile));

            var buildScript = new FileInfo(ccInputs.BuildFile);

            if (buildScript.Length == 0)
            {
                throw new InvalidOperationException(StringUtil.Loc("CodeCoverageBuildFileIsEmpty", ccInputs.BuildFile));
            }

            // see jacoco gradle documentation for more details. https://docs.gradle.org/current/userguide/jacoco_plugin.html

            var jacocoExclude = CodeCoverageUtilities.TrimToEmptyString(ccInputs.Exclude).Replace('.', '/');
            var jacocoInclude = CodeCoverageUtilities.TrimToEmptyString(ccInputs.Include).Replace('.', '/');
            var exclude       = string.IsNullOrEmpty(jacocoExclude) ? string.Empty : string.Join(",", jacocoExclude.Split(':').Select(
                                                                                                     exclPackage => exclPackage.EndsWith("*") ? ("'" + exclPackage + "/**'") : ("'" + exclPackage + ".class'")));
            var include = string.IsNullOrEmpty(jacocoInclude) ? string.Empty : string.Join(",", jacocoInclude.Split(':').Select(
                                                                                               inclPackage => inclPackage.EndsWith("*") ? ("'" + inclPackage + "/**'") : ("'" + inclPackage + ".class'")));

            var enableJacoco = string.Empty;

            if (ccInputs.IsMultiModule)
            {
                enableJacoco = @"
                    allprojects { apply plugin: 'jacoco' }

                    allprojects {
	                    repositories {
                            mavenCentral()
                        }
                    }

                    def jacocoExcludes = [" + CodeCoverageUtilities.TrimToEmptyString(exclude) + @"]
                    def jacocoIncludes = [" + CodeCoverageUtilities.TrimToEmptyString(include) + @"]

                    subprojects {
	
                        jacocoTestReport {
		                    doFirst {
			                    classDirectories = fileTree(dir: """             + ccInputs.ClassFilesDirectories + @""").exclude(jacocoExcludes).include(jacocoIncludes)
		                    }
		
		                    reports {
			                    html.enabled = true
			                    html.destination ""${buildDir}/jacocoHtml""
                                xml.enabled = true    
	                            xml.destination ""${buildDir}"     + "/" + _summaryFile + @"""
                            }
                        }
	
	                    test {
		                    jacoco {
			                    append = true
			                    destinationFile = file("""             + ccInputs.ReportDirectory + "/" + _jacocoExecPrefix + ".exec\"" + @")
		                    }
	                    }
                    }" + @"
                    task jacocoRootReport(type: org.gradle.testing.jacoco.tasks.JacocoReport) {
	                    dependsOn = subprojects.test
	                    executionData = files(subprojects.jacocoTestReport.executionData)
	                    sourceDirectories = files(subprojects.sourceSets.main.allSource.srcDirs)
	                    classDirectories = files()
	
	                    doFirst {
		                    subprojects.each {
			                    if (new File(""${it.sourceSets.main.output.classesDir}"").exists()) {
				                    logger.info(""Class directory exists in sub project: ${it.name}"")
				                    logger.info(""Adding class files ${it.sourceSets.main.output.classesDir}"")
				                    classDirectories += fileTree(dir: ""${it.sourceSets.main.output.classesDir}"", includes: jacocoIncludes, excludes: jacocoExcludes)
			                    } else {
				                    logger.error(""Class directory does not exist in sub project: ${it.name}"")
			                    }
		                    }
	                    }
	
	                    reports {
		                    html.enabled = true
                            xml.enabled = true    
		                    xml.destination """         + ccInputs.ReportDirectory + "/" + _summaryFile + @"""
		                    html.destination """         + ccInputs.ReportDirectory + @"""
	                    }
                    }
                    ";
            }
            else
            {
                enableJacoco = @"
                    allprojects { apply plugin: 'jacoco' }

                    allprojects {
	                    repositories {
                            mavenCentral()
                        }
                    }

                    def jacocoExcludes = [" + CodeCoverageUtilities.TrimToEmptyString(exclude) + @"]
                    def jacocoIncludes = [" + CodeCoverageUtilities.TrimToEmptyString(include) + @"]


	
                    jacocoTestReport {
	                    doFirst {
		                    classDirectories = fileTree(dir: """         + ccInputs.ClassFilesDirectories + @""").exclude(jacocoExcludes).include(jacocoIncludes)
	                    }
		
	                    reports {
	                        html.enabled = true
                            xml.enabled = true    
	                        xml.destination """     + ccInputs.ReportDirectory + "/" + _summaryFile + @"""
	                        html.destination """     + ccInputs.ReportDirectory + @"""
                        }
                    }
	
                    test {
                        finalizedBy jacocoTestReport
	                    jacoco {
		                    append = true
		                    destinationFile = file("""         + ccInputs.ReportDirectory + "/" + _jacocoExecPrefix + ".exec\"" + @")
	                    }
                    }
                    ";
            }
            File.AppendAllText(ccInputs.BuildFile, enableJacoco);
            context.Output(StringUtil.Loc("CodeCoverageEnabled", "jacoco", "gradle"));
        }