我正在尝试将一个脚本放在一起,我可以在 CI 构建中使用它,该脚本将用作我的 Typescript Mono-repo 项目的 linter。
我想要完成的是查看.js
项目/包存储库中是否有任何文件,但避免使用node_modules
它们所在的文件夹以及common
文件夹及其所有子目录和文件。
文件结构是这样的
project/
├── apps/
│ ├── app1
├── common/
│ ├── folder1
│ ├── folder1
│ ├── etc
├── lib/
│ ├── lib1
├── services/
│ ├── service1
services,lib,apps
所有 npm 项目的子目录。
目前我尝试过的一些不同尝试包括:
find . \( ! -name node_modules \) -o \( ! -path common -prune \) -name "*.js" -print
但即使我在或任何其他列入白名单的文件夹中创建虚拟.js
文件,它似乎也不会返回任何内容。/project
此尝试似乎是最接近的,因为它打印出了测试文件,但它也找到了 中的文件common
,但它应该被列入黑名单。
find . -type d \( -path common -o -name node_modules \) -prune -false -o -name '*.js'
该运行的输出:
./test.js
./common/temp/pnpmfile.js
./common/temp/pnpm-store/2/registry.npmjs.org/ipaddr.js
./common/config/rush/pnpmfile.js
./common/scripts/install-run.js
./common/scripts/install-run-rushx.js
./common/scripts/install-run-rush.js
./services/test.js
我想要此脚本的总体目标是,如果在白名单目录中没有找到文件,则退出 0;如果在黑名单目录之外找到文件,.js
则返回退出 1 。.js
我是个新手,对 shell 命令缺乏经验,所以任何帮助将不胜感激,提前谢谢您!
答案1
你的命令几乎是正确的。修复它:
find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -print
这会修剪任何名为node_modules
或 位于 的内容./common
。请注意,使用的路径名-path
是以顶级搜索路径为开头的路径,因此.
在这种情况下必须以开头。
您-false
使用的不是必需的。如果node_modules
或 也与您之后的测试./common
相匹配,则需要它。这也是您可能想要使用 的时候,但现在您不必这样做。-name
-o
-type d
测试:
$ tree
.
|-- common
| `-- file.js
|-- dir
| |-- common
| | `-- file.js
| |-- file.js
| `-- node_modules
| `-- file.js
`-- node_modules
`-- file.js
5 directories, 5 files
$ find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -print
./dir/file.js
./dir/common/file.js
找到该文件./dir/common/file.js
是因为它位于未修剪的目录中(common
仅当它位于当前目录的正下方时才被修剪)。
别处,看来你只想看看有没有任何*.js
未修剪目录中匹配的文件。您可以通过以下方式有效地做到这一点
if find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -exec echo . \; | grep -q .
then
echo there are JS files
else
echo there are no JS files
fi
在这里,每当我找到文件时,我都会输出一个点(可以是任何字符),并用于grep -q .
检测find
.当发现某些内容时,grep
将以零退出状态终止,表示“成功”,并且该if
语句将采用第一个分支。find
一旦该命令尝试向grep
不再监听的管道写入另一个点,该命令就会终止。
答案2
如果您使用 -path ,请使用完全声明的路径,例如./common
或用于-name
匹配找到的树中的任何位置。
这个命令对我来说是一个测试。
find . -type d \( -name common -o -name node_modules \) -prune -false -o -name '*.js'
答案3
在查看和测试上述一些答案后,我最终使用的命令是:
find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -print
我必须保留 arg 的原因-print
是我发现运行它时得到的输出没有将-print
某些文件夹显示为如下输出:
./common
./lib/trader-sdk/node_modules
./lib/is-ticker-symbol/node_modules
./apps/cron-app/node_modules
./services/templating-service/node_modules
./services/api-service/node_modules
./services/trading-services/node_modules
./services/sentiment-service/node_modules
但是当我添加-print
arg 时,输出什么也没有,这是在这种情况下所期望的。
奖励:这是最后一个用例,一个基本脚本,它将检查我的 TypeScript mono-repo,以确保没有人尝试将任何构建.js
文件合并到 master 中。
#!/bin/bash
jsFiles=$(find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -print)
if [ -z "$jsFiles" ]
then
echo "No JS files found, free to proceed"
exit 0
else
echo "JS files found, unable to proceed"
exit 1
fi