diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 2deba8579a..489e1ab984 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -3,6 +3,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`). ## [Unreleased] +* Depending on the file system, executing `gradle spotlessApply` might change permission on the changed files from `644` to `755`; fixes ([#656](https://github.com/diffplug/spotless/pull/656)) * Bump default ktfmt from 0.15 to 0.16, and remove duplicated logic for the --dropbox-style option ([#642](https://github.com/diffplug/spotless/pull/648)) ## [5.1.0] - 2020-07-13 diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessApply.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessApply.java index b93ac6f2a8..a815d5c33c 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessApply.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessApply.java @@ -68,7 +68,7 @@ public void visitFile(FileVisitDetails fileVisitDetails) { File originalSource = new File(getProject().getProjectDir(), path); try { getLogger().debug("Copying " + fileVisitDetails.getFile() + " to " + originalSource); - Files.copy(fileVisitDetails.getFile().toPath(), originalSource.toPath(), StandardCopyOption.REPLACE_EXISTING); + Files.copy(fileVisitDetails.getFile().toPath(), originalSource.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskImpl.java b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskImpl.java index f3f359c09d..23c0679558 100644 --- a/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskImpl.java +++ b/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskImpl.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.util.Comparator; import org.gradle.api.GradleException; @@ -80,6 +81,8 @@ private void processInputFile(Formatter formatter, File input) throws IOExceptio throw new IllegalStateException("Every file has a parent folder."); } Files.createDirectories(parentDir); + // Need to copy the original file to the tmp location just to remember the file attributes + Files.copy(input.toPath(), output.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES); dirtyState.writeCanonicalTo(output); } } diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FilePermissionsTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FilePermissionsTest.java new file mode 100644 index 0000000000..63f86f902b --- /dev/null +++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FilePermissionsTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2020 DiffPlug + * + * Licensed 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. + */ +package com.diffplug.gradle.spotless; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.PosixFilePermissions; + +import org.assertj.core.api.AbstractStringAssert; +import org.assertj.core.api.Assertions; +import org.junit.Test; + +import com.diffplug.spotless.FileSignature; + +public class FilePermissionsTest extends GradleIntegrationHarness { + @Test + public void spotlessApplyShouldPreservePermissions() throws IOException { + if (FileSignature.machineIsWin()) { + // need unix filesystem + return; + } + setFile("build.gradle").toLines( + "buildscript { repositories { mavenCentral() } }", + "plugins {", + " id 'com.diffplug.spotless'", + "}", + "", + "spotless {", + " java {", + " target file('test.java')", + " googleJavaFormat('1.2')", + " }", + "}"); + setFile("test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test"); + + Path path = rootFolder().toPath().resolve("test.java"); + Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr--r--")); + assertPermissions(path).isEqualTo("rwxr--r--"); + + gradleRunner().withArguments("spotlessApply").build(); + assertFile("test.java").sameAsResource("java/googlejavaformat/JavaCodeFormatted.test"); + assertPermissions(path).isEqualTo("rwxr--r--"); + } + + private AbstractStringAssert assertPermissions(Path path) throws IOException { + return Assertions.assertThat(PosixFilePermissions.toString(Files.getPosixFilePermissions(path))); + } +}