Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2cd0d5f
Experiments with jacoco-filter logic.
miroslavpojer Jun 24, 2025
07d08f2
Debug and experiments.
miroslavpojer Jun 24, 2025
05e69ea
Debug and experiments.
miroslavpojer Jun 24, 2025
ea41aa5
Debug and experiments.
miroslavpojer Jun 24, 2025
5b985af
Debug and experiments.
miroslavpojer Jun 24, 2025
58b25eb
Debug and experiments.
miroslavpojer Jun 24, 2025
22de274
Debug and experiments.
miroslavpojer Jun 24, 2025
ade6e12
Debug and experiments.
miroslavpojer Jun 24, 2025
5e63281
Debug and experiments.
miroslavpojer Jun 24, 2025
9c87408
Debug and experiments.
miroslavpojer Jun 24, 2025
037cba2
Debug and experiments.
miroslavpojer Jun 24, 2025
2716b31
Debug and experiments.
miroslavpojer Jun 25, 2025
5f8b22e
Debug and experiments.
miroslavpojer Jun 25, 2025
883e78d
Debug and experiments.
miroslavpojer Jun 26, 2025
e2ae558
Debug and experiments.
miroslavpojer Jun 26, 2025
5e78ae8
Debug and experiments.
miroslavpojer Jun 26, 2025
fd327ec
Debug and experiments.
miroslavpojer Jun 26, 2025
6869371
Debug and experiments.
miroslavpojer Jun 26, 2025
c01f80a
Debug and experiments.
miroslavpojer Jun 26, 2025
58ed86e
Final changes.
miroslavpojer Jun 26, 2025
44a803b
Update agent/src/main/scala/za/co/absa/atum/agent/AtumAgent.scala
miroslavpojer Jun 26, 2025
e481938
Minor fixes and cleanup.
miroslavpojer Jun 26, 2025
23a0a5a
Merge remote-tracking branch 'origin/feature/jacoco-filtering' into f…
miroslavpojer Jun 26, 2025
527bfbc
Merge branch 'master' into feature/jacoco-filtering
miroslavpojer Sep 1, 2025
93c0a63
Initial removal of the old Jacoco solution.
miroslavpojer Sep 1, 2025
92ba25e
Comment out jacoco from project.
miroslavpojer Sep 1, 2025
d106bb4
Introduced auto-plugin.
miroslavpojer Sep 1, 2025
594d5a7
Re-activated jacoco in CI.
miroslavpojer Sep 1, 2025
d687d92
Removed database module from jacoco coverage.
miroslavpojer Sep 1, 2025
203ddfb
Fixed expected path to jacoco.xml file.
miroslavpojer Sep 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .github/workflows/jacoco_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,13 @@ jobs:
id: jacocorun
run: sbt jacoco

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Check coverage thresholds and add reports in PR comments
id: jacoco
uses: MoranaApps/jacoco-report@v2
with:
token: '${{ secrets.GITHUB_TOKEN }}'
paths: |
**/target/*${{ env.scalaShort }}*/jacoco/report/jacoco.xml
**/target/jacoco/report/jacoco.xml
exclude-paths: |
database/target/**
sensitivity: "detail"
Expand Down
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,16 @@ represents all currently supported measurement types (aka measures):
sbt jacoco
```

Code coverage wil be generated on path:
The HTML report of coverage will be generated on the path:

```
{project-root}/{module}/target/jacoco/report/index.html
```

The XML report of coverage will be generated on the path:

```
{project-root}/{module}/target/jvm-{scala_version}/jacoco/report/html
{project-root}/{module}/target/jacoco/report/jacoco.xml
```

## How to Run in IntelliJ
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class AtumContext private[agent] (
*/
def currentMeasures: Set[AtumMeasure] = measures




/**
* Returns the sub-partition context in the AtumContext.
*
Expand Down
11 changes: 10 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* limitations under the License.
*/

import sbt.Keys.name
import sbt.*
import sbt.Keys.*
import Dependencies.*
import Dependencies.Versions.spark3
import VersionAxes.*
Expand Down Expand Up @@ -69,6 +69,7 @@ lazy val server = {
)
.enablePlugins(AssemblyPlugin)
.enablePlugins(AutomateHeaderPlugin)
.enablePlugins(FilteredJacocoAgentPlugin)
.addSingleScalaBuild(Setup.serverAndDbScalaVersion, Dependencies.serverDependencies)
.dependsOn(model)

