Skip to content

Conversation

@berezovskyi
Copy link
Member

@berezovskyi berezovskyi commented Dec 28, 2025

This script runs various Maven plugins to gather information about:

  1. Code deprecations (calls to @Deprecated methods/classes).
  2. Outdated dependencies (using versions-maven-plugin).
  3. Outdated plugins (using versions-maven-plugin).
  4. Unused declared dependencies (using maven-dependency-plugin).

@berezovskyi
Copy link
Member Author

@Jad-el-khoury this is something I made for the https://github.com/eclipse-lyo/lyo.designer/pull/303 but then realized that it would be useful for any major Lyo and Java upgrade.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a PowerShell script that analyzes Maven projects to identify technical debt and maintenance issues by running Maven plugins to detect code deprecations, outdated dependencies and plugins, and unused dependencies.

Key Changes

  • Adds a comprehensive PowerShell script with parameter-driven options to check for deprecations only or include transitive dependencies
  • Implements Maven output parsing logic to extract and format relevant information from multiple Maven plugin executions
  • Includes Java version mismatch detection to warn users about potential JAVA_HOME inconsistencies

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +90 to +94
if ($line -match "The following dependencies in Dependency Management have newer versions:") {
$currentSection = "Transitive"
$bufferedArtifact = ""
continue
}
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern assumes transitive dependencies come from "Dependency Management" section, but the versions-maven-plugin output may vary. Some transitive dependencies might appear in different sections or not be clearly marked. Consider documenting this assumption or verifying it handles all cases correctly.

Copilot uses AI. Check for mistakes.
Comment on lines +227 to +228
# Artifact lines in this section usually start with [WARNING] and contain colons like group:artifact:ver
if ($line -match "^\[WARNING\]\s+.*:.*:.*") {
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern "^[WARNING]\s+.:.:.*" is too permissive and may capture unrelated warning messages that happen to contain colons. A more specific pattern matching Maven artifact coordinates (groupId:artifactId:type:version:scope) would be more reliable, such as "^[WARNING]\s+[^:]+:[^:]+:[^:]+:[^:]+:[^:]+".

Suggested change
# Artifact lines in this section usually start with [WARNING] and contain colons like group:artifact:ver
if ($line -match "^\[WARNING\]\s+.*:.*:.*") {
# Artifact lines in this section usually start with [WARNING] and contain Maven coordinates like groupId:artifactId:type:version:scope
if ($line -match "^\[WARNING\]\s+[^:]+:[^:]+:[^:]+:[^:]+:[^:]+") {

Copilot uses AI. Check for mistakes.
Comment on lines +226 to +231
# Stop capturing if we hit another section or INFO log that isn't an artifact
# Artifact lines in this section usually start with [WARNING] and contain colons like group:artifact:ver
if ($line -match "^\[WARNING\]\s+.*:.*:.*") {
$unusedDeps += ($line -replace "^\[WARNING\]\s*", "")
} elseif ($line -match "^\[INFO\]" -or ($line -match "^\[WARNING\]" -and $line -notmatch "dependencies found")) {
# If we hit a new warning header or info, stop
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The capturing logic may stop prematurely when encountering an INFO line. If there are INFO-level messages interspersed with the unused dependencies warnings (which can happen in Maven output), this will miss some unused dependencies. Consider a more robust approach that only stops when a clear section boundary is detected.

Suggested change
# Stop capturing if we hit another section or INFO log that isn't an artifact
# Artifact lines in this section usually start with [WARNING] and contain colons like group:artifact:ver
if ($line -match "^\[WARNING\]\s+.*:.*:.*") {
$unusedDeps += ($line -replace "^\[WARNING\]\s*", "")
} elseif ($line -match "^\[INFO\]" -or ($line -match "^\[WARNING\]" -and $line -notmatch "dependencies found")) {
# If we hit a new warning header or info, stop
# Stop capturing only when we clearly leave the unused-dependencies section.
# Artifact lines in this section usually start with [WARNING] and contain colons like group:artifact:ver
if ($line -match "^\[WARNING\]\s+.*:.*:.*") {
$unusedDeps += ($line -replace "^\[WARNING\]\s*", "")
} elseif (
# Non-artifact WARNING (e.g., a new warning header) ends this section
($line -match "^\[WARNING\]" -and $line -notmatch "dependencies found") -or
# Clear Maven section boundaries / build summary also end this section
$line -match "^\[INFO\]\s+---" -or # new plugin goal section
$line -match "^\[INFO\]\s+BUILD\s+(SUCCESS|FAILURE)" -or
$line -match "^\[INFO\]\s+-{10,}" # long separator line
) {

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +32
$pomPath = Resolve-Path $PomFile
} else {
$pomPath = Join-Path $PSScriptRoot "pom.xml"
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PomFile parameter is not validated for existence before being used. If a user provides a non-existent file path, Resolve-Path will throw an error that will be difficult to understand. Consider adding validation to check if the file exists and provide a clear error message if it doesn't.

Suggested change
$pomPath = Resolve-Path $PomFile
} else {
$pomPath = Join-Path $PSScriptRoot "pom.xml"
if (-not (Test-Path -LiteralPath $PomFile)) {
throw "The specified PomFile '$PomFile' does not exist. Please provide a valid path to pom.xml."
}
$pomPath = Resolve-Path -LiteralPath $PomFile
} else {
$defaultPom = Join-Path $PSScriptRoot "pom.xml"
if (-not (Test-Path -LiteralPath $defaultPom)) {
throw "No PomFile was specified and the default pom.xml was not found at '$defaultPom'."
}
$pomPath = Resolve-Path -LiteralPath $defaultPom

Copilot uses AI. Check for mistakes.
# Resolve symlinks if possible or just take the path
$javaItem = Get-Item $javaExe
if ($javaItem.LinkType -eq "SymbolicLink") {
$javaExe = $javaItem.Target
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Target property of a symbolic link can be a string or an array, depending on the platform and PowerShell version. Directly assigning it to a scalar variable may cause issues. Consider handling both cases or using the first element if it's an array.

Suggested change
$javaExe = $javaItem.Target
$target = $javaItem.Target
if ($target -is [Array]) {
$javaExe = $target[0]
} else {
$javaExe = $target
}

Copilot uses AI. Check for mistakes.
[string[]]$Params
)
$mvnCmd = "mvn"
if ($IsWindows) { $mvnCmd = "mvn.cmd" }
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable $IsWindows is not available in Windows PowerShell 5.1 and below (only in PowerShell Core 6+). This will cause the script to fail on older Windows systems. Consider adding a check to define $IsWindows if it doesn't exist, such as: if (-not (Test-Path variable:IsWindows)) { $IsWindows = $true }

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants