Commit 28cf6985 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '339785-new-cron-library' into 'master'

Add library to convert cron to human readable

See merge request gitlab-org/gitlab!74450
parents 27e5d7a3 dc1a952e
...@@ -65,5 +65,7 @@ More examples of how to write a cron schedule can be found at ...@@ -65,5 +65,7 @@ More examples of how to write a cron schedule can be found at
## How GitLab parses cron syntax strings ## How GitLab parses cron syntax strings
GitLab uses [`fugit`](https://github.com/floraison/fugit) to parse cron syntax GitLab uses [`fugit`](https://github.com/floraison/fugit) to parse cron syntax
strings on the server and [cron-validate](https://github.com/Airfooox/cron-validate) strings on the server and [cron-validator](https://github.com/TheCloudConnectors/cron-validator)
to validate cron syntax in the browser. to validate cron syntax in the browser. GitLab uses
[`cRonstrue`](https://github.com/bradymholt/cRonstrue) to convert cron to human-readable strings
in the browser.
import cronstrue from 'cronstrue/i18n';
import { convertToTitleCase, humanize } from '~/lib/utils/text_utility'; import { convertToTitleCase, humanize } from '~/lib/utils/text_utility';
import { sprintf, s__, n__ } from '~/locale'; import { getPreferredLocales, sprintf, s__, n__ } from '~/locale';
import { NO_RULE_MESSAGE } from './constants'; import { NO_RULE_MESSAGE } from './constants';
const getActionText = (scanType) => const getActionText = (scanType) =>
...@@ -33,7 +34,9 @@ const humanizeBranches = (originalBranches) => { ...@@ -33,7 +34,9 @@ const humanizeBranches = (originalBranches) => {
}; };
const humanizeCadence = (cadence) => { const humanizeCadence = (cadence) => {
return cadence; return cronstrue
.toString(cadence, { locale: getPreferredLocales()[0], verbose: true })
.toLowerCase();
}; };
const humanizePipelineRule = (rule) => { const humanizePipelineRule = (rule) => {
...@@ -44,10 +47,10 @@ const humanizePipelineRule = (rule) => { ...@@ -44,10 +47,10 @@ const humanizePipelineRule = (rule) => {
}; };
const humanizeScheduleRule = (rule) => { const humanizeScheduleRule = (rule) => {
return sprintf( return sprintf(s__('SecurityOrchestration|Scan to be performed %{cadence} on the %{branches}'), {
s__('SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}'), cadence: humanizeCadence(rule.cadence),
{ cadence: humanizeCadence(rule.cadence), branches: humanizeBranches(rule.branches) }, branches: humanizeBranches(rule.branches),
); });
}; };
const HUMANIZE_RULES_METHODS = { const HUMANIZE_RULES_METHODS = {
......
...@@ -34,6 +34,11 @@ describe('humanizeActions', () => { ...@@ -34,6 +34,11 @@ describe('humanizeActions', () => {
}); });
describe('humanizeRules', () => { describe('humanizeRules', () => {
beforeEach(() => {
// Need to spy on window.navigator.languages as it is read-only
jest.spyOn(window.navigator, 'languages', 'get').mockReturnValueOnce(['en']);
});
it('returns the empty rules message in an Array if no rules are specified', () => { it('returns the empty rules message in an Array if no rules are specified', () => {
expect(humanizeRules([])).toStrictEqual([NO_RULE_MESSAGE]); expect(humanizeRules([])).toStrictEqual([NO_RULE_MESSAGE]);
}); });
...@@ -44,13 +49,13 @@ describe('humanizeRules', () => { ...@@ -44,13 +49,13 @@ describe('humanizeRules', () => {
it('returns a single rule as a human-readable string', () => { it('returns a single rule as a human-readable string', () => {
expect(humanizeRules([mockRules[0]])).toStrictEqual([ expect(humanizeRules([mockRules[0]])).toStrictEqual([
'Scan to be performed every */10 * * * * on the main branch', 'Scan to be performed every 10 minutes, every hour, every day on the main branch',
]); ]);
}); });
it('returns multiple rules with different number of branches as human-readable strings', () => { it('returns multiple rules with different number of branches as human-readable strings', () => {
expect(humanizeRules(mockRules)).toStrictEqual([ expect(humanizeRules(mockRules)).toStrictEqual([
'Scan to be performed every */10 * * * * on the main branch', 'Scan to be performed every 10 minutes, every hour, every day on the main branch',
'Scan to be performed on every pipeline on the release/* and staging branches', 'Scan to be performed on every pipeline on the release/* and staging branches',
'Scan to be performed on every pipeline on the release/1.*, canary and staging branches', 'Scan to be performed on every pipeline on the release/1.*, canary and staging branches',
]); ]);
......
...@@ -30807,7 +30807,7 @@ msgstr "" ...@@ -30807,7 +30807,7 @@ msgstr ""
msgid "SecurityOrchestration|Scan execution policies can only be created by project owners." msgid "SecurityOrchestration|Scan execution policies can only be created by project owners."
msgstr "" msgstr ""
msgid "SecurityOrchestration|Scan to be performed every %{cadence} on the %{branches}" msgid "SecurityOrchestration|Scan to be performed %{cadence} on the %{branches}"
msgstr "" msgstr ""
msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}" msgid "SecurityOrchestration|Scan to be performed on every pipeline on the %{branches}"
......
...@@ -3863,9 +3863,14 @@ create-require@^1.1.0: ...@@ -3863,9 +3863,14 @@ create-require@^1.1.0:
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
cron-validator@^1.1.1: cron-validator@^1.1.1:
version "1.1.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/cron-validator/-/cron-validator-1.1.1.tgz#0a27bb75508c7bc03c8b840d2d9f170eeacb5615" resolved "https://registry.yarnpkg.com/cron-validator/-/cron-validator-1.2.1.tgz#0f0de2de36d231a6ace0e43ffc6c0564fe6edf1a"
integrity sha512-vfZb05w/wezuwPZBDvdIBmJp2BvuJExHeyKRa5oBqD2ZDXR61hb3QgPc/3ZhBEQJlAy8Jlnn5XC/JCT3IDqxwg== integrity sha512-RqdpGSokGFICPc8qAkT38aXqZLLanXghQTK2q7a2x2FabSwDd2ARrazd5ElEWAXzToUcMG4cZIwDH+5RM0q1mA==
cronstrue@^1.122.0:
version "1.122.0"
resolved "https://registry.yarnpkg.com/cronstrue/-/cronstrue-1.122.0.tgz#bd6838077b476d28f61d381398b47b8c3912a126"
integrity sha512-PFuhZd+iPQQ0AWTXIEYX+t3nFGzBrWxmTWUKJOrsGRewaBSLKZ4I1f8s2kryU75nNxgyugZgiGh2OJsCTA/XlA==
cropper@^2.3.0: cropper@^2.3.0:
version "2.3.0" version "2.3.0"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment