2

我正在使用以下 groovy 脚本对某些文件集(比如 Java 文件)进行更改,在这里我想在文件中添加包(如果还没有的话)并且下面的代码可以完成这项工作(在这里可以随意提出优化建议)但是它更新该文件中的换行符,这是我宁愿避免的,有什么建议吗?

void addIfRequired(def directory, def filePath) {
    def inputFile = new File(filePath)
    boolean containsPackage = false;
    List<String> lines = inputFile.readLines();
    for (def eachLine : lines) {
        eachLine = eachLine.trim();
        if (eachLine.startsWith("package ")) {
            containsPackage = true
            break
        } else if (eachLine.startsWith("import ")) {
            // Stop looking if we don't get package till import statement.
            break;
        }
    }
    if (!containsPackage) {
        String lineSeparator = System.getProperty("line.separator");
        // The following API generates the package name
        def packageN = getPackage(inputFile, directory)
        boolean packageAdded = false;
        StringBuilder outputTxt = new StringBuilder();
        for (def line : lines) {
            if (!packageAdded && line.startsWith("import ")) {
                outputTxt.append("package " + packageN + ";" + lineSeparator)
                packageAdded = true;
            }
            outputTxt.append(line);
            outputTxt.append(lineSeparator);
        }
        inputFile.write(outputTxt.toString());
    }
}
4

1 回答 1

1

我相信您的解决方案可以处理这种情况,但请记住,这对于输入文件可能会变得棘手,例如:

// Dangerous comment
// 
// import com.oldcompany.Bogus;

import com.foo.Example;

public MyClass {
}

但是,如果没有导入,您的解决方案(和我的)都将失败:

// random comment
// 

public MyClass {
}

假设必须有一个导入,这是使用正则表达式的一种方法:

def addIfRequired = { def directory, def filePath ->
    def inputFile = new File(filePath)
    boolean containsPackage = false;
    List<String> lines = inputFile.readLines();
    for (def eachLine : lines) {
        eachLine = eachLine.trim();
        if (eachLine.startsWith("package ")) {
            containsPackage = true
            break
        } else if (eachLine.startsWith("import ")) {
            // Stop looking if we don't get package till import statement.
            break;
        }
    }
    if (!containsPackage) {
        def lineSeparator = System.getProperty("line.separator")
        // The following API generates the package name
        // def packageN = getPackage(inputFile, directory)
        def packageN = lineSeparator + "package com.abc.example;" + lineSeparator
        // TODO: potentially re-write the above code to use getText() so that 
        // we aren't reading the file twice. This could be tricky if the file is 
        // from an OS different from the OS used for this script ?

        String text = inputFile.getText()
        String replacement = packageN + "${lineSeparator}import"
        def regex = lineSeparator + /\s*import/
        String newText = text.replaceFirst(regex, replacement)

        inputFile.withWriter { def writer ->
            writer.write(newText)
        }        
    }
}

笔记:

  • 谓词代码(确定是否package存在)不变。一个缺点是它读取文件两次。重写谓词代码留给读者作为练习。
  • 此代码从 import 语句中修剪前导空格。这有点混乱,但我认为可以纠正,如果这是优先事项。
  • 为了纠正“无法导入”的问题,我们可能只是在第一行写了包。
于 2013-08-15T06:19:29.027 回答