Expand All @@ -90,6 +91,7 @@ lazy val agent = (projectMatrix in file("agent"))
javacOptions ++= Setup.clientJavacOptions
): _*
)
.enablePlugins(FilteredJacocoAgentPlugin)
.addSparkCrossBuild(SparkVersionAxis(spark3), Setup.clientSupportedScalaVersions, Dependencies.agentDependencies)
.dependsOn(model)

Expand All @@ -104,6 +106,7 @@ lazy val model = (projectMatrix in file("model"))
javacOptions ++= Setup.clientJavacOptions,
): _*
)
.enablePlugins(FilteredJacocoAgentPlugin)
.addScalaCrossBuild(Setup.clientSupportedScalaVersions, Dependencies.modelDependencies)

/**
Expand Down Expand Up @@ -139,5 +142,11 @@ lazy val reader = (projectMatrix in file("reader"))
javacOptions ++= Setup.clientJavacOptions
): _*
)
.enablePlugins(FilteredJacocoAgentPlugin)
.addScalaCrossBuild(Setup.clientSupportedScalaVersions, Dependencies.readerDependencies)
.dependsOn(model)

// Run activate jacoco + clean + test + per-module reports across the whole build + deactivate jacoco
addCommandAlias("jacoco", "; jacocoOn; clean; test; jacocoReportAll; jacocoOff")
addCommandAlias("jacocoOff", "; set every jacocoPluginEnabled := false")
addCommandAlias("jacocoOn", "; set every jacocoPluginEnabled := true")
11 changes: 11 additions & 0 deletions jacoco_filter.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
inputs = ["**/*2.13*/**/jacoco.xml"]
exclude_paths = []
verbose = true

rules = [
# filter-out method from AtumAgent class
#"method:za.co.absa.atum.agent.AtumAgent#dispatcherFromConfig*",

# filter-out method from AtumAgent object
#"method:za.co.absa.atum.agent.AtumAgent$#dispatcherFromConfig*"
]
154 changes: 154 additions & 0 deletions jmf-rules.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# jacoco-method-filter — Default Rules & HowTo (Scala + Java)
#
# This file defines which methods should be annotated as *Generated so JaCoCo ignores them.
# One rule per line.
#
# ─────────────────────────────────────────────────────────────────────────────
# HOW TO USE (quick)
# 1) Replace YOUR.PACKAGE.ROOT with your project’s package root (e.g., com.example.app).
# 2) Start with the CONSERVATIVE section only.
# 3) If clean, enable STANDARD. Use AGGRESSIVE only inside DTO/auto‑generated packages.
# 4) Keep rules narrow (by package), prefer flags (synthetic/bridge) for compiler artifacts,
# and add `id:` labels so logs are easy to read.
#
# ─────────────────────────────────────────────────────────────────────────────
# ALLOWED SYNTAX (cheat sheet)
#
# General form:
# <FQCN_glob>#<method_glob>(<descriptor_glob>) [FLAGS and PREDICATES...]
#
# FQCN_glob (dot form; $ allowed for inner classes):
# Examples: *.model.*, com.example.*, *
#
# method_glob (glob on method name):
# Examples: copy | $anonfun$* | get* | *_$eq
#
# descriptor_glob (JVM descriptor in (args)ret). You may omit it entirely.
# • Omitting descriptor ⇒ treated as "(*)*" (any args, any return).
# • Short/empty forms "", "()", "(*)" normalize to "(*)*".
# Examples:
# (I)I # takes int, returns int
# (Ljava/lang/String;)V # takes String, returns void
# () or (*) or omitted # any args, any return
#
# FLAGS (optional) — space or comma separated:
# public | protected | private | synthetic | bridge | static | abstract
#
# PREDICATES (optional):
# ret:<glob> # match return type only (e.g., ret:V, ret:I, ret:Lcom/example/*;)
# id:<string> # identifier shown in logs/reports
# name-contains:<s> # method name must contain <s>
# name-starts:<s> # method name must start with <s>
# name-ends:<s> # method name must end with <s>
#
# Notes
# - Always use dot-form (com.example.Foo) for class names.
# - Comments (# …) and blank lines are ignored.
#
# ─────────────────────────────────────────────────────────────────────────────
# QUICK EXAMPLES
#
# Simple wildcards
# *#*(*)
# → Match EVERY method in EVERY class (any package). Useful only for diagnostics.
# "(*)" normalizes to "(*)*" ⇒ any args, any return.
# *.dto.*#*(*)
# → Match every method on any class under any package segment named "dto".
# Good when you treat DTOs as generated/boilerplate.

