Search code examples
android-studioandroid-gradle-pluginbuild.gradlemacos-high-sierra

"project.copy" not working on MacOS High Sierra


In my Android Studio project I have a small script, which creates from different Language Resources, strings.xml for Android and .lproj for iOS.

Until now, everything worked fine but then I upgraded to MacOS High Sierra. And now in my Android Studio project the gradle-Task which creates my String values fails cause it could not open the values-da Folder while moving the string.xml into the res/ Folder.

The part where it fails is here:

project.fileTree(dir: scriptPath).visit {
    FileVisitDetails details ->
        if (details.file.name.startsWith("values-")) {
            println "copying " + details.file.absolutePath + " to " + resPath;
            //It fails here at .copy
            project.copy {
                from details.file.absolutePath
                into resPath + "/" + details.file.name
                // copy english resources to base values folder
                if (details.file.name.equals("values-en")) {
                    into resPath + "/values"
                }
            }

            details.file.deleteDir();
        }
} 

My first guess was, that this could be related to the new Filesystem. Does anyone have similar Problems? I could verify that I probably is caused by High Sierra, cause my colleague has the same problem after updating to High Sierra.

Here the "What went wrong"-Message:

* What went wrong:
A problem occurred evaluating project ':app'.
> Could not read directory path '/Some/path/from/User/values-da'.

Here is the Stacktrace I got while running the task with --stacktrace:

Caused by: org.gradle.api.GradleException: Could not read directory    path '/Some/path/from/User/values-da'.
08:14:17.474 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.file.collections.jdk7.Jdk7DirectoryWalker$1.postVisitDirectory(Jdk7DirectoryWalker.java:109)
08:14:17.474 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.file.collections.jdk7.Jdk7DirectoryWalker$1.postVisitDirectory(Jdk7DirectoryWalker.java:58)
08:14:17.475 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.file.collections.jdk7.Jdk7DirectoryWalker.walkDir(Jdk7DirectoryWalker.java:58)
08:14:17.475 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.file.collections.DirectoryFileTree.walkDir(DirectoryFileTree.java:163)
08:14:17.475 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.file.collections.DirectoryFileTree.visitFrom(DirectoryFileTree.java:147)
08:14:17.475 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.file.collections.DirectoryFileTree.visit(DirectoryFileTree.java:132)
08:14:17.476 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.file.collections.FileTreeAdapter.visit(FileTreeAdapter.java:110)
08:14:17.476 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.file.AbstractFileTree.visit(AbstractFileTree.java:123)
08:14:17.476 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.file.CompositeFileTree.visit(CompositeFileTree.java:64)
08:14:17.476 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.file.CompositeFileTree.visit(CompositeFileTree.java:58)
08:14:17.476 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.file.FileTree$visit.call(Unknown Source)
08:14:17.476 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at build_4z109ko3musne9trwmjez6vxh$_run_closure6.doCall(/Users/mtuchner/fotoplus-android/frontend-android/app/build.gradle:230)
08:14:17.477 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:70)
08:14:17.477 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.util.ConfigureUtil.configureTarget(ConfigureUtil.java:160)
08:14:17.477 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.util.ConfigureUtil.configureSelf(ConfigureUtil.java:136)
08:14:17.477 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.AbstractTask.configure(AbstractTask.java:528)
08:14:17.477 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.internal.tasks.DefaultTaskContainer.create(DefaultTaskContainer.java:137)
08:14:17.478 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.api.tasks.TaskContainer$create.call(Unknown Source)
08:14:17.478 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at build_4z109ko3musne9trwmjez6vxh.run(/Users/mtuchner/fotoplus-android/frontend-android/app/build.gradle:184)
08:14:17.478 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:90)
08:14:17.478 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]   ... 62 more

Solution

  • I could fix my problem with a small change. After posting the stack trace I've seen, that the ".postVisitDirectory" Method of the JDK7FileProvider throws the error.

    The documentation says, that this method is always called, after a visit in the FileTree. So I took the Delete Operation and out of the current visit and put it into a closure behind the .visit{} and it compiles again.

    Here the code:

    List<File> dirsToDelete = new ArrayList<File>()
    // copy string resources from shared
    project.fileTree(dir: scriptPath).visit {
        FileVisitDetails details ->
            if (details.file.name.startsWith("values-")) {
                println "copying " + details.file.absolutePath + " to " + resPath;
                    project.copy {
                        from details.file.absolutePath
                        into resPath + "/" + details.file.name
                        // copy english resources to base values folder
                        if (details.file.name.equals("values-en")) {
                            into resPath + "/values"
                        }
                        dirsToDelete.add(details.file)
                }
            }
    }.with {
        for(Iterator<File> i = dirsToDelete.iterator(); i.hasNext();) {
            File file = i.next();
            file.deleteDir();
        }
    }