Skip to content

Commit d8946c3

Browse files
authored
Auto rewrite (#2477)
* Format code * Add rewrite profile * Rewrite improvements * Automatically review PRs with OpenRewrite recipe runs
1 parent 1f37c6b commit d8946c3

28 files changed

Lines changed: 607 additions & 331 deletions

File tree

.github/workflows/comment-pr.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Description: This workflow is triggered when the `receive-pr` workflow completes to post suggestions on the PR.
2+
# Since this pull request has write permissions on the target repo, we should **NOT** execute any untrusted code.
3+
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
4+
---
5+
name: comment-pr
6+
7+
on:
8+
workflow_run:
9+
workflows: ["receive-pr"]
10+
types:
11+
- completed
12+
13+
jobs:
14+
post-suggestions:
15+
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-a-workflow-based-on-the-conclusion-of-another-workflow
16+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
17+
runs-on: ubuntu-latest
18+
env:
19+
# https://docs.github.com/en/actions/reference/authentication-in-a-workflow#permissions-for-the-github_token
20+
ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21+
timeout-minutes: 10
22+
steps:
23+
- uses: actions/checkout@v4
24+
with:
25+
ref: ${{github.event.workflow_run.head_branch}}
26+
repository: ${{github.event.workflow_run.head_repository.full_name}}
27+
28+
# Download the patch
29+
- uses: actions/download-artifact@v4
30+
with:
31+
name: patch
32+
github-token: ${{ secrets.GITHUB_TOKEN }}
33+
run-id: ${{ github.event.workflow_run.id }}
34+
- name: Apply patch
35+
run: |
36+
git apply git-diff.patch --allow-empty
37+
rm git-diff.patch
38+
39+
# Download the PR number
40+
- uses: actions/download-artifact@v4
41+
with:
42+
name: pr_number
43+
github-token: ${{ secrets.GITHUB_TOKEN }}
44+
run-id: ${{ github.event.workflow_run.id }}
45+
- name: Read pr_number.txt
46+
run: |
47+
PR_NUMBER=$(cat pr_number.txt)
48+
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
49+
rm pr_number.txt
50+
51+
# Post suggestions as a comment on the PR
52+
- uses: googleapis/code-suggester@v4
53+
with:
54+
command: review
55+
pull_number: ${{ env.PR_NUMBER }}
56+
git_dir: '.'

.github/workflows/receive-pr.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Description: This workflow runs OpenRewrite recipes against opened pull request and upload the patch.
2+
# Since this pull request receives untrusted code, we should **NOT** have any secrets in the environment.
3+
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
4+
---
5+
name: receive-pr
6+
7+
on:
8+
pull_request:
9+
types: [opened, synchronize]
10+
branches:
11+
- main
12+
13+
concurrency:
14+
group: '${{ github.workflow }} @ ${{ github.ref }}'
15+
cancel-in-progress: true
16+
17+
jobs:
18+
upload-patch:
19+
runs-on: ubuntu-latest
20+
timeout-minutes: 10
21+
steps:
22+
- uses: actions/checkout@v4
23+
with:
24+
ref: ${{github.event.pull_request.head.ref}}
25+
repository: ${{github.event.pull_request.head.repo.full_name}}
26+
- uses: actions/setup-java@v4
27+
with:
28+
java-version: '21'
29+
distribution: 'temurin'
30+
cache: 'maven'
31+
32+
# Capture the PR number
33+
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#using-data-from-the-triggering-workflow
34+
- name: Create pr_number.txt
35+
run: echo "${{ github.event.number }}" > pr_number.txt
36+
- uses: actions/upload-artifact@v4
37+
with:
38+
name: pr_number
39+
path: pr_number.txt
40+
- name: Remove pr_number.txt
41+
run: rm -f pr_number.txt
42+
43+
# Execute recipes
44+
- name: Apply OpenRewrite recipes
45+
run: mvn --activate-profiles openrewrite org.openrewrite.maven:rewrite-maven-plugin:run
46+
47+
# Capture the diff
48+
- name: Create patch
49+
run: |
50+
git diff | tee git-diff.patch
51+
- uses: actions/upload-artifact@v4
52+
with:
53+
name: patch
54+
path: git-diff.patch

core/src/test/java/feign/BaseBuilderTest.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 The Feign Authors
2+
* Copyright 2012-2024 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -45,11 +45,9 @@ private void test(BaseBuilder<?, ?> builder, int expectedFieldsCount)
4545
for (Field field : fields) {
4646
field.setAccessible(true);
4747
Object mockedValue = field.get(enriched);
48-
if (mockedValue instanceof List) {
49-
assertThat((List) mockedValue)
50-
.withFailMessage("Enriched list missing contents %s", field)
51-
.isNotEmpty();
52-
mockedValue = ((List<Object>) mockedValue).get(0);
48+
if (mockedValue instanceof List<?> list) {
49+
assertThat(list).withFailMessage("Enriched list missing contents %s", field).isNotEmpty();
50+
mockedValue = list.getFirst();
5351
}
5452
assertThat(Mockito.mockingDetails(mockedValue).isMock())
5553
.as("Field was not enriched " + field)

core/src/test/java/feign/ClientTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ void testConvertAndSendWithContentLength() throws IOException {
9292
Map<String, List<String>> requestProperties = urlConnection.getRequestProperties();
9393
String requestProperty = urlConnection.getRequestProperty(Util.CONTENT_LENGTH);
9494
/*
95-
* By default, "Content-Length" will not be added because this key is in the
96-
* restrictedHeaderSet of HttpURLConnection.
97-
* Unless set system property "sun.net.http.allowRestrictedHeaders" to "true"
95+
* By default, "Content-Length" will not be added because this key is in the restrictedHeaderSet
96+
* of HttpURLConnection. Unless set system property "sun.net.http.allowRestrictedHeaders" to
97+
* "true"
9898
*/
9999
assertNull(requestProperties.get(Util.CONTENT_LENGTH));
100100
}

core/src/test/java/feign/DefaultContractInheritanceTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 The Feign Authors
2+
* Copyright 2012-2024 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -45,9 +45,9 @@ void simpleParameterizedBaseApi() throws Exception {
4545

4646
assertThat(md).hasSize(1);
4747

48-
assertThat(md.get(0).configKey()).isEqualTo("SimpleParameterizedApi#get(String)");
49-
assertThat(md.get(0).returnType()).isEqualTo(String.class);
50-
assertThat(md.get(0).template()).hasHeaders(entry("Foo", asList("Bar")));
48+
assertThat(md.getFirst().configKey()).isEqualTo("SimpleParameterizedApi#get(String)");
49+
assertThat(md.getFirst().returnType()).isEqualTo(String.class);
50+
assertThat(md.getFirst().template()).hasHeaders(entry("Foo", asList("Bar")));
5151
}
5252

5353
@Test

core/src/test/java/feign/DefaultContractTest.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 The Feign Authors
2+
* Copyright 2012-2024 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -695,16 +695,16 @@ void parameterizedHeaderExpandApi() throws Exception {
695695

696696
assertThat(md).hasSize(1);
697697

698-
assertThat(md.get(0).configKey())
698+
assertThat(md.getFirst().configKey())
699699
.isEqualTo("ParameterizedHeaderExpandApi#getZone(String,String)");
700-
assertThat(md.get(0).returnType()).isEqualTo(String.class);
701-
assertThat(md.get(0).template())
700+
assertThat(md.getFirst().returnType()).isEqualTo(String.class);
701+
assertThat(md.getFirst().template())
702702
.hasHeaders(
703703
entry("Authorization", asList("{authHdr}")),
704704
entry("Accept", asList("application/json")));
705705
// Ensure that the authHdr expansion was properly detected and did not create a
706706
// formParam
707-
assertThat(md.get(0).formParams()).isEmpty();
707+
assertThat(md.getFirst().formParams()).isEmpty();
708708
}
709709

710710
@Test
@@ -715,16 +715,16 @@ void parameterizedHeaderNotStartingWithCurlyBraceExpandApi() throws Exception {
715715

716716
assertThat(md).hasSize(1);
717717

718-
assertThat(md.get(0).configKey())
718+
assertThat(md.getFirst().configKey())
719719
.isEqualTo("ParameterizedHeaderNotStartingWithCurlyBraceExpandApi#getZone(String,String)");
720-
assertThat(md.get(0).returnType()).isEqualTo(String.class);
721-
assertThat(md.get(0).template())
720+
assertThat(md.getFirst().returnType()).isEqualTo(String.class);
721+
assertThat(md.getFirst().template())
722722
.hasHeaders(
723723
entry("Authorization", asList("Bearer {authHdr}")),
724724
entry("Accept", asList("application/json")));
725725
// Ensure that the authHdr expansion was properly detected and did not create a
726726
// formParam
727-
assertThat(md.get(0).formParams()).isEmpty();
727+
assertThat(md.getFirst().formParams()).isEmpty();
728728
}
729729

730730
@Headers("Authorization: Bearer {authHdr}")
@@ -816,7 +816,7 @@ void staticMethodsOnInterfaceIgnored() throws Exception {
816816
final List<MethodMetadata> mds =
817817
contract.parseAndValidateMetadata(StaticMethodOnInterface.class);
818818
assertThat(mds).hasSize(1);
819-
final MethodMetadata md = mds.get(0);
819+
final MethodMetadata md = mds.getFirst();
820820
assertThat(md.configKey()).isEqualTo("StaticMethodOnInterface#get(String)");
821821
}
822822

@@ -834,7 +834,7 @@ void defaultMethodsOnInterfaceIgnored() throws Exception {
834834
final List<MethodMetadata> mds =
835835
contract.parseAndValidateMetadata(DefaultMethodOnInterface.class);
836836
assertThat(mds).hasSize(1);
837-
final MethodMetadata md = mds.get(0);
837+
final MethodMetadata md = mds.getFirst();
838838
assertThat(md.configKey()).isEqualTo("DefaultMethodOnInterface#get(String)");
839839
}
840840

@@ -847,8 +847,9 @@ interface SubstringQuery {
847847
void paramIsASubstringOfAQuery() throws Exception {
848848
final List<MethodMetadata> mds = contract.parseAndValidateMetadata(SubstringQuery.class);
849849

850-
assertThat(mds.get(0).template().queries()).containsExactly(entry("q", asList("body:{body}")));
851-
assertThat(mds.get(0).formParams()).isEmpty(); // Prevent issue 424
850+
assertThat(mds.getFirst().template().queries())
851+
.containsExactly(entry("q", asList("body:{body}")));
852+
assertThat(mds.getFirst().formParams()).isEmpty(); // Prevent issue 424
852853
}
853854

854855
@Test

core/src/test/java/feign/FeignExceptionTest.java

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 The Feign Authors
2+
* Copyright 2012-2024 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -173,25 +173,27 @@ void canGetResponseHeadersFromException() {
173173
@Test
174174
void lengthOfBodyExceptionTest() {
175175
String bigResponse =
176-
"I love a storm in early May\n"
177-
+ "When springtime’s boisterous, firstborn thunder\n"
178-
+ "Over the sky will gaily wander\n"
179-
+ "And growl and roar as though in play.\n"
180-
+ "\n"
181-
+ "A peal, another — gleeful, cheering…\n"
182-
+ "Rain, raindust… On the trees, behold!-\n"
183-
+ "The drops hang, each a long pearl earring;\n"
184-
+ "Bright sunshine paints the thin threads gold.\n"
185-
+ "\n"
186-
+ "A stream downhill goes rushing reckless,\n"
187-
+ "And in the woods the birds rejoice.\n"
188-
+ "Din. Clamour. Noise. All nature echoes\n"
189-
+ "The thunder’s youthful, merry voice.\n"
190-
+ "\n"
191-
+ "You’ll say: ‘Tis laughing, carefree Hebe —\n"
192-
+ "She fed her father’s eagle, and\n"
193-
+ "The Storm Cup brimming with a seething\n"
194-
+ "And bubbling wine dropped from her hand";
176+
"""
177+
I love a storm in early May
178+
When springtime’s boisterous, firstborn thunder
179+
Over the sky will gaily wander
180+
And growl and roar as though in play.
181+
182+
A peal, another — gleeful, cheering…
183+
Rain, raindust… On the trees, behold!-
184+
The drops hang, each a long pearl earring;
185+
Bright sunshine paints the thin threads gold.
186+
187+
A stream downhill goes rushing reckless,
188+
And in the woods the birds rejoice.
189+
Din. Clamour. Noise. All nature echoes
190+
The thunder’s youthful, merry voice.
191+
192+
You’ll say: ‘Tis laughing, carefree Hebe —
193+
She fed her father’s eagle, and
194+
The Storm Cup brimming with a seething
195+
And bubbling wine dropped from her hand\
196+
""";
195197

196198
Request request =
197199
Request.create(

core/src/test/java/feign/LoggerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ void expectMessages(List<String> expectedMessages) {
534534

535535
@Override
536536
protected void log(String configKey, String format, Object... args) {
537-
messages.add(methodTag(configKey) + String.format(format, args));
537+
messages.add(methodTag(configKey) + format.formatted(args));
538538
}
539539

540540
// @Override

core/src/test/java/feign/RequestTemplateTest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,10 @@ void resolveTemplateWithBodyTemplateSetsBodyAndContentLength() {
326326
new RequestTemplate()
327327
.method(HttpMethod.POST)
328328
.bodyTemplate(
329-
"%7B\"customer_name\": \"{customer_name}\", \"user_name\": \"{user_name}\", "
330-
+ "\"password\": \"{password}\"%7D",
329+
"""
330+
%7B"customer_name": "{customer_name}", "user_name": "{user_name}", \
331+
"password": "{password}"%7D\
332+
""",
331333
Util.UTF_8);
332334

333335
template =

core/src/test/java/feign/client/DefaultClientTest.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,7 @@
2424
import feign.RetryableException;
2525
import feign.assertj.MockWebServerAssertions;
2626
import java.io.IOException;
27-
import java.net.HttpURLConnection;
28-
import java.net.InetSocketAddress;
29-
import java.net.ProtocolException;
30-
import java.net.Proxy;
31-
import java.net.Proxy.Type;
32-
import java.net.SocketAddress;
33-
import java.net.URL;
27+
import java.net.*;
3428
import java.util.Collections;
3529
import okhttp3.mockwebserver.MockResponse;
3630
import okhttp3.mockwebserver.SocketPolicy;
@@ -131,12 +125,13 @@ void canOverrideHostnameVerifier() throws IOException, InterruptedException {
131125
@Test
132126
void canCreateWithImplicitOrNoCredentials() throws Exception {
133127
Proxied proxied =
134-
new Proxied(TrustingSSLSocketFactory.get(), null, new Proxy(Type.HTTP, proxyAddress));
128+
new Proxied(TrustingSSLSocketFactory.get(), null, new Proxy(Proxy.Type.HTTP, proxyAddress));
135129
assertThat(proxied).isNotNull();
136130
assertThat(proxied.getCredentials()).isNullOrEmpty();
137131

138132
/* verify that the proxy */
139-
HttpURLConnection connection = proxied.getConnection(new URL("http://www.example.com"));
133+
HttpURLConnection connection =
134+
proxied.getConnection(URI.create("http://www.example.com").toURL());
140135
assertThat(connection).isNotNull().isInstanceOf(HttpURLConnection.class);
141136
}
142137

@@ -146,13 +141,14 @@ void canCreateWithExplicitCredentials() throws Exception {
146141
new Proxied(
147142
TrustingSSLSocketFactory.get(),
148143
null,
149-
new Proxy(Type.HTTP, proxyAddress),
144+
new Proxy(Proxy.Type.HTTP, proxyAddress),
150145
"user",
151146
"password");
152147
assertThat(proxied).isNotNull();
153148
assertThat(proxied.getCredentials()).isNotBlank();
154149

155-
HttpURLConnection connection = proxied.getConnection(new URL("http://www.example.com"));
150+
HttpURLConnection connection =
151+
proxied.getConnection(URI.create("http://www.example.com").toURL());
156152
assertThat(connection).isNotNull().isInstanceOf(HttpURLConnection.class);
157153
}
158154
}

0 commit comments

Comments
 (0)