Grunt plugin for generating static analysis reports with plato complexity analysis
npx @tessl/cli install tessl/npm-grunt-plato@1.4.0Grunt Plato is a Grunt plugin that generates static analysis reports using the plato library. It provides comprehensive code complexity analysis and visualization for JavaScript projects by integrating with JSHint for code quality checks and complexity-report for cyclomatic complexity metrics.
npm install grunt-plato --save-devAs a Grunt plugin, grunt-plato is loaded and used within a Gruntfile:
grunt.loadNpmTasks('grunt-plato');module.exports = function(grunt) {
grunt.initConfig({
plato: {
your_target: {
files: {
'output/directory': ['src/**/*.js', 'test/**/*.js']
}
}
}
});
grunt.loadNpmTasks('grunt-plato');
grunt.registerTask('analyze', ['plato']);
};Grunt Plato is a wrapper around the plato library that integrates static analysis capabilities into the Grunt build system. The plugin:
The plugin serves as a bridge between Grunt's task-based build system and plato's code analysis engine, allowing developers to integrate complexity analysis into their automated build processes.
The plugin registers a multi-task named 'plato' that generates static analysis charts.
grunt.registerMultiTask('plato', 'Generate static analysis charts with plato', function() {
// Task implementation
});Configuration options that can be passed to the plato task.
interface PlatoOptions {
/** JSHint configuration options for code linting */
jshint?: JSHintOptions | false;
/** Path to .jshintrc file for JSHint configuration */
jshintrc?: string;
/** Path to .eslintrc file for ESLint configuration */
eslintrc?: string;
/** Complexity analysis options passed to complexity-report */
complexity?: ComplexityOptions;
/** Regular expression to exclude files from analysis */
exclude?: RegExp;
/** Path to file containing list of files to exclude */
excludeFromFile?: string;
}
interface JSHintOptions {
options?: any;
globals?: { [key: string]: boolean };
}
interface ComplexityOptions {
/** Use new maintainability index calculation */
newmi?: boolean;
/** Include logical OR operators in complexity calculation */
logicalor?: boolean;
/** Include switch case statements in complexity calculation */
switchcase?: boolean;
/** Include for-in loops in complexity calculation */
forin?: boolean;
/** Include try-catch blocks in complexity calculation */
trycatch?: boolean;
}
// Default options applied by the plugin
interface DefaultPlatoOptions {
jshint: {};
jshintrc: '';
complexity: {
newmi: true;
};
}Usage Examples:
// Basic configuration
grunt.initConfig({
plato: {
analysis: {
files: {
'reports': ['src/**/*.js']
}
}
}
});
// With custom options
grunt.initConfig({
plato: {
analysis: {
options: {
jshint: {
options: {
strict: true,
unused: true
},
globals: {
jQuery: false,
console: false
}
},
complexity: {
logicalor: false,
switchcase: false,
forin: true,
trycatch: true
},
exclude: /\.min\.js$/
},
files: {
'reports': ['src/**/*.js']
}
}
}
});
// Using external configuration files
grunt.initConfig({
plato: {
analysis: {
options: {
jshintrc: '.jshintrc',
eslintrc: '.eslintrc',
excludeFromFile: '.platoignore'
},
files: {
'reports': ['src/**/*.js']
}
}
}
});
// Disabling JSHint
grunt.initConfig({
plato: {
analysis: {
options: {
jshint: false
},
files: {
'reports': ['src/**/*.js']
}
}
}
});
// JSHint options normalization example
// Input: { jshint: { strict: true, globals: { jQuery: false } } }
// Normalized to: { jshint: { options: { strict: true }, globals: { jQuery: false } } }
grunt.initConfig({
plato: {
analysis: {
options: {
jshint: {
strict: true,
unused: true,
globals: {
jQuery: false,
console: false
}
}
},
files: {
'reports': ['src/**/*.js']
}
}
}
});The plato task follows this execution pattern:
Options Processing:
{ jshint: {}, jshintrc: '', complexity: { newmi: true } } with user-provided optionsoptions property, wraps them in { options: userOptions, globals: userGlobals || {} }Exclusion Processing:
excludeFromFile is specified, reads the file line by linePlato Inspection: Calls plato.inspect() with processed options using source files from this.filesSrc and destination directory from this.files[0].dest
The task uses standard Grunt file configuration:
interface FileConfiguration {
files: {
[destinationDirectory: string]: string[] | string;
};
}Examples:
// Single destination with multiple sources
plato: {
analysis: {
files: {
'reports/complexity': ['src/**/*.js', 'lib/**/*.js']
}
}
}
// Multiple targets
plato: {
src_analysis: {
files: {
'reports/src': ['src/**/*.js']
}
},
test_analysis: {
files: {
'reports/test': ['test/**/*.js']
}
}
}The plato task generates the following output structure in the destination directory:
index.html - Main report page with overview and navigationreport.js - JavaScript data for interactive featuresreport.json - Raw analysis data in JSON formatfiles/ - Directory containing detailed reports for individual filesassets/ - Static assets (CSS, JavaScript, images) for report stylingEach analyzed file gets a corresponding report in the files/ directory with complexity metrics, maintainability index, and code quality analysis.