mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-13 07:26:26 +00:00
146 lines
4.5 KiB
JavaScript
146 lines
4.5 KiB
JavaScript
const later = require('later');
|
|
const moment = require('moment-timezone');
|
|
|
|
module.exports = {
|
|
hasValidSchedule,
|
|
isScheduledNow,
|
|
};
|
|
|
|
function fixShortHours(input) {
|
|
return input.replace(/( \d?\d)((a|p)m)/g, '$1:00$2');
|
|
}
|
|
|
|
function hasValidSchedule(schedule) {
|
|
let message;
|
|
// check if any of the schedules fail to parse
|
|
const hasFailedSchedules = schedule.some(scheduleText => {
|
|
const massagedText = fixShortHours(scheduleText);
|
|
const parsedSchedule = later.parse.text(massagedText);
|
|
if (parsedSchedule.error !== -1) {
|
|
message = `Failed to parse schedule "${scheduleText}"`;
|
|
// It failed to parse
|
|
return true;
|
|
}
|
|
if (parsedSchedule.schedules.some(s => s.m)) {
|
|
message = `Schedule "${scheduleText}" should not specify minutes`;
|
|
return true;
|
|
}
|
|
if (
|
|
!parsedSchedule.schedules.some(
|
|
s => s.d !== undefined || s.D || s.t_a !== undefined || s.t_b
|
|
)
|
|
) {
|
|
message = `Schedule "${scheduleText}" has no days of week or time of day`;
|
|
return true;
|
|
}
|
|
// It must be OK
|
|
return false;
|
|
});
|
|
if (hasFailedSchedules) {
|
|
// If any fail then we invalidate the whole thing
|
|
return [false, message];
|
|
}
|
|
return [true];
|
|
}
|
|
|
|
function isScheduledNow(config) {
|
|
const { logger } = config;
|
|
let configSchedule = config.schedule;
|
|
logger.debug({ schedule: configSchedule }, `Checking schedule`);
|
|
if (
|
|
!configSchedule ||
|
|
configSchedule.length === 0 ||
|
|
configSchedule[0] === ''
|
|
) {
|
|
logger.debug('No schedule defined');
|
|
return true;
|
|
}
|
|
if (!Array.isArray(configSchedule)) {
|
|
logger.warn(
|
|
`config schedule is not an array: ${JSON.stringify(configSchedule)}`
|
|
);
|
|
configSchedule = [configSchedule];
|
|
}
|
|
const [validSchedule, errorMessage] = hasValidSchedule(configSchedule);
|
|
if (!validSchedule) {
|
|
logger.warn(errorMessage);
|
|
return true;
|
|
}
|
|
let now = moment();
|
|
logger.debug(`now=${now.format()}`);
|
|
// Adjust the time if repo is in a different timezone to renovate
|
|
if (config.timezone) {
|
|
// TODO: check for validity manually
|
|
now = now.tz(config.timezone);
|
|
logger.debug(`now=${now.format()}`);
|
|
}
|
|
// Get today in text form, e.g. "Monday";
|
|
const currentDay = now.format('dddd');
|
|
logger.debug(`currentDay=${currentDay}`);
|
|
// Get the number of seconds since midnight
|
|
const currentSeconds =
|
|
now.hours() * 3600 + now.minutes() * 60 + now.seconds();
|
|
logger.debug(`currentSeconds=${currentSeconds}`);
|
|
// Support a single string but massage to array for processing
|
|
logger.debug(`Checking ${configSchedule.length} schedule(s)`);
|
|
// We run if any schedule matches
|
|
const isWithinSchedule = configSchedule.some(scheduleText => {
|
|
const parsedSchedule = later.parse.text(fixShortHours(scheduleText));
|
|
logger.debug({ parsedSchedule }, `Checking schedule "${scheduleText}"`);
|
|
// Later library returns array of schedules
|
|
return parsedSchedule.schedules.some(schedule => {
|
|
// Check if days are defined
|
|
if (schedule.d) {
|
|
logger.debug({ schedule_d: schedule.d }, `schedule.d`);
|
|
// We need to compare text instead of numbers because
|
|
// 'moment' adjusts day of week for locale while 'later' does not
|
|
// later days run from 1..7
|
|
const dowMap = [
|
|
null,
|
|
'Sunday',
|
|
'Monday',
|
|
'Tuesday',
|
|
'Wednesday',
|
|
'Thursday',
|
|
'Friday',
|
|
'Saturday',
|
|
];
|
|
const scheduledDays = schedule.d.map(day => dowMap[day]);
|
|
logger.debug({ scheduledDays }, `scheduledDays`);
|
|
if (scheduledDays.indexOf(currentDay) === -1) {
|
|
logger.debug(
|
|
`Does not match schedule because ${currentDay} is not in ${scheduledDays}`
|
|
);
|
|
return false;
|
|
}
|
|
}
|
|
// Check for start time
|
|
if (schedule.t_a) {
|
|
const startSeconds = schedule.t_a[0];
|
|
if (currentSeconds < startSeconds) {
|
|
logger.debug(
|
|
`Does not match schedule because ${currentSeconds} is earlier than ${startSeconds}`
|
|
);
|
|
return false;
|
|
}
|
|
}
|
|
// Check for end time
|
|
if (schedule.t_b) {
|
|
const endSeconds = schedule.t_b[0];
|
|
if (currentSeconds > endSeconds) {
|
|
logger.debug(
|
|
`Does not match schedule because ${currentSeconds} is later than ${endSeconds}`
|
|
);
|
|
return false;
|
|
}
|
|
}
|
|
logger.debug(`Matches schedule ${scheduleText}`);
|
|
return true;
|
|
});
|
|
});
|
|
if (!isWithinSchedule) {
|
|
logger.debug('Package not scheduled');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|