From af6d6a87898ce1c9676da3c15d5a4a64ab9c1e6d Mon Sep 17 00:00:00 2001 From: Tom Carman Date: Tue, 21 May 2024 23:22:50 +0100 Subject: [PATCH] feat: initial implementation of field-description-minimum-length rule --- src/rules/_rules.ts | 3 +- src/rules/field-description-minimum-length.ts | 54 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/rules/field-description-minimum-length.ts diff --git a/src/rules/_rules.ts b/src/rules/_rules.ts index 4af6e45..e51e617 100644 --- a/src/rules/_rules.ts +++ b/src/rules/_rules.ts @@ -1,3 +1,4 @@ import FieldShouldHaveADescription from './field-should-have-a-description.js'; import ObjectShouldHaveADescription from './object-should-have-a-description.js'; -export { FieldShouldHaveADescription, ObjectShouldHaveADescription }; +import FieldDescriptionMinimumLength from './field-description-minimum-length.js'; +export { FieldShouldHaveADescription, ObjectShouldHaveADescription, FieldDescriptionMinimumLength }; diff --git a/src/rules/field-description-minimum-length.ts b/src/rules/field-description-minimum-length.ts new file mode 100644 index 0000000..9c00c59 --- /dev/null +++ b/src/rules/field-description-minimum-length.ts @@ -0,0 +1,54 @@ +import * as fs from 'node:fs'; +import type { Result } from 'sarif'; +import { XMLParser } from 'fast-xml-parser'; +// import type { SfCustomField } from '../common/metadata-types.js'; +import { RuleClass, SingleRuleResult } from '../common/types.js'; +import { SfCustomField } from '../common/metadata-types.js'; + +export default class FieldDescriptionMinimumLength implements RuleClass { + public ruleId: string = 'field-description-minimum-length'; + public shortDescriptionText = 'Custom Field Description does not meet the minimum length.'; + public fullDescriptionText = 'A Custom Field should have a description, describing how the field is used.'; + public level: Result.level = 'warning'; + public startLine = 1; + public endLine = 1; + public files: string[] = []; + public results: SingleRuleResult[] = []; + + public setFiles(files: string[]): void { + this.files = files; + } + + public execute(): void { + const customFields = this.files.filter( + (file) => (file.includes('__c') || file.includes('__e')) && file.endsWith('.field-meta.xml') + ); + + const ruleViolations = customFields.filter((file) => { + const fileText = fs.readFileSync(file, 'utf-8'); + const parser = new XMLParser({ ignoreDeclaration: true }); + const customField = parser.parse(fileText) as SfCustomField; + const customFieldContents = customField.CustomField; + + if (customFieldContents.description) { + return customFieldContents.description.length < 100; + } + }); + + // + + // // eslint-disable-next-line no-console + // console.log(JSON.stringify(customField)); + // // console.log(customField.CustomField.visibleLines); + // } else { + // // eslint-disable-next-line no-console + // console.log(`Custom field ${customFieldContents.fullName} has no attribute visibleLines`); + // } + + // return !file.includes(''); + + for (const ruleViolation of ruleViolations) { + this.results.push(new SingleRuleResult(ruleViolation, this.startLine, this.endLine)); + } + } +}