Skip to content

Commit

Permalink
Add format and format-all tasks to grunt
Browse files Browse the repository at this point in the history
`grunt format` now runs js-beautify and sortImports on all js files in a given repo (or the current one if none is given). In addition, you can use `grunt format --verify` to just check that the files are formatted, but not actually modify them. This could be useful for a pre-commit hook.

The `grunt format-all` variation is similar to lint-all in that it runs format on all the repos that are libraries of the supplied repo.
  • Loading branch information
NickCrews committed Nov 22, 2020
1 parent 98561b4 commit f0f6877
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 5 deletions.
17 changes: 17 additions & 0 deletions js/grunt/Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const generateTestHTML = require( './generateTestHTML' );
const generateThumbnails = require( './generateThumbnails' );
const generateTwitterCard = require( './generateTwitterCard' );
const getPhetLibs = require( './getPhetLibs' );
const format = require( './format' );
const lint = require( './lint' );
const fixEOL = require( './fixEOL' );
const migrate = require( './migrate' );
Expand Down Expand Up @@ -275,6 +276,22 @@ module.exports = function( grunt ) {
lint( getPhetLibs( repo ), cache );
} ) );

grunt.registerTask( 'format', 'format js files that are specific to this repository', wrapTask( async () => {

//Don't actually modify the files, just verify them?
const verifyOnly = !!grunt.option( 'verify' );

format( [ repo ], verifyOnly );
} ) );

grunt.registerTask( 'format-all', 'format all js files that are required to build this repository (for all supported brands)', wrapTask( async () => {

//Don't actually modify the files, just verify them?
const verifyOnly = !!grunt.option( 'verify' );

format( getPhetLibs( repo ), verifyOnly );
} ) );

grunt.registerTask( 'generate-development-html',
'Generates top-level SIM_en.html file based on the preloads in package.json.',
wrapTask( async () => {
Expand Down
90 changes: 90 additions & 0 deletions js/grunt/format.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright 2020, Nick Crews

/**
* Runs the formatting rules on the specified files.
*
* @author @NickCrews
*/

'use strict';

// modules
const beautify = require( 'js-beautify' );
const fs = require( 'fs' );
const grunt = require( 'grunt' );
const sortImports = require( './sortImports' );

const OPTIONS = {
"html": {
"allowed_file_extensions": [ "htm", "html", "xhtml", "shtml", "xml", "svg" ],
"brace_style": "collapse",
"end_with_newline": false,
"indent_char": " ",
"indent_handlebars": false,
"indent_inner_html": false,
"indent_size": 2,
"indent_scripts": "keep",
"max_preserve_newlines": 1,
"preserve_newlines": true,
"unformatted": [ "a", "span", "img", "code", "pre", "sub", "sup", "em", "strong", "b", "i", "u", "strike", "big", "small", "pre", "h1", "h2", "h3", "h4", "h5", "h6" ],
"wrap_line_length": 0
},
"css": {
"allowed_file_extensions": [ "css", "scss", "sass", "less" ],
"end_with_newline": false,
"newline_between_rules": true,
"indent_char": " ",
"indent_size": 2,
"selector_separator": " ",
"selector_separator_newline": true
},
"js": {
"allowed_file_extensions": [ "js", "json", "jshintrc", "jsbeautifyrc", "sublime-settings" ],
"brace_style": "collapse-preserve-inline",
"break_chained_methods": false,
"e4x": false,
"end_with_newline": true,
"indent_char": " ",
"indent_level": 0,
"indent_size": 2,
"indent_with_tabs": false,
"jslint_happy": false,
"keep_array_indentation": false,
"keep_function_indentation": false,
"max_preserve_newlines": 0,
"preserve_newlines": true,
"space_after_anon_function": false,
"space_before_conditional": true,
"space_in_empty_paren": false,
"space_in_paren": true,
"unescape_strings": false,
"wrap_line_length": 0
}
}

function formatFile( absPath, verifyOnly = false ) {
let before = fs.readFileSync( absPath, 'utf-8' );
const formatted = beautify.js( before, OPTIONS );
if ( !verifyOnly ){
fs.writeFileSync( absPath, formatted, 'utf-8' );
}
const alreadySorted = sortImports( absPath, verifyOnly );
return alreadySorted && ( before == formatted );
}

/**
* Formats the specified repositories.
* @public
*
* @param {Array.<string>} repos
* @param {boolean} verifyOnly - Don't rewrite files
*/
module.exports = function( repos, verifyOnly = false) {

repos.forEach( repo => {
grunt.file.recurse(
`../${repo}/js`,
absPath => formatFile( absPath, verifyOnly )
) } );

}
15 changes: 10 additions & 5 deletions js/grunt/sortImports.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ const isImport = line => line.startsWith( 'import ' );

/**
* @param {string} file
* @param {boolean} verifyOnly - Don't rewrite file, just verify already sorted
* @returns {boolean} - Was the file properly sorted to begin with?
*/
module.exports = function( file ) {
let contents = fs.readFileSync( file, 'utf-8' );
let lines = contents.split( /\r?\n/ );
module.exports = function( file, verifyOnly = false ) {
const before = fs.readFileSync( file, 'utf-8' );
let lines = before.split( /\r?\n/ );

// remove the grouping comments
lines = lines.filter( ( line, i ) => {
Expand Down Expand Up @@ -67,6 +69,9 @@ module.exports = function( file ) {
firstImportIndex--;
}

contents = lines.join( '\n' );
fs.writeFileSync( file, contents, 'utf-8' );
const after = lines.join( '\n' );
if (!verifyOnly){
fs.writeFileSync( file, after, 'utf-8' );
}
return (after == before);
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"eslint": "^6.8.0",
"eslint-plugin-react": "^7.18.0",
"grunt": "~1.1.0",
"grunt-jsbeautifier": "^0.2.13",
"jimp": "^0.2.0",
"jpeg-js": "~0.1.1",
"jscpd": "^0.6.18",
Expand Down

0 comments on commit f0f6877

Please sign in to comment.