From 77708881845c9520e29e878db66830d88a5467c5 Mon Sep 17 00:00:00 2001
From: Marina <marinaflessa@gmail.com>
Date: Thu, 6 Jan 2022 16:24:42 +0100
Subject: [PATCH] feat: Add 'and', 'or' and 'containsString' to handlebar
 helpers (#13341)

---
 docs/usage/templates.md         | 20 ++++++++++++++++
 lib/util/template/index.spec.ts | 42 +++++++++++++++++++++++++++++++++
 lib/util/template/index.ts      | 19 +++++++++++++++
 3 files changed, 81 insertions(+)

diff --git a/docs/usage/templates.md b/docs/usage/templates.md
index de2ea87d46..73f333da8c 100644
--- a/docs/usage/templates.md
+++ b/docs/usage/templates.md
@@ -36,3 +36,23 @@ If you want to print pretty JSON with Handlebars you can use the built-in functi
 `{{{stringToPrettyJSON myvar}}}`
 
 In the example above `myvar` is a variable/field, that contains valid JSON.
+
+### containsString
+
+Returns `true` if a given string is a substring.
+
+`{{#if (containsString depName 'python')}}Python{{else}}Other{{/if}}`
+
+### and
+
+Returns `true` only if all expressions are `true`.
+
+`{{#if (and isMajor hasReleaseNotes)}}Backwards Incompatible release! Check out the Release notes.{{/if}}`
+
+In the example above, it will only show a text if `isMajor=true` and `hasReleaseNotes=true`.
+
+### or
+
+Returns `true` if at least one expression is `true`.
+
+`{{#if (or isPatch isSingleVersion}}Small update, safer to merge and release.{{else}}Check out the changelog for all versions before merging!{{/if}}`
diff --git a/lib/util/template/index.spec.ts b/lib/util/template/index.spec.ts
index 55ab3c7b27..a89b76b0e9 100644
--- a/lib/util/template/index.spec.ts
+++ b/lib/util/template/index.spec.ts
@@ -18,6 +18,48 @@ describe('util/template/index', () => {
     expect(output).toContain('github');
     expect(output).not.toContain('123test');
   });
+  it('containsString', () => {
+    const userTemplate =
+      "{{#if (containsString platform 'git')}}True{{else}}False{{/if}}";
+    const input = { platform: 'github' };
+    const output = template.compile(userTemplate, input);
+    expect(output).toContain('True');
+  });
+  it('not containsString', () => {
+    const userTemplate =
+      "{{#if (containsString platform 'hub')}}True{{else}}False{{/if}}";
+    const input = { platform: 'gitlab' };
+    const output = template.compile(userTemplate, input);
+    expect(output).toContain('False');
+  });
+  it('and returns true when all parameters are true', () => {
+    const userTemplate =
+      '{{#if (and isMajor isSingleVersion isReplacement)}}True{{else}}False{{/if}}';
+    const input = { isMajor: true, isSingleVersion: true, isReplacement: true };
+    const output = template.compile(userTemplate, input);
+    expect(output).toContain('True');
+  });
+  it('and returns false when at least one parameter is false', () => {
+    const userTemplate =
+      '{{#if (and isMajor isPatch isGithub)}}True{{else}}False{{/if}}';
+    const input = { isMajor: true, isPatch: false, isReplacement: true };
+    const output = template.compile(userTemplate, input);
+    expect(output).toContain('False');
+  });
+  it('or returns true when at least one is true', () => {
+    const userTemplate =
+      '{{#if (or isMajor isPatch isReplacement)}}True{{else}}False{{/if}}';
+    const input = { isMajor: false, isPatch: true, isReplacement: false };
+    const output = template.compile(userTemplate, input);
+    expect(output).toContain('True');
+  });
+  it('or returns false when all are false', () => {
+    const userTemplate =
+      '{{#if (or isMajor isPatch isReplacement)}}True{{else}}False{{/if}}';
+    const input = { isMajor: false, isPatch: false, isReplacement: false };
+    const output = template.compile(userTemplate, input);
+    expect(output).toContain('False');
+  });
   it('string to pretty JSON ', () => {
     const userTemplate =
       '{{{ stringToPrettyJSON \'{"some":{"fancy":"json"}}\'}}}';
diff --git a/lib/util/template/index.ts b/lib/util/template/index.ts
index 344c398da5..a57d8fd43e 100644
--- a/lib/util/template/index.ts
+++ b/lib/util/template/index.ts
@@ -17,6 +17,25 @@ handlebars.registerHelper(
     (context || '').replace(new RegExp(find, 'g'), replace) // TODO #12873
 );
 
+handlebars.registerHelper('containsString', (str, subStr, options) =>
+  str.includes(subStr)
+);
+
+handlebars.registerHelper({
+  and(...args) {
+    // Need to remove the 'options', as last parameter
+    // https://handlebarsjs.com/api-reference/helpers.html
+    args.pop();
+    return args.every(Boolean);
+  },
+  or(...args) {
+    // Need to remove the 'options', as last parameter
+    // https://handlebarsjs.com/api-reference/helpers.html
+    args.pop();
+    return args.some(Boolean);
+  },
+});
+
 export const exposedConfigOptions = [
   'additionalBranchPrefix',
   'addLabels',
-- 
GitLab