cron_parser

package module
v0.0.0-...-e7b2d52 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 20, 2024 License: GPL-3.0 Imports: 5 Imported by: 0

README

cron_parser

Using the package

As a CLI command

Unpack the provided archive, then:

~$ go build -o cron_parser ./cmd 
~$ ./cron_parser "*/15 0 1,15 * 1-5 /usr/bin/find"
minute        0 15 30 45
hour          0
day of month  1 15
month         1 2 3 4 5 6 7 8 9 10 11 12
day of week   1 2 3 4 5
command       /usr/bin/find

As an imported library

  1. ensure the license is acceptable
  2. write your code like:
package whatever

import (
	"fmt"

	"code.osinet.fr/fgm/cron_parser"
)

func myFunc(crontabRow string) error {
	ce, err := cron_parser.ParseCron(crontabRow)
	if err != nil {
		return err
	}
	// To access the numbers in an individual selection, like hours:
	fmt.Printf("Hours: %v\n", ce.Hour.Enumerate())
	
	// To print the resolve expression
	fmt.Println(ce)
	return nil
}

Developing with the package

Running tests
~$ go test -race -count=1 -coverprofile=cover.out ./...
~$ go tool cover -html=cover.out

You should observe around 98% coverage.

Repo layout

Although the instructions do not explicitly require it, this code looks like a reusable feature, and has to be developed like one.

In such a case, the official best practice is to place the code at the repo root for easier import, and the non-importable CLI command in a cmd directory.

The third-party tests in cron_parser_robfig_test are the test cases from the popular github.com/robfig/go-cron package, published under the MIT license, thus allowing reuse. They are merged with the native test suite to ensure maximal compatibility with common expectations.

Grammar

For the purpose of this version, period selectors are described like this:

  • selector: a comma-separated list of steps, possibly degenerated to a single value
  • step: a star, or a slash-separated pair of values
    • a star is interpreted as a range min-max where min and max are the values defined for the selector to which the step belongs
    • the first member is a range
    • the second member is the step value
    • the degenerate case with a single value and no slash is interpreted as having /1 appended
  • range: a hyphen-separated pair of values
    • the degenerate case with a single value X and no hyphen is interpreted as X-X
Steps behavior

While the Vixie cron documentation, which introduces steps, is ambiguous on the starting value, only providing 0-23/2 and */2 as examples, the interpretation of the step here, as used by other parsers, is that the steps start with the first value in the specification, not in the native interval for the selector type.

In practice this means that for a days selector, where the selector type min/max are 1/31, expression 2-15/4 will generate [2 6 10 14], not [4 8 12] as would be the case if the step applied to the whole selector type range.

This is, for example the interpretation used by Elmah.io cron parser.

Licensing

Licensed under the General Public License, version 3 or later.

Test data taken from the github.com/robfig/cron package, under its MIT license.

Documentation

Overview

Package cron_parser implements a subset of the standard five-fields cron syntax.

It does not support special times like '@yearly", user names, seconds, or the "H" Jenkins notation.

It only handles Sunday == 0, not Sunday == 7.

Index

Constants

View Source
const (
	ErrEmptySpec       = ErrorString("empty spec string")
	ErrFiveFields      = ErrorString("expected 5 fields")
	ErrIntParsing      = ErrorString("failed to parse int from")
	ErrInvalidString   = ErrorString("invalid UTF-8 string")
	ErrMultipleHyphens = ErrorString("too many hyphens")
	ErrMultipleSlashes = ErrorString("too many slashes")
	ErrNeedsPositive   = ErrorString("should be a positive number")
	ErrRangeAboveMax   = ErrorString("above maximum")
	ErrRangeBelowMin   = ErrorString("below minimum")
	ErrRangeBeyond     = ErrorString("beyond end of range")

	Wildcard = "*"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type BasicSelector

type BasicSelector struct {
	Len   int    // The number of elements in the range
	Label string // The string describing the selector role
	Start byte   // The first element
	// contains filtered or unexported fields
}

BasicSelector is a struct implementation of Selector.

func (*BasicSelector) ApplySource

func (bs *BasicSelector) ApplySource(src string) error

func (*BasicSelector) Enumerate

func (bs *BasicSelector) Enumerate() []byte

func (*BasicSelector) String

func (bs *BasicSelector) String() string

type CronExpression

type CronExpression struct {
	Minute  Selector
	Hour    Selector
	Day     Selector
	Month   Selector
	Weekday Selector
	Command string
}

func ParseCron

func ParseCron(expr string) (*CronExpression, error)

func (*CronExpression) String

func (c *CronExpression) String() string

type ErrorString

type ErrorString string

ErrorString is a string used as an error.

func (ErrorString) Error

func (e ErrorString) Error() string

Error implements the builtin error interface.

type Selector

type Selector interface {
	// ApplySource completes the selector by applying a source expression to it and parsing.
	//
	// It assumes the argument to be a valid UTF-8 string.
	ApplySource(string) error

	// Enumerate emits the list of integers designated by the Selector
	Enumerate() []byte

	fmt.Stringer
}

Selector describes one of the 5 time-related fields at the beginning of crontab line.

type SelectorBuilder

type SelectorBuilder func() Selector
var (
	MinuteSelector  SelectorBuilder = func() Selector { return &BasicSelector{Len: 60, Start: 0, Label: "minute"} }
	HourSelector    SelectorBuilder = func() Selector { return &BasicSelector{Len: 24, Start: 0, Label: "hour"} }
	DaySelector     SelectorBuilder = func() Selector { return &BasicSelector{Len: 31, Start: 1, Label: "day of month"} }
	MonthSelector   SelectorBuilder = func() Selector { return &BasicSelector{Len: 12, Start: 1, Label: "month"} }
	WeekDaySelector SelectorBuilder = func() Selector { return &BasicSelector{Len: 7, Start: 0, Label: "day of week"} }
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL