Update to cron v3, ability to show next issues creation timestamps and little refactor.
This commit is contained in:
		
							
								
								
									
										5
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
									
									
									
									
								
							| @@ -12,6 +12,11 @@ run: | ||||
| 	GPT_CONFIG=$(CONFIG) ./periodicator | ||||
| 	rm periodicator | ||||
|  | ||||
| run-show-next-creation-ts: | ||||
| 	go build -ldflags $(LINKER_FLAGS) -o periodicator . | ||||
| 	GPT_CONFIG=$(CONFIG) ./periodicator -show-next-creation-ts | ||||
| 	rm periodicator | ||||
|  | ||||
| run-version: | ||||
| 	go build -ldflags $(LINKER_FLAGS) -o periodicator . | ||||
| 	GPT_CONFIG=$(CONFIG) ./periodicator -version | ||||
|   | ||||
							
								
								
									
										3
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								go.mod
									
									
									
									
									
								
							| @@ -3,12 +3,13 @@ module go.dev.pztrn.name/periodicator | ||||
| go 1.17 | ||||
|  | ||||
| require ( | ||||
| 	github.com/robfig/cron v1.2.0 | ||||
| 	github.com/robfig/cron/v3 v3.0.1 | ||||
| 	github.com/xanzy/go-gitlab v0.51.1 | ||||
| 	gopkg.in/yaml.v2 v2.2.2 | ||||
| ) | ||||
|  | ||||
| require ( | ||||
| 	github.com/adhocore/gronx v0.2.5 // indirect | ||||
| 	github.com/golang/protobuf v1.5.2 // indirect | ||||
| 	github.com/google/go-querystring v1.1.0 // indirect | ||||
| 	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect | ||||
|   | ||||
							
								
								
									
										6
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								go.sum
									
									
									
									
									
								
							| @@ -33,6 +33,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 | ||||
| dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= | ||||
| github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||||
| github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= | ||||
| github.com/adhocore/gronx v0.2.5 h1:trVgNYPle0IcsGDt0XGz78zN8Soek0YrcQtQ+Cs+jko= | ||||
| github.com/adhocore/gronx v0.2.5/go.mod h1:7oUY1WAU8rEJWmAxXR2DN0JaO4gi9khSgKjiRypqteg= | ||||
| github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= | ||||
| github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= | ||||
| github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= | ||||
| @@ -125,8 +127,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||
| github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | ||||
| github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= | ||||
| github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= | ||||
| github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= | ||||
| github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= | ||||
| github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import ( | ||||
| 	"log" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/robfig/cron" | ||||
| 	"github.com/robfig/cron/v3" | ||||
| 	g "github.com/xanzy/go-gitlab" | ||||
| 	"go.dev.pztrn.name/periodicator/internal/gitlab" | ||||
| ) | ||||
| @@ -39,6 +39,37 @@ func (b *BaseTask) checkIfOpenedTaskExists(issues []*g.Issue) bool { | ||||
| 	return foundAndNotClosed | ||||
| } | ||||
|  | ||||
| func (b *BaseTask) getIssues() ([]*g.Issue, error) { | ||||
| 	// nolint:wrapcheck | ||||
| 	return b.client.GetIssuesByTitle(b.projectID, b.title) | ||||
| } | ||||
|  | ||||
| func (b *BaseTask) getLastCreationTimestamp(issues []*g.Issue) time.Time { | ||||
| 	lastTaskCreationTS := b.executionStartTimestamp | ||||
|  | ||||
| 	for _, issue := range issues { | ||||
| 		if issue.ClosedAt != nil && issue.CreatedAt.After(lastTaskCreationTS) { | ||||
| 			lastTaskCreationTS = *issue.CreatedAt | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return lastTaskCreationTS | ||||
| } | ||||
|  | ||||
| func (b *BaseTask) getNextCreationTimestamp(lastTaskCreationTS time.Time) time.Time { | ||||
| 	// Set up cron job parser. | ||||
| 	cp := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow) | ||||
|  | ||||
| 	schedule, err := cp.Parse(b.cron) | ||||
| 	if err != nil { | ||||
| 		b.log("Failed to parse cron string: " + err.Error()) | ||||
|  | ||||
| 		return lastTaskCreationTS | ||||
| 	} | ||||
|  | ||||
| 	return schedule.Next(lastTaskCreationTS) | ||||
| } | ||||
|  | ||||
| func (b *BaseTask) log(message string) { | ||||
| 	log.Println("Task '" + b.title + "': " + message) | ||||
| } | ||||
| @@ -46,7 +77,7 @@ func (b *BaseTask) log(message string) { | ||||
| // Run executes task procedure. | ||||
| func (b *BaseTask) Run() { | ||||
| 	// Get similar tasks. | ||||
| 	issues, err := b.client.GetIssuesByTitle(b.projectID, b.title) | ||||
| 	issues, err := b.getIssues() | ||||
| 	if err != nil { | ||||
| 		b.log("Error while getting issues from Gitlab: " + err.Error()) | ||||
|  | ||||
| @@ -65,29 +96,16 @@ func (b *BaseTask) Run() { | ||||
| 	b.log("No still opened tasks found, checking if we should create new one...") | ||||
|  | ||||
| 	// Get latest task creation timestamp from Gitlab. | ||||
| 	lastTaskCreationTS := b.executionStartTimestamp | ||||
|  | ||||
| 	for _, issue := range issues { | ||||
| 		if issue.ClosedAt != nil && issue.CreatedAt.After(lastTaskCreationTS) { | ||||
| 			lastTaskCreationTS = *issue.CreatedAt | ||||
| 		} | ||||
| 	} | ||||
| 	lastTaskCreationTS := b.getLastCreationTimestamp(issues) | ||||
|  | ||||
| 	b.log("Last task creation timestamp: " + lastTaskCreationTS.String()) | ||||
|  | ||||
| 	// Set up cron job parser. | ||||
| 	cp := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow) | ||||
|  | ||||
| 	schedule, err := cp.Parse(b.cron) | ||||
| 	if err != nil { | ||||
| 		b.log("Failed to parse cron string: " + err.Error()) | ||||
|  | ||||
| 	// Figure out next task creation and deadline timestamps. | ||||
| 	nextCreationTS := b.getNextCreationTimestamp(lastTaskCreationTS) | ||||
| 	if nextCreationTS.Equal(lastTaskCreationTS) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// Figure out next task creation and deadline timestamps. | ||||
| 	nextCreationTS := schedule.Next(lastTaskCreationTS) | ||||
|  | ||||
| 	// Check if task should be created and create if so. | ||||
| 	if nextCreationTS.Before(time.Now()) { | ||||
| 		// Deadlines should be calculated until first one will appear AFTER today. | ||||
|   | ||||
| @@ -4,6 +4,31 @@ import ( | ||||
| 	"go.dev.pztrn.name/periodicator/internal/gitlab" | ||||
| ) | ||||
|  | ||||
| // PrintCreationTSes prints tasks creation timestamps. | ||||
| func PrintCreationTSes(client *gitlab.Client, tasks []Config) { | ||||
| 	for _, task := range tasks { | ||||
| 		t := &BaseTask{ | ||||
| 			client:                  client, | ||||
| 			projectID:               task.ProjectID, | ||||
| 			title:                   task.Title, | ||||
| 			body:                    task.Body, | ||||
| 			tags:                    task.Tags, | ||||
| 			executionStartTimestamp: task.ExecutionStart.GetTimestamp(), | ||||
| 			cron:                    task.Cron, | ||||
| 			dueIn:                   task.DueIn, | ||||
| 		} | ||||
|  | ||||
| 		// Get similar tasks. | ||||
| 		// ToDo: refactor? | ||||
| 		issues, err := t.getIssues() | ||||
| 		if err != nil { | ||||
| 			panic("Error while getting issues from Gitlab: " + err.Error()) | ||||
| 		} | ||||
|  | ||||
| 		t.log(t.getNextCreationTimestamp(t.getLastCreationTimestamp(issues)).String()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Process processes passed tasks. | ||||
| func Process(client *gitlab.Client, tasks []Config) { | ||||
| 	for _, task := range tasks { | ||||
|   | ||||
							
								
								
									
										10
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								main.go
									
									
									
									
									
								
							| @@ -11,7 +11,10 @@ import ( | ||||
| 	"go.dev.pztrn.name/periodicator/internal/tasks" | ||||
| ) | ||||
|  | ||||
| var showVersion = flag.Bool("version", false, "Show version information and exit") | ||||
| var ( | ||||
| 	showNextCreationTS = flag.Bool("show-next-creation-ts", false, "Show tasks next creation timestamps") | ||||
| 	showVersion        = flag.Bool("version", false, "Show version information and exit") | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	flag.Parse() | ||||
| @@ -28,5 +31,10 @@ func main() { | ||||
|  | ||||
| 	c := gitlab.NewGitlabClient(&cfg.Gitlab) | ||||
|  | ||||
| 	if *showNextCreationTS { | ||||
| 		tasks.PrintCreationTSes(c, cfg.Tasks) | ||||
| 		os.Exit(0) | ||||
| 	} | ||||
|  | ||||
| 	tasks.Process(c, cfg.Tasks) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user