CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-scoverage--scalac-scoverage-plugin

Comprehensive code coverage tool for Scala providing statement and branch coverage through compiler plugin instrumentation and report generation

Pending
Overview
Eval results
Files

io-utils.mddocs/

File I/O Utilities

The IOUtils object provides utilities for working with coverage data files, measurement files, and report output. It handles file operations, measurement data loading, and directory management for the scoverage ecosystem.

Core API

IOUtils Object

object IOUtils {
  // File operations
  def writeToFile(file: File, str: String, encoding: Option[String]): Unit
  def readStreamAsString(in: InputStream): String
  
  // Measurement file handling
  def findMeasurementFiles(dataDir: File): Array[File]
  def findMeasurementFiles(dataDir: String): Array[File] 
  def measurementFile(dataDir: File): File
  def measurementFile(dataDir: String): File
  def invoked(files: Seq[File], encoding: String = "UTF-8"): Set[(Int, String)]
  
  // Report file utilities
  def reportFile(outputDir: File, debug: Boolean = false): File
  
  // Directory operations
  def clean(dataDir: File): Unit
  def clean(dataDir: String): Unit
  def scoverageDataDirsSearch(baseDir: File): Seq[File]
  
  // Path utilities
  def getName(path: String): String
  
  // System utilities
  def getTempDirectory: File
  def getTempPath: String
}

File Operations

Writing Files with Encoding

def writeToFile(file: File, str: String, encoding: Option[String]): Unit

Writes string content to a file with specified encoding support.

Usage Examples:

import java.io.File
import scoverage.reporter.IOUtils

// Write with UTF-8 encoding
val reportFile = new File("target/report.html")
val htmlContent = "<html><body>Coverage Report</body></html>"
IOUtils.writeToFile(reportFile, htmlContent, Some("UTF-8"))

// Write with default encoding
IOUtils.writeToFile(reportFile, htmlContent, None)

// Write with specific encoding
IOUtils.writeToFile(reportFile, htmlContent, Some("ISO-8859-1"))

Reading Input Streams

def readStreamAsString(in: InputStream): String

Reads an InputStream completely into a string.

Usage Examples:

import scoverage.reporter.IOUtils

// Read from resource stream
val cssStream = getClass.getResourceAsStream("/scoverage/pure-min.css")
val cssContent = IOUtils.readStreamAsString(cssStream)
cssStream.close()

// Read from file input stream
val fileStream = new FileInputStream("data.txt")
try {
  val content = IOUtils.readStreamAsString(fileStream)
  println(s"Read ${content.length} characters")
} finally {
  fileStream.close()
}

Measurement File Handling

Finding Measurement Files

def findMeasurementFiles(dataDir: File): Array[File]
def findMeasurementFiles(dataDir: String): Array[File]

Locates all measurement files in a scoverage data directory.

Usage Examples:

import java.io.File
import scoverage.reporter.IOUtils

// Find measurement files in directory
val dataDir = new File("target/scoverage-data")
val measurementFiles = IOUtils.findMeasurementFiles(dataDir)

println(s"Found ${measurementFiles.length} measurement files:")
measurementFiles.foreach { file =>
  println(s"  ${file.getName}")
}

// Using string path
val measurementFiles2 = IOUtils.findMeasurementFiles("target/scoverage-data")

Getting Current Thread's Measurement File

def measurementFile(dataDir: File): File
def measurementFile(dataDir: String): File

Returns the measurement file for the current thread.

Usage Examples:

import scoverage.reporter.IOUtils

// Get measurement file for current thread
val dataDir = new File("target/scoverage-data")
val currentThreadFile = IOUtils.measurementFile(dataDir)
println(s"Current thread measurement file: ${currentThreadFile.getName}")

// The file will be named like: scoverage.measurements.12345
// where 12345 is the current thread ID

Loading Measurement Data

def invoked(files: Seq[File], encoding: String = "UTF-8"): Set[(Int, String)]

Loads invocation data from measurement files, returning statement IDs and test names.

Usage Examples:

import java.io.File
import scoverage.reporter.IOUtils

// Load measurement data from all files
val dataDir = new File("target/scoverage-data")
val measurementFiles = IOUtils.findMeasurementFiles(dataDir)
val measurements = IOUtils.invoked(measurementFiles.toSeq)