# Scala case class helpers
# *.model.*#copy(*)
# → Matches Scala case-class `copy` methods under `*.model.*`.
# Hides boilerplate clones with any parameter list and any return.
# *.model.*#productArity()
# → Matches zero-arg `productArity` (case-class/Product API).
# *.model.*#productElement(*)
# → Matches `productElement(int)` (or any descriptor form) on case classes.
# *.model.*#productPrefix()
# → Matches `productPrefix()`; returns the case class' constructor name.

# Companion objects and defaults
# *.model.*$*#apply(*)
# → Matches companion `apply` factories under `*.model.*` (any args).
# BE CAREFUL: can hide real factory logic; keep the package scope narrow.
# *.model.*$*#unapply(*)
# → Matches extractor `unapply` methods in companions under `*.model.*`.
# *#*$default$*(*)
# → Matches Scala-generated default-argument helpers everywhere.
# Safe to keep enabled; they’re compiler-synthesized.

# Anonymous / synthetic / bridge
# *#$anonfun$*
# → Matches any method whose name contains `$anonfun$` (Scala lambdas).
# Consider adding `synthetic` and/or a package scope in real configs.
# *#*(*):synthetic # any synthetic
# → Matches ANY method marked `synthetic` (compiler-generated).
# Powerful; scope by package to avoid hiding intentional glue code.
# *#*(*):bridge # any bridge
# → Matches Java generic bridge methods the compiler inserts.
# Usually safe globally, but scoping is still recommended.

# Setters / fluent APIs
# *.dto.*#*_$eq(*)
# → Matches Scala var setters in DTO packages (e.g., `name_=(...)`).
# Good for excluding trivial field writes.
# *.builder.*#with*(*)
# → Matches builder-style fluent setters (`withXxx(...)`) in builder pkgs.
# Treats chainable configuration as boilerplate.
# *.client.*#with*(*) ret:Lcom/api/client/*
# → Like above but ONLY when the return type matches your client package.
# The `ret:` predicate protects real logic that returns other types.

# Return-type constraints
# *.jobs.*#*(*):ret:V
# → Any method under `*.jobs.*` returning `void` (`V`). Often orchestration.
# *.math.*#*(*):ret:I
# → Any method under `*.math.*` returning primitive int (`I`).
# *.model.*#*(*):ret:Lcom/example/model/*
# → Any method under `*.model.*` that returns a type in `com.example.model`.
# Handy when the *return type* uniquely identifies boilerplate.

# ─────────────────────────────────────────────────────────────────────────────
# GLOBALS RULES
# ─────────────────────────────────────────────────────────────────────────────
# ** all case class boilerplate

# Scala case class helpers
*#canEqual(*) id:case-canequal
*#equals(*) id:case-equals
*#apply(*) id:case-apply
*#unapply(*) id:case-unapply
*#hashCode(*) id:case-hashcode
*#copy(*) id:case-copy
*#copy$default$*(*) id:case-copy-defaults
*#productElement() id:case-prod-element
*#productArity() id:case-prod-arity
*#productPrefix() id:case-prod-prefix
*#productIterator() id:case-prod-iterator
*#tupled() id:case-tupled
*#curried() id:case-curried
*#toString() id:case-tostring
*#name() id:case-name
*#groups() id:case-groups
*#optionalAttributes() id:case-optionalAttributes

# Companion objects, constructors, and static definitions
*$#<init>(*) id:gen-ctor # constructors
*$#<clinit>() id:gen-clinit # static initializer blocks

# Companion objects and defaults
*$*#apply(*) id:comp-apply
*$*#unapply(*) id:comp-unapply
*$*#toString(*) id:comp-tostring
*$*#readResolve(*) id:comp-readresolve

# anonymous class created by a macro expansion
*$macro$*#$anonfun$inst$macro$* id:macro-inst
*$macro$*#inst$macro$* id:macro-inst

# lambda
*#* synthetic name-contains:$anonfun$ id:scala-anonfun

# ─────────────────────────────────────────────────────────────────────────────
# DIRECT RULES
# ─────────────────────────────────────────────────────────────────────────────
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ case class AdditionalDataDTO(
object AdditionalDataDTO {
implicit val encodeAdditionalDataDTO: Encoder[AdditionalDataDTO] = deriveEncoder
implicit val decodeAdditionalDataDTO: Decoder[AdditionalDataDTO] = deriveDecoder

}
Loading
Loading