Skip to content

Commit

Permalink
Merge branch 'main' into eason-preserve_annotation_values
Browse files Browse the repository at this point in the history
  • Loading branch information
timtebeek authored Jan 6, 2025
2 parents 1c90a62 + a3249f2 commit a490f18
Show file tree
Hide file tree
Showing 212 changed files with 13,070 additions and 2,491 deletions.
61 changes: 0 additions & 61 deletions .github/workflows/receive-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,64 +17,3 @@ jobs:
uses: openrewrite/gh-automation/.github/workflows/receive-pr.yml@main
with:
recipe: 'org.openrewrite.recipes.OpenRewriteBestPracticesSubset'
rewrite_yml: |
---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.recipes.OpenRewriteBestPracticesSubset
displayName: OpenRewrite best practices
description: Best practices for OpenRewrite recipe development.
recipeList:
- org.openrewrite.recipes.JavaRecipeBestPracticesSubset
- org.openrewrite.recipes.RecipeTestingBestPracticesSubset
- org.openrewrite.recipes.RecipeNullabilityBestPracticesSubset
#- org.openrewrite.java.OrderImports
- org.openrewrite.java.format.EmptyNewlineAtEndOfFile
- org.openrewrite.staticanalysis.InlineVariable
- org.openrewrite.staticanalysis.MissingOverrideAnnotation
- org.openrewrite.staticanalysis.UseDiamondOperator
---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.recipes.JavaRecipeBestPracticesSubset
displayName: Java Recipe best practices
description: Best practices for Java recipe development.
preconditions:
- org.openrewrite.java.search.FindTypes:
fullyQualifiedTypeName: org.openrewrite.Recipe
checkAssignability: true
recipeList:
- org.openrewrite.java.recipes.BlankLinesAroundFieldsWithAnnotations
- org.openrewrite.java.recipes.ExecutionContextParameterName
- org.openrewrite.java.recipes.MissingOptionExample
- org.openrewrite.java.recipes.RecipeEqualsAndHashCodeCallSuper
- org.openrewrite.java.recipes.UseTreeRandomId
- org.openrewrite.staticanalysis.NeedBraces
#- org.openrewrite.staticanalysis.RemoveSystemOutPrintln
---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.recipes.RecipeTestingBestPracticesSubset
displayName: Recipe testing best practices
description: Best practices for testing recipes.
preconditions:
- org.openrewrite.java.search.FindTypes:
fullyQualifiedTypeName: org.openrewrite.test.RewriteTest
checkAssignability: true
recipeList:
- org.openrewrite.java.recipes.RewriteTestClassesShouldNotBePublic
#- org.openrewrite.java.recipes.SelectRecipeExamples
- org.openrewrite.java.recipes.SourceSpecTextBlockIndentation
- org.openrewrite.java.testing.cleanup.RemoveTestPrefix
- org.openrewrite.java.testing.cleanup.TestsShouldNotBePublic
- org.openrewrite.staticanalysis.NeedBraces
- org.openrewrite.staticanalysis.RemoveSystemOutPrintln
---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.recipes.RecipeNullabilityBestPracticesSubset
displayName: Recipe nullability best practices
description: Use OpenRewrite internal nullability annotations; drop JetBrains annotations; use `package-info.java` instead.
recipeList:
- org.openrewrite.staticanalysis.NullableOnMethodReturnType
- org.openrewrite.java.RemoveAnnotation:
annotationPattern: '@org.jetbrains.annotations.NotNull'
- org.openrewrite.java.RemoveAnnotation:
annotationPattern: '@jakarta.annotation.Nonnull'
#- org.openrewrite.java.jspecify.MigrateToJspecify
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionSha256Sum=f397b287023acdba1e9f6fc5ea72d22dd63669d59ed4a289a29b1a76eee151c6
distributionSha256Sum=7a00d51fb93147819aab76024feece20b6b84e420694101f276be952e08bef03
4 changes: 0 additions & 4 deletions rewrite-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ dependencies {

api("org.jspecify:jspecify:latest.release")

// Pinning okhttp while waiting on 5.0.0
// https://github.com/openrewrite/rewrite/issues/1479
compileOnly("com.squareup.okhttp3:okhttp:4.9.3")

implementation("org.apache.commons:commons-compress:latest.release")

implementation("io.micrometer:micrometer-core:1.9.+")
Expand Down
61 changes: 43 additions & 18 deletions rewrite-core/src/main/java/org/openrewrite/GitRemote.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,51 +113,64 @@ public Parser() {
* @return the clone url
*/
public URI toUri(GitRemote remote, String protocol) {
return buildUri(remote.service, remote.origin, remote.path, protocol);
}

/**
* Build a {@link URI} clone url from components, if that protocol is supported (configured) by the matched server
*
* @param service the type of SCM service
* @param origin the origin of the SCM service, any protocol will be stripped (and not used for matching)
* @param path the path to the repository
* @param protocol the protocol to use. Supported protocols: ssh, http, https
* @return the clone URL if it could be created.
* @throws IllegalArgumentException if the protocol is not supported by the server.
*/
public URI buildUri(Service service, String origin, String path, String protocol) {
if (!ALLOWED_PROTOCOLS.contains(protocol)) {
throw new IllegalArgumentException("Invalid protocol: " + protocol + ". Must be one of: " + ALLOWED_PROTOCOLS);
}
URI selectedBaseUrl;

if (remote.service == Service.Unknown) {
if (PORT_PATTERN.matcher(remote.origin).find()) {
throw new IllegalArgumentException("Unable to determine protocol/port combination for an unregistered origin with a port: " + remote.origin);
if (service == Service.Unknown) {
if (PORT_PATTERN.matcher(origin).find()) {
throw new IllegalArgumentException("Unable to determine protocol/port combination for an unregistered origin with a port: " + origin);
}
selectedBaseUrl = URI.create(protocol + "://" + stripProtocol(remote.origin));
selectedBaseUrl = URI.create(protocol + "://" + stripProtocol(origin));
} else {
selectedBaseUrl = servers.stream()
.filter(server -> server.allOrigins()
.stream()
.anyMatch(origin -> origin.equalsIgnoreCase(stripProtocol(remote.origin)))
.anyMatch(o -> o.equalsIgnoreCase(stripProtocol(origin)))
)
.flatMap(server -> server.getUris().stream())
.filter(uri -> uri.getScheme().equals(protocol))
.filter(uri -> Parser.normalize(uri).getScheme().equals(protocol))
.findFirst()
.orElseGet(() -> {
URI normalizedUri = Parser.normalize(remote.origin);
URI normalizedUri = Parser.normalize(origin);
if (!normalizedUri.getScheme().equals(protocol)) {
throw new IllegalStateException("No matching server found that supports ssh for origin: " + remote.origin);
throw new IllegalArgumentException("Unable to build clone URL. No matching server found that supports " + protocol + " for origin: " + origin);
}
return normalizedUri;
});
}

String path = remote.path.replaceFirst("^/", "");
path = path.replaceFirst("^/", "");
boolean ssh = protocol.equals("ssh");
switch (remote.service) {
switch (service) {
case Bitbucket:
if (!ssh) {
path = "scm/" + remote.path;
path = "scm/" + path;
}
break;
case AzureDevOps:
if (ssh) {
path = "v3/" + remote.path;
path = "v3/" + path;
} else {
path = remote.path.replaceFirst("([^/]+)/([^/]+)/(.*)", "$1/$2/_git/$3");
path = path.replaceFirst("([^/]+)/([^/]+)/(.*)", "$1/$2/_git/$3");
}
break;
}
if (remote.service != Service.AzureDevOps) {
if (service != Service.AzureDevOps) {
path += ".git";
}
String maybeSlash = selectedBaseUrl.toString().endsWith("/") ? "" : "/";
Expand Down Expand Up @@ -203,11 +216,18 @@ public Parser registerRemote(Service service, String origin) {
return this;
}

/**
* Find a registered remote server by an origin.
*
* @param origin the origin of the server. Any protocol will be stripped (and not used to match)
* @return The server if found, or an unknown type server with a normalized url/origin if not found.
*/
public RemoteServer findRemoteServer(String origin) {
return servers.stream().filter(server -> server.origin.equalsIgnoreCase(origin))
String strippedOrigin = stripProtocol(origin);
return servers.stream().filter(server -> server.origin.equalsIgnoreCase(strippedOrigin))
.findFirst()
.orElseGet(() -> {
URI normalizedUri = normalize(origin);
URI normalizedUri = normalize(strippedOrigin);
String normalizedOrigin = normalizedUri.getHost() + maybePort(normalizedUri.getPort(), normalizedUri.getScheme());
return new RemoteServer(Service.Unknown, normalizedOrigin, normalizedUri);
});
Expand Down Expand Up @@ -281,6 +301,10 @@ private String repositoryPath(RemoteServerMatch match, URI normalizedUri) {

private static final Pattern PORT_PATTERN = Pattern.compile(":\\d+(/.+)(/.+)+");

static URI normalize(URI url) {
return normalize(url.toString());
}

static URI normalize(String url) {
try {
URIish uri = new URIish(url);
Expand Down Expand Up @@ -374,10 +398,11 @@ public Set<String> allOrigins() {
Set<String> origins = new LinkedHashSet<>();
origins.add(origin);
for (URI uri : uris) {
URI normalized = Parser.normalize(uri.toString());
URI normalized = Parser.normalize(uri);
origins.add(Parser.stripProtocol(normalized.toString()));
}
return origins;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,38 +21,40 @@
import org.jspecify.annotations.Nullable;
import org.openrewrite.trait.Reference;

import java.lang.ref.SoftReference;
import java.util.*;

@Incubating(since = "8.39.0")
public interface SourceFileWithReferences extends SourceFile {

References getReferences();

default SoftReference<References> build(@Nullable SoftReference<@Nullable References> references) {
References cache = references == null ? null : references.get();
if (cache == null || cache.getSourceFile() != this) {
return new SoftReference<>(References.build(this));
}
return references;
}

@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
class References {
@Getter(AccessLevel.PRIVATE)
private final SourceFile sourceFile;
@Getter
private final Set<Reference> references;

public Collection<Reference> findMatches(Reference.Matcher matcher) {
return findMatchesInternal(matcher, null);
}

public Collection<Reference> findMatches(Reference.Matcher matcher, Reference.Kind kind) {
return findMatchesInternal(matcher, kind);
}

private List<Reference> findMatchesInternal(Reference.Matcher matcher, Reference.@Nullable Kind kind) {
List<Reference> list = new ArrayList<>();
for (Reference ref : references) {
if ((kind == null || ref.getKind().equals(kind)) && ref.matches(matcher) ) {
if (ref.matches(matcher)) {
list.add(ref);
}
}
return list;
}

public static References build(SourceFile sourceFile) {
private static References build(SourceFile sourceFile) {
Set<Reference> references = new HashSet<>();
ServiceLoader<Reference.Provider> loader = ServiceLoader.load(Reference.Provider.class);
loader.forEach(provider -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ private Collection<Map<String, Object>> loadResources(ResourceType resourceType)
for (Object resource : yaml.loadAll(yamlSource)) {
if (resource instanceof Map) {
@SuppressWarnings("unchecked") Map<String, Object> resourceMap = (Map<String, Object>) resource;
if (resourceType.equals(ResourceType.fromSpec((String) resourceMap.get("type")))) {
if (resourceType == ResourceType.fromSpec((String) resourceMap.get("type"))) {
resources.add(resourceMap);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ public boolean matches(String str) {
}

public static boolean matches(NameCaseConvention convention, String str) {
if (str.isEmpty()) {
return false;
}
switch (convention) {
case LOWER_CAMEL:
if (!Character.isLowerCase(str.charAt(0)) && str.charAt(0) != '$') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,18 @@ public class ReflectionUtils {
* Cache for {@link Class#getDeclaredMethods()} plus equivalent default methods
* from Java 8 based interfaces, allowing for fast iteration.
*/
private static final Map<Class<?>, Method[]> declaredMethodsCache = new ConcurrentHashMap<>(256);
private static final Map<Class<?>, Method[]> DECLARED_METHODS_CACHE = new ConcurrentHashMap<>(256);

public static boolean isClassAvailable(String fullyQualifiedClassName) {
try {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
ClassLoader classLoader = contextClassLoader == null ? ReflectionUtils.class.getClassLoader() : contextClassLoader;
Class.forName(fullyQualifiedClassName, false, classLoader);
return true;
} catch (ClassNotFoundException e) {
return false;
}
}

public static @Nullable Method findMethod(Class<?> clazz, String name, Class<?>... paramTypes) {
Class<?> searchType = clazz;
Expand All @@ -54,7 +65,7 @@ public class ReflectionUtils {
}

private static Method[] getDeclaredMethods(Class<?> clazz) {
Method[] result = declaredMethodsCache.get(clazz);
Method[] result = DECLARED_METHODS_CACHE.get(clazz);
if (result == null) {
try {
Method[] declaredMethods = clazz.getDeclaredMethods();
Expand All @@ -70,7 +81,7 @@ private static Method[] getDeclaredMethods(Class<?> clazz) {
} else {
result = declaredMethods;
}
declaredMethodsCache.put(clazz, (result.length == 0 ? EMPTY_METHOD_ARRAY : result));
DECLARED_METHODS_CACHE.put(clazz, (result.length == 0 ? EMPTY_METHOD_ARRAY : result));
} catch (Throwable ex) {
throw new IllegalStateException("Failed to introspect Class [" + clazz.getName() +
"] from ClassLoader [" + clazz.getClassLoader() + "]", ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -720,4 +720,14 @@ public static String formatUriForPropertiesFile(String uri) {
public static boolean hasLineBreak(@Nullable String s) {
return s != null && LINE_BREAK.matcher(s).find();
}

public static boolean containsWhitespace(String s) {
for (int i = 0; i < s.length(); ++i) {
if (Character.isWhitespace(s.charAt(i))) {
return true;
}
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -92,6 +93,9 @@ public InputStream getInputStream(ExecutionContext ctx) {
try {
Path localArchive = cache.compute(uri, () -> {
//noinspection resource
if ("file".equals(uri.getScheme())) {
return Files.newInputStream(Paths.get(uri));
}
HttpSender.Response response = httpSender.send(httpSender.get(uri.toString()).build());
if (response.isSuccessful()) {
return response.getBody();
Expand Down
Loading

0 comments on commit a490f18

Please sign in to comment.