println(s"Loaded ${measurements.size} statement invocations")
measurements.take(5).foreach { case (id, testName) =>
  if (testName.nonEmpty) {
    println(s"Statement $id was invoked by test: $testName")
  } else {
    println(s"Statement $id was invoked (no test name recorded)")
  }
}

// Load with specific encoding
val measurementsLatin1 = IOUtils.invoked(measurementFiles.toSeq, "ISO-8859-1")

Applying Measurements to Coverage

import scoverage.domain.Coverage
import scoverage.reporter.IOUtils

// Complete workflow: load and apply measurements
val coverage: Coverage = loadCoverageData()
val dataDir = new File("target/scoverage-data")
val measurementFiles = IOUtils.findMeasurementFiles(dataDir)
val measurements = IOUtils.invoked(measurementFiles.toSeq)

// Apply measurements to coverage
coverage.apply(measurements)

println(s"Coverage after applying measurements:")
println(s"  Statements: ${coverage.invokedStatementCount}/${coverage.statementCount}")
println(s"  Coverage: ${coverage.statementCoverageFormatted}%")

Report File Utilities

Getting Report File Paths

def reportFile(outputDir: File, debug: Boolean = false): File

Returns the standard scoverage XML report file path.

Usage Examples:

import java.io.File
import scoverage.reporter.IOUtils

val outputDir = new File("target/scoverage-report")

// Standard report file
val standardReport = IOUtils.reportFile(outputDir, debug = false)
println(s"Standard report: ${standardReport.getName}")  // scoverage.xml

// Debug report file
val debugReport = IOUtils.reportFile(outputDir, debug = true)
println(s"Debug report: ${debugReport.getName}")        // scoverage-debug.xml

Directory Operations

Cleaning Data Directories

def clean(dataDir: File): Unit
def clean(dataDir: String): Unit

Removes all measurement files from a data directory.

Usage Examples:

import java.io.File
import scoverage.reporter.IOUtils

// Clean measurement files from directory
val dataDir = new File("target/scoverage-data")
println(s"Cleaning measurement files from: ${dataDir.getPath}")
IOUtils.clean(dataDir)

// Clean using string path
IOUtils.clean("target/scoverage-data")

// Clean after generating reports
def generateReportsAndClean(coverage: Coverage): Unit = {
  // Generate reports...
  generateHtmlReport(coverage)
  generateXmlReport(coverage)
  
  // Clean up measurement files
  IOUtils.clean("target/scoverage-data")
  println("Measurement files cleaned up")
}

Searching for Scoverage Data Directories

def scoverageDataDirsSearch(baseDir: File): Seq[File]

Recursively searches for scoverage data directories within a base directory.

Usage Examples:

import java.io.File
import scoverage.reporter.IOUtils

// Search for all scoverage data directories in project
val projectRoot = new File(".")
val dataDirs = IOUtils.scoverageDataDirsSearch(projectRoot)

println(s"Found ${dataDirs.size} scoverage data directories:")
dataDirs.foreach { dir =>
  println(s"  ${dir.getPath}")
}

// Use found directories for aggregation
if (dataDirs.nonEmpty) {
  val aggregatedCoverage = CoverageAggregator.aggregatedCoverage(dataDirs, projectRoot)
  println(s"Aggregated coverage: ${aggregatedCoverage.statementCoverageFormatted}%")
}

Path Utilities

Extracting File Names from Paths

def getName(path: String): String

Extracts the filename from a path, handling both Unix and Windows separators.

Usage Examples:

import scoverage.reporter.IOUtils

// Unix-style paths
val unixPath = "/path/to/file.scala"
println(IOUtils.getName(unixPath))  // "file.scala"

// Windows-style paths  
val windowsPath = "C:\\path\\to\\file.scala"
println(IOUtils.getName(windowsPath))  // "file.scala"

// Mixed separators
val mixedPath = "/path\\to/file.scala"
println(IOUtils.getName(mixedPath))  // "file.scala"

System Utilities

Working with Temporary Directories

def getTempDirectory: File
def getTempPath: String

Access to system temporary directory.

Usage Examples:

