Gradle:如何将绝对路径列表复制到单个目录中

时间:2017-10-06 02:38:18

标签: gradle groovy

在Gradle中,我尝试将绝对路径列表复制到一个目录中,但我希望将绝对路径的最后一个组件保留为目标目录的子文件夹。

目前我有:

.disable-scroll .ion-page {
    pointer-events: auto;
}

但这导致def copyTask = tasks.create(name: "copyFolders", type: Copy, overwrite: true) { from ["/sources/a-1/first", "/sources/a-3/b-1/c-1/second"] into "/destination" } /sources/foo/bar中包含的文件被复制到/sources/one/two/three/path。相反,我希望/destination包含/destinationbar文件夹(其中包含内容)。

它应该能够正确处理这种情况:

path

- >

sources
├── a-1
│   └── fist
│       └── lorem.txt
|       └── subfolder
│           └── lorem2.txt
├── a-2
│   └── fist-b
│       └── lorem.txt
|       └── subfolder
│           └── lorem2.txt
└── a-3
    └── b-1
        └── c-1
            └── second
                └── ipsum.log

根据@szymon的回答,我得到了:

destination
├── first
│   └── lorem.txt
│   └── subfolder
│       └── lorem2.txt
└── path
    └── ipsum.log

但这错误地导致:

def copyTask = tasks.create(name: "copyToDestDir", type: Copy, overwrite: true) {
    includeEmptyDirs = false
    def fromDir = "/sources"
    def sourcePaths = ["/sources/a-1/first", "/sources/a-3/b-1/c-1/second"]
    from fileTree(fromDir).dir.listFiles()
    eachFile { copySpec ->
        def shouldBeCopied = false
        sourcePaths.find {
            if (copySpec.getFile().getCanonicalPath().startsWith(it)) {
                shouldBeCopied = true
                return true // break iteration
            }
        }
        if (shouldBeCopied) {
            String[] parts = file.path.split('/')
            copySpec.path = parts.size() > 1 ? "${parts[parts.size() - 2]}/${parts[parts.size() - 1]}" : parts[0]
        } else {
            copySpec.exclude()
        }
    }
    into destDir
}

如何实现这一目标?

2 个答案:

答案 0 :(得分:3)

尝试以下Gradle任务:

task copyFiles(type: Copy, overwrite: true) {
    includeEmptyDirs = false
    from fileTree("sources").dir.listFiles()
    eachFile { file ->
        String[] parts = file.path.split('/')
        file.path = parts.size() > 1 ? "${parts[parts.size() - 2]}/${parts[parts.size() - 1]}" : parts[0]
    }
    into "destDir"
}

整个部分发生在我们指定目标eachFile {}的{​​{1}}闭包中 - 我使用了这种命令式方法,但它可以替换为保留最后文件夹和文件名的花式正则表达式并替换所有其他空字符串的部分(我试图提出这样的正则表达式,但我失败了。)

如何运作

我的输入目录如下所示:

file.path

我执行任务:

sources
├── foo
│   └── bar
│       └── lorem.txt
└── one
    └── two
        └── three
            └── path
                └── ipsum.log

#: ./gradlew copyFiles :copyFiles UP-TO-DATE BUILD SUCCESSFUL 看起来像这样:

destDir

使用Gradle destDir ├── bar │   └── lorem.txt └── path └── ipsum.log 2.14.13.5-rc-2

进行测试

答案 1 :(得分:0)

我终于解决了这个问题。请注意,顶级into指令是必需的,或者它不起作用,嵌套的into指令相对于顶级指令。

def copyTask = tasks.create(name: "copyToDestDir", type: Copy, overwrite: true) {
    includeEmptyDirs = false
    def fromDir = "/sources"
    def sourcePaths = ["/sources/a-1/first", "/sources/a-3/b-1/c-1/second"]
    def destDir = "/destination"
    sourcePaths.each { sourcePath ->
        from(sourcePath) {
            into sourcePath.substring(sourcePath.lastIndexOf('/') + 1)
        }
    }
    into destDir
    dependsOn cleanUpDestDir
}

感谢@SzymonStepniak的灵感。