Skip to content

refactor(#4729): move pinfos method to new PackageInfos class#4797

Merged
yegor256 merged 1 commit into
objectionary:masterfrom
volodya-lombrozo:4729-refactor-pinfos
Jan 13, 2026
Merged

refactor(#4729): move pinfos method to new PackageInfos class#4797
yegor256 merged 1 commit into
objectionary:masterfrom
volodya-lombrozo:4729-refactor-pinfos

Conversation

@volodya-lombrozo

@volodya-lombrozo volodya-lombrozo commented Jan 13, 2026

Copy link
Copy Markdown
Member

This PR refactors the pinfos(Path) method from MjTranspile.java into a new class PackageInfos, resolving puzzle 4717.

Fixes #4729

Summary by CodeRabbit

Release Notes

  • Refactor

    • Reorganized the internal implementation of package information file generation to improve code maintainability and ensure consistent file generation behavior across the build process.
  • Tests

    • Added comprehensive test coverage to validate proper creation of package information files in project subdirectories while correctly excluding the root directory.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings January 13, 2026 11:18
@coderabbitai

coderabbitai Bot commented Jan 13, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR refactors the package-info generation logic from MjTranspile.java into a new PackageInfos utility class. The exec() method now delegates to PackageInfos.create() instead of calling an internal pinfos() method. Tests are enabled and added to validate the extracted functionality.

Changes

Cohort / File(s) Summary
Core Refactoring
eo-maven-plugin/src/main/java/org/eolang/maven/MjTranspile.java, eo-maven-plugin/src/main/java/org/eolang/maven/PackageInfos.java
Extracted private pinfos() method (~56 lines) from MjTranspile into new PackageInfos utility class; updated exec() to invoke PackageInfos(...).create() instead; removed Pattern PACKAGE and associated imports
Test Coverage
eo-maven-plugin/src/test/java/org/eolang/maven/MjTranspileTest.java, eo-maven-plugin/src/test/java/org/eolang/maven/PackageInfosTest.java
Enabled previously disabled test in MjTranspileTest; added new PackageInfosTest with two test methods validating creation behavior in subdirectories and root exclusion

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • #4302: Related through enabling tests in MjTranspileTest that were previously disabled
  • #4728: Implements the same refactoring pattern for extracting package-info generation logic with class consolidation

Suggested labels

core

Suggested reviewers

  • yegor256
  • maxonfjvipon

Poem

🐰 A puzzle solved with graceful care,
Package-info logic moved with flair,
From MjTranspile's tangled nest,
To PackageInfos class—refactored best!
Tests enabled, new ones born,
A cleaner codebase greets the morn! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely describes the main refactoring: moving the pinfos method from MjTranspile to a new PackageInfos class, which aligns with the changeset.
Linked Issues check ✅ Passed The PR successfully addresses issue #4729 by extracting the pinfos method into a dedicated PackageInfos class [#4729], and the puzzle text has been removed from MjTranspile.java as required.
Out of Scope Changes check ✅ Passed All changes are directly related to the refactoring objective: the pinfos method extraction, new PackageInfos class creation, existing test enablement, and new test coverage for the refactored functionality.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Performance Analysis

All benchmarks are within the acceptable range. No critical degradation detected (threshold is 100%). Please refer to the detailed report for more information.

Click to see the detailed report
Test Base Score PR Score Change % Change Unit Mode
benchmarks.XmirBench.xmirToEO 197.217 163.309 -33.908 -17.19% ms/op Average Time

✅ Performance gain: benchmarks.XmirBench.xmirToEO is faster by 33.908 ms/op (17.19%)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @eo-maven-plugin/src/main/java/org/eolang/maven/PackageInfos.java:
- Around line 48-50: The Files.walk(this.root) stream in PackageInfos is not
closed; change the code that builds dirs to open the Stream<Path> in a
try-with-resources (e.g., try (Stream<Path> walk = Files.walk(this.root)) { dirs
= walk.filter(...).collect(...) }) so the stream is automatically closed; update
the declaration of dirs (and any surrounding scope) so the collected List<Path>
is assigned inside the try block and available afterward.
🧹 Nitpick comments (1)
eo-maven-plugin/src/test/java/org/eolang/maven/PackageInfosTest.java (1)

21-55: Consider adding a test for generated content verification.

The existing tests verify file creation count and existence, but don't verify the content of generated package-info.java files. Consider adding a test that verifies the package declaration matches the directory structure (e.g., package subdir.subsubdir; for the nested directory).

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ffbd7b and ca472d8.

📒 Files selected for processing (4)
  • eo-maven-plugin/src/main/java/org/eolang/maven/MjTranspile.java
  • eo-maven-plugin/src/main/java/org/eolang/maven/PackageInfos.java
  • eo-maven-plugin/src/test/java/org/eolang/maven/MjTranspileTest.java
  • eo-maven-plugin/src/test/java/org/eolang/maven/PackageInfosTest.java
💤 Files with no reviewable changes (1)
  • eo-maven-plugin/src/test/java/org/eolang/maven/MjTranspileTest.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: CodeQL analysis (java)
  • GitHub Check: Agent
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: benchmark
  • GitHub Check: qulice
  • GitHub Check: mvn (macos-15, 23)
  • GitHub Check: trufflehog
  • GitHub Check: mvn (ubuntu-24.04, 23)
  • GitHub Check: mvn (ubuntu-24.04, 17)
  • GitHub Check: snippets
  • GitHub Check: mvn (windows-2022, 23)
  • GitHub Check: ort
  • GitHub Check: pr-size
  • GitHub Check: integration
🔇 Additional comments (5)
eo-maven-plugin/src/main/java/org/eolang/maven/PackageInfos.java (2)

70-83: LGTM!

The content generation logic is clean and correctly produces the expected package-info.java structure with the auto-generated header and package declaration.


20-38: LGTM!

The class structure follows good practices: final class with immutable state, package-private visibility for internal use, and clear Javadoc.

eo-maven-plugin/src/main/java/org/eolang/maven/MjTranspile.java (1)

118-118: LGTM!

Clean delegation to the new PackageInfos utility class. The refactoring maintains the same behavior while improving code organization by separating the package-info generation concern.

eo-maven-plugin/src/test/java/org/eolang/maven/PackageInfosTest.java (2)

24-41: LGTM!

Good test coverage for the happy path scenario with nested subdirectories. The assertions correctly verify both the count and file existence.


43-55: LGTM!

Correctly tests the edge case where the root directory has no subdirectories, ensuring no package-info.java is created in the root itself.

Comment on lines +48 to +50
final List<Path> dirs = Files.walk(this.root)
.filter(file -> Files.isDirectory(file) && !file.equals(this.root))
.collect(Collectors.toList());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Resource leak: Files.walk() stream is not closed.

Files.walk() returns a Stream<Path> backed by I/O resources that must be explicitly closed. Using .collect() does not close the underlying stream, which can lead to file handle exhaustion.

🔧 Proposed fix using try-with-resources
         if (Files.exists(this.root)) {
-            final List<Path> dirs = Files.walk(this.root)
-                .filter(file -> Files.isDirectory(file) && !file.equals(this.root))
-                .collect(Collectors.toList());
+            final List<Path> dirs;
+            try (java.util.stream.Stream<Path> stream = Files.walk(this.root)) {
+                dirs = stream
+                    .filter(file -> Files.isDirectory(file) && !file.equals(this.root))
+                    .collect(Collectors.toList());
+            }
             for (final Path dir : dirs) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
final List<Path> dirs = Files.walk(this.root)
.filter(file -> Files.isDirectory(file) && !file.equals(this.root))
.collect(Collectors.toList());
final List<Path> dirs;
try (java.util.stream.Stream<Path> stream = Files.walk(this.root)) {
dirs = stream
.filter(file -> Files.isDirectory(file) && !file.equals(this.root))
.collect(Collectors.toList());
}
🤖 Prompt for AI Agents
In @eo-maven-plugin/src/main/java/org/eolang/maven/PackageInfos.java around
lines 48 - 50, The Files.walk(this.root) stream in PackageInfos is not closed;
change the code that builds dirs to open the Stream<Path> in a
try-with-resources (e.g., try (Stream<Path> walk = Files.walk(this.root)) { dirs
= walk.filter(...).collect(...) }) so the stream is automatically closed; update
the declaration of dirs (and any surrounding scope) so the collected List<Path>
is assigned inside the try block and available afterward.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 refactors the pinfos(Path) method from MjTranspile.java into a new standalone class PackageInfos, improving adherence to the Single Responsibility Principle. The refactoring resolves puzzle #4717.

Changes:

  • Created new PackageInfos class to encapsulate package-info.java file creation logic
  • Added comprehensive unit tests for the new PackageInfos class in PackageInfosTest.java
  • Updated MjTranspile.java to use the new class and removed unused imports
  • Enabled previously disabled test savesValidContentToPackageInfoFile in MjTranspileTest.java

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
PackageInfos.java New class containing refactored logic for creating package-info.java files in subdirectories
PackageInfosTest.java New test file with comprehensive unit tests for PackageInfos class
MjTranspile.java Removed pinfos method and updated to use new PackageInfos class; cleaned up unused imports
MjTranspileTest.java Re-enabled test that verifies valid content in package-info.java files

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

Comment on lines +30 to +40
MatcherAssert.assertThat(
"We should create exactly two package-info.java files for two subdirectories",
new PackageInfos(tmp).create(),
Matchers.equalTo(2)
);
MatcherAssert.assertThat(
"package-info.java should be created in the both subdirectories",
Files.exists(subdir.resolve("package-info.java"))
&& Files.exists(subsubdir.resolve("package-info.java")),
Matchers.is(true)
);

Copilot AI Jan 13, 2026

Copy link

Choose a reason for hiding this comment

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

This test contains two assertions, which violates the project guideline that each test should contain only one assertion. Consider splitting this into two separate tests: one to verify the count of created files, and another to verify the existence of package-info.java files in subdirectories.

Copilot generated this review using guidance from organization custom instructions.
Comment on lines +45 to +54
MatcherAssert.assertThat(
"No package-info.java files should be created in the root directory",
new PackageInfos(tmp).create(),
Matchers.equalTo(0)
);
MatcherAssert.assertThat(
"package-info.java should not be created in the root directory",
Files.exists(tmp.resolve("package-info.java")),
Matchers.is(false)
);

Copilot AI Jan 13, 2026

Copy link

Choose a reason for hiding this comment

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

This test contains two assertions, which violates the project guideline that each test should contain only one assertion. Consider splitting this into two separate tests: one to verify the count of created files is 0, and another to verify package-info.java does not exist in the root directory.

Copilot generated this review using guidance from organization custom instructions.
Comment on lines +48 to +50
final List<Path> dirs = Files.walk(this.root)
.filter(file -> Files.isDirectory(file) && !file.equals(this.root))
.collect(Collectors.toList());

Copilot AI Jan 13, 2026

Copy link

Choose a reason for hiding this comment

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

The variable name "dirs" is a compound abbreviation. According to the project guidelines, compound variable names should be avoided in favor of single-word nouns. Consider renaming to "directories" or simply "paths" to follow the naming convention.

Copilot generated this review using guidance from organization custom instructions.
Comment on lines +52 to +53
final String pkg = this.root.relativize(dir).toString()
.replace(File.separator, ".");

Copilot AI Jan 13, 2026

Copy link

Choose a reason for hiding this comment

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

The variable name "pkg" is an abbreviation. According to the project guidelines, compound or abbreviated variable names should be avoided in favor of single-word nouns. Consider renaming to "package" (though this is a Java keyword, so "name" might be a better alternative).

Copilot generated this review using guidance from organization custom instructions.
@volodya-lombrozo

Copy link
Copy Markdown
Member Author

@yegor256 could you have a look, please?

@yegor256 yegor256 merged commit 872de42 into objectionary:master Jan 13, 2026
32 of 33 checks passed
@yegor256

Copy link
Copy Markdown
Member

@volodya-lombrozo thanks!

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.

Required Refactor: {@link #pinfos(Path)} Misplacement in MjTranspile.java

3 participants