Skip to content

Commit

Permalink
Update: shebang gets fixable (fixes #8)
Browse files Browse the repository at this point in the history
  • Loading branch information
mysticatea committed Dec 28, 2015
1 parent 1962795 commit f03f8ed
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ Some rules are slow because it searches `package.json` and opens it.
- [no-missing-import](docs/rules/no-missing-import.md) - Disallow invalid `import` and `export` declarations.
- [no-missing-require](docs/rules/no-missing-require.md) - Disallow invalid `require()`s.
- [no-unsupported-features](docs/rules/no-unsupported-features.md) - Disallow unsupported ECMAScript features on the specified version.
- [shebang](docs/rules/shebang.md) - Suggest correct usage of shebang.
- [shebang](docs/rules/shebang.md) - Suggest correct usage of shebang. (fixable)
2 changes: 2 additions & 0 deletions docs/rules/shebang.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
When we make a CLI tool on Node.js, we add `bin` field to `package.json`, then we add a shebang the entry file.
This rule suggests correct usage of shebang.

**Fixable:** This rule is automatically fixable using the `--fix` flag on the command line.

## Rule Details

This rule looks up `package.json` file from each linitng target file.
Expand Down
30 changes: 22 additions & 8 deletions lib/rules/shebang.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ var getPackageJson = require("../util/get-package-json");
// Helpers
//------------------------------------------------------------------------------

var NODE_SHEBANG = "#!/usr/bin/env node\n";
var SHEBANG_PATTERN = /^#\!.+?\n/;

/**
* Checks whether or not a given path is a `bin` file.
*
Expand All @@ -41,13 +44,14 @@ function isBinFile(filePath, convert) {
}

/**
* Checks whether or not a given code has the valid shebang for Node.js.
* Gets the shebang line (includes a line ending) from a given code.
*
* @param {SourceCode} sourceCode - A source code object to check.
* @returns {boolean} `true` if the source code has the valid shebang.
* @returns {string} shebang if exists. Otherwise an empty string.
*/
function hasShebang(sourceCode) {
return /^#\!\/usr\/bin\/env node\n/.test(sourceCode.text);
function getShebang(sourceCode) {
var m = SHEBANG_PATTERN.exec(sourceCode.text);
return (m && m[0]) || "";
}

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -82,20 +86,30 @@ module.exports = function(context) {
}

var needsShebang = isBinFile(filePath, convertBinPath);
var shebang = hasShebang(sourceCode);
if (needsShebang === shebang) {
var shebang = getShebang(sourceCode);
if (needsShebang ? shebang === NODE_SHEBANG : !shebang) {
return;
}

if (needsShebang) {
context.report({
node: node,
message: "This file needs shebang \"#!/usr/bin/env node\"."
message: "This file needs shebang \"#!/usr/bin/env node\".",
fix: function(fixer) {
if (shebang) {
return fixer.replaceTextRange([0, shebang.length], NODE_SHEBANG);
} else {
return fixer.insertTextBefore(node, NODE_SHEBANG);
}
}
});
} else {
context.report({
node: node,
message: "This file needs no shebang."
message: "This file needs no shebang.",
fix: function(fixer) {
return fixer.removeRange([0, shebang.length]);
}
});
}
}
Expand Down
14 changes: 14 additions & 0 deletions tests/lib/rules/shebang.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,79 +108,93 @@ ruleTester.run("shebang", rule, {
{
filename: fixture("string-bin/bin/test.js"),
code: "hello();",
output: "#!/usr/bin/env node\nhello();",
errors: ["This file needs shebang \"#!/usr/bin/env node\"."]
},
{
filename: fixture("string-bin/bin/test.js"),
code: "#!/usr/bin/node\nhello();",
output: "#!/usr/bin/env node\nhello();",
errors: ["This file needs shebang \"#!/usr/bin/env node\"."]
},
{
filename: fixture("string-bin/lib/test.js"),
code: "#!/usr/bin/env node\nhello();",
output: "hello();",
errors: ["This file needs no shebang."]
},
{
filename: fixture("object-bin/bin/a.js"),
code: "hello();",
output: "#!/usr/bin/env node\nhello();",
errors: ["This file needs shebang \"#!/usr/bin/env node\"."]
},
{
filename: fixture("object-bin/bin/b.js"),
code: "#!/usr/bin/node\nhello();",
output: "#!/usr/bin/env node\nhello();",
errors: ["This file needs shebang \"#!/usr/bin/env node\"."]
},
{
filename: fixture("object-bin/bin/c.js"),
code: "#!/usr/bin/env node\nhello();",
output: "hello();",
errors: ["This file needs no shebang."]
},
{
filename: fixture("no-bin-field/lib/test.js"),
code: "#!/usr/bin/env node\nhello();",
output: "hello();",
errors: ["This file needs no shebang."]
},

// convertBinPath
{
filename: fixture("string-bin/src/bin/test.js"),
code: "hello();",
output: "#!/usr/bin/env node\nhello();",
options: [{"convertBinPath": ["bin", "src/bin"]}],
errors: ["This file needs shebang \"#!/usr/bin/env node\"."]
},
{
filename: fixture("string-bin/src/bin/test.js"),
code: "#!/usr/bin/node\nhello();",
output: "#!/usr/bin/env node\nhello();",
options: [{"convertBinPath": ["bin", "src/bin"]}],
errors: ["This file needs shebang \"#!/usr/bin/env node\"."]
},
{
filename: fixture("string-bin/src/lib/test.js"),
code: "#!/usr/bin/env node\nhello();",
output: "hello();",
options: [{"convertBinPath": ["bin", "src/bin"]}],
errors: ["This file needs no shebang."]
},
{
filename: fixture("object-bin/src/bin/a.js"),
code: "hello();",
output: "#!/usr/bin/env node\nhello();",
options: [{"convertBinPath": ["bin", "src/bin"]}],
errors: ["This file needs shebang \"#!/usr/bin/env node\"."]
},
{
filename: fixture("object-bin/src/bin/b.js"),
code: "#!/usr/bin/node\nhello();",
output: "#!/usr/bin/env node\nhello();",
options: [{"convertBinPath": ["bin", "src/bin"]}],
errors: ["This file needs shebang \"#!/usr/bin/env node\"."]
},
{
filename: fixture("object-bin/src/bin/c.js"),
code: "#!/usr/bin/env node\nhello();",
output: "hello();",
options: [{"convertBinPath": ["bin", "src/bin"]}],
errors: ["This file needs no shebang."]
},
{
filename: fixture("no-bin-field/src/lib/test.js"),
code: "#!/usr/bin/env node\nhello();",
output: "hello();",
options: [{"convertBinPath": ["bin", "src/bin"]}],
errors: ["This file needs no shebang."]
}
Expand Down

0 comments on commit f03f8ed

Please sign in to comment.