Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
129 changes: 129 additions & 0 deletions .github/scripts/BinariesListUpdates.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.stream.Stream;
import org.apache.maven.search.api.Record;
import org.apache.maven.search.api.SearchRequest;
import org.apache.maven.search.backend.smo.SmoSearchBackend;
import org.apache.maven.search.backend.smo.SmoSearchBackendFactory;

import static java.util.FormatProcessor.FMT;
import static org.apache.maven.search.api.MAVEN.ARTIFACT_ID;
import static org.apache.maven.search.api.MAVEN.CLASSIFIER;
import static org.apache.maven.search.api.MAVEN.GROUP_ID;
import static org.apache.maven.search.api.MAVEN.VERSION;
import static org.apache.maven.search.api.request.BooleanQuery.and;
import static org.apache.maven.search.api.request.FieldQuery.fieldQuery;

/**
* Scans for binaries-list files and checks if newer versions of the declared dependencies exist.
*
* <pre>org.apache.maven.indexer:search-backend-smo</pre> must be in classpath.
*
* @author mbien
*/
public class BinariesListUpdates {

// java --enable-preview --source 22 --class-path "lib/*" BinariesListUpdates.java /path/to/netbeans/project
public static void main(String[] args) throws IOException, InterruptedException {

if (args.length != 1 || Files.notExists(Path.of(args[0]).resolve("README.md"))) {
throw new IllegalArgumentException("path to netbeans folder expected");
}

Path path = Path.of(args[0]);
try (Stream<Path> dependencyFiles = Files.find(path, 10, (p, a) -> p.getFileName().toString().equals("binaries-list"));
SmoSearchBackend backend = SmoSearchBackendFactory.createDefault()) {
dependencyFiles.sorted().forEach(p -> {
try {
checkDependencies(p, backend);
} catch (IOException | InterruptedException ex) {
throw new RuntimeException(ex);
}
});
}
}

private static void checkDependencies(Path path, SmoSearchBackend backend) throws IOException, InterruptedException {
System.out.println(path);
try (Stream<String> lines = Files.lines(path).parallel()) {

// 321C614F85F1DEA6BB08C1817C60D53B7F3552FD org.fusesource.jansi:jansi:2.4.0
lines.filter(l -> !l.startsWith("#"))
.filter(l -> l.length() > 40 && l.charAt(40) == ' ')
.map(l -> l.substring(40+1))
.forEach(l -> {

String[] comp = l.split("\\:");
if (comp.length == 3 || comp.length == 4) {
String gid = comp[0].strip();
String aid = comp[1].strip();
String version = comp[2].strip();
String classifier = comp.length == 4 ? comp[3].strip() : null;
try {
String gac;
String latest;
if (classifier == null) {
latest = queryLatestVersion(backend, gid, aid);
gac = String.join(":", gid, aid);
} else {
latest = queryLatestVersion(backend, gid, aid, classifier.split("@")[0]);
gac = String.join(":", gid, aid, classifier);
}
if (!version.equals(latest)) {
System.out.println(FMT." %-50s\{gac} \{version} -> \{latest}");
}
} catch (IOException | InterruptedException ex) {
throw new RuntimeException(ex);
}
} else {
System.out.println(" skip: '"+l+"'");
}
});
}
System.out.println();
}

private static String queryLatestVersion(SmoSearchBackend backend, String gid, String aid) throws IOException, InterruptedException {
return queryLatestVersion(backend, new SearchRequest(and(fieldQuery(GROUP_ID, gid), fieldQuery(ARTIFACT_ID, aid))));
}

private static String queryLatestVersion(SmoSearchBackend backend, String gid, String aid, String classifier) throws IOException, InterruptedException {
return queryLatestVersion(backend, new SearchRequest(and(fieldQuery(GROUP_ID, gid), fieldQuery(ARTIFACT_ID, aid), fieldQuery(CLASSIFIER, classifier))));
}

// reduce concurrency level if needed
private final static Semaphore requests = new Semaphore(4);

private static String queryLatestVersion(SmoSearchBackend backend, SearchRequest request) throws IOException, InterruptedException {
requests.acquire();
try {
List<Record> result = backend.search(request).getPage();
return !result.isEmpty() ? result.getFirst().getValue(VERSION) : null;
} finally {
requests.release();
}
}

}
64 changes: 64 additions & 0 deletions .github/workflows/dependency-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

name: NetBeans Dependency Checks

on:
# pull_request:
# Allows you to run this workflow manually from the Actions tab in GitHub UI
workflow_dispatch:

# cancel other workflow run in the same head-base group if it exists
concurrency:
group: dep-checker-${{ github.head_ref || github.run_id }}-${{ github.base_ref }}
cancel-in-progress: true

defaults:
run:
shell: bash

jobs:

base-build:
name: Check Dependencies
runs-on: ubuntu-latest
timeout-minutes: 20
steps:

- name: Set up JDK
uses: actions/setup-java@v3
with:
java-version: '22-ea'
distribution: 'zulu'

- name: Checkout ${{ github.ref }} ( ${{ github.sha }} )
uses: actions/checkout@v4
with:
persist-credentials: false
submodules: false
show-progress: false

- name: Check Dependencies
run: |
mvn -q dependency:get -Dartifact=org.apache.maven.indexer:search-backend-smo:7.1.1
mvn -q dependency:copy -Dartifact=org.apache.maven.indexer:search-backend-smo:7.1.1 -DoutputDirectory=./lib
mvn -q dependency:copy -Dartifact=org.apache.maven.indexer:search-api:7.1.1 -DoutputDirectory=./lib
mvn -q dependency:copy -Dartifact=com.google.code.gson:gson:2.10.1 -DoutputDirectory=./lib
echo "<pre>" >> $GITHUB_STEP_SUMMARY
java --enable-preview --source 22 -cp "lib/*" .github/scripts/BinariesListUpdates.java ./ | tee -a $GITHUB_STEP_SUMMARY
echo "</pre>" >> $GITHUB_STEP_SUMMARY
rm -Rf lib