在Grunt构建中验证CSV文件

时间:2017-05-08 17:10:19

标签: csv gruntjs lint

如何在Grunt构建中验证CSV文件(编码,标题,分隔符,列数)?我看了CSVLint,但既没有让它工作,也不知道如何将它包含在Grunt中。

编辑:PapaParse看起来很有希望,但也没有Grunt集成。

1 个答案:

答案 0 :(得分:2)

虽然PapaParse的grunt集成不存在,但可以通过在Gruntfile.js内配置自定义Function Task来使用其API。

通过npm安装papaparse

首先,cd到您的项目目录,通过npm安装papaparse并将其添加到项目devDependencies的{​​{1}}部分。为此,请通过CLI工具运行以下命令:

package.json

<强> Gruntfile.js

以下要点显示了如何在$ npm i -D papaparse中配置名为validateCSV的自定义功能任务。

Gruntfile.js

备注

以下代码行(取自上面的module.exports = function(grunt) { // Requirements var fs = require('fs'); var Papa = require('papaparse'); // Other project configuration tasks. grunt.initConfig({ // ... }); /** * Register a custom Function task to validate .csv files using Papa Parse. */ grunt.registerTask('validateCSV', 'Lint .csv files via Papa Parse', function() { var glob = './csv/*.csv'; // <-- Note: Edit glob pattern as required. var success = true; // Create an Array of all .csv files using the glob pattern provided. var csvFiles = grunt.file.expand(glob).map(function(file) { return file; }); // Report if no .csv files were found and return early. if (csvFiles.length === 0) { grunt.log.write('No .csv files were found'); return; } // Loop over each .csv file in the csvFiles Array. csvFiles.forEach(function(csvFile) { // Read the contents of the .csv file. var csvString = fs.readFileSync(csvFile, { encoding: 'utf8' }); // Parse the .csv contents via Papa Parse. var papa = Papa.parse(csvString, { delimiter: ',', newline: '', quoteChar: '"', header: true, skipEmptyLines: true // For additional config options visit: // http://papaparse.com/docs#config }); // Basic error and success logging. if (papa.errors.length > 0) { grunt.log.error('Error(s) in file: '['red'] + csvFile['red']); // Report each error for a single .csv file. // For additional Papa Parse errors visit: // http://papaparse.com/docs#errors papa.errors.forEach(function(error) { grunt.log.write('\n type: ' + error.type); grunt.log.write('\n code: ' + error.code); grunt.log.write('\n message: ' + error.message); grunt.log.write('\n row: ' + error.row + '\n\n'); }); // Indicate that a .csv file failed validation. success = false; } else { grunt.log.ok('No errors found in file: ' + csvFile); } }); // If errors are found in any of the .csv files this will // prevent subsequent defined tasks from being processed. if (!success) { grunt.fail.warn('Errors(s) were found when validating .csv files'); } }); // Register the custom Function task. grunt.registerTask('default', [ 'validateCSV' // ... ]); }; ):

Gruntfile.js

...需要根据您的项目要求进行更改/编辑。目前,globbing pattern假设所有var glob = './csv/*.csv'; 个文件都位于名为.csv的文件夹中。

可能还需要根据您的要求设置config选项。

自定义功能任务还包括一些将记录到CLI的基本错误和成功报告。

运行任务

要运行grunt任务,只需通过CLI工具执行以下操作:

csv

编辑:更新后的答案 (根据以下评论...)

  

是否也可以&#34;配置&#34;来自内部的任务   $ grunt validateCSV?例如,linting不同的CSV目录?

要实现此目的,您可以创建一个单独的Javascript模块,导出Registered MutliTask

让我们称之为grunt.initConfig()并将其保存到名为papaparse.js的目录中,该目录与custom-grunt-tasks

位于同一顶级目录中

注意:此Gruntfile.js文件和目录名称可以是您喜欢的任何名称,但是您需要更新.js中的引用。

<强> papaparse.js

Gruntfile.js

<强> Gruntfile.js

您的module.exports = function(grunt) { 'use strict'; // Requirements var fs = require('fs'); var Papa = require('papaparse'); grunt.registerMultiTask('papaparse', 'Misc Tasks', function() { // Default options. These are used when no options are // provided via the initConfig({...}) papaparse task. var options = this.options({ quotes: false, delimiter: ',', newline: '', quoteChar: '"', header: true, skipEmptyLines: true }); // Loop over each path provided via the src array. this.data.src.forEach(function(dir) { // Append a forward slash If a directory path // provided does not end in with one. if (dir.slice(-1) !== '/') { dir += '/'; } // Generate the globbin pattern. var glob = [dir, '*.csv'].join(''); // Create an Array of all .csv files using the glob pattern. var csvFiles = grunt.file.expand(glob).map(function(file) { return file; }); // Report if no .csv files were found and return early. if (csvFiles.length === 0) { grunt.log.write( '>> No .csv files found using the globbing '['yellow'] + 'pattern: '['yellow'] + glob['yellow'] ); return; } // Loop over each .csv file in the csvFiles Array. csvFiles.forEach(function(csvFile) { var success = true; // Read the contents of the .csv file. var csvString = fs.readFileSync(csvFile, { encoding: 'utf8' }); // Parse the .csv contents via Papa Parse. var papa = Papa.parse(csvString, options); // Basic error and success logging. if (papa.errors.length > 0) { grunt.log.error('Error(s) in file: '['red'] + csvFile['red']); // Report each error for a single .csv file. // For additional Papa Parse errors visit: // http://papaparse.com/docs#errors papa.errors.forEach(function(error) { grunt.log.write('\n type: ' + error.type); grunt.log.write('\n code: ' + error.code); grunt.log.write('\n message: ' + error.message); grunt.log.write('\n row: ' + error.row + '\n\n'); }); // Indicate that a .csv file failed validation. success = false; } else { grunt.log.ok('No errors found in file: ' + csvFile); } // If errors are found in any of the .csv files this will prevent // subsequent files and defined tasks from being processed. if (!success) { grunt.fail.warn('Errors(s) found when validating .csv files'); } }); }); }); }; 可以配置如下:

Gruntfile.js

运行任务

module.exports = function(grunt) { grunt.initConfig({ // ... papaparse: { setOne: { src: ['./csv/', './csv2'] }, setTwo: { src: ['./csv3/'], options: { skipEmptyLines: false } } } }); // Load the custom multiTask named `papaparse` - which is defined in // `papaparse.js` stored in the directory named `custom-grunt-tasks`. grunt.loadTasks('./custom-grunt-tasks'); // Register and add papaparse to the default Task. grunt.registerTask('default', [ 'papaparse' // <-- This runs Targets named setOne and setTwo // ... ]); // `papaparse.js` allows for multiple targets to be defined, so // you can use the colon notation to just run one Target. // The following only runs the setTwo Target. grunt.registerTask('processOneTarget', [ 'papaparse:setTwo' // ... ]); }; 任务已添加到papaparse任务的taskList数组中,因此可以通过CLI工具输入以下内容来执行该任务:

$ grunt

备注

  1. 通过CLI输入default来运行示例要点将处理名为$ grunt.csv和{{1}的目录中的所有csv个文件}。

  2. 通过CLI运行csv2将仅处理名为csv3的目录中的$ grunt processOneTarget个文件。

  3. 由于.csv使用csv3,您会注意到papaparse.js中定义的MultiTask任务中包含两个目标。即papaparseGruntfile.js

  4. setOne目标setTwo数组定义了应该处理的两个目录的路径。即目录setOnesrc。我们将使用./csv/中定义的默认./csv2选项处理这些路径中找到的所有.csv个文件,因为目标未定义任何自定义papaparse

  5. papaparse.js目标options数组定义了一个目录的路径。 (即setTwo)。使用src中定义的默认./csv3/选项处理此路径中找到的所有.csv文件,但papaparse选项除外,因为它设置为{ {1}}。

  6. 您可能会发现,在papaparse.js数组中使用多个路径定义一个目标,而没有任何自定义选项,可以满足您的要求。例如:

  7. skipEmptyLines

    希望这有帮助!