2017-05-08 4 views
1

Wie kann ich CSV-Dateien (Codierung, Überschrift, Trennzeichen, Spaltenanzahl) in meinem Grunt-Build validieren? Ich habe einen Blick auf CSVLint geworfen, aber weder es zu arbeiten noch zu wissen, wie man es in Grunt einbezieht.validiere CSV-Dateien in Grunt Build

Edit: PapaParse sieht vielversprechend aus, hat aber auch keine Grunt-Integration.

Antwort

2

Obwohl grunt Integration für PapaParse nicht existiert seine API kann durch die Konfiguration eines benutzerdefinierten Function Task in Ihrem Gruntfile.js verwendet werden.


installieren papaparse über npm

Erstens cd zu Ihrem Projektverzeichnis, papaparse über npm installieren und an den devDependencies Abschnitt Ihrer Projekte package.json hinzuzufügen. Um dies zu tun Sie den folgenden Befehl über die CLI-Tool ausführen:

$ npm i -D papaparse


Gruntfile.js

Die folgende Kern zeigt, wie eine benutzerdefinierte Funktion konfigurieren Aufgabe namens validateCSV in Ihrem 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' 
     // ... 
    ]); 

}; 

Hinweise

Die folgende Codezeile (aus dem oben Gruntfile.js genommen), die lautet:

var glob = './csv/*.csv'; 

... müssen Ihr Projekt geändert/bearbeitet werden gemäß Anforderungen. Derzeit geht die globbing pattern davon aus, dass alle .csv Dateien in einem Ordner mit dem Namen csv gespeichert sind.

Sie können auch müssen die config Optionen nach Ihren Anforderungen.

Die benutzerdefinierte Funktionsaufgabe enthält auch einige grundlegende Fehler- und Erfolgsberichte, die im CLI protokolliert werden.


den Task-Lauf

die Grunzen Aufgabe einfach führen Sie den folgenden über CLI-Tool auszuführen:

$ grunt validateCSV


EDIT: Aktualisiert Antwort(basierend auf dem folgenden Kommentar ...)

Wäre es auch innerhalb der grunt.initConfig() „zu konfigurieren“, um die Aufgabe möglich sein? Zum Beispiel linting verschiedene CSV-Verzeichnisse?

Um dies zu erreichen, können Sie ein separates Javascript-Modul erstellen, das eine Registered MutliTask exportiert.

Ermöglicht es papaparse.js nennen und es in ein Verzeichnis speichern custom-grunt-tasks benannt, die als Gruntfile.js in der gleichen Top-Level-Verzeichnis befindet

Hinweis: Diese .js Datei- und Verzeichnisnamen ein beliebiger Name sein können, die Sie bevorzugen, können Sie jedoch müssen die Referenzen innerhalb Gruntfile.js aktualisiert werden.

papaparse.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

Ihre Gruntfile.js dann konfiguriert etwas wie das sein kann:

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' 
     // ... 
    ]); 

}; 

Ausführen der Aufgabe

Die papaparse Aufgabe hat zur taskList Array der default Aufgabe hinzugefügt wurde, so dass es durch Eingabe der folgenden über CLI-Werkzeug ausgeführt werden können:

$ grunzen

Hinweise

  1. Wenn Sie das Beispiel gist ausführen, indem Sie $ grunt über Ihre CLI eingeben, werden alle .csv Dateien in der Verzeichnisse mit den Namen csv, csv2 und csv3.

  2. Das Ausführen von $ grunt processOneTarget über Ihre CLI verarbeitet nur .csv Dateien im Verzeichnis csv3.

  3. Als papaparse.js nutzt ein MultiTask Sie werden feststellen, dass sie zwei Ziele in Gruntfile.js definiert in der papaparse Aufgabe bemerken. Nämlich setOne und setTwo.

  4. Das setOne Ziel src Array definiert Pfade zu zwei Verzeichnissen, die verarbeitet werden sollen. I.e. Verzeichnisse ./csv/ und ./csv2. Alle in diesen Pfaden gefundenen .csv Dateien werden mit den Standardoptionen papaparse verarbeitet, die in papaparse.js definiert sind, da das Ziel keine benutzerdefinierten options definiert.

  5. Das setTwo Ziel src Array definiert einen Pfad zu einem Verzeichnis. (I.e. ./csv3/). Alle in diesem Pfad gefundenen .csv Dateien werden mit den Standardoptionen papaparse verarbeitet, die in papaparse.js definiert sind, mit Ausnahme der Option skipEmptyLines, die auf false eingestellt ist.

  6. Sie können feststellen, dass die einfache Definition eines Ziels in Gruntfile.js mit mehreren Pfaden im src Array ohne benutzerdefinierte Optionen Ihren Anforderungen entspricht. Zum Beispiel:

// ... 
    grunt.initConfig({ 
     // ... 
     papaparse: { 
      myTask: { 
       src: ['./csv/', './csv2', './csv3'] 
      } 
     } 
     // ... 
    }); 
// ... 

Hoffnung hilft das!

+0

Großartig, danke. Wäre es auch möglich, die Aufgabe innerhalb der grunt.initConfig() zu "konfigurieren"? Zum Beispiel linting verschiedene CSV-Verzeichnisse? – Christopher

+0

** Aktualisierte Antwort: ** Sieht aus, als gäbe es eine Möglichkeit, es über 'grunt.initConfig()' zu konfigurieren - Siehe den überarbeiteten _ "EDIT: Aktualisierte Antwort" _ Abschnitt meiner ursprünglichen Antwort. – RobC