运行 zprint-cli 通过 NPM 脚本递归地处理嵌套目录中的多个文件

Run zprint-cli recursively on multiple files in nested directories via NPM scripts

目标: 使用 npm 脚本 运行 zprint-clj 对嵌套文件夹中的每个文件使用适当的文件扩展名。

zprint-clj 每次 运行 时都需要输入文件名和输出文件名。例如:zprint-clj -i <filein.ext> -o <fileout.ext>

我很难理解如何对具有匹配文件扩展名的每个文件递归 运行 command/script。我发现的教程和指南似乎不涉及需要使用 library 命令输入特定文件的库。

我对这个过程还很陌生,所以我可能忽略了一些明显的东西。

简答:

您没有忽略一些显而易见的事情。而是您想要的功能根本不存在的情况。

遗憾的是 zprint-clj 不提供递归处理嵌套文件夹包中 .clj 文件的选项。每次使用它只接受一个输入文件。

也许您应该 post 请求将此功能添加到项目 GitHub 存储库 here.

同时,为了满足您的要求,您可以考虑创建一个利用 zprint-cli 的自定义节点脚本。然后可以通过您的 npm script.

调用此脚本

带解决方案的长答案:

下面演示了满足您要求的解决方案。

1。附加包

首先,您需要 cd 到您的项目目录并通过 npm 在本地安装一些额外的包(注意:我们还将在 devDependencies 部分 package.json):

  1. 通过 运行 安装 cli-glob:

    npm i -D cli-glob
    
  2. 接下来,通过运行安装shelljs

    npm i -D shelljs
    
  3. 而且,如果您还没有在本地安装它,请通过 运行:

    安装 zprint-clj
    npm i -D zprint-clj
    

2。自定义节点脚本

接下来创建自定义节点脚本如下。让我们将文件命名为 recursive-zprint.js 并将其保存到项目文件夹根目录中名为 .scripts 的隐藏目录中。

    project
    ├─── .scripts
    │    └─── recursive-zprint.js
    ├─── node_modules
    └─── ...

recursive-zprint.js

const path = require('path');
const readline = require('readline');
const shelljs = require('shelljs');

const TICK = process.platform === 'win32' ? '√' : '✔';

var outputDir = '';
var verbose = false;

// Setup interface to read glob paths piped to stdin.
const rl = readline.createInterface({
  input: process.stdin,
  output: null,
  terminal: false
});

// Read each line from process.stdin
// (i.e. the filepath for each .clj found via the glob pattern)
rl.on('line', function (filePath) {
  formatData(filePath);
});

// Handle the optional `-o` argument for the output dir.
if (process.argv.indexOf('-o') !== -1) {
  outputDir = process.argv[process.argv.indexOf('-o') + 1];
}

// Handle the optional `-v` argument for verbose logging.
if (process.argv.indexOf('-v') !== -1) {
  verbose = true;
}

/**
 * Gets the path to node_modules/.bin executable.
 * @param {string} command - The executable name
 * @returns {string} The path to the executable.
 */
function getBin(command) {
  return path.join('node_modules', '.bin', command);
}

/**
 * Obtains the destination path for where the formated file should be saved.
 * Creates directories, and executes the zprint command . If the `-o` argument
 * is not specified via the npm-script the original file is overwritten.
 *
 * @param {String} srcPath - The path to the source file.
 */
function formatData(srcPath) {
  const destPath = getDestPath(srcPath);
  makeDirectory(path.dirname(destPath));
  shelljs.exec(getBin('zprint-clj') + ' -i ' + srcPath + ' -o ' + destPath);

  // Log formatted filepath to console.
  if (verbose) {
    shelljs.echo('\x1b[32m%s\x1b[0m', TICK, destPath);
  }
}

/**
 * Obtains destination path for where to save the formatted file. Joins the
 * source path, excluding the root directory, with the given output path.
 *
 * @param {String} srcPath - The path to the source file.
 * @return {String} - The destination file path.
 */
function getDestPath(srcPath) {
  if (outputDir) {
    const parts = srcPath.split(path.sep);
    parts.shift();
    return path.join(outputDir,  parts.join(path.sep));
  }
  return srcPath;
}

/**
 * Create a new directory and intermediate directories if necessary.
 * @param {String} dirPath - The path for the directory.
 */
function makeDirectory(dirPath) {
  if (!shelljs.test('-d', dirPath)) {
    shelljs.mkdir('-p', dirPath);
  }
}

3。配置 npm-scripts

按如下方式配置您的 npm-script。让脚本命名为 zprint:

覆盖原文件...`

{
  ...
  "scripts": {
    "zprint": "glob \"src/**/*.clj\" | node .scripts/recursive-zprint"
  },
  ...
}

注意以下几点:

  1. 上面的脚本利用 cli-glob 获取存储在 src 目录中的每个 .clj 文件的路径。您需要将 \"src/**/*.clj\" 部分替换为适合您项目的 glob 模式。

  2. glob 模式找到的文件列表然后通过管道传输到自定义节点脚本(即 recursive-zprint.js)。

  3. 使用此配置的所有原始来源 .clj 将被格式化数据覆盖。

避免覆盖原文件...

为避免覆盖原始 .clj 文件 recursive-zprint.js 允许通过指定输出目录的脚本传递可选的 -o 参数。

{
  ...
  "scripts": {
    "zprint": "glob \"src/**/*.clj\" | node .scripts/recursive-zprint -o \"path/to/output\""
  },
  ...
}

注意以下几点:

  1. 此示例配置包括附加的 -o 参数,后跟格式化文件的保存路径。

  2. 如果您要使用 -o 参数,您将再次需要用适合您的项目的输出路径替换 \"path/to/output\" 部分。

4。源目录与结果目录

鉴于显示的最后一个 npm 脚本配置(利用 -o 参数的配置)。假设我们有一个 src 目录,其中包含如下文件:

    project
    ├─── src
    │   ├─── a.clj
    │   ├─── x
    │   │   ├─── b.clj
    │   │   └─── y
    │   │       └─── c.clj
    │   └─── d.clj
    └─── ...

在运行 npm run zprint之后,通过您的CLI,结果输出将如下(注意原始源子目录保留在结果输出中):

    project
    ├─── path
    │   └─── to
    │       └─── output
    │           ├─── a.clj
    │           ├─── x
    │           │   ├─── b.clj
    │           │   └─── y
    │           │       └─── c.clj
    │           └─── d.clj
    ├─── src
    │   └─── ... (same as before)
    └─── ...

5。详细日志记录

如果你想在每个文件成功格式化后将路径记录到控制台,你也可以添加 -v 可选参数。例如:

{
  ...
  "scripts": {
    "zprint": "glob \"src/**/*.clj\" | node .scripts/recursive-zprint -v -o \"path/to/output\""
  },
  ...
}