diff --git a/rewrite-java/src/main/java/org/openrewrite/java/format/RemoveTrailingWhitespaceVisitor.java b/rewrite-java/src/main/java/org/openrewrite/java/format/RemoveTrailingWhitespaceVisitor.java index 872381ea97..68a4d7a54a 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/format/RemoveTrailingWhitespaceVisitor.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/format/RemoveTrailingWhitespaceVisitor.java @@ -57,7 +57,8 @@ public Space visitSpace(Space space, Space.Location loc, P p) { String whitespace = s.getWhitespace(); int lastNewline = whitespace.lastIndexOf('\n'); // Skip import prefixes, leave those up to OrderImports which better understands that domain - if (lastNewline > 0 && loc != Space.Location.IMPORT_PREFIX) { + // Skip compilation unit prefix to preserve shebangs and other file-level prefixes + if (lastNewline > 0 && loc != Space.Location.IMPORT_PREFIX && loc != Space.Location.COMPILATION_UNIT_PREFIX) { StringBuilder ws = new StringBuilder(); for (int i = 0; i < whitespace.length(); i++) { char c = whitespace.charAt(i); diff --git a/rewrite-javascript/src/integTest/java/org/openrewrite/javascript/RemoveTrailingWhitespaceTest.java b/rewrite-javascript/src/integTest/java/org/openrewrite/javascript/RemoveTrailingWhitespaceTest.java new file mode 100644 index 0000000000..03272f766a --- /dev/null +++ b/rewrite-javascript/src/integTest/java/org/openrewrite/javascript/RemoveTrailingWhitespaceTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * 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. + */ +package org.openrewrite.javascript; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.openrewrite.Issue; +import org.openrewrite.java.format.RemoveTrailingWhitespace; +import org.openrewrite.javascript.rpc.JavaScriptRewriteRpc; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; +import org.openrewrite.test.TypeValidation; + +import static org.openrewrite.javascript.Assertions.javascript; + +class RemoveTrailingWhitespaceTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec.recipe(new RemoveTrailingWhitespace()); + } + + @AfterEach + void after() { + JavaScriptRewriteRpc.shutdownCurrent(); + } + + @Issue("https://github.com/openrewrite/rewrite/issues/6274") + @Test + void doNotRemoveShebang() { + rewriteRun( + javascript( + """ + #!/usr/bin/env node + + /** + * Generate llms.txt and llms-full.txt for OpenRewrite documentation + */ + """ + ) + ); + } +}