Skip to content

Commit

Permalink
commitlint: start using FP patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
knocte committed Sep 10, 2024
1 parent 2100e2c commit 34c5a37
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 77 deletions.
110 changes: 52 additions & 58 deletions commitlint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,19 @@ let bodyMaxLineLength = 64;
let headerMaxLineLength = 50;
let footerMaxLineLength = 150;

function notNullStringErrorMessage(stringType: string): string {
return `This is unexpected because ${stringType} should never be null`;
function notStringErrorMessage(variableName: string): string {
return `This is unexpected because ${variableName} should have been a string`;
}

function extractStringFromCommitlintParam(
paramName: string,
variable: any
): string {
let str = Helpers.assertNotNone(
Helpers.convertAnyToString(variable),
notStringErrorMessage(paramName)
);
return str;
}

export default {
Expand Down Expand Up @@ -64,27 +75,21 @@ export default {
{
rules: {
"body-prose": ({ raw }: { raw: any }) => {
let rawStr = Helpers.assertNotNull(
Helpers.convertAnyToString(raw),
notNullStringErrorMessage("raw")
);
let rawStr = extractStringFromCommitlintParam("raw", raw);

return Plugins.bodyProse(rawStr);
},

"commit-hash-alone": ({ raw }: { raw: any }) => {
let rawStr = Helpers.assertNotNull(
Helpers.convertAnyToString(raw),
notNullStringErrorMessage("raw")
);
let rawStr = extractStringFromCommitlintParam("raw", raw);

return Plugins.commitHashAlone(rawStr);
},

"empty-wip": ({ header }: { header: any }) => {
let headerStr = Helpers.assertNotNull(
Helpers.convertAnyToString(header),
notNullStringErrorMessage("header")
let headerStr = extractStringFromCommitlintParam(
"header",
header
);

return Plugins.emptyWip(headerStr);
Expand All @@ -95,9 +100,9 @@ export default {
_: any,
maxLineLength: number
) => {
let headerStr = Helpers.assertNotNull(
Helpers.convertAnyToString(header),
notNullStringErrorMessage("header")
let headerStr = extractStringFromCommitlintParam(
"header",
header
);

return Plugins.headerMaxLengthWithSuggestions(
Expand All @@ -107,15 +112,12 @@ export default {
},

"footer-notes-misplacement": ({ body }: { body: any }) => {
let bodyStr = Helpers.convertAnyToString(body);
return Plugins.footerNotesMisplacement(bodyStr);
let maybeBody = Helpers.convertAnyToString(body);
return Plugins.footerNotesMisplacement(maybeBody);
},

"footer-refs-validity": ({ raw }: { raw: any }) => {
let rawStr = Helpers.assertNotNull(
Helpers.convertAnyToString(raw),
notNullStringErrorMessage("raw")
);
let rawStr = extractStringFromCommitlintParam("raw", raw);

return Plugins.footerRefsValidity(rawStr);
},
Expand All @@ -125,72 +127,67 @@ export default {
}: {
header: any;
}) => {
let headerStr = Helpers.assertNotNull(
Helpers.convertAnyToString(header),
notNullStringErrorMessage("header")
let headerStr = extractStringFromCommitlintParam(
"header",
header
);

return Plugins.preferSlashOverBackslash(headerStr);
},

"proper-issue-refs": ({ raw }: { raw: any }) => {
let rawStr = Helpers.assertNotNull(
Helpers.convertAnyToString(raw),
notNullStringErrorMessage("raw")
);
let rawStr = extractStringFromCommitlintParam("raw", raw);

return Plugins.properIssueRefs(rawStr);
},

"title-uppercase": ({ header }: { header: any }) => {
let headerStr = Helpers.assertNotNull(
Helpers.convertAnyToString(header),
notNullStringErrorMessage("header")
let headerStr = extractStringFromCommitlintParam(
"header",
header
);

return Plugins.titleUppercase(headerStr);
},

"too-many-spaces": ({ raw }: { raw: any }) => {
let rawStr = Helpers.assertNotNull(
Helpers.convertAnyToString(raw),
notNullStringErrorMessage("raw")
);
let rawStr = extractStringFromCommitlintParam("raw", raw);

return Plugins.tooManySpaces(rawStr);
},

"type-space-after-colon": ({ header }: { header: any }) => {
let headerStr = Helpers.assertNotNull(
Helpers.convertAnyToString(header),
notNullStringErrorMessage("header")
let headerStr = extractStringFromCommitlintParam(
"header",
header
);

return Plugins.typeSpaceAfterColon(headerStr);
},

"type-with-square-brackets": ({ header }: { header: any }) => {
let headerStr = Helpers.assertNotNull(
Helpers.convertAnyToString(header),
notNullStringErrorMessage("header")
let headerStr = extractStringFromCommitlintParam(
"header",
header
);

return Plugins.typeWithSquareBrackets(headerStr);
},

// NOTE: we use 'header' instead of 'subject' as a workaround to this bug: https://github.com/conventional-changelog/commitlint/issues/3404
"subject-lowercase": ({ header }: { header: any }) => {
let headerStr = Helpers.assertNotNull(
Helpers.convertAnyToString(header),
notNullStringErrorMessage("header")
let headerStr = extractStringFromCommitlintParam(
"header",
header
);

return Plugins.subjectLowercase(headerStr);
},

"type-space-after-comma": ({ header }: { header: any }) => {
let headerStr = Helpers.assertNotNull(
let headerStr = Helpers.assertNotNone(
Helpers.convertAnyToString(header),
notNullStringErrorMessage("header")
notStringErrorMessage("header")
);

return Plugins.typeSpaceAfterComma(headerStr);
Expand All @@ -201,35 +198,32 @@ export default {
_: any,
maxLineLength: number
) => {
let bodyStr = Helpers.convertAnyToString(body);
let maybeBody = Helpers.convertAnyToString(body);
return Plugins.bodySoftMaxLineLength(
bodyStr,
maybeBody,
maxLineLength
);
},

"body-paragraph-line-min-length": ({ body }: { body: any }) => {
let bodyStr = Helpers.convertAnyToString(body);
let maybeBody = Helpers.convertAnyToString(body);
return Plugins.bodyParagraphLineMinLength(
bodyStr,
maybeBody,
headerMaxLineLength,
bodyMaxLineLength
);
},

"trailing-whitespace": ({ raw }: { raw: any }) => {
let rawStr = Helpers.assertNotNull(
Helpers.convertAnyToString(raw),
notNullStringErrorMessage("raw")
);
let rawStr = extractStringFromCommitlintParam("raw", raw);

return Plugins.trailingWhitespace(rawStr);
},

"type-space-before-paren": ({ header }: { header: any }) => {
let headerStr = Helpers.assertNotNull(
Helpers.convertAnyToString(header),
notNullStringErrorMessage("header")
let headerStr = extractStringFromCommitlintParam(
"header",
header
);

return Plugins.typeSpaceBeforeParen(headerStr);
Expand Down
26 changes: 22 additions & 4 deletions commitlint/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { None, Some, Option, OptionStatic, TypeHelpers } from "./fpHelpers.js";

export abstract class Helpers {
public static errMessageSuffix =
"\nFor reference, these are the guidelines that include our commit message conventions: https://github.com/nblockchain/conventions/blob/master/docs/WorkflowGuidelines.md";
Expand All @@ -16,9 +18,25 @@ export abstract class Helpers {
}

// to convert from 'any' type
public static convertAnyToString(potentialString: any): string | null {
// this null/undefined check is required, otherwise, String(null) might give us the stupid string "null"
return potentialString ? String(potentialString) : null;
public static convertAnyToString(potentialString: any): Option<string> {
if (TypeHelpers.IsNullOrUndefined(potentialString)) {
return OptionStatic.None;
}
// this type check is required, otherwise, String(null) would give us the stupid string "null"
if (TypeHelpers.IsInstanceOf(potentialString, String)) {
return new Some(String(potentialString));
}
return OptionStatic.None;
}

public static assertNotNone(
text: Option<string>,
errorMessage: string
): string {
if (text instanceof None) {
throw new Error(errorMessage);
}
return text.value;
}

public static assertNotNull(
Expand Down Expand Up @@ -72,7 +90,7 @@ export abstract class Helpers {

public static findUrls(text: string) {
var urlRegex = /(https?:\/\/[^\s]+)/g;
return text.match(urlRegex);
return OptionStatic.OfObj(text.match(urlRegex));
}

public static isCommitUrl(url: string) {
Expand Down
38 changes: 23 additions & 15 deletions commitlint/plugins.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Option, Some, None } from "./fpHelpers.js";
import { Option, Some, None, OptionStatic } from "./fpHelpers.js";
import { abbr } from "./abbreviations.js";
import { Helpers } from "./helpers.js";

Expand Down Expand Up @@ -91,13 +91,18 @@ export abstract class Plugins {

let urls = Helpers.findUrls(rawStr);

let gitRepo = process.env["GITHUB_REPOSITORY"];
if (gitRepo !== undefined && urls !== null) {
for (let url of urls.entries()) {
let urlStr = url[1].toString();
if (Helpers.isCommitUrl(urlStr) && urlStr.includes(gitRepo)) {
offence = true;
break;
let gitRepo = OptionStatic.OfObj(process.env["GITHUB_REPOSITORY"]);
if (!(gitRepo instanceof None)) {
if (!(urls instanceof None)) {
for (let url of urls.value.entries()) {
let urlStr = url[1].toString();
if (
Helpers.isCommitUrl(urlStr) &&
urlStr.includes(gitRepo.value)
) {
offence = true;
break;
}
}
}
}
Expand Down Expand Up @@ -155,10 +160,11 @@ export abstract class Plugins {
return [!offence, message + Helpers.errMessageSuffix];
}

public static footerNotesMisplacement(bodyStr: string | null) {
public static footerNotesMisplacement(body: Option<string>) {
let offence = false;

if (bodyStr !== null) {
if (!(body instanceof None)) {
let bodyStr = body.value;
bodyStr = Helpers.removeAllCodeBlocks(bodyStr).trim();
let seenBody = false;
let seenFooter = false;
Expand Down Expand Up @@ -377,12 +383,13 @@ export abstract class Plugins {
}

public static bodySoftMaxLineLength(
bodyStr: string | null,
body: Option<string>,
bodyMaxLineLength: number
) {
let offence = false;

if (bodyStr !== null) {
if (!(body instanceof None)) {
let bodyStr = body.value;
bodyStr = bodyStr.trim();
bodyStr = Helpers.removeAllCodeBlocks(bodyStr).trim();

Expand Down Expand Up @@ -434,13 +441,14 @@ export abstract class Plugins {
}

public static bodyParagraphLineMinLength(
bodyStr: string | null,
body: Option<string>,
paragraphLineMinLength: number,
paragraphLineMaxLength: number
) {
let offence: Option<string> = new None();
let offence: Option<string> = OptionStatic.None;

if (bodyStr !== null) {
if (!(body instanceof None)) {
let bodyStr = body.value;
bodyStr = Helpers.removeAllCodeBlocks(bodyStr).trim();

let paragraphs = Helpers.splitByEOLs(bodyStr, 2);
Expand Down

0 comments on commit 34c5a37

Please sign in to comment.