使用`find`查找pom.xml文件并执行maven构建,忽略嵌套的POM

时间:2018-06-13 19:27:50

标签: bash shell

我目前有几个具有不同文件夹结构的应用程序。我正在使用maven来构建这些应用。我遇到了一些问题。有时主pom.xml文件位于根目录中,有时则位于子目录中。我只想使用主/最高目录中的主pom.xml进行maven构建。我从find运行workspace命令(下面有更多详细信息)。如何在不依赖文件夹结构的情况下实现这一目标?

Shell命令:

find * -maxdepth 1 -name pom.xml -execdir mvn clean package -Dmaven.test.error.ignore=true -Dmaven.test.failure.ignore=true \;

这适用于此文件夹结构:

workspace
|-- app1
|   |-- pom.xml
|   |-- abrt.conf
|   |-- gpg_keys
|   `-- web
|       |-- pom.xml
|       `-- test.conf

返回:

app1/pom.xml

该命令会返回一些具有此文件夹结构的pom.xml个文件:

workspace
|   |-- pom.xml
|   |-- abrt.conf
|   |-- gpg_keys
|   `-- web
|       |-- pom.xml
|       `-- test.conf

返回:

web/pom.xml
pom.xml

4 个答案:

答案 0 :(得分:2)

因为 find 操作广度优先,除非明确告知不这样做,否则第一个结果将始终是最浅的。因此,您只需要在找到单个POM文件后告诉它退出。





在GNU find 中,有一个 -quit 行动就是为了这个目的:




  find。 -name pom.xml \
 -execdir mvn clean package -Dmaven.test.error.ignore = true -Dmaven.test.failure.ignore = true \; \
 -quit
  




如果您不能保证GNU 找到,但保证有bash,你可以只读取第一个结果并对其进行操作:




 如果IFS = read -r -d''pom_filename< <(find。-name pom.xml -print0);然后
 (cd  - “$ {pom_filename%/ *}”&& exec mvn clean package -Dmaven.test.error.ignore = true -Dmaven.test.failure.ignore = true)
 fi
  




注意使用 -print0 - 这样我们就可以避免恶意命名的目录(带有换行符)通过在列表中注入额外的名称来实现行为。








现在,让我们考虑一个棘手的案例:

&#xA ;

 <代码> A / pom.xml的&#XA; A /分/的pom.xml&#XA; B / pom.xml的&#XA; B /分/的pom.xml&#XA;  
&#xA;&#xA;

如果你想运行两个 A和B,而不是A / sub或B / sub,那么事情会变得更多有趣的是:

&#xA;&#xA;
  find。 \&#XA; -type d -exec test -e'{} /pom.xml'';' \&#XA; -execdir mvn clean pkg ...';' \&#XA; -prune&#xA;  
&#xA;&#xA;

请注意,我们使用 -prune 告诉 find 停止递归到存在 pom.xml 的任何目录,但只有在我们已经在那里运行构建之后。

&#xA;

答案 1 :(得分:0)

如果没有find(在评论中建议替换为*),只需执行.,即可从最高目录列到最低目录。管道到head -1以获取列表中的第一个。将所有这些放入命令替换($(...))以分配变量。改为使用您的变量运行相同的命令。由于您现在可能在文件名中包含/,因此我们不需要-name-maxdepth*

pomxmlfile="$(find . -name pom.xml | head -1)"
find "$pomxmlfile" -execdir mvn clean package -Dmaven.test.error.ignore=true -Dmaven.test.failure.ignore=true \;

答案 2 :(得分:0)

此行找到具有最短路径的pom.xml(即最接近目录树顶部的pom)并从其目录中执行mvn

find . -name pom.xml | awk '{print length($0) " " $0}' | sort -n | cut -d ' ' -f 2- | head -n 1 | xargs -I {} bash -c 'cd $(dirname {}) && mvn clean package -Dmaven.test.error.ignore=true -Dmaven.test.failure.ignore=true \;'

管道分解:

  • 查找当前目录下的所有pom.xml
  • 将行的长度添加到行的开头
  • 按行号(即长度)排序第一行
  • 删除长度
  • 仅保留第一行(即最短行)
  • mvn文件
  • 的目录运行pom.xml

答案 3 :(得分:0)

我不确定。如果主pom.xml位于目录a/b/c中且其他pom.xml位于a以外的a/b/c以下的子目录中,那么主pom.xml必须有最短的路径字符串。所以在这种情况下,我猜这个命令会调出最接近root的pom.xml,并且可以从aa/ba/b/c执行:

find -name pom.xml | awk 'NR==1 || length() < length(s) { s = $0 } END { print s }'