Skip to content

Commit c067bec

Browse files
authored
Update API part 3 (#68)
1 parent bd5b5f3 commit c067bec

73 files changed

Lines changed: 1149 additions & 675 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/skills/branch-review.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Skill: Branch Review
2+
3+
## Purpose
4+
Review the current branch against `develop` and report only material issues with high signal: bugs, regressions, API breaks, resource/concurrency risks, and behavior changes.
5+
6+
## When to Use
7+
- Before opening a pull request to `develop`
8+
- After major refactoring or API changes
9+
- When you want a strict, impact-focused review
10+
11+
## Review Scope (RLib-specific)
12+
1. **Public API compatibility first**
13+
- Treat removals/signature changes in public API as high priority by default
14+
- If branch is intentionally alpha-breaking, mark these as accepted and continue
15+
16+
2. **Prioritize API surface over internals**
17+
- Start with changed files in `src/main/java`
18+
- Prioritize non-`impl/` packages
19+
- Review `impl/` changes when they can affect exposed behavior
20+
21+
3. **Javadoc quality is part of API review**
22+
- Check public API javadocs for:
23+
- `@since 10.0.0`
24+
- Active voice descriptions
25+
- No trailing periods in `@param`/`@return`
26+
- No unnecessary getter/setter javadocs
27+
28+
4. **Collections performance pattern**
29+
- Verify empty-state fast paths (`isEmpty()`) in collection operations
30+
- Ensure no unnecessary allocation/iteration when collections are empty
31+
32+
5. **Runtime/integration constraints**
33+
- Many integration tests use Testcontainers
34+
- If Docker is unavailable, call out that integration validation is limited
35+
36+
6. **Testing conventions awareness**
37+
- Prefer AssertJ assertions
38+
- Keep test naming and style aligned with repo conventions
39+
40+
7. **Version mapping correctness**
41+
- For version-to-name lookups (for example OS distribution naming), verify runtime version normalization before map access
42+
- Confirm behavior for real version formats (for example `10.15.7`, `14.4.1`, `15.1`) with targeted tests
43+
44+
8. **Path handling in file discovery**
45+
- Ensure file discovery helpers return full/usable paths when downstream code reads files
46+
- Flag bare filename returns that make behavior depend on current working directory
47+
48+
## Process
49+
50+
### 1. Gather branch diff
51+
```bash
52+
git --no-pager diff --name-only develop...HEAD
53+
git --no-pager diff --stat develop...HEAD
54+
git --no-pager diff develop...HEAD
55+
```
56+
57+
### 2. Triage files
58+
- Group into:
59+
- Public API changes
60+
- Internal behavior/refactoring
61+
- Documentation-only changes
62+
63+
### 3. Review by risk
64+
- Public API contract changes
65+
- Behavioral logic changes
66+
- Concurrency/resource handling
67+
- Performance-sensitive paths
68+
- Documentation contract gaps (for public API)
69+
70+
### 4. Report findings
71+
Use this format:
72+
- **Severity:** High / Medium / Low
73+
- **File:** path
74+
- **Issue:** concise technical problem
75+
- **Impact:** why it matters in real usage
76+
- **Fix:** concrete recommendation
77+
78+
Only include findings that are actionable and materially important.
79+
80+
## Output Expectations
81+
- If no material issues: explicitly state no material issues found
82+
- If issues exist: provide a short prioritized list
83+
- Do not include style-only or trivial nits

.github/skills/generate-branch-summary.md

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,6 @@ Group modifications by their nature:
3737
Create a section in `summary.md` with this format:
3838

3939
```markdown
40-
# Branch: <branch-name>
41-
42-
**Status:** <Ready for review / In progress / Draft>
43-
**Commits:** <number> (e.g., "1 (abc1234 - 'commit message')" or "3 commits")
44-
**Version:** <old-version> → <new-version> (if applicable)
45-
4640
## Changes Summary
4741

4842
### <Category 1> (e.g., "New Array API")
@@ -87,6 +81,8 @@ Create a section in `summary.md` with this format:
8781
- Use bullet points for lists
8882
- Use bold (`**`) for emphasis on key terms
8983
- Use inline code (`` ` ` ``) for class/method names
84+
- Do not add a `Branch:` section or heading in the summary
85+
- Do not add `Status`, `Commits`, or `Version` metadata lines in the summary
9086

9187
### 6. Output Location
9288
Always write to `summary.md` in the repository root, replacing or updating the previous summary section.
@@ -97,12 +93,6 @@ If `summary.md` already contains unrelated sections (e.g., documentation of othe
9793
## Example Output
9894

9995
```markdown
100-
# Branch: update-api-part-2
101-
102-
**Status:** Ready for review
103-
**Commits:** 1 (1367d9b - "small improvements")
104-
**Version:** 10.0.alpha13 → 10.0.alpha14
105-
10696
## Changes Summary
10797

10898
### 1. New Array API: `tryTrimTo(int)`

.github/skills/generate-javadoc.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ When the user asks to:
3737
2. **Function @return** - use "the function result" for consistency
3838
3. **Predicate @return** - use "true if the arguments match the predicate" or "true if the arguments match the predicate, false otherwise"
3939
4. **Supplier @return** - describe what is supplied (e.g., "the char value" not just "a result")
40+
5. **Signature-text alignment** - ensure class-level description and type-parameter text match the exact argument order in `make(...)`/`accept(...)` methods (for example, `A, int, C` must be described as "an object, an int, and another object", while `A, B, int` must be described as "two objects and one int")
4041

4142
### Javadoc Standards
4243
Each documented element must include:
@@ -129,6 +130,7 @@ public interface IntObjConsumer<B> {
129130
- Remove obvious/redundant javadocs (getters, setters, constants)
130131
- Remove duplicate `@see` references
131132
- Add missing `@since` tags
133+
- Fix swapped functional-interface descriptions so they match the method signature argument order
132134

133135
## Execution Steps
134136

@@ -145,9 +147,10 @@ public interface IntObjConsumer<B> {
145147
3. **Read each file** to understand existing documentation state
146148

147149
4. **Add Javadocs** using `replace_string_in_file` tool:
148-
- Add class-level Javadoc with description and `@since`
149-
- Add method-level Javadocs with description and `@since`
150-
- Add `@param`/`@return` only for non-trivial methods
150+
- Add class-level Javadoc with description and `@since`
151+
- Add method-level Javadocs with description and `@since`
152+
- Add `@param`/`@return` only for non-trivial methods
153+
- For functional interfaces, verify description wording against the exact parameter order in method signatures
151154

152155
5. **Validate changes:**
153156
```bash

.github/workflows/develop.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ jobs:
1414
contents: write
1515
pull-requests: write
1616
steps:
17-
- uses: actions/checkout@v4
17+
- uses: actions/checkout@v6
1818

1919
- name: Set up JDK 21
20-
uses: actions/setup-java@v4
20+
uses: actions/setup-java@v5
2121
with:
2222
java-version: '21'
2323
distribution: 'temurin'
2424

2525
- name: Setup Gradle
26-
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
26+
uses: gradle/actions/setup-gradle@v6
2727

2828
- name: Compile all modules
2929
run: ./gradlew testClasses
@@ -32,7 +32,7 @@ jobs:
3232
run: ./gradlew test
3333

3434
- name: Generate test report
35-
uses: mikepenz/action-junit-report@v5
35+
uses: mikepenz/action-junit-report@v6
3636
if: success() || failure() # always run even if the previous step fails
3737
with:
3838
report_paths: '**/build/test-results/test/TEST-*.xml'
@@ -61,13 +61,13 @@ jobs:
6161
permissions:
6262
contents: write
6363
steps:
64-
- uses: actions/checkout@v4
64+
- uses: actions/checkout@v6
6565

6666
- name: Set up JDK 21
67-
uses: actions/setup-java@v4
67+
uses: actions/setup-java@v5
6868
with:
6969
java-version: '21'
7070
distribution: 'temurin'
7171

7272
- name: Generate and submit dependency graph
73-
uses: gradle/actions/dependency-submission@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
73+
uses: gradle/actions/dependency-submission@v6

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
/**/build
1111
/**/out
1212
/**/.gradle
13+
/summary.md

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ repositories {
4545
}
4646
4747
ext {
48-
rlibVersion = "10.0.alpha14"
48+
rlibVersion = "10.0.alpha15"
4949
}
5050
5151
dependencies {

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
rootProject.version = "10.0.alpha14"
1+
rootProject.version = "10.0.alpha15"
22
group = 'javasabr.rlib'
33

44
allprojects {

rlib-classpath/src/main/java/javasabr/rlib/classpath/impl/ClassPathScannerImpl.java

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@
2222
import javasabr.rlib.io.impl.ReuseBytesInputStream;
2323
import javasabr.rlib.io.impl.ReuseBytesOutputStream;
2424
import javasabr.rlib.io.util.IoUtils;
25-
import javasabr.rlib.logger.api.Logger;
26-
import javasabr.rlib.logger.api.LoggerManager;
2725
import lombok.AccessLevel;
26+
import lombok.CustomLog;
2827
import lombok.Getter;
2928
import lombok.experimental.Accessors;
3029
import lombok.experimental.FieldDefaults;
@@ -33,13 +32,12 @@
3332
/**
3433
* @author JavaSaBr
3534
*/
35+
@CustomLog
3636
@Accessors(fluent = true)
3737
@Getter(AccessLevel.PROTECTED)
3838
@FieldDefaults(level = AccessLevel.PROTECTED)
3939
public class ClassPathScannerImpl implements ClassPathScanner {
40-
41-
protected static final Logger LOGGER = LoggerManager.getLogger(ClassPathScanner.class);
42-
40+
4341
private static final String CLASS_PATH = System.getProperty("java.class.path");
4442
private static final String PATH_SEPARATOR = File.pathSeparator;
4543
private static final String CLASS_EXTENSION = ".class";
@@ -176,10 +174,10 @@ private void loadClass(
176174
if (!name.endsWith(CLASS_EXTENSION)) {
177175
return;
178176
} else if(MODULE_INFO_CLASS.equals(name)) {
179-
LOGGER.debug("Skip loading module-info...");
177+
log.debug("Skip loading module-info...");
180178
return;
181179
} else if(name.startsWith(META_INF_PREFIX)) {
182-
LOGGER.debug("Skip loading META-INF class...");
180+
log.debug("Skip loading META-INF class...");
183181
return;
184182
}
185183

@@ -199,19 +197,19 @@ private void loadClass(
199197
className = result.toString();
200198

201199
} catch (Exception e) {
202-
LOGGER.warning(name, File.separator, "Incorrect replaced class name:[%s] to java path, used separator:[%s]"::formatted);
200+
log.warn(name, File.separator, "Incorrect replaced class name:[%s] to java path, used separator:[%s]"::formatted);
203201
return;
204202
}
205203

206-
LOGGER.debug(className, "Try to load class:[%s]"::formatted);
204+
log.debug(className, "Try to load class:[%s]"::formatted);
207205
try {
208206
container.add(loader().loadClass(className));
209207
} catch (NoClassDefFoundError error) {
210-
LOGGER.warning(className, name, rootPath, file,
208+
log.warn(className, name, rootPath, file,
211209
"Can't load class:[%s] with original name:[%s], root folder:[%s] and class file:[%s]"::formatted);
212-
LOGGER.warning(error);
210+
log.warn(error);
213211
} catch (Throwable e) {
214-
LOGGER.warning(e);
212+
log.warn(e);
215213
}
216214
}
217215

@@ -220,7 +218,7 @@ private void scanDirectory(
220218
MutableArray<Class<?>> classes,
221219
MutableArray<String> resources,
222220
Path directory) {
223-
LOGGER.debug(directory, "Scanning directory:[%s]"::formatted);
221+
log.debug(directory, "Scanning directory:[%s]"::formatted);
224222
try (DirectoryStream<Path> stream = Files.newDirectoryStream(directory)) {
225223
for (Path file : stream) {
226224

@@ -261,15 +259,15 @@ private void scanDirectory(
261259
}
262260

263261
} catch (IOException ex) {
264-
LOGGER.warning(ex);
262+
log.warn(ex);
265263
}
266264
}
267265

268266
private void scanJar(MutableArray<Class<?>> classes, MutableArray<String> resources, Path jarFile) {
269-
LOGGER.debug(jarFile, "Scanning jar:[%s]"::formatted);
267+
log.debug(jarFile, "Scanning jar:[%s]"::formatted);
270268

271269
if (!Files.exists(jarFile)) {
272-
LOGGER.warning(jarFile, "Jar file:[%s] does not exists"::formatted);
270+
log.warn(jarFile, "Jar file:[%s] does not exists"::formatted);
273271
return;
274272
}
275273

@@ -280,10 +278,10 @@ private void scanJar(MutableArray<Class<?>> classes, MutableArray<String> resour
280278
try (var jin = new JarInputStream(Files.newInputStream(jarFile))) {
281279
scanJarInputStream(classes, resources, rout, rin, buffer, jin);
282280
} catch (ZipException e) {
283-
LOGGER.warning(jarFile, "Can't open zip file:[%s]"::formatted);
284-
LOGGER.warning(e);
281+
log.warn(jarFile, "Can't open zip file:[%s]"::formatted);
282+
log.warn(e);
285283
} catch (IOException e) {
286-
LOGGER.warning(e);
284+
log.warn(e);
287285
}
288286
}
289287

@@ -317,7 +315,7 @@ private void scanJarInputStream(
317315
}
318316

319317
private void scanJar(MutableArray<Class<?>> classes, MutableArray<String> resources, InputStream jarFile) {
320-
LOGGER.debug(jarFile, "Scanning jar:[%s]"::formatted);
318+
log.debug(jarFile, "Scanning jar:[%s]"::formatted);
321319

322320
var rout = new ReuseBytesOutputStream();
323321
var rin = new ReuseBytesInputStream();
@@ -326,10 +324,10 @@ private void scanJar(MutableArray<Class<?>> classes, MutableArray<String> resour
326324
try (var jin = new JarInputStream(jarFile)) {
327325
scanJarInputStream(classes, resources, rout, rin, buffer, jin);
328326
} catch (final ZipException e) {
329-
LOGGER.warning(jarFile, arg -> "Can't open zip file " + arg);
330-
LOGGER.warning(e);
327+
log.warn(jarFile, arg -> "Can't open zip file " + arg);
328+
log.warn(e);
331329
} catch (final IOException e) {
332-
LOGGER.warning(e);
330+
log.warn(e);
333331
}
334332
}
335333

@@ -347,7 +345,7 @@ public void scan(@Nullable Predicate<String> filter) {
347345
continue;
348346
}
349347

350-
LOGGER.debug(file, "Scanning file:[%s]"::formatted);
348+
log.debug(file, "Scanning file:[%s]"::formatted);
351349

352350
var filename = file
353351
.getFileName()
@@ -363,7 +361,7 @@ public void scan(@Nullable Predicate<String> filter) {
363361
this.classes = classes.toArray(ArrayUtils.EMPTY_CLASS_ARRAY);
364362
this.resources = resources.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
365363

366-
LOGGER.debug(
364+
log.debug(
367365
classes().length,
368366
resources().length,
369367
"Scanned [%s] classes and [%s] resources"::formatted);

rlib-classpath/src/main/java/javasabr/rlib/classpath/impl/ManifestClassPathScannerImpl.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
import javasabr.rlib.collections.array.MutableArray;
1515
import javasabr.rlib.common.util.Utils;
1616
import lombok.AccessLevel;
17+
import lombok.CustomLog;
1718
import lombok.experimental.FieldDefaults;
1819

1920
/**
2021
* @author JavaSaBr
2122
*/
23+
@CustomLog
2224
@FieldDefaults(level = AccessLevel.PROTECTED, makeFinal = true)
2325
public class ManifestClassPathScannerImpl extends ClassPathScannerImpl {
2426

@@ -50,7 +52,7 @@ protected Array<String> calculateManifestClassPath() {
5052
URL url = urls.nextElement();
5153
InputStream is = url.openStream();
5254
if (is == null) {
53-
LOGGER.warning(url, arg -> "not found input stream for the url " + arg);
55+
log.warn(url, arg -> "not found input stream for the url " + arg);
5456
continue;
5557
}
5658

@@ -72,7 +74,7 @@ protected Array<String> calculateManifestClassPath() {
7274
}
7375

7476
} catch (Exception exc) {
75-
LOGGER.warning(exc);
77+
log.warn(exc);
7678
}
7779
}
7880

0 commit comments

Comments
 (0)