no-unpublished-bin.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * @author Toru Nagashima
  3. * See LICENSE file in root directory for full license.
  4. */
  5. "use strict"
  6. const path = require("path")
  7. const getConvertPath = require("../util/get-convert-path")
  8. const getNpmignore = require("../util/get-npmignore")
  9. const getPackageJson = require("../util/get-package-json")
  10. /**
  11. * Checks whether or not a given path is a `bin` file.
  12. *
  13. * @param {string} filePath - A file path to check.
  14. * @param {string|object|undefined} binField - A value of the `bin` field of `package.json`.
  15. * @param {string} basedir - A directory path that `package.json` exists.
  16. * @returns {boolean} `true` if the file is a `bin` file.
  17. */
  18. function isBinFile(filePath, binField, basedir) {
  19. if (!binField) {
  20. return false
  21. }
  22. if (typeof binField === "string") {
  23. return filePath === path.resolve(basedir, binField)
  24. }
  25. return Object.keys(binField).some(
  26. key => filePath === path.resolve(basedir, binField[key])
  27. )
  28. }
  29. module.exports = {
  30. meta: {
  31. docs: {
  32. description: "disallow `bin` files that npm ignores",
  33. category: "Possible Errors",
  34. recommended: true,
  35. url:
  36. "https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-unpublished-bin.md",
  37. },
  38. type: "problem",
  39. fixable: null,
  40. schema: [
  41. {
  42. type: "object",
  43. properties: {
  44. //
  45. convertPath: getConvertPath.schema,
  46. },
  47. },
  48. ],
  49. },
  50. create(context) {
  51. return {
  52. Program(node) {
  53. // Check file path.
  54. let rawFilePath = context.getFilename()
  55. if (rawFilePath === "<input>") {
  56. return
  57. }
  58. rawFilePath = path.resolve(rawFilePath)
  59. // Find package.json
  60. const p = getPackageJson(rawFilePath)
  61. if (!p) {
  62. return
  63. }
  64. // Convert by convertPath option
  65. const basedir = path.dirname(p.filePath)
  66. const relativePath = getConvertPath(context)(
  67. path.relative(basedir, rawFilePath).replace(/\\/gu, "/")
  68. )
  69. const filePath = path.join(basedir, relativePath)
  70. // Check this file is bin.
  71. if (!isBinFile(filePath, p.bin, basedir)) {
  72. return
  73. }
  74. // Check ignored or not
  75. const npmignore = getNpmignore(filePath)
  76. if (!npmignore.match(relativePath)) {
  77. return
  78. }
  79. // Report.
  80. context.report({
  81. node,
  82. message:
  83. "npm ignores '{{name}}'. Check 'files' field of 'package.json' or '.npmignore'.",
  84. data: { name: relativePath },
  85. })
  86. },
  87. }
  88. },
  89. }