Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use cron-parser #23142

Merged
merged 9 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/usage/configuration-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -3367,7 +3367,7 @@ To restrict `aws-sdk` to only monthly updates, you could add this package rule:

Technical details: We mostly rely on the text parsing of the library [@breejs/later](https://github.com/breejs/later) but only its concepts of "days", "time_before", and "time_after".
Read the parser documentation at [breejs.github.io/later/parsers.html#text](https://breejs.github.io/later/parsers.html#text).
To parse Cron syntax, Renovate uses [@cheap-glitch/mi-cron](https://github.com/cheap-glitch/mi-cron).
To parse Cron syntax, Renovate uses [cron-parser](https://github.com/harrisiirak/cron-parser).
Renovate does not support scheduled minutes or "at an exact time" granularity.

<!-- prettier-ignore -->
Expand Down
2 changes: 2 additions & 0 deletions lib/workers/repository/update/branch/schedule.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ describe('workers/repository/update/branch/schedule', () => {

it('returns true if schedule uses cron syntax', () => {
expect(schedule.hasValidSchedule(['* 5 * * *'])[0]).toBeTrue();
expect(schedule.hasValidSchedule(['* * * * * 6L'])[0]).toBeTrue();
expect(schedule.hasValidSchedule(['* * */2 6#1'])[0]).toBeTrue();
});

it('massages schedules', () => {
Expand Down
36 changes: 29 additions & 7 deletions lib/workers/repository/update/branch/schedule.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import later from '@breejs/later';
import { parseCron } from '@cheap-glitch/mi-cron';
import is from '@sindresorhus/is';
import {
CronExpression,
DayOfTheMonthRange,
DayOfTheWeekRange,
HourRange,
MonthRange,
parseExpression,
} from 'cron-parser';
import { DateTime } from 'luxon';
import { fixShortHours } from '../../../../config/migration';
import type { RenovateConfig } from '../../../../config/types';
Expand All @@ -13,6 +20,14 @@ const scheduleMappings: Record<string, string> = {
monthly: 'before 5am on the first day of the month',
};

function parseCron(scheduleText: string): CronExpression | undefined {
try {
return parseExpression(scheduleText);
rarkins marked this conversation as resolved.
Show resolved Hide resolved
} catch (err) {
return undefined;
}
}

export function hasValidTimezone(timezone: string): [true] | [false, string] {
if (!DateTime.local().setZone(timezone).isValid) {
return [false, `Invalid schedule: Unsupported timezone ${timezone}`];
Expand All @@ -36,7 +51,7 @@ export function hasValidSchedule(
const parsedCron = parseCron(scheduleText);
if (parsedCron !== undefined) {
if (
parsedCron.minutes.length !== 60 ||
parsedCron.fields.minute.length !== 60 ||
scheduleText.indexOf(minutesChar) !== 0
) {
message = `Invalid schedule: "${scheduleText}" has cron syntax, but doesn't have * as minutes`;
Expand Down Expand Up @@ -83,27 +98,34 @@ export function hasValidSchedule(
function cronMatches(cron: string, now: DateTime): boolean {
const parsedCron = parseCron(cron);

// istanbul ignore if: doesn't return undefined but type will include undefined
// it will always parse because it is checked beforehand
// istanbul ignore if
if (!parsedCron) {
return false;
}

if (parsedCron.hours.indexOf(now.hour) === -1) {
if (parsedCron.fields.hour.indexOf(now.hour as HourRange) === -1) {
// Hours mismatch
return false;
}

if (parsedCron.days.indexOf(now.day) === -1) {
if (
parsedCron.fields.dayOfMonth.indexOf(now.day as DayOfTheMonthRange) === -1
) {
// Days mismatch
return false;
}

if (!parsedCron.weekDays.includes(now.weekday % 7)) {
if (
!parsedCron.fields.dayOfWeek.includes(
(now.weekday % 7) as DayOfTheWeekRange
)
) {
// Weekdays mismatch
return false;
}

if (parsedCron.months.indexOf(now.month) === -1) {
if (parsedCron.fields.month.indexOf(now.month as MonthRange) === -1) {
// Months mismatch
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@
"@aws-sdk/client-s3": "3.363.0",
"@breejs/later": "4.1.0",
"@cdktf/hcl2json": "0.17.1",
"@cheap-glitch/mi-cron": "1.0.1",
"@iarna/toml": "3.0.0",
"@opentelemetry/api": "1.4.1",
"@opentelemetry/context-async-hooks": "1.14.0",
Expand Down Expand Up @@ -180,6 +179,7 @@
"clean-git-ref": "2.0.1",
"commander": "11.0.0",
"conventional-commits-detector": "1.0.3",
"cron-parser": "4.8.1",
rarkins marked this conversation as resolved.
Show resolved Hide resolved
"deepmerge": "4.3.1",
"dequal": "2.0.3",
"detect-indent": "6.1.0",
Expand Down
14 changes: 8 additions & 6 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1354,11 +1354,6 @@
dependencies:
fs-extra "^11.1.1"

"@cheap-glitch/mi-cron@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@cheap-glitch/mi-cron/-/mi-cron-1.0.1.tgz#111f4ce746c269aedf74533ac806881763a68f99"
integrity sha512-kxl7vhg+SUgyHRn22qVbR9MfSm5CzdlYZDJTbGemqFFi/Jmno/hdoQIvBIPoqFY9dcPyxzOUNRRFn6x88UQMpw==

"@chevrotain/types@^9.1.0":
version "9.1.0"
resolved "https://registry.yarnpkg.com/@chevrotain/types/-/types-9.1.0.tgz#689f2952be5ad9459dae3c8e9209c0f4ec3c5ec4"
Expand Down Expand Up @@ -4872,6 +4867,13 @@ create-require@^1.1.0:
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==

cron-parser@4.8.1:
version "4.8.1"
resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-4.8.1.tgz#47062ea63d21d78c10ddedb08ea4c5b6fc2750fb"
integrity sha512-jbokKWGcyU4gl6jAfX97E1gDpY12DJ1cLJZmoDzaAln/shZ+S3KBFBuA2Q6WeUN4gJf/8klnV1EfvhA2lK5IRQ==
dependencies:
luxon "^3.2.1"

cross-env@7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
Expand Down Expand Up @@ -7840,7 +7842,7 @@ lru-cache@^9.0.0:
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61"
integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==

luxon@3.3.0, luxon@^3.3.0:
luxon@3.3.0, luxon@^3.2.1, luxon@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.3.0.tgz#d73ab5b5d2b49a461c47cedbc7e73309b4805b48"
integrity sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==
Expand Down