{"id":17179357,"url":"https://github.com/benkeen/grunt-search","last_synced_at":"2025-07-04T01:36:08.950Z","repository":{"id":12486156,"uuid":"15155507","full_name":"benkeen/grunt-search","owner":"benkeen","description":"Grunt plugin that searches a list of files and logs all findings in various formats.","archived":false,"fork":false,"pushed_at":"2016-02-21T19:42:12.000Z","size":48,"stargazers_count":15,"open_issues_count":3,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-27T07:36:02.750Z","etag":null,"topics":["grunt","grunt-plugins"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benkeen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-12-13T05:25:19.000Z","updated_at":"2020-07-29T03:39:00.000Z","dependencies_parsed_at":"2022-08-27T19:10:41.120Z","dependency_job_id":null,"html_url":"https://github.com/benkeen/grunt-search","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benkeen%2Fgrunt-search","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benkeen%2Fgrunt-search/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benkeen%2Fgrunt-search/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benkeen%2Fgrunt-search/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benkeen","download_url":"https://codeload.github.com/benkeen/grunt-search/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248351382,"owners_count":21089270,"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":["grunt","grunt-plugins"],"created_at":"2024-10-15T00:25:44.251Z","updated_at":"2025-04-13T16:31:11.026Z","avatar_url":"https://github.com/benkeen.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## grunt-search\n\nThis is a Grunt plugin that searches a list of files for particular search strings and logs the results in JSON, XML,\ntext or JUnit format - or just output to the console. It also provides an option to fail the build process, should you\nneed it.\n\n### Use-case\n\nThere are a bunch of search-and-replace Grunt plugins out there, but we needed something simpler for logging purposes\nonly. We wanted to run various tests on our codebase to look for certain things: inline styles, inline event handlers,\nold, unwanted HTML tags. None of these weren't significant enough to warrant failing the build, but they do give a\nclue as the health of the codebase.\n\nSo basically, we run this function along with `jshint` in our dev environments to warn us about the accumulation of crap.\n\n### Installation\n\nThis plugin requires Grunt v0.4.1+.\n\nIn your project folder, run the following command:\n\n```js\nnpm install grunt-search --save-dev\n```\n\nOnce the plugin has been installed, you need to add this line of JS to your gruntfile:\n\n```js\ngrunt.loadNpmTasks('grunt-search');\n```\n\nThat will reference this module and allow you to use it.\n\n\n### Usage examples\n\nIf you're familiar with Grunt, it's pretty straightforward to use. Here's a few example searches so you can get the idea\nof how it operates.\n\n```js\ngrunt.initConfig({\n    search: {\n\n        // Example 1: search for inline style tags\n        inlineStyles: {\n            files: {\n                src: [\"*.html\", \"**/*.hbs\"]\n            },\n            options: {\n                searchString: /style\\s?=\\s?[\"']*/g,\n                logFile: \"tmp/results.json\"\n            }\n        },\n\n        // Example 2: look for any developers leaving obscenities in the codebase\n        obscenities: {\n            files: {\n                src: [\"*\"]\n            },\n            options: {\n                searchString: /(poop|fart|Barbara\\sStreisand)/g,\n                logFile: \"tmp/results.xml\",\n                logFormat: \"xml\",\n                failOnMatch: true,\n                onMatch: function(match) {\n                    // called when a match is made. The parameter is an object of the\n                    // following structure: { file: \"\", line: X, match: \"\" }\n                },\n                onComplete: function(matches) {\n                    // called when all files have been parsed for the target. The\n                    // matches parameter is an object of the format:\n                    // `{ numMatches: N, matches: {} }`. The matches /property is\n                    // an object of filename =\u003e array of matches\n                },\n            }\n        },\n\n        // Example 3: search a PHP codebase for short-tags and just output the findings to\n        // the console (short tags can be disabled, so this helps prevent them sneaking in!)\n\t\tshort_tags: {\n\t\t\tfiles: {\n\t\t\t\tsrc: [\"**/*.php\"]\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tsearchString: /(\u003c\\?[^p])|(\u003c\\?$)/,\n\t\t\t\tlogFormat: \"console\"\n\t\t\t}\n\t\t},\n\n\t\t// Example 4: custom logging function. This example shows how you can access the raw results to\n\t\t// do whatever you want with it.\n\t\tchicken_sounds: {\n\t\t\tfiles: {\n\t\t\t\tsrc: [\"*\"],\n\t\t\t},\n\t\t\toptions: {\n\t\t\t\tsearchString: /cluck|cluckity|bwaaaaaah!|/,\n\t\t\t\tlogFormat: \"custom\",\n\t\t\t\tcustomLogFormatCallback: function(params) {\n\t\t\t\t\t/*\n\t\t\t\t\t// here, params is an object containing the following\n\t\t\t\t\t{\n\t\t\t\t\t\tfilePaths: [], // an array of file paths\n\t\t\t\t\t\tresults: [], // the results\n\t\t\t\t\t\tnumResults: X // the number of results\n\t\t\t\t\t}\n\t\t\t\t\t*/\n\t\t\t\t}\n\t\t\t}\n\t\t}\n    }\n});\n```\n\n### File matching\n\nThe `files` property should be an object with a single `src` property containing an array of files, or file patterns.\nThis plugin uses Grunt's file globbing patterns, documented here:\nhttp://gruntjs.com/configuring-tasks\n\n\n### Options\n\nThe `options` property can contain any of the following:\n\n#### required setting\n- *searchString*: a string or regexp, or array of strings/regexps. This is the string or strings you're looking for.\n\n#### optional settings\n- *logFormat*: (optional, defaults to `json`) the format of the log file: `json`, `xml`, `junit`, `text`, `custom`,\nor `console`. The json, XML, text and console options are self explanatory; the junit option logs the information in\nan XML format understood by JUnit; and the custom option lets you pass off the logging to your own function, defined\n(or at least accessible) to your gruntfile. For that, you need to\n- *customLogFormatCallback* (optional, unless you choose `custom` for the logFormat setting). If you want, you can define\nyour own logging function to access the raw info. Take a look at the chicken_sounds example above to see how to configure\nthis, and the data structure you get passed to your callback function.\n- *logFile*: (required, unless logFormat is set to `console`) the location of the file to be created. Like all things with\nGrunt, this is relative to the Grunt root.\n- *failOnMatch*: (optional, defaults to `false`). This option lets you choose to fail the build process if any matches\nare found.\n- *outputExaminedFiles*: (optional) a boolean - default to `false`). Sometimes it's not totally clear what files are\nbeing matched by the file globbing. When this option is set to `true`, the generated output file contains a list of the\nfiles that had been examined.\n- *scopeMatchToFile*: (optional) a boolean - default to `false`. Determines if the match should be scoped to the line or file.\nFor example, when set to `true`, all matches would be handled for files and parameters for *onMatch*\nand *logCondition* would be passed as `{ file: \"\", line: [X, X], match: [\"\", \"\"] }` per one for each file where one\nor multiple matches occurred.\n- *onComplete*: (optional) a function. This is called when all file searching is complete. It's passed a single parameter.\nAn object of the following format: `{ numMatches: N, matches: {} }`. The matches property is an object of\nfilename =\u003e array of matches. Note: this function doesn't get called in the event of a fatal error (i.e. a required\noptions parameter wasn't properly included).\n- *onMatch*: (optional) a function. This is called after each match is made. It's passed a single parameter - an object\nwith the following structure: `{ file: \"\", line: X, match: \"\" }`\n- *logCondition*: (optional) a function. This can be called to check if this match should be included in output. It's\npassed a single parameter - an object with the following structure: `{ file: \"\", line: X, match: \"\" }`. If this function\nreturns `true` the match would be included, if `false` it is not.\n- *JUnitTestsuiteName*: (optional) a function. If *logFormat* property set to `true` this function would be evaluated to determine if should this item be marked in JUnit report or not. It's passed two parameters, file dir object\nwith the following structure: `{ line: X, match: \"\" }` ( or `{ line: [X,..], match: [\"\",..] }`, if scopeMatchToFile set to `true` ). If this function returns `true` JUnit will mark this match as failed, if `false` JUnit will mark this match as passed.\n- *JUnitTestsuiteName*: (optional) a string - name for test suite in JUnit report.\n- *JUnitFailureMessage*: (optional) a string - message for failed test suites in JUnit report.\n\nNote: if either of the required parameters are omitted, the build will fail.\n\n### Changelog\n\n- *0.1.8* - Feb 21, 2016 - Grunt 1.0 compatibility update.\n- *0.1.7* - May 12th, 2015 - searchString now allows arrays; generated output of XML, JSON and text now include search query details.\n- *0.1.6* - May 17th, 2014 - custom log option added. jshint added and additional JUnit options added by [Sergei Z.](https://github.com/sagens42)\n- *0.1.5* - May 13th, 2014 - logCondition and scopeMatchToFile, courtesy of [Sergei Z.](https://github.com/sagens42)\n- *0.1.4* - Mar 5th, 2014. `junit` logFile option value added for generating JUnit XML reports. Courtesy of Sergii Iavorsky.\n- *0.1.3* - Dec 18th, 2013. `console` logFile option value added for simply outputting results to console. Now the number of\nmatches is always output to the console regardless of logFile type, as well as being logged in the generated file.\n- *0.1.2* - Dec 15th, 2013. Tests added, minor tweaks.\n- *0.1.1* - Dec 14th, 2013. Bug fix for JSON report files.\n- *0.1.0* - Dec 13th, 2013. Initial release.\n\n### Things To Improve\n\n- Each file being examined is loaded entirely into memory right now. From a memory perspective it would be better to\nstream them in.\n- Multi-line matches won't work.\n- Having some sort of omit list for the file search would be pretty nice. I find that often it finds dud matches in specific files, but I still want the general blobbing map to be searched...\n- Better tests!\n\n### License\n\nMIT, baby.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenkeen%2Fgrunt-search","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenkeen%2Fgrunt-search","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenkeen%2Fgrunt-search/lists"}