// Copyright 2019 Drone IO, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package core import ( "context" "errors" "time" "github.com/gosimple/slug" "github.com/robfig/cron" ) var ( errCronExprInvalid = errors.New("Invalid Cronjob Expression") errCronNameInvalid = errors.New("Invalid Cronjob Name") errCronBranchInvalid = errors.New("Invalid Cronjob Branch") ) type ( // Cron defines a cron job. Cron struct { ID int64 `json:"id"` RepoID int64 `json:"repo_id"` Name string `json:"name"` Expr string `json:"expr"` Next int64 `json:"next"` Prev int64 `json:"prev"` Event string `json:"event"` Branch string `json:"branch"` Target string `json:"target,omitempty"` Disabled bool `json:"disabled"` Created int64 `json:"created"` Updated int64 `json:"updated"` Version int64 `json:"version"` } // CronStore persists cron information to storage. CronStore interface { // List returns a cron list from the datastore. List(context.Context, int64) ([]*Cron, error) // Ready returns a cron list from the datastore ready for execution. Ready(context.Context, int64) ([]*Cron, error) // Find returns a cron job from the datastore. Find(context.Context, int64) (*Cron, error) // FindName returns a cron job from the datastore. FindName(context.Context, int64, string) (*Cron, error) // Create persists a new cron job to the datastore. Create(context.Context, *Cron) error // Update persists an updated cron job to the datastore. Update(context.Context, *Cron) error // Delete deletes a cron job from the datastore. Delete(context.Context, *Cron) error } ) // Validate validates the required fields and formats. func (c *Cron) Validate() error { _, err := cron.Parse(c.Expr) if err != nil { return errCronExprInvalid } switch { case c.Name == "": return errCronNameInvalid case c.Name != slug.Make(c.Name): return errCronNameInvalid case c.Branch == "": return errCronBranchInvalid default: return nil } } // SetExpr sets the cron expression name and updates // the next execution date. func (c *Cron) SetExpr(expr string) error { _, err := cron.Parse(expr) if err != nil { return errCronExprInvalid } c.Expr = expr return c.Update() } // SetName sets the cronjob name. func (c *Cron) SetName(name string) { c.Name = slug.Make(name) } // Update updates the next Cron execution date. func (c *Cron) Update() error { sched, err := cron.Parse(c.Expr) if err != nil { return err } c.Next = sched.Next(time.Now()).Unix() return nil }