Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

generateRule.js 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. "use strict";
  2. var _fs = require("fs");
  3. var _promises = _interopRequireDefault(require("fs/promises"));
  4. var _path = require("path");
  5. var _lodash = _interopRequireDefault(require("lodash"));
  6. var _openEditor = _interopRequireDefault(require("open-editor"));
  7. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  8. function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
  9. function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  10. // Todo: Would ideally have prompts, e.g., to ask for whether type was problem/layout, etc.
  11. const [,, ruleName, ...options] = process.argv;
  12. const recommended = options.includes('--recommended');
  13. (async () => {
  14. if (!ruleName) {
  15. console.error('Please supply a rule name');
  16. return;
  17. }
  18. if (/[A-Z]/u.test(ruleName)) {
  19. console.error('Please ensure the rule has no capital letters');
  20. return;
  21. }
  22. const ruleNamesPath = './test/rules/ruleNames.json';
  23. const ruleNames = JSON.parse(await _promises.default.readFile(ruleNamesPath, 'utf8'));
  24. if (!ruleNames.includes(ruleName)) {
  25. ruleNames.push(ruleName);
  26. ruleNames.sort();
  27. }
  28. await _promises.default.writeFile(ruleNamesPath, JSON.stringify(ruleNames, null, 2) + '\n');
  29. console.log('ruleNames', ruleNames);
  30. const ruleTemplate = `import iterateJsdoc from '../iterateJsdoc';
  31. export default iterateJsdoc(({
  32. context,
  33. utils,
  34. }) => {
  35. // Rule here
  36. }, {
  37. iterateAllJsdocs: true,
  38. meta: {
  39. docs: {
  40. description: '',
  41. url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-${ruleName}',
  42. },
  43. schema: [
  44. {
  45. additionalProperies: false,
  46. properties: {
  47. // Option properties here (or remove the object)
  48. },
  49. type: 'object',
  50. },
  51. ],
  52. type: 'suggestion',
  53. },
  54. });
  55. `;
  56. const camelCasedRuleName = _lodash.default.camelCase(ruleName);
  57. const rulePath = `./src/rules/${camelCasedRuleName}.js`;
  58. if (!(0, _fs.existsSync)(rulePath)) {
  59. await _promises.default.writeFile(rulePath, ruleTemplate);
  60. }
  61. const ruleTestTemplate = `export default {
  62. invalid: [
  63. {
  64. code: \`
  65. \`,
  66. errors: [{
  67. line: '',
  68. message: '',
  69. }],
  70. },
  71. ],
  72. valid: [
  73. {
  74. code: \`
  75. \`,
  76. },
  77. ],
  78. };
  79. `;
  80. const ruleTestPath = `./test/rules/assertions/${camelCasedRuleName}.js`;
  81. if (!(0, _fs.existsSync)(ruleTestPath)) {
  82. await _promises.default.writeFile(ruleTestPath, ruleTestTemplate);
  83. }
  84. const ruleReadmeTemplate = `### \`${ruleName}\`
  85. |||
  86. |---|---|
  87. |Context|everywhere|
  88. |Tags|\`\`|
  89. |Recommended|${recommended ? 'true' : 'false'}|
  90. |Settings||
  91. |Options||
  92. <!-- assertions ${camelCasedRuleName} -->
  93. `;
  94. const ruleReadmePath = `./.README/rules/${ruleName}.md`;
  95. if (!(0, _fs.existsSync)(ruleReadmePath)) {
  96. await _promises.default.writeFile(ruleReadmePath, ruleReadmeTemplate);
  97. }
  98. const replaceInOrder = async ({
  99. path,
  100. oldRegex,
  101. checkName,
  102. newLine,
  103. oldIsCamel
  104. }) => {
  105. const offsets = [];
  106. let readme = await _promises.default.readFile(path, 'utf8');
  107. readme.replace(oldRegex, (matchedLine, n1, offset, str, {
  108. oldRule
  109. }) => {
  110. offsets.push({
  111. matchedLine,
  112. offset,
  113. oldRule
  114. });
  115. });
  116. offsets.sort(({
  117. oldRule
  118. }, {
  119. oldRule: oldRuleB
  120. }) => {
  121. // eslint-disable-next-line no-extra-parens
  122. return oldRule < oldRuleB ? -1 : oldRule > oldRuleB ? 1 : 0;
  123. });
  124. let alreadyIncluded = false;
  125. const itemIndex = offsets.findIndex(({
  126. oldRule
  127. }) => {
  128. alreadyIncluded || (alreadyIncluded = oldIsCamel ? camelCasedRuleName === oldRule : ruleName === oldRule);
  129. return oldIsCamel ? camelCasedRuleName < oldRule : ruleName < oldRule;
  130. });
  131. let item = itemIndex !== undefined && offsets[itemIndex];
  132. if (item && itemIndex === 0 && // This property would not always be sufficient but in this case it is.
  133. oldIsCamel) {
  134. item.offset = 0;
  135. }
  136. if (!item) {
  137. item = offsets.pop();
  138. item.offset += item.matchedLine.length;
  139. }
  140. if (alreadyIncluded) {
  141. console.log(`Rule name is already present in ${checkName}.`);
  142. } else {
  143. readme = readme.slice(0, item.offset) + (item.offset ? '\n' : '') + newLine + (item.offset ? '' : '\n') + readme.slice(item.offset);
  144. await _promises.default.writeFile(path, readme);
  145. }
  146. };
  147. await replaceInOrder({
  148. checkName: 'README',
  149. newLine: `{"gitdown": "include", "file": "./rules/${ruleName}.md"}`,
  150. oldRegex: /\n\{"gitdown": "include", "file": ".\/rules\/(?<oldRule>[^.]*).md"\}/gu,
  151. path: './.README/README.md'
  152. });
  153. await replaceInOrder({
  154. checkName: 'index import',
  155. newLine: `import ${camelCasedRuleName} from './rules/${camelCasedRuleName}';`,
  156. oldIsCamel: true,
  157. oldRegex: /\nimport (?<oldRule>[^ ]*) from '.\/rules\/\1';/gu,
  158. path: './src/index.js'
  159. });
  160. await replaceInOrder({
  161. checkName: 'index recommended',
  162. newLine: `${' '.repeat(8)}'jsdoc/${ruleName}': '${recommended ? 'warn' : 'off'}',`,
  163. oldRegex: /\n\s{8}'jsdoc\/(?<oldRule>[^']*)': '[^']*',/gu,
  164. path: './src/index.js'
  165. });
  166. await replaceInOrder({
  167. checkName: 'index rules',
  168. newLine: `${' '.repeat(4)}'${ruleName}': ${camelCasedRuleName},`,
  169. oldRegex: /\n\s{4}'(?<oldRule>[^']*)': [^,]*,/gu,
  170. path: './src/index.js'
  171. });
  172. await Promise.resolve().then(() => _interopRequireWildcard(require('./generateReadme.js')));
  173. /*
  174. console.log('Paths to open for further editing\n');
  175. console.log(`open ${ruleReadmePath}`);
  176. console.log(`open ${rulePath}`);
  177. console.log(`open ${ruleTestPath}\n`);
  178. */
  179. // Set chdir as somehow still in operation from other test
  180. process.chdir((0, _path.resolve)(__dirname, '../../'));
  181. await (0, _openEditor.default)([// Could even add editor line column numbers like `${rulePath}:1:1`
  182. ruleReadmePath, ruleTestPath, rulePath]);
  183. })();
  184. //# sourceMappingURL=generateRule.js.map