import scoverage.reporter.IOUtils

// Get temp directory as File
val tempDir = IOUtils.getTempDirectory
println(s"Temp directory: ${tempDir.getPath}")

// Get temp path as String
val tempPath = IOUtils.getTempPath
println(s"Temp path: $tempPath")

// Use for temporary coverage data
val tempCoverageDir = new File(tempDir, "scoverage-temp")
tempCoverageDir.mkdirs()

// ... perform coverage operations ...

// Clean up
tempCoverageDir.delete()

Advanced Usage Patterns

Batch File Processing

import java.io.File
import scoverage.reporter.IOUtils

def processCoverageFiles(rootDir: File): Unit = {
  // Find all data directories
  val dataDirs = IOUtils.scoverageDataDirsSearch(rootDir)
  
  dataDirs.foreach { dataDir =>
    println(s"Processing directory: ${dataDir.getPath}")
    
    // Find and process measurement files
    val measurementFiles = IOUtils.findMeasurementFiles(dataDir)
    if (measurementFiles.nonEmpty) {
      val measurements = IOUtils.invoked(measurementFiles.toSeq)
      println(s"  Found ${measurements.size} measurement records")
      
      // Process measurements...
    } else {
      println(s"  No measurement files found")
    }
  }
}

Multi-Encoding File Handling

import java.io.File
import scoverage.reporter.IOUtils

def writeReportWithFallback(file: File, content: String, preferredEncoding: String): Unit = {
  try {
    IOUtils.writeToFile(file, content, Some(preferredEncoding))
    println(s"Written with $preferredEncoding encoding")
  } catch {
    case _: java.nio.charset.UnsupportedCharsetException =>
      println(s"$preferredEncoding not supported, falling back to UTF-8")
      IOUtils.writeToFile(file, content, Some("UTF-8"))
  }
}

Resource Management

import scoverage.reporter.IOUtils

def readResourceSafely(resourcePath: String): Option[String] = {
  Option(getClass.getResourceAsStream(resourcePath)) match {
    case Some(stream) =>
      try {
        Some(IOUtils.readStreamAsString(stream))
      } finally {
        stream.close()
      }
    case None =>
      println(s"Resource not found: $resourcePath")
      None
  }
}

// Usage
val cssContent = readResourceSafely("/scoverage/pure-min.css")
cssContent.foreach { css =>
  IOUtils.writeToFile(new File("target/pure-min.css"), css, Some("UTF-8"))
}

Error Handling

Common Issues and Solutions

File Permission Errors:

import java.io.IOException

try {
  IOUtils.writeToFile(reportFile, content, Some("UTF-8"))
} catch {
  case ex: IOException =>
    println(s"Failed to write file: ${ex.getMessage}")
    // Check directory permissions, create parent directories, etc.
}

Encoding Issues:

import java.nio.charset.UnsupportedCharsetException

try {
  val measurements = IOUtils.invoked(measurementFiles, "CUSTOM-ENCODING")
} catch {
  case ex: UnsupportedCharsetException =>
    println(s"Unsupported encoding, using UTF-8: ${ex.getMessage}")
    val measurements = IOUtils.invoked(measurementFiles, "UTF-8")
}

Missing Directories:

val dataDir = new File("target/scoverage-data")
if (!dataDir.exists()) {
  println(s"Data directory does not exist: ${dataDir.getPath}")
} else {
  val measurementFiles = IOUtils.findMeasurementFiles(dataDir)
  if (measurementFiles.isEmpty) {
    println("No measurement files found in directory")
  }
}

Best Practices

  1. Always Close Streams: Use try-finally or resource management when working with streams
  2. Handle Encoding: Specify encoding explicitly when reading/writing files
  3. Validate Paths: Check that directories exist before attempting file operations
  4. Error Recovery: Provide fallback mechanisms for common failures
  5. Clean Up: Use the clean() method to remove temporary measurement files when appropriate

Install with Tessl CLI

npx tessl i tessl/maven-org-scoverage--scalac-scoverage-plugin

docs

aggregation.md

cobertura-reports.md

coverage-model.md

html-reports.md

index.md

io-utils.md

plugin.md

runtime.md

serialization.md

xml-reports.md

tile.json