[英]Using `find` to find pom.xml file and do a maven build, ignoring nested POMs
I currently have a couple of applications with different folder structures. 我目前有几个具有不同文件夹结构的应用程序。 I am using maven
for building these apps. 我正在使用maven
来构建这些应用程序。 I am running into some issues. 我遇到了一些问题。 At times the main pom.xml
file is in the root directory and other times it is in the sub-directory. 有时主pom.xml
文件位于根目录中,而其他时候则位于子目录中。 I only want to do a maven build with the main pom.xml
found in the main/highest directory. 我只想使用在main / highest目录中找到的主要pom.xml
进行Maven构建。 I am running the find
command from workspace
(below for more details). 我正在从workspace
运行find
命令(有关更多详细信息,请参见下文)。 How could I achieve this without depending on the folder structure? 在不依赖文件夹结构的情况下如何实现?
Shell Command: Shell命令:
find * -maxdepth 1 -name pom.xml -execdir mvn clean package -Dmaven.test.error.ignore=true -Dmaven.test.failure.ignore=true \;
This works with this folder structure: 这适用于以下文件夹结构:
workspace
|-- app1
| |-- pom.xml
| |-- abrt.conf
| |-- gpg_keys
| `-- web
| |-- pom.xml
| `-- test.conf
returns: 收益:
app1/pom.xml
The command does returns a couple of pom.xml
files with this folder structure: 该命令确实返回了几个具有以下文件夹结构的pom.xml
文件:
workspace
| |-- pom.xml
| |-- abrt.conf
| |-- gpg_keys
| `-- web
| |-- pom.xml
| `-- test.conf
returns: 收益:
web/pom.xml
pom.xml
Because find
operates breadth-first unless explicitly told to do otherwise, the first result will always be the shallowest. 因为除非明确要求否则find
操作是广度优先的,所以第一个结果将始终是最浅的。 Thus, you just need to tell it to quit after finding a single POM file. 因此,您只需要在找到单个POM文件后告诉它退出即可。
In GNU find
, there's a -quit
action for exactly this purpose: 在GNU find
,有一个-quit
操作正是出于这个目的:
find . -name pom.xml \
-execdir mvn clean package -Dmaven.test.error.ignore=true -Dmaven.test.failure.ignore=true \; \
-quit
If you aren't guaranteed to have GNU find
, but are guaranteed to have bash, you can read just the first result and operate on that: 如果不能保证可以使用GNU find
,但是可以保证可以使用bash,则可以只读取第一个结果并对其进行操作:
if IFS= read -r -d '' pom_filename < <(find . -name pom.xml -print0); then
(cd -- "${pom_filename%/*}" && exec mvn clean package -Dmaven.test.error.ignore=true -Dmaven.test.failure.ignore=true)
fi
Note the use of -print0
-- that way we avoid maliciously-named directories (with newlines) being able to influence behavior by injecting extra names into the list. 请注意-print0
的使用-这样我们可以避免通过将多余的名称注入列表来避免使用恶意名称的目录(使用换行符)来影响行为。
Now, let's consider a trickier case: 现在,让我们考虑一个更棘手的情况:
A/pom.xml
A/sub/pom.xml
B/pom.xml
B/sub/pom.xml
If you want to run for both A and B, but not A/sub or B/sub, then things get a bit more interesting: 如果您想为A和B 都跑,但不是A /分或B /次,然后事情就变得更有趣:
find . \
-type d -exec test -e '{}/pom.xml' ';' \
-execdir mvn clean pkg ... ';' \
-prune
Note that we're using -prune
to tell find
to stop recursing into any directory where a pom.xml
exists, but only after we already ran a build there. 请注意,我们正在使用-prune
告诉find
停止递归到pom.xml
存在的任何目录,但pom.xml
是我们已经在其中运行了构建。
Just do a find
without the *
(replace with .
as suggested in comment) to list from highest directory to the lowest. 只需find
不带*
(按注释中的.
替换)即可从最高目录到最低目录列出。 Pipe to head -1
to get the first one of the list. 移至head -1
可获得列表中的第一个。 Put all of this into a command substitution ( $(...)
) to assign a variable. 将所有这些都放入命令替换( $(...)
)中以分配变量。 Run the same command with your variable instead. 而是使用变量运行相同的命令。 Since you may have /
in the file name now, we will not need -name
, -maxdepth
or *
. 由于您现在的文件名中可能带有/
,因此我们不需要-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 \;
This line finds the pom.xml
with the shortest path (ie the pom nearest the top of the directory tree) and executes mvn
from its directory: 这一行找到路径最短的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 \;'
Pipe chain breakdown: 管链故障:
pom.xml
under current directory 在当前目录下找到所有pom.xml
mvn
from the directory of the pom.xml
file 从pom.xml
文件的目录运行mvn
I'm not sure. 我不确定。 If the main pom.xml
is in a directory a/b/c
and no other pom.xml
is in a subdirectory below a
other than a/b/c
, then the main pom.xml
must have the shortest path string. 如果主pom.xml
是目录中的a/b/c
并没有其他pom.xml
是在下边的子目录a
比其他a/b/c
,那么主要pom.xml
必须的最短路径字符串。 So in that case I guess this command brings up the pom.xml
closest to root and can be executed from either a
, a/b
, or a/b/c
: 因此,在那种情况下,我猜想此命令将调出最接近root的pom.xml
,并且可以从a
, a/b
或a/b/c
:
find -name pom.xml | awk 'NR==1 || length() < length(s) { s = $0 } END { print s }'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.