Compare commits

..

3 Commits

Author SHA1 Message Date
Julien Fontanet
10093afb91 feat(cron): 1.0.1 2018-02-19 17:06:17 +01:00
Julien Fontanet
58032738b9 chore(cron): replace luxon with moment-timezone (#2657) 2018-02-19 17:04:04 +01:00
Julien Fontanet
89cbbaeeea chore: fix yarn.lock 2018-02-19 15:52:17 +01:00
12 changed files with 56 additions and 67 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@xen-orchestra/cron",
"version": "1.0.0",
"version": "1.0.1",
"license": "ISC",
"description": "Focused, well maintained, cron parser/scheduler",
"keywords": [
@@ -38,7 +38,7 @@
},
"dependencies": {
"lodash": "^4.17.4",
"luxon": "^0.5.2"
"moment-timezone": "^0.5.14"
},
"devDependencies": {
"@babel/cli": "7.0.0-beta.40",

View File

@@ -1,4 +1,4 @@
import { DateTime } from 'luxon'
import moment from 'moment-timezone'
import next from './next'
import parse from './parse'
@@ -41,7 +41,10 @@ class Job {
class Schedule {
constructor (pattern, zone = 'utc') {
this._schedule = parse(pattern)
this._dateTimeOpts = { zone }
this._createDate =
zone.toLowerCase() === 'utc'
? moment.utc
: zone === 'local' ? moment : () => moment.tz(zone)
}
createJob (fn) {
@@ -51,7 +54,7 @@ class Schedule {
next (n) {
const dates = new Array(n)
const schedule = this._schedule
let date = DateTime.fromObject(this._dateTimeOpts)
let date = this._createDate()
for (let i = 0; i < n; ++i) {
dates[i] = (date = next(schedule, date)).toJSDate()
}
@@ -59,7 +62,7 @@ class Schedule {
}
_nextDelay () {
const now = DateTime.fromObject(this._dateTimeOpts)
const now = this._createDate()
return next(this._schedule, now) - now
}

View File

@@ -1,10 +1,10 @@
import moment from 'moment-timezone'
import sortedIndex from 'lodash/sortedIndex'
import { DateTime } from 'luxon'
const NEXT_MAPPING = {
month: { year: 1 },
day: { month: 1 },
weekday: { week: 1 },
date: { month: 1 },
day: { week: 1 },
hour: { day: 1 },
minute: { hour: 1 },
}
@@ -13,38 +13,37 @@ const getFirst = values => (values !== undefined ? values[0] : 0)
const setFirstAvailable = (date, unit, values) => {
if (values === undefined) {
return date
return
}
const curr = date.get(unit)
const next = values[sortedIndex(values, curr) % values.length]
if (curr === next) {
return date
return
}
const newDate = date.set({ [unit]: next })
return newDate > date ? newDate : newDate.plus(NEXT_MAPPING[unit])
const timestamp = +date
date.set(unit, next)
if (timestamp > +date) {
date.add(NEXT_MAPPING[unit])
}
return true
}
// returns the next run, after the passed date
export default (schedule, fromDate) => {
let date = fromDate
let date = moment(fromDate)
.set({
second: 0,
millisecond: 0,
})
.plus({ minute: 1 })
.add({ minute: 1 })
const { minute, hour, dayOfMonth, month, dayOfWeek } = schedule
date = setFirstAvailable(date, 'minute', minute)
setFirstAvailable(date, 'minute', minute)
let tmp
tmp = setFirstAvailable(date, 'hour', hour)
if (tmp !== date) {
date = tmp.set({
minute: getFirst(minute),
})
if (setFirstAvailable(date, 'hour', hour)) {
date.set('minute', getFirst(minute))
}
let loop
@@ -52,30 +51,30 @@ export default (schedule, fromDate) => {
do {
loop = false
tmp = setFirstAvailable(date, 'month', month)
if (tmp !== date) {
date = tmp.set({
day: 1,
if (setFirstAvailable(date, 'month', month)) {
date.set({
date: 1,
hour: getFirst(hour),
minute: getFirst(minute),
})
}
let newDate = date.clone()
if (dayOfMonth === undefined) {
if (dayOfWeek !== undefined) {
tmp = setFirstAvailable(date, 'weekday', dayOfWeek)
setFirstAvailable(newDate, 'day', dayOfWeek)
}
} else if (dayOfWeek === undefined) {
tmp = setFirstAvailable(date, 'day', dayOfMonth)
setFirstAvailable(newDate, 'date', dayOfMonth)
} else {
tmp = DateTime.min(
setFirstAvailable(date, 'day', dayOfMonth),
setFirstAvailable(date, 'weekday', dayOfWeek)
)
const dateDay = newDate.clone()
setFirstAvailable(dateDay, 'date', dayOfMonth)
setFirstAvailable(newDate, 'day', dayOfWeek)
newDate = moment.min(dateDay, newDate)
}
if (tmp !== date) {
loop = tmp.month !== date.month
date = tmp.set({
if (+date !== +newDate) {
loop = date.month() !== newDate.month()
date = newDate.set({
hour: getFirst(hour),
minute: getFirst(minute),
})

View File

@@ -1,17 +1,15 @@
/* eslint-env jest */
import mapValues from 'lodash/mapValues'
import { DateTime } from 'luxon'
import moment from 'moment-timezone'
import next from './next'
import parse from './parse'
const N = (pattern, fromDate = '2018-04-09T06:25') =>
next(parse(pattern), DateTime.fromISO(fromDate, { zone: 'utc' })).toISO({
includeOffset: false,
suppressMilliseconds: true,
suppressSeconds: true,
})
const N = (pattern, fromDate = '2018-04-09T06:25') => {
const iso = next(parse(pattern), moment.utc(fromDate)).toISOString()
return iso.slice(0, iso.lastIndexOf(':'))
}
describe('next()', () => {
mapValues(

View File

@@ -173,12 +173,7 @@ export default createParser({
{
aliases: 'jan feb mar apr may jun jul aug sep oct nov dec'.split(' '),
name: 'month',
range: [1, 12],
// this function is applied to numeric entries (not steps)
//
// currently parse month 0-11
post: value => value + 1,
range: [0, 11],
},
{
aliases: 'mon tue wen thu fri sat sun'.split(' '),

View File

@@ -8,16 +8,16 @@ describe('parse()', () => {
minute: [0],
hour: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
dayOfMonth: [1, 11, 21, 31],
month: [1, 3, 5, 8, 11],
month: [0, 2, 4, 7, 10],
})
})
it('correctly parse months', () => {
expect(parse('* * * 0,11 *')).toEqual({
month: [1, 12],
month: [0, 11],
})
expect(parse('* * * jan,dec *')).toEqual({
month: [1, 12],
month: [0, 11],
})
})

View File

@@ -30,7 +30,7 @@
"node": ">=4"
},
"dependencies": {
"@xen-orchestra/cron": "^1.0.0",
"@xen-orchestra/cron": "^1.0.1",
"babel-runtime": "^6.11.6",
"lodash": "^4.16.2"
},

View File

@@ -20,7 +20,7 @@
"node": ">=6"
},
"dependencies": {
"@xen-orchestra/cron": "^1.0.0",
"@xen-orchestra/cron": "^1.0.1",
"d3-time-format": "^2.1.1",
"json5": "^0.5.1",
"lodash": "^4.17.4"

View File

@@ -34,7 +34,7 @@
"node": ">=4"
},
"dependencies": {
"@xen-orchestra/cron": "^1.0.0",
"@xen-orchestra/cron": "^1.0.1",
"babel-runtime": "^6.23.0",
"handlebars": "^4.0.6",
"html-minifier": "^3.5.8",

View File

@@ -34,7 +34,7 @@
"dependencies": {
"@marsaud/smb2-promise": "^0.2.1",
"@nraynaud/struct-fu": "^1.0.1",
"@xen-orchestra/cron": "^1.0.0",
"@xen-orchestra/cron": "^1.0.1",
"ajv": "^6.1.1",
"app-conf": "^0.5.0",
"archiver": "^2.1.0",

View File

@@ -31,7 +31,7 @@
},
"devDependencies": {
"@nraynaud/novnc": "0.6.1",
"@xen-orchestra/cron": "^1.0.0",
"@xen-orchestra/cron": "^1.0.1",
"ansi_up": "^2.0.2",
"asap": "^2.0.6",
"babel-core": "^6.26.0",

View File

@@ -4957,10 +4957,6 @@ ftp@~0.3.10:
readable-stream "1.1.x"
xregexp "2.0.0"
full-icu@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/full-icu/-/full-icu-1.2.0.tgz#6bd8bf565f696aab30df503de2d47b92d9f1046f"
function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@@ -7518,12 +7514,6 @@ ltx@^2.5.0, ltx@^2.6.2:
dependencies:
inherits "^2.0.1"
luxon@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/luxon/-/luxon-0.5.2.tgz#80d93f8e8a30e3a5bafa1d05a464872920e08be1"
dependencies:
full-icu "^1.2.0"
make-dir@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51"
@@ -11497,6 +11487,10 @@ validate-npm-package-license@^3.0.1:
spdx-correct "~1.0.0"
spdx-expression-parse "~1.0.0"
value-matcher@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/value-matcher/-/value-matcher-0.1.0.tgz#4e42230385ca4fb90fc2c9c7f5e0f8a89ace1048"
value-or-function@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813"