0

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

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

我很难理解如何在具有匹配文件扩展名的每个文件上递归运行命令/脚本。我发现的教程和指南似乎没有处理需要使用 library 命令键入特定文件的库。

我对这个过程还是新手,所以我可能会忽略一些明显的东西。

4

1 回答 1

1

简短的回答:

你没有忽略一些明显的东西。而是您想要的功能根本不存在的情况。

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

也许您应该在此处的项目 GitHub 存储库中发布添加此功能的请求。

同时,为了满足您的要求,您可以考虑创建一个使用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
    └─── ...

递归-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用于获取.clj存储在src多层目录中的每个文件的路径。您需要\"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\""
  },
  ...
}
于 2018-03-13T12:12:18.943 回答