{"id":21916381,"url":"https://github.com/dsheiko/jscodesniffer","last_synced_at":"2025-03-22T09:30:50.240Z","repository":{"id":5947269,"uuid":"7168045","full_name":"dsheiko/jscodesniffer","owner":"dsheiko","description":"⛔️ [DEPRECATED] Tool to ensure that your JavaScript code does not violate the specified coding standard (Idiomatic Style Manifesto or JQuery Core Style Guidelines)","archived":false,"fork":false,"pushed_at":"2021-05-07T09:35:26.000Z","size":1224,"stargazers_count":42,"open_issues_count":5,"forks_count":7,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-02-27T12:06:20.599Z","etag":null,"topics":["code-sniffer","deprecated","idiomatic-js","jquery-coding-style","linter","naming-conventions","obsolete","standard","static-analyzer"],"latest_commit_sha":null,"homepage":"http://dsheiko.github.io/jscodesniffer/","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dsheiko.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-12-14T16:10:21.000Z","updated_at":"2023-02-27T22:36:12.000Z","dependencies_parsed_at":"2022-08-31T03:00:48.016Z","dependency_job_id":null,"html_url":"https://github.com/dsheiko/jscodesniffer","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsheiko%2Fjscodesniffer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsheiko%2Fjscodesniffer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsheiko%2Fjscodesniffer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsheiko%2Fjscodesniffer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dsheiko","download_url":"https://codeload.github.com/dsheiko/jscodesniffer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244937746,"owners_count":20535123,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-sniffer","deprecated","idiomatic-js","jquery-coding-style","linter","naming-conventions","obsolete","standard","static-analyzer"],"created_at":"2024-11-28T19:17:43.829Z","updated_at":"2025-03-22T09:30:50.132Z","avatar_url":"https://github.com/dsheiko.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"JSCodeSniffer v.2.x\n==============\n\n[![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/)\n\n\u003e WARNING - THIS PROJECT IS NO LONGER MAINTAINED!!!\n\n[![NPM](https://nodei.co/npm/jscodesniffer.png)](https://nodei.co/npm/jscodesniffer/)\n\n[![Build Status](https://travis-ci.org/dsheiko/jscodesniffer.png)](https://travis-ci.org/dsheiko/jscodesniffer)\n[![Bower version](https://badge.fury.io/bo/jscodesniffer.svg)](http://badge.fury.io/bo/jscodesniffer)\n[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dsheiko/jscodesniffer?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n\nJSCodeSniffer is a node.js application that checks JavaScript code style consistency according to a provided coding style, just like phpcs.\nOne can define a custom coding style by using described below JSON notation or use one of predefined standards.\n\n\n## Features\n* Tool is available as UMD (can be used [with nodejs](#a-use) or as a [RequireJS module](#a-amd))\n* Predefined popular coding styles ([jQuery Coding Style Guide](http://contribute.jquery.org/style-guide/js/), [Idiomatic Style Manifesto](https://github.com/rwaldron/idiomatic.js/))\n* Reports in the style of [phpcs](https://github.com/squizlabs/PHP_CodeSniffer)\n* Solution ready for [Continuous Integration](#a-ci)\n    - Provided [Git pre-commit hook script](#a-git)\n    - Provided [SVN pre-commit hook script](#a-svn)\n    - Provided [Grunt task](#a-grunt)\n    - Provided [Jenkins CheckStyle report](#a-ant)\n* Custom standard [can be easily configured](#a-standard) by using JSON notation\n* Scripts can be associated to a coding style in block comments [using `jscs` tag](#a-env)\n* Relaxing options can be provided with [real-time configuration](#a-realtime) (`.jscsrc`) per project\n* Ignore list can be provided with [`.jscsignore`](#a-jscsignore)  per project\n* Thoroughly covered with automated tests: 200+ unit-tests, 70+ integration tests\n\n## Install\nYou have at least three installation options:\n### Download or clone the Git repository\n```\ngit clone https://github.com/dsheiko/jscodesniffer.git\n```\n### Install by using Node.js Package Manager\n```\nsudo npm  install jscodesniffer -g\n```\n### Install by using Bower.io Package Manager\n```\nbower install --save jscodesniffer\n```\n\n## \u003ca name=\"a-use\"\u003e\u003c/a\u003e Using JSCodeSniffer in the command line\n\nSimply get detailed report on a target (file or directory) coding style according to jQuery Coding Style Guide\n```bash\n./jscs source-code.js --standard=Jquery  --report-full\n```\nor\n```bash\nnode jscs.js source-code.js  --standard=Jquery  --report-full\n```\nor\n```bash\n./jscs js/dir1 file1.js js/dir2 file2.js --standard=Jquery  --report-full\n```\n\n![JS CodeSniffer Full Report Example](https://raw.github.com/dsheiko/jscodesniffer/master/doc/sample1.jpg \"JS CodeSniffer Full Report Example\")\n\nGet detailed report on the coding style for all *.js/*.json files of the 'lib' folder according to jQuery Coding Style Guide\n```bash\n./jscs lib --standard=Jquery --report-full\n```\n\nGet summary report\n```bash\n./jscs lib --report-summary\n```\n![JS CodeSniffer Summary Report Example](https://raw.github.com/dsheiko/jscodesniffer/master/doc/sample2.jpg \"JS CodeSniffer Summary Report Example\")\n\nGet XML report (which allows you to parse the output easily and use the results in your own scripts)\n```bash\n./jscs lib --report=xml\n```\n\nGet Checkstyle report (that is supported by wide range of 3rd party software. E.g. Jenkins via a plugin)\n```bash\n./jscs lib --report=checkstyle\n```\n\nReport to a file (by default report goes to stdout)\n```bash\n./jscs lib --report-file=filePath\n```\n\nDisable colors in the report\n```bash\n./jscs lib --highlight=0\n```\n\nDefine width of report screen\n```bash\n./jscs lib --reportWidth=84\n```\n\n\n## \u003ca name=\"a-amd\"\u003e\u003c/a\u003e Using JSCodeSniffer as RequireJS (AMD) module\n\n1. Install the package or download and unpack it into you project folder\n\n```bash\n npm i jscodesniffer\n```\n\n2. Use RequireJS to load required modules\n\n```javascript\nrequire( [ \"\u003cesprima-js-path\u003e/esprima\", \"\u003cpkg-path\u003e/lib/Sniffer\", \"\u003cpkg-path\u003e/lib/Dictionary/en\", \"\u003cpkg-path\u003e/lib/Dictionary\" ], function( esprima, Sniffer, en, Dictionary ) {\n  var sniffer = new Sniffer( esprima ),\n      dictionary = new Dictionary( en ),\n      logger, messages;\n\n    // Get sniffer report\n    logger = sniffer.getTestResults( node.srcCode.value, { standard: \"Jquery\" } ),\n    // Translate messages\n    messages = dictionary.translateBulk( logger.getMessages(), true );\n    // Output report\n    console.log( messages );\n});\n```\n\n\n## \u003ca name=\"a-env\"\u003e\u003c/a\u003e Environments\n\nStandard to sniff against can be enforced on the file by following instructions directly in the code\n```javascript\n/* jscs standard:Jquery */\n```\nOld form introduced in version 1.x.x is also supported\n```javascript\n/* @jscs standard:Jquery */\n```\n\n## \u003ca name=\"a-realtime\"\u003e\u003c/a\u003e Real-Time Configuration\n\nAdjusting options can be provided as manual standard in `.jscsrc` file placed in the root of your project.\nJSCodesniffer will search upward recursively until it finds any. It will extend the specified standard rule-sets\nwith the defenitions provided in this real-time configuration file. `.jscsrc` syntax is pretty much the same as standard\ndefenition file except it doesn't need to be UMD (just JSON). I you need disable particular rule-sets you can simply\nempty rule-set configurations:\n\n```bash\n{\n  \"Indentation\": false,\n  \"QuoteConventions\": false\n}\n```\n\n## \u003ca name=\"a-jscsignore\"\u003e\u003c/a\u003e .jscsignore\n\nSpecifies files to ignore in the same format as [`.gitignore`](http://git-scm.com/docs/gitignore)\n\nWith `.jscsignore` in project root directory:\n```bash\nstandard/**/*.js\n```\n\nThe code sniffer produces following output:\n```bash\n node jscs.js ./standard --standard=Jquery\n * `standard/Idiomatic.js` ignored in concordance with .jscsignore\n * `standard/Jquery.js` ignored in concordance with .jscsignore\n JsCodeSniffer 2.1.15 (https://github.com/dsheiko/jscodesniffer)\n```\n\n## \u003ca name=\"a-standard\"\u003e\u003c/a\u003e Declaring coding style\nStandard declaration are located in `standard` directory. You can store there in a file named after your custom standard name\nthe rule-sets that you want your code be validated against. To make the defenition available for AMD/RequireJs, the JSON notation is supposed\nto be wrapped as a UMD module.\n\nNOTE: Conventions 'Any ; used as a statement terminator must be at the end of the line' and 'Multi-line Statements is checked'\nare tested by JSHint and therefore not provided with sniffs (See [http://contribute.jquery.org/style-guide/js/#linting] for details).\n\n```javascript\n{\n  /*\n    defines what characters allowed for line indentation\n  */\n    \"Indentation\": {\n      \"allowOnlyTabs\": true,\n      \"allowOnlySpaces\": true,\n      \"disallowMixed\": true,\n      \"ignoreBlockComments\": true\n    },\n  /*\n    defines if trailing spaces allowed for lines\n  */\n    \"LineSpacing\": {\n      \"allowLineTrailingSpaces\": false\n    },\n  /*\n    defines allowed range for line length\n  */\n    \"LineLength\": {\n      \"allowMaxLength\": 80,\n      \"allowMinLength\": 0\n    },\n  /*\n    defines spacing conventions for comma punctuator\n    Example:\n    // good\n    var foo, bar;\n    // bad\n    var foo , bar;\n  */\n    \"CommaPunctuatorSpacing\": {\n      \"disallowPrecedingSpaces\": false\n    },\n  /*\n    defines spacing conventions for semicolon punctuator\n    Example:\n    // good\n    var foo;\n    // bad\n    var foo ;\n  */\n    \"SemicolonPunctuatorSpacing\": {\n      \"disallowPrecedingSpaces\": false\n    },\n\n  /*\n    defines scoping rules for compound statements\n\n    Example:\n    // good\n    if ( true ) {\n      var foo = \"bar\";\n    }\n    // bad\n    if ( true ) var foo = \"bar\";\n\n    All the constrains are optional.\n    if ( true )__{..}, for (..)__{..} - opening brace preceding whitespace\n    if ( true ) {__..}, for (..){__..} - opening brace trailing whitespace\n    if ( true ) {..__}, for (..){..__} - closing brace preceding whitespace\n  */\n    \"CompoundStatementConventions\": {\n      \"for\": [\n        \"IfStatement\",\n        \"SwitchStatement\",\n        \"WhileStatement\",\n        \"DoWhileStatement\",\n        \"ForStatement\",\n        \"ForInStatement\",\n        \"WithStatement\",\n        \"TryStatement\"\n      ],\n      \"requireBraces\": true,\n      \"requireMultipleLines\": true,\n      \"allowOpeningBracePrecedingWhitespaces\": 1,\n      \"allowOpeningBraceTrailingWhitespaces\": 1,\n      \"requireOpeningBracePrecedingNewLine\": true,\n      \"requireOpeningBraceTrailingNewLine\": true,\n      \"allowClosingBracePrecedingWhitespaces\": 1,\n      \"requireClosingBracePrecedingNewLine\": true\n    },\n    /*\n    defines spacing conventions for unary expressions\n\n    Example:\n    !!100 // good\n    !! 100 // bad\n    */\n    \"UnaryExpressionIdentifierSpacing\": {\n      \"allowTrailingWhitespaces\" : 0\n    },\n    /*\n    defines spacing conventions for ternary conditionals\n\n    Example:\n    foo = true ? 1 : 0; // good\n    foo = true ?1:0; // bad\n    */\n    \"TernaryConditionalPunctuatorsSpacing\": {\n      \"allowTestTrailingWhitespaces\": 1,\n      \"allowConsequentPrecedingWhitespaces\": 1,\n      \"allowConsequentTrailingWhitespaces\": 1,\n      \"allowAlternatePrecedingWhitespaces\": 1,\n       /*\n        Optional modifier.\n        When undefined the sniffer treats nesting statements the same\n            as regular\n        When false, no rules applied for nesting statements\n        When defined, the corresponding rules go for nesting statements\n        foo( a?b:c )\n        */\n      \"ifNesting\": {\n        \"allowTestTrailingWhitespaces\": 0,\n        \"allowConsequentPrecedingWhitespaces\": 0,\n        \"allowConsequentTrailingWhitespaces\": 0,\n        \"allowAlternatePrecedingWhitespaces\": 0\n      }\n    },\n    /*\n    defines spacing conventions for empty constructs\n    \"for\" qualifier takes an array of tokens compatible with\n    Mozilla Parser AST (https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API)\n\n    Example:\n    obj = {}; // good\n    obj = {  }; // bad\n    */\n    \"EmptyConstructsSpacing\": {\n      \"for\": [\n        \"ObjectExpression\",\n        \"ArrayExpression\",\n        \"CallExpression\"\n      ],\n      \"allowWhitespaces\": false\n    },\n   /*\n    defines spacing conventions for object literals\n\n    Example:\n    obj = { prop: 1 }; // good\n    obj = { prop:1 };// bad\n    */\n    \"ObjectLiteralSpacing\": {\n      \"allowKeyPrecedingWhitespaces\": 1,\n      \"allowKeyTrailingWhitespaces\": 0,\n      \"allowValuePrecedingWhitespaces\": 1,\n      \"allowValueTrailingWhitespaces\": 1\n    },\n   /*\n    defines spacing conventions for array literals\n\n    Example:\n    arr = [ 1, 2 ]; // good\n    arr = [1,2]; // bad\n    */\n    \"ArrayLiteralSpacing\": {\n      \"allowElementPrecedingWhitespaces\": 1,\n      \"allowElementTrailingWhitespaces\": 1,\n      /*\n      Optional modifier.\n      \"for\" qualifier takes an array of tokens compatible with\n      Mozilla Parser AST (https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API)\n      When qualifier \"for\" is missing the exception rules gets applied for any node type\n      */\n      \"exceptions\": {\n        \"singleElement\": {\n          \"for\": [ \"Literal\" ],\n          \"allowElementPrecedingWhitespaces\": 0,\n          \"allowElementTrailingWhitespaces\": 0\n        },\n        \"firstElement\": {\n          \"for\": [ \"Literal\" ],\n          \"allowElementPrecedingWhitespaces\": 1\n        },\n        \"lastElement\": {\n          \"for\": [ \"Literal\" ],\n          \"allowElementTrailingWhitespaces\": 1\n        }\n      }\n    },\n   /*\n    defines type of quotes to use across the code-base\n\n    Example:\n    foo = \"text\"; // good\n    foo = 'text'; // bad\n    */\n    \"QuoteConventions\": {\n      \"allowDoubleQuotes\": true,\n      \"allowSingleQuotes\": false\n    },\n    /*\n    defines naming conventions for variables\n    Note: variable of all uppercase (including $_0-9) are considered as constants and ignored by the sniffer\n\n    Example:\n    var camelCase; // good\n    var not_camel_case; // bad\n    */\n    \"VariableNamingConventions\": {\n      \"allowCase\": [\"camel\"],\n      \"allowRepeating\": true,\n      \"allowNumbers\": true\n    },\n   /*\n    defines naming conventions for functions\n\n    Example:\n    var PascalCase; // good\n    var not_camel_or_pascal_case; // bad\n    */\n    \"FunctionNamingConventions\": {\n      \"allowCase\": [\"camel\", \"pascal\"],\n      \"allowRepeating\": true,\n      \"allowNumbers\": true\n    },\n    /*\n    defines naming conventions for new expressions\n\n    Example:\n    obj = new Constructor(); // good\n    obj = new constructor(); // bad\n    */\n    \"NewExpressionCalleeNamingConventions\": {\n      \"allowCase\": [ \"pascal\" ],\n      \"allowRepeating\": true,\n      \"allowNumbers\": true\n    },\n\n   /*\n    defines spacing conventions for arguments\n\n    Example:\n    fn( 1, 2 ); // good\n    fn(1,2); // bad\n    */\n    \"ArgumentsSpacing\": {\n      \"allowArgPrecedingWhitespaces\": 1,\n      \"allowArgTrailingWhitespaces\": 1,\n      /*\n        Optional modifier.\n       \"for\" qualifier takes an array of tokens compatible with\n        Mozilla Parser AST (https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API)\n        When qualifier \"for\" is missing the exception rules gets applied for any node type\n      */\n      \"exceptions\": {\n        \"singleArg\" : {\n          \"for\": [ \"FunctionExpression\", \"ArrayExpression\", \"ObjectExpression\" ],\n          \"allowArgPrecedingWhitespaces\": 0,\n          \"allowArgTrailingWhitespaces\": 0\n        },\n        \"firstArg\": {\n          \"for\": [ \"FunctionExpression\" ],\n          \"allowArgPrecedingWhitespaces\": 0\n        },\n        \"lastArg\": {\n          \"for\": [ \"FunctionExpression\" ],\n          \"allowArgTrailingWhitespaces\": 0\n        }\n      },\n      /*\n        Optional modifier.\n        When undefined the sniffer treats nesting statements the same\n            as regular\n        When false, no rules applied for nesting statements\n        When defined, the corresponding rules go for nesting statements\n        foo( bar(1,1) )\n        */\n      \"ifNesting\": {\n        \"allowArgPrecedingWhitespaces\": 0,\n        \"allowArgTrailingWhitespaces\": 0\n      }\n    },\n  /*\n    defines spacing conventions for parameters\n\n    Example:\n    function fn( foo, bar ){}; // good\n    function fn(foo,bar){}; // bad\n    */\n    \"ParametersSpacing\": {\n      \"allowParamPrecedingWhitespaces\": 1,\n      \"allowParamTrailingWhitespaces\": 1,\n      \"exceptions\": {\n        \"singleParam\": {\n          \"for\": [ \"Identifier\" ],\n          \"allowParamPrecedingWhitespaces\": 0,\n          \"allowParamTrailingWhitespaces\": 0\n        },\n        \"firstParam\": {\n          \"for\": [ \"Identifier\" ],\n          \"allowParamPrecedingWhitespaces\": 1,\n          \"allowParamTrailingWhitespaces\": 0\n        },\n        \"lastParam\": {\n          \"for\": [ \"Identifier\" ],\n          \"allowParamPrecedingWhitespaces\": 1\n          \"allowParamTrailingWhitespaces\": 0\n        }\n      }\n    },\n    /*\n    defines how methods can be placed when a chain of method calls is too long to fit on one line\n\n    Example:\n    // good\n    elements\n    .addClass( \"foo\" )\n    .children();\n\n    // bad\n    elements.addClass( \"foo\" )\n    .children();\n    */\n\n    \"ChainedMethodCallsPerLineConventions\": {\n      \"requireOnePerLineWhenMultilineCaller\": true\n    },\n    /*\n    defines spacing conventions for chains of method calls\n    Example:\n    // good\n    elements.addClass( \"foo\" )\n\n    // bad\n    elements.  addClass( \"foo\" )\n    */\n    \"ChainedMethodCallsSpacing\": {\n      \"allowPrecedingPropertyWhitespaces\": 0\n    },\n    /*\n    defines spacing conventions for operators (including declarator)\n\n    Example:\n    foo = 1 + 1; // good\n    foo = 1+1; // bad\n    */\n    \"OperatorSpacing\" : {\n      \"allowOperatorPrecedingWhitespaces\": 1,\n      \"allowOperatorTrailingWhitespaces\": 1\n    },\n    /*\n    defines conventions for variable declarations\n\n    Example:\n    // good\n    (function(){\n      var foo, bar;\n    })();\n\n    // bad\n    (function(){\n      var foo;\n      var bar;\n    })();\n    */\n    \"VariableDeclarationPerScopeConventions\" : {\n      \"disallowMultiplePerBlockScope\": true,\n      \"requireInTheBeginning\": true\n    },\n    /*\n    defines conventions for object declarations\n\n    Example:\n    // good\n    o = { p1: 1, p2: 2 }\n    // good\n    o = {\n      p1: 1,\n      p2: 2\n    }\n    // bad\n    o = {\n      p1: 1, p2: 2 }\n     */\n    \"ObjectLiteralConventions\": {\n      \"requireOnePerLineWhenMultiline\": true\n    },\n    /*\n    defines conventions for array declarations\n\n    Example:\n    // good\n    arr = [ 1, \"two\" ]\n    // good\n    arr = [\n      1,\n      \"two\"\n    ]\n    // bad\n    arr = [\n      1, \"two\" ]\n    */\n    \"ArrayLiteralConventions\": {\n      \"requireOnePerLineWhenMultiline\": true\n    }\n  }\n```\n\n# \u003ca name=\"a-ci\"\u003e\u003c/a\u003eJSCodeSniffer and Continuous Integration\n\n## \u003ca name=\"a-ant\"\u003e\u003c/a\u003eSetting up [Apache Ant](http://ant.apache.org/) build script reporting to [Jenkins](http://jenkins-ci.org) Checkstyle plugin.\nNOTE: If you have phpcs-ci ant target, invoke it prior to this one. Jscs will find created by phpcs checkstyle.xml and extend its body instead of overriding the report.\n```xml\n\u003ctarget name=\"jscs-ci\"\n         description=\"Find coding standard violations using JS_CodeSniffer and print human readable output.\"\u003e\n  \u003cexec executable=\"jscs\"\u003e\n   \u003carg value=\"--standard=Jquery\" /\u003e\n   \u003carg value=\"--report=checkstyle\" /\u003e\n   \u003carg value=\"--report-file=${basedir}/build/logs/checkstyle.xml\" /\u003e\n   \u003carg path=\"${basedir}/src\" /\u003e\n  \u003c/exec\u003e\n \u003c/target\u003e\n```\n\n## \u003ca name=\"a-grunt\"\u003e\u003c/a\u003eSetting up [Grunt](http://gruntjs.com/) task\n\n*Gruntfile.js*\n```javascript\ngrunt.loadNpmTasks('grunt-jscodesniffer');\ngrunt.initConfig({\n     // Validate against jQuery coding standard\n     jscs: {\n        options: {\n            \"standard\": \"Jquery\"\n        },\n        all: [\"js-folder\"]\n     }\n  });\n```\n*package.json*\n```javascript\n\"devDependencies\": {\n    //..\n    \"grunt-jscodesniffer\": \"*\"\n  }\n```\n\n## \u003ca name=\"a-svn\"\u003e\u003c/a\u003e Using the Subversion pre-commit hook\n\nA pre-commit hook is a feature available in the Subversion version control system that allows code to be validated before it is committed to the repository.\nEdit scripts/jscs-svn-pre-commit and replace JSCS value with your own path to JS CodeSniffer\n```bash\nJSCS = \"/your-path/jscodesniffer\"\n```\n\nMake a symlink of scripts/jscs-svn-pre-commit in your repository hooks folder. E.g.\n```bash\nln -s /\u003cfull path\u003e/scripts/jscs-svn-pre-commit /repositories/\u003cproject\u003e/hooks/pre-commit\n```\n\n## \u003ca name=\"a-git\"\u003e\u003c/a\u003e Using the git pre-commit hook\nMake a symlink of scripts/jscs-git-pre-commit in your repository .git/hooks folder. E.g.\n```bash\nln -s /\u003cfull path\u003e/scripts/jscs-git-pre-commit /\u003cproject\u003e/.git/hooks/pre-commit\n```\n\n\n## API Notes\n\nHigh-level interface example (the report in stdout):\n```javascript\nvar argv = [ \"node\", \"jscs\", \"./source-dir/\", \"--standard=Jquery\", \"--report-full\" ],\n\t\tjscodesniffer = require( \"jscodesniffer\" );\n\njscodesniffer( argv, process.cwd() );\n```\n\nLow-level one example:\n```javascript\nvar Sniffer = require( \"./lib/Sniffer\" ),\n\t\tsniffer = new Sniffer(),\n\t\tsrc = \"var a= 1;\",\n\t\toptions = {\n\t\t\tstandard: \"Jquery\"\n\t\t},\n\t\tlogger = sniffer.getTestResults( src, options, {} );\n\nconsole.log(logger.getMessages());\n\n/*\n  [ { sniff: 'OperatorSpacing',\n    errorCode: 'OperatorPrecedingWhitespaces',\n    range: [ 5, 5 ],\n    loc: {  start: { line: 1, column: 5 }, end: { line: 1, column: 5 }  },\n    payload:\n     { actual: 0,\n       expected: 1,\n       excerpt: '',\n       trace: '..a=..',\n       where: '\u003c' } } ]\n\n*/\n```\n\n## Developing a sniff\n\nLet's consider a sniff, which validates the number of spaces preceding parameter list in a function declaration.\nFirst of all, we need to apply the defined rules to function declarations only. Syntax Tree gives us\nprecise information about any function declaration in the code. As the sniff will rely on Syntax Tree we\nplace the new module to /Lib/Sniff/SyntaxTree and name it according to the defined\nrule-set `FunctionDeclarationParameterListSpacing` (has to be also presented in `SyntaxAnalizer`).\n\nEvery sniff module has method `validateRule`. There we simply enlist the option validators:\n```\nutils.validateRule( rule, \"allowPrecedingWhitespaces\", \"number\", true );\n```\n\nMethod `run` performs the sniffing job. There we lop off all the inappropriate nodes (`node.type === \"FunctionDeclaration\"`).\nNow we have to determine what the node parts correspond to the rule. In this case we need\nfunction identifier (`node.id`) and the following token representing opening parenthesis. Unfortunately the Syntax Tree\ndoesn't contain any information about such tokens as grouping parentheses. However we can ask TokenIterator for help.\nLet's get the token corresponding to the function identifier:\n```\ntokenIt = tokenIterator.findByLeftPos( node.id.range[ 0 ] );\n```\nNow we can simply request the token following this one as `tokenIt.get( 1 )` (and preceding as `tokenIt.get( -1 )`.\nSo the spaces of our interest are expected between those two tokens. We can make sure we point to the right code\nfragment like that:\n\n```\nsourceCode.extract( node.id.range[ 1 ], tokenIt.get( 1 ).range[ 0 ] ).print();\n```\n\nto make the real check, we use the following mixin:\n```\nmixin.sniffExcerpt( node.id, tokenIt.get( 1 ),\n  rule.allowPrecedingWhitespaces, \"FunctionDeclarationParamListPrecedingSpacing\", \"\u003c\" );\n```\n\n[![Analytics](https://ga-beacon.appspot.com/UA-1150677-13/dsheiko/jscodesniffer)](http://githalytics.com/dsheiko/jscodesniffer)\n\n[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/dsheiko/jscodesniffer/trend.png)](https://bitdeli.com/free \"Bitdeli Badge\")\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsheiko%2Fjscodesniffer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdsheiko%2Fjscodesniffer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsheiko%2Fjscodesniffer/lists"}