diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0d27038a9..5b5f975cb 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,5 +1,5 @@ #ALL -* @vikramdevtron @nishant-d @prakarsh-dt +* @vikramdevtron @nishant-d @prakarsh-dt @vivek-devtron #Github Specific diff --git a/Makefile b/Makefile index b46c73856..b7c31a836 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ TARGET_BRANCH?=main +# TARGET_BRANCH=feature-branch make dep-update-oss all: build diff --git a/chart-sync/Makefile b/chart-sync/Makefile index ac7862f4e..3e0c99669 100644 --- a/chart-sync/Makefile +++ b/chart-sync/Makefile @@ -37,7 +37,6 @@ docker-build-push: docker-build-image docker push ${REGISTRY}/chart-sync:${TAG} dep-update-oss: - go mod edit -replace=github.com/devtron-labs/common-lib=github.com/devtron-labs/devtron-services/common-lib@$(TARGET_BRANCH) \ - -replace=github.com/devtron-labs/chart-sync=github.com/devtron-labs/devtron-services/chart-sync@$(TARGET_BRANCH) + go mod edit -replace=github.com/devtron-labs/common-lib=github.com/devtron-labs/devtron-services/common-lib@$(TARGET_BRANCH) go mod tidy go mod vendor diff --git a/chart-sync/go.mod b/chart-sync/go.mod index b200ad2ac..cc18fcdc2 100644 --- a/chart-sync/go.mod +++ b/chart-sync/go.mod @@ -5,7 +5,7 @@ go 1.22.4 toolchain go1.22.6 replace ( - github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96 + github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 helm.sh/helm/v3 v3.14.3 => github.com/devtron-labs/helm/v3 v3.14.1-0.20240401080259-90238cf69e42 ) diff --git a/chart-sync/go.sum b/chart-sync/go.sum index e1dcf1021..783a482a2 100644 --- a/chart-sync/go.sum +++ b/chart-sync/go.sum @@ -54,8 +54,8 @@ github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96 h1:WVCAsCLoNNmPb+zUlf1aI2iSy1HHVpip4GxGGwBo0C0= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96/go.mod h1:t8dMjhJ1KFaGO2V9dR/cB/WIB3lQhP/wfFthEzgcW/4= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 h1:8fW1BLQ0YqIE5J8sQjKk+6pOG8JTVp/EGHYn3PM9WX4= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0/go.mod h1:KpKnF4OSpQNDJmb4wVZq3Za88ePBw4xec2GOAGRm5UQ= github.com/devtron-labs/helm/v3 v3.14.1-0.20240401080259-90238cf69e42 h1:pJmK44QaSztOiZe0iQHNf0sdy5KwkAeceydyhOG4RaY= github.com/devtron-labs/helm/v3 v3.14.1-0.20240401080259-90238cf69e42/go.mod h1:v6myVbyseSBJTzhmeE39UcPLNv6cQK6qss3dvgAySaE= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= diff --git a/chart-sync/vendor/modules.txt b/chart-sync/vendor/modules.txt index bbb392684..77e582802 100644 --- a/chart-sync/vendor/modules.txt +++ b/chart-sync/vendor/modules.txt @@ -93,7 +93,7 @@ github.com/containerd/platforms # github.com/davecgh/go-spew v1.1.1 ## explicit github.com/davecgh/go-spew/spew -# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96 +# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 ## explicit; go 1.21 github.com/devtron-labs/common-lib/helmLib/registry github.com/devtron-labs/common-lib/utils/http @@ -785,4 +785,4 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.3.0 ## explicit; go 1.12 sigs.k8s.io/yaml -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96 +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 diff --git a/ci-runner/Makefile b/ci-runner/Makefile index 1f1031acc..cd8071d1e 100644 --- a/ci-runner/Makefile +++ b/ci-runner/Makefile @@ -32,7 +32,6 @@ docker-build-push: docker-build-image dep-update-oss: - go mod edit -replace=github.com/devtron-labs/common-lib=github.com/devtron-labs/devtron-services/common-lib@$(TARGET_BRANCH) \ - -replace=github.com/devtron-labs/ci-runner=github.com/devtron-labs/devtron-services/ci-runner@$(TARGET_BRANCH) + go mod edit -replace=github.com/devtron-labs/common-lib=github.com/devtron-labs/devtron-services/common-lib@$(TARGET_BRANCH) go mod tidy go mod vendor \ No newline at end of file diff --git a/ci-runner/go.mod b/ci-runner/go.mod index d3eb4057d..faff11dbf 100644 --- a/ci-runner/go.mod +++ b/ci-runner/go.mod @@ -4,7 +4,7 @@ go 1.21 toolchain go1.21.8 -replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96 +replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 require ( github.com/Knetic/govaluate v3.0.0+incompatible diff --git a/ci-runner/go.sum b/ci-runner/go.sum index a12280aa6..a2cdc9251 100644 --- a/ci-runner/go.sum +++ b/ci-runner/go.sum @@ -57,8 +57,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96 h1:WVCAsCLoNNmPb+zUlf1aI2iSy1HHVpip4GxGGwBo0C0= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96/go.mod h1:t8dMjhJ1KFaGO2V9dR/cB/WIB3lQhP/wfFthEzgcW/4= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 h1:8fW1BLQ0YqIE5J8sQjKk+6pOG8JTVp/EGHYn3PM9WX4= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0/go.mod h1:KpKnF4OSpQNDJmb4wVZq3Za88ePBw4xec2GOAGRm5UQ= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/cli v24.0.6+incompatible h1:fF+XCQCgJjjQNIMjzaSmiKJSCcfcXb3TWTcc7GAneOY= diff --git a/ci-runner/vendor/modules.txt b/ci-runner/vendor/modules.txt index c1ea6dc23..06ec83a12 100644 --- a/ci-runner/vendor/modules.txt +++ b/ci-runner/vendor/modules.txt @@ -118,7 +118,7 @@ github.com/cespare/xxhash/v2 # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/devtron-labs/common-lib v0.19.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96 +# github.com/devtron-labs/common-lib v0.19.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 ## explicit; go 1.21 github.com/devtron-labs/common-lib/blob-storage github.com/devtron-labs/common-lib/constants @@ -841,4 +841,4 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.3.0 ## explicit; go 1.12 sigs.k8s.io/yaml -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96 +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 diff --git a/common-lib/timeRangeLib/constant.go b/common-lib/timeRangeLib/constant.go index 8a30b2154..e4ed49d03 100644 --- a/common-lib/timeRangeLib/constant.go +++ b/common-lib/timeRangeLib/constant.go @@ -31,4 +31,5 @@ const ( ToBeforeFrom ErrorMessage = "Invalid value of hourMinuteFrom or hourMinuteTo for same day ,hourMinuteFrom >hourMinuteTo" BothLessThanZeroAndFromGreaterThanTo ErrorMessage = "invalid value of DayFrom or DayTo,DayFrom and DayTo is less than zero and dayFrom > dayTo" DayFromOrToNotValid ErrorMessage = "invalid value of dayFrom or dayTo" + InvalidHourMinuteForWeeklyAndDaily ErrorMessage = "HourMinuteFrom should be less than HourMinuteTo in daily or weekly Frequency" ) diff --git a/common-lib/timeRangeLib/fixedWindowUtil_test.go b/common-lib/timeRangeLib/fixedWindowUtil_test.go index ba1c606c8..bca445a77 100644 --- a/common-lib/timeRangeLib/fixedWindowUtil_test.go +++ b/common-lib/timeRangeLib/fixedWindowUtil_test.go @@ -15,7 +15,6 @@ func TestGetWindowForFixedTime(t *testing.T) { // Define the time zones with GMT offsets locBangui, _ := time.LoadLocation("Africa/Bangui") // GMT+01:00 locParamaribo, _ := time.LoadLocation("America/Paramaribo") // GMT-03:00 - zeroTime := time.Time{} // Define test cases with different time zones testCases := []struct { name string @@ -39,8 +38,8 @@ func TestGetWindowForFixedTime(t *testing.T) { { name: "Target time in Africa/Bangui (GMT+01:00), after the range (Outside)", targetTime: time.Date(2024, 10, 14, 19, 30, 0, 0, locBangui), // 7:30 AM GMT+01 (outside) - expectedStart: time.Time{}, // zeroTime - expectedEnd: time.Time{}, // zeroTime + expectedStart: time.Date(2024, 10, 14, 10, 0, 0, 0, locBangui), // zeroTime + expectedEnd: time.Date(2024, 10, 14, 18, 0, 0, 0, locBangui), // zeroTime }, { @@ -58,8 +57,8 @@ func TestGetWindowForFixedTime(t *testing.T) { { name: "Target time in America/Paramaribo (GMT-03:00), after the range (Outside)", targetTime: time.Date(2024, 10, 14, 14, 30, 0, 0, locParamaribo), // 2:30 PM GMT-03 (outside) - expectedStart: zeroTime, // zeroTime - expectedEnd: zeroTime, // zeroTime + expectedStart: time.Date(2024, 10, 14, 6, 0, 0, 0, locParamaribo), // zeroTime + expectedEnd: time.Date(2024, 10, 14, 14, 0, 0, 0, locParamaribo), }, } diff --git a/common-lib/timeRangeLib/helperUtils.go b/common-lib/timeRangeLib/helperUtils.go index 20f4352e6..b044d55ce 100644 --- a/common-lib/timeRangeLib/helperUtils.go +++ b/common-lib/timeRangeLib/helperUtils.go @@ -48,9 +48,20 @@ func constructDateTime(hourMinute string, days int) time.Time { func isToBeforeFrom(from, to string) bool { parseHourFrom, _ := time.Parse(hourMinuteFormat, from) parsedHourTo, _ := time.Parse(hourMinuteFormat, to) - return parsedHourTo.Before(parseHourFrom) + return parsedHourTo.Before(parseHourFrom) || parsedHourTo.Equal(parseHourFrom) } func isTimeInBetween(timeCurrent, periodStart, periodEnd time.Time) bool { return (timeCurrent.After(periodStart) && timeCurrent.Before(periodEnd)) || timeCurrent.Equal(periodStart) } + +// Validate the date from and date to handle same day limits +func isDateFromBeforeTo(timeFrom, timeTo time.Time) bool { + yearFrom, monthFrom, dayFrom := timeFrom.Date() + yearTo, monthTo, dayTo := timeTo.Date() + // Create new dates without the time component for comparison + dateFrom := time.Date(yearFrom, monthFrom, dayFrom, 0, 0, 0, 0, time.UTC) + dateTo := time.Date(yearTo, monthTo, dayTo, 0, 0, 0, 0, time.UTC) + // Return true if dateFrom is strictly less than dateTo + return dateFrom.Before(dateTo) +} diff --git a/common-lib/timeRangeLib/parser.go b/common-lib/timeRangeLib/parser.go index 45ae985e5..aa90f3154 100644 --- a/common-lib/timeRangeLib/parser.go +++ b/common-lib/timeRangeLib/parser.go @@ -22,19 +22,22 @@ import ( "time" ) -func (tr TimeRange) GetTimeRangeWindow(targetTime time.Time) (nextWindowEdge time.Time, isTimeBetween bool, err error) { +func (tr TimeRange) GetTimeRangeWindow(targetTime time.Time) (nextWindowEdge time.Time, isTimeBetween, isExpired bool, err error) { err = tr.ValidateTimeRange() if err != nil { - return nextWindowEdge, false, err + return nextWindowEdge, false, false, err } windowStart, windowEnd, err := tr.getWindowForTargetTime(targetTime) if err != nil { - return nextWindowEdge, isTimeBetween, err + return nextWindowEdge, isTimeBetween, isExpired, err } if isTimeInBetween(targetTime, windowStart, windowEnd) { - return windowEnd, true, nil + return windowEnd, true, false, nil } - return windowStart, false, nil + if targetTime.After(windowEnd) { + return windowEnd, false, true, nil + } + return windowStart, false, false, nil } func (tr TimeRange) getWindowForTargetTime(targetTime time.Time) (time.Time, time.Time, error) { @@ -73,14 +76,51 @@ func (tr TimeRange) getWindowStartAndEndTime(targetTime time.Time) (time.Time, t windowStart := schedule.Next(timeMinusDuration) windowEnd = windowStart.Add(duration) + // Calculate start and end of the previous window + timeMinusPrevDuration := tr.currentTimeMinusPrevWindowDuration(targetTime, 2*prevDuration) + windowPrevStart := schedule.Next(timeMinusPrevDuration) + windowPrevEnd := windowPrevStart.Add(duration) + + // Move back through windows until `windowPrevEnd` is less than `targetTime` + for windowPrevEnd.After(targetTime) && targetTime.Before(windowEnd) { + prevDuration += prevDuration + timeMinusPrevDuration = tr.currentTimeMinusPrevWindowDuration(targetTime, prevDuration) + windowPrevStart = schedule.Next(timeMinusPrevDuration) + windowPrevEnd = windowPrevStart.Add(duration) + } + windowStart, windowEnd = tr.applyStartEndBoundary(windowStart, windowEnd) + + // edge case where targetTime is within a recurrence boundary + if windowEnd.Equal(windowStart) && targetTime.Before(windowEnd) { + return windowPrevStart, windowPrevEnd, nil + } return windowStart, windowEnd, nil } +/* +There are three possible cases for windowStart and windowEnd +relative to the defined time range (TimeFrom to TimeTo): + +1. windowStart < TimeFrom + - The window has not yet started. + +2. windowStart > TimeTo + - The occurrence has expired because the window starts after the end date. + +3. windowEnd > TimeTo + - The occurrence has expired because the window ends after the end date. + +In each case, windowStart and windowEnd represent the next occurrence calculated based on the current time. +*/ + func (tr TimeRange) applyStartEndBoundary(windowStart time.Time, windowEnd time.Time) (time.Time, time.Time) { if !tr.TimeFrom.IsZero() && windowStart.Before(tr.TimeFrom) { windowStart = tr.TimeFrom } + if !tr.TimeTo.IsZero() && windowStart.After(tr.TimeTo) { + windowStart = tr.TimeTo + } if !tr.TimeTo.IsZero() && windowEnd.After(tr.TimeTo) { windowEnd = tr.TimeTo } @@ -88,6 +128,12 @@ func (tr TimeRange) applyStartEndBoundary(windowStart time.Time, windowEnd time. } func (tr TimeRange) currentTimeMinusWindowDuration(targetTime time.Time, duration time.Duration) time.Time { + if !tr.TimeFrom.IsZero() && targetTime.Before(tr.TimeFrom) { + return tr.TimeFrom.Add(-1 * duration) + } + return targetTime.Add(-1 * duration) +} +func (tr TimeRange) currentTimeMinusPrevWindowDuration(targetTime time.Time, duration time.Duration) time.Time { return targetTime.Add(-1 * duration) } @@ -97,11 +143,25 @@ func (tr TimeRange) currentTimeMinusWindowDuration(targetTime time.Time, duratio // while tr.TimeFrom and tr.TimeTo are in GMT. Therefore, to compare them accurately, (in case of Fixed it happens) // we convert the time range to match the time zone of targetTime. func (tr TimeRange) getWindowForFixedTime(targetTime time.Time) (time.Time, time.Time) { - var windowStartOrEnd time.Time timeFromInLocation := tr.TimeFrom.In(targetTime.Location()) timeToInLocation := tr.TimeTo.In(targetTime.Location()) - if targetTime.After(timeToInLocation) { - return windowStartOrEnd, windowStartOrEnd - } return timeFromInLocation, timeToInLocation } +func (tr TimeRange) SanitizeTimeFromAndTo(loc *time.Location) TimeRange { + if !tr.TimeFrom.IsZero() { + // Update TimeFrom with the parsed hour and minute while keeping date and location + tr.TimeFrom = time.Date( + tr.TimeFrom.Year(), tr.TimeFrom.Month(), tr.TimeFrom.Day(), + 0, 0, 0, 1, loc, + ) + + } + if !tr.TimeTo.IsZero() { + // Update TimeTo with the parsed hour and minute while keeping date and location + tr.TimeTo = time.Date( + tr.TimeTo.Year(), tr.TimeTo.Month(), tr.TimeTo.Day(), + 23, 59, 59, 0, loc, + ) + } + return tr +} diff --git a/common-lib/timeRangeLib/parser_test.go b/common-lib/timeRangeLib/parser_test.go index aa972d0ef..1a16facbf 100644 --- a/common-lib/timeRangeLib/parser_test.go +++ b/common-lib/timeRangeLib/parser_test.go @@ -22,247 +22,367 @@ import ( ) func TestGetScheduleSpec_FixedFrequency(t *testing.T) { - // Define test cases + testCases := []struct { description string timeRange TimeRange targetTime time.Time expectedWindowEdge time.Time expectedIsBetween bool + expectedIsExpired bool + expectErr bool }{ { - - description: "Target time outside the time range", + description: "Target time within the time range", timeRange: TimeRange{ - TimeFrom: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.Local), - TimeTo: time.Date(2024, time.February, 26, 17, 0, 0, 0, time.Local), + TimeFrom: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.UTC), + TimeTo: time.Date(2024, time.February, 26, 17, 0, 0, 0, time.UTC), Frequency: Fixed, }, - targetTime: time.Date(2024, time.Month(2), 26, 18, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, - expectedIsBetween: false, + targetTime: time.Date(2024, time.February, 26, 10, 0, 0, 0, time.UTC), + expectedWindowEdge: time.Date(2024, time.February, 26, 17, 0, 0, 0, time.UTC), + expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time outside the time range", + description: "Target time before the time range", timeRange: TimeRange{ - TimeFrom: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.Local), - TimeTo: time.Date(2024, time.February, 26, 7, 0, 0, 0, time.Local), + TimeFrom: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.UTC), + TimeTo: time.Date(2024, time.February, 26, 17, 0, 0, 0, time.UTC), Frequency: Fixed, }, - targetTime: time.Date(2024, time.Month(2), 26, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, + targetTime: time.Date(2024, time.February, 26, 7, 0, 0, 0, time.UTC), + expectedWindowEdge: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.UTC), expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time before the time range", + description: "Target time after the time range", timeRange: TimeRange{ - TimeFrom: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.Local), - TimeTo: time.Date(2024, time.February, 26, 11, 0, 0, 0, time.Local), + TimeFrom: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.UTC), + TimeTo: time.Date(2024, time.February, 26, 17, 0, 0, 0, time.UTC), Frequency: Fixed, }, - targetTime: time.Date(2024, time.February, 26, 7, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.February, 26, 18, 0, 0, 0, time.UTC), + expectedWindowEdge: time.Date(2024, time.February, 26, 17, 0, 0, 0, time.UTC), expectedIsBetween: false, + expectedIsExpired: true, + expectErr: false, }, { - description: "Target time outside the time range and TimeFrom is equal to TimeTo", + description: "Invalid time range (TimeFrom after TimeTo)", timeRange: TimeRange{ - TimeFrom: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.Local), - TimeTo: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.Local), + TimeFrom: time.Date(2024, time.February, 26, 18, 0, 0, 0, time.UTC), + TimeTo: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.UTC), Frequency: Fixed, }, - targetTime: time.Date(2024, time.Month(2), 26, 07, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.February, 26, 10, 0, 0, 0, time.UTC), expectedWindowEdge: time.Time{}, expectedIsBetween: false, + expectedIsExpired: false, + expectErr: true, }, { - description: "Target time ", + description: "Target time exactly at TimeFrom boundary", timeRange: TimeRange{ - TimeFrom: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.Local), - TimeTo: time.Date(2024, time.February, 26, 11, 0, 0, 0, time.Local), + TimeFrom: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.UTC), + TimeTo: time.Date(2024, time.February, 26, 17, 0, 0, 0, time.UTC), Frequency: Fixed, }, - targetTime: time.Date(2024, time.Month(2), 26, 9, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.February, 26, 11, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.UTC), + expectedWindowEdge: time.Date(2024, time.February, 26, 17, 0, 0, 0, time.UTC), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, + { - description: "Target time within the time range", + description: "Target time within daily window", timeRange: TimeRange{ - HourMinuteFrom: "08:00", - HourMinuteTo: "17:00", + TimeFrom: time.Date(2024, time.October, 2, 0, 0, 0, 0, time.UTC), + TimeTo: time.Date(2024, time.October, 13, 0, 0, 0, 0, time.UTC), Frequency: Daily, + HourMinuteFrom: "02:00", + HourMinuteTo: "18:00", }, - targetTime: time.Date(2024, time.Month(2), 26, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 26, 17, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.October, 3, 10, 0, 0, 0, time.UTC), + expectedWindowEdge: time.Date(2024, time.October, 3, 18, 0, 0, 0, time.UTC), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time inside the time range for same start and end", + description: "Target time before daily window", timeRange: TimeRange{ - HourMinuteFrom: "08:00", - HourMinuteTo: "08:00", + TimeFrom: time.Date(2024, time.October, 2, 0, 0, 0, 0, time.UTC), + TimeTo: time.Date(2024, time.October, 13, 0, 0, 0, 0, time.UTC), Frequency: Daily, + HourMinuteFrom: "02:00", + HourMinuteTo: "18:00", }, - targetTime: time.Date(2024, time.Month(2), 26, 18, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 27, 8, 0, 0, 0, time.Local), - expectedIsBetween: true, + targetTime: time.Date(2024, time.October, 3, 1, 0, 0, 0, time.UTC), + expectedWindowEdge: time.Date(2024, time.October, 3, 2, 0, 0, 0, time.UTC), + expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time inside the time range for same start and end", + description: "Target time after daily window", timeRange: TimeRange{ - HourMinuteFrom: "08:70", - HourMinuteTo: "08:00", + TimeFrom: time.Date(2024, time.October, 2, 0, 0, 0, 0, time.UTC), + TimeTo: time.Date(2024, time.October, 13, 0, 0, 0, 0, time.UTC), Frequency: Daily, + HourMinuteFrom: "02:00", + HourMinuteTo: "18:00", }, - targetTime: time.Date(2024, time.Month(2), 26, 18, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, + targetTime: time.Date(2024, time.October, 3, 19, 0, 0, 0, time.UTC), + expectedWindowEdge: time.Date(2024, time.October, 4, 02, 0, 0, 0, time.UTC), expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time inside the time range for same start and end", + description: "Target time outside the overall time range", timeRange: TimeRange{ - HourMinuteFrom: "12:00ab", - HourMinuteTo: "14:00ab", + TimeFrom: time.Date(2024, time.October, 2, 02, 0, 0, 0, time.UTC), + TimeTo: time.Date(2024, time.October, 13, 18, 0, 0, 0, time.UTC), Frequency: Daily, + HourMinuteFrom: "02:00", + HourMinuteTo: "18:00", }, - targetTime: time.Date(2024, time.Month(2), 26, 18, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, + targetTime: time.Date(2024, time.October, 14, 10, 0, 0, 0, time.UTC), + expectedWindowEdge: time.Date(2024, time.October, 13, 18, 0, 0, 0, time.UTC), expectedIsBetween: false, + expectedIsExpired: true, + expectErr: false, }, { - description: "Target time inside the time range for same start and end", + description: "Target time exactly at start of daily window", timeRange: TimeRange{ - HourMinuteFrom: "08:59", - HourMinuteTo: "24:00", + TimeFrom: time.Date(2024, time.October, 2, 0, 0, 0, 0, time.UTC), + TimeTo: time.Date(2024, time.October, 13, 0, 0, 0, 0, time.UTC), Frequency: Daily, + HourMinuteFrom: "02:00", + HourMinuteTo: "18:00", }, - targetTime: time.Date(2024, time.Month(2), 26, 18, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, + targetTime: time.Date(2024, time.October, 3, 2, 0, 0, 0, time.UTC), + expectedWindowEdge: time.Date(2024, time.October, 3, 18, 0, 0, 0, time.UTC), + expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, + }, + { + description: "Target time exactly at end of daily window", + timeRange: TimeRange{ + TimeFrom: time.Date(2024, time.October, 2, 0, 0, 0, 0, time.UTC), + TimeTo: time.Date(2024, time.October, 13, 0, 0, 0, 0, time.UTC), + Frequency: Daily, + HourMinuteFrom: "02:00", + HourMinuteTo: "18:00", + }, + targetTime: time.Date(2024, time.October, 3, 18, 0, 0, 0, time.UTC), + expectedWindowEdge: time.Date(2024, time.October, 4, 02, 0, 0, 0, time.UTC), expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, + { - description: "Target time outside the time range", + description: "Infinite start time, target time within daily window", timeRange: TimeRange{ - HourMinuteFrom: "08:00", - HourMinuteTo: "07:00", + TimeFrom: time.Time{}, // Infinite start + TimeTo: time.Date(2024, time.October, 13, 0, 0, 0, 0, time.UTC), Frequency: Daily, + HourMinuteFrom: "02:00", + HourMinuteTo: "18:00", }, - targetTime: time.Date(2024, time.Month(2), 26, 18, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 27, 07, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.October, 3, 10, 0, 0, 0, time.UTC), + expectedWindowEdge: time.Date(2024, time.October, 3, 18, 0, 0, 0, time.UTC), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time inside the time range and HourMinuteFromHourMinuteTo", + description: "Weekly recurrence with end date - outside time range but not expired", timeRange: TimeRange{ HourMinuteFrom: "08:00", - HourMinuteTo: "07:00", + HourMinuteTo: "09:00", Weekdays: []time.Weekday{time.Monday, time.Wednesday, time.Friday}, Frequency: Weekly, + TimeTo: time.Date(2024, time.February, 29, 0, 0, 0, 0, time.Local), // Ends after targetTime }, - targetTime: time.Date(2024, time.Month(2), 26, 8, 30, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 27, 7, 0, 0, 0, time.Local), - expectedIsBetween: true, + targetTime: time.Date(2024, time.February, 26, 10, 0, 0, 0, time.Local), // Monday but outside range + expectedWindowEdge: time.Date(2024, time.February, 28, 8, 0, 0, 0, time.Local), // Next valid start on Wednesday + expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time before the time range HourMinuteFrom>HourMinuteTo", + description: "Weekly recurrence - next valid weekday within range", timeRange: TimeRange{ HourMinuteFrom: "08:00", - HourMinuteTo: "07:00", + HourMinuteTo: "09:00", Weekdays: []time.Weekday{time.Monday, time.Wednesday, time.Friday}, Frequency: Weekly, }, - targetTime: time.Date(2024, time.Month(2), 26, 7, 30, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 26, 8, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.February, 27, 7, 0, 0, 0, time.Local), // Tuesday, before Wednesday window + expectedWindowEdge: time.Date(2024, time.February, 28, 8, 0, 0, 0, time.Local), // Next window end on Wednesday expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time after the time range HourMinuteFrom>HourMinuteTo", + description: "Weekly recurrence - target time in previous window, next occurrence", timeRange: TimeRange{ HourMinuteFrom: "08:00", - HourMinuteTo: "07:00", + HourMinuteTo: "09:00", Weekdays: []time.Weekday{time.Monday, time.Wednesday, time.Friday}, Frequency: Weekly, }, - targetTime: time.Date(2024, time.Month(2), 27, 7, 30, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 28, 8, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.February, 26, 6, 0, 0, 0, time.Local), // Before Monday window + expectedWindowEdge: time.Date(2024, time.February, 26, 8, 0, 0, 0, time.Local), // End of Monday window expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time inside the time range HourMinuteFrom==HourMinuteTo", + description: "Weekly recurrence - target time after all valid windows in week but not expired", timeRange: TimeRange{ HourMinuteFrom: "08:00", - HourMinuteTo: "08:00", + HourMinuteTo: "09:00", Weekdays: []time.Weekday{time.Monday, time.Wednesday, time.Friday}, Frequency: Weekly, }, - targetTime: time.Date(2024, time.Month(2), 26, 8, 30, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 27, 8, 00, 0, 0, time.Local), - expectedIsBetween: true, + targetTime: time.Date(2024, time.March, 1, 10, 0, 0, 0, time.Local), // After last window in week (friday) + expectedWindowEdge: time.Date(2024, time.March, 4, 8, 0, 0, 0, time.Local), // Next Monday at 8:00 + expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, + { - description: "Target time inside the time range HourMinuteFromHourMinuteTo", + description: "WeeklyRange recurrence with end date - target within range before end date", timeRange: TimeRange{ HourMinuteFrom: "08:00", - HourMinuteTo: "07:00", + HourMinuteTo: "10:00", WeekdayFrom: 1, WeekdayTo: 3, Frequency: WeeklyRange, + TimeTo: time.Date(2024, time.Month(3), 1, 0, 0, 0, 0, time.Local), // End date is Friday }, - targetTime: time.Date(2024, time.Month(2), 28, 10, 30, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(3), 4, 8, 00, 0, 0, time.Local), - expectedIsBetween: false, + targetTime: time.Date(2024, time.Month(2), 26, 9, 0, 0, 0, time.Local), // Within range on Monday + expectedWindowEdge: time.Date(2024, time.Month(2), 28, 10, 0, 0, 0, time.Local), // End of range on Wednesday + expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time before the time range HourMinuteFrom>HourMinuteTo", + description: "WeeklyRange recurrence with end date - target within range after end date", timeRange: TimeRange{ HourMinuteFrom: "08:00", - HourMinuteTo: "07:00", + HourMinuteTo: "10:00", WeekdayFrom: 1, WeekdayTo: 3, Frequency: WeeklyRange, + TimeTo: time.Date(2024, time.Month(2), 27, 10, 0, 0, 0, time.Local), // End date is Tuesday }, - targetTime: time.Date(2024, time.Month(2), 28, 7, 30, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(3), 4, 8, 00, 0, 0, time.Local), + targetTime: time.Date(2024, time.Month(2), 28, 8, 30, 0, 0, time.Local), // Wednesday after end date + expectedWindowEdge: time.Date(2024, time.Month(2), 27, 10, 00, 0, 0, time.Local), // No recurrence as end date has passed expectedIsBetween: false, + expectedIsExpired: true, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo ", + description: "WeeklyRange recurrence with end date - target outside range before end date", timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: 26, - DayTo: 4, - Frequency: Monthly, + HourMinuteFrom: "08:00", + HourMinuteTo: "10:00", + WeekdayFrom: 1, + WeekdayTo: 3, + Frequency: WeeklyRange, + TimeTo: time.Date(2024, time.Month(3), 1, 0, 0, 0, 0, time.Local), }, - targetTime: time.Date(2024, time.Month(4), 27, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(5), 4, 8, 0, 0, 0, time.Local), - expectedIsBetween: true, + targetTime: time.Date(2024, time.Month(2), 25, 9, 0, 0, 0, time.Local), // Sunday before range starts + expectedWindowEdge: time.Date(2024, time.Month(2), 26, 8, 0, 0, 0, time.Local), // Next start on Monday + expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, + { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec ", + description: "WeeklyRange recurrence with start and end dates - target within range and period", timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: 26, - DayTo: 4, - Frequency: Monthly, + HourMinuteFrom: "08:00", + HourMinuteTo: "10:00", + WeekdayFrom: 1, + WeekdayTo: 3, + Frequency: WeeklyRange, + TimeFrom: time.Date(2024, time.Month(2), 24, 0, 0, 0, 0, time.Local), // Saturday + TimeTo: time.Date(2024, time.Month(3), 1, 0, 0, 0, 0, time.Local), // Friday }, - targetTime: time.Date(2024, time.Month(12), 27, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2025, time.Month(1), 4, 8, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.Month(2), 26, 8, 30, 0, 0, time.Local), // Within range on Monday + expectedWindowEdge: time.Date(2024, time.Month(2), 28, 10, 0, 0, 0, time.Local), // End of range on Wednesday expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec ", + description: "WeeklyRange recurrence with start and end dates - target after end date", timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: 26, - DayTo: 4, - Frequency: Monthly, + HourMinuteFrom: "08:00", + HourMinuteTo: "10:00", + WeekdayFrom: 1, + WeekdayTo: 3, + Frequency: WeeklyRange, + TimeFrom: time.Date(2024, time.Month(2), 24, 0, 0, 0, 0, time.Local), + TimeTo: time.Date(2024, time.Month(2), 27, 10, 0, 0, 0, time.Local), // Tuesday }, - targetTime: time.Date(2024, time.Month(12), 4, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(12), 26, 9, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.Month(2), 28, 9, 0, 0, 0, time.Local), // Wednesday after end date + expectedWindowEdge: time.Date(2024, time.Month(2), 27, 10, 0, 0, 0, time.Local), // No recurrence as period has expired expectedIsBetween: false, + expectedIsExpired: true, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec ", + description: "WeeklyRange recurrence with start and end dates - target before start date", timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: 26, - DayTo: 4, - Frequency: Monthly, + HourMinuteFrom: "08:00", + HourMinuteTo: "10:00", + WeekdayFrom: 1, + WeekdayTo: 3, + Frequency: WeeklyRange, + TimeFrom: time.Date(2024, time.Month(2), 26, 0, 0, 0, 0, time.Local), // Start date is Monday + TimeTo: time.Date(2024, time.Month(3), 1, 0, 0, 0, 0, time.Local), // End date is Friday }, - targetTime: time.Date(2025, time.Month(1), 4, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2025, time.Month(1), 26, 9, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.Month(2), 25, 9, 0, 0, 0, time.Local), // Sunday before start date + expectedWindowEdge: time.Date(2024, time.Month(2), 26, 8, 0, 0, 0, time.Local), // Next start on Monday expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, + { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec and target time is for next month ", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: 26, - DayTo: 4, - Frequency: Monthly, - }, - targetTime: time.Date(2025, time.Month(1), 1, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2025, time.Month(1), 4, 8, 0, 0, 0, time.Local), - expectedIsBetween: true, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec and target time is for next month ", + description: "Target time between the time range with HourMinuteFrom > HourMinuteTo and DayTo > DayFrom (April)", timeRange: TimeRange{ HourMinuteFrom: "09:00", HourMinuteTo: "08:00", - DayFrom: -2, - DayTo: -1, + DayFrom: 4, + DayTo: 28, Frequency: Monthly, }, - targetTime: time.Date(2025, time.Month(1), 30, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2025, time.Month(1), 31, 8, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.Month(4), 27, 10, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(4), 28, 8, 0, 0, 0, time.Local), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec and target time is for next month ", + description: "Target time between the time range with HourMinuteFrom > HourMinuteTo and DayFrom > DayTo (December)", timeRange: TimeRange{ HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: -1, - DayTo: -3, + HourMinuteTo: "11:00", + DayFrom: 3, + DayTo: 27, Frequency: Monthly, }, - targetTime: time.Date(2025, time.Month(1), 30, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, + targetTime: time.Date(2024, time.Month(12), 28, 10, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2025, time.Month(1), 3, 9, 0, 0, 0, time.Local), expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, + { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec and target time is for next month ", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "10:00", - DayFrom: -3, - DayTo: 4, - Frequency: Monthly, - }, - targetTime: time.Date(2024, time.Month(3), 4, 8, 59, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(3), 4, 10, 0, 0, 0, time.Local), - expectedIsBetween: true, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec and target time is for next month ", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "10:00", - DayFrom: -3, - DayTo: 4, - Frequency: Monthly, - }, - targetTime: time.Date(2024, time.Month(3), 4, 9, 59, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(3), 4, 10, 0, 0, 0, time.Local), - expectedIsBetween: true, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec and target time is for next month ", + description: "Target time within the time range with DayFrom < DayTo, target time for next month", timeRange: TimeRange{ - HourMinuteFrom: "09:00", + HourMinuteFrom: "08:00", HourMinuteTo: "10:00", - DayFrom: -3, - DayTo: 4, + DayFrom: 4, + DayTo: 26, Frequency: Monthly, }, - targetTime: time.Date(2024, time.Month(3), 4, 10, 1, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(3), 29, 9, 0, 0, 0, time.Local), + targetTime: time.Date(2025, time.Month(1), 2, 10, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2025, time.Month(1), 4, 8, 0, 0, 0, time.Local), expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec and target time is for next month ", + description: "Target time outside the time range with DayFrom < DayTo, target time for next month", timeRange: TimeRange{ HourMinuteFrom: "09:00", - HourMinuteTo: "10:00", + HourMinuteTo: "08:00", DayFrom: -3, - DayTo: 4, + DayTo: -1, Frequency: Monthly, }, - targetTime: time.Date(2024, time.Month(2), 1, 9, 30, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 4, 10, 0, 0, 0, time.Local), + targetTime: time.Date(2025, time.Month(1), 30, 10, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2025, time.Month(1), 31, 8, 0, 0, 0, time.Local), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, + { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec and target time is for next month ", + description: "Target time at the edge of the time range", timeRange: TimeRange{ HourMinuteFrom: "09:00", HourMinuteTo: "10:00", - DayFrom: -3, - DayTo: 4, + DayFrom: 25, + DayTo: -3, Frequency: Monthly, }, - targetTime: time.Date(2024, time.Month(2), 4, 10, 1, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 27, 9, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.Month(2), 24, 4, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(2), 25, 9, 0, 0, 0, time.Local), expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, + { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec and target time is for next month ", + description: "Target time at the edge of the time range with HourMinuteFrom > HourMinuteTo", timeRange: TimeRange{ HourMinuteFrom: "09:00", HourMinuteTo: "10:00", - DayFrom: -3, - DayTo: 4, + DayFrom: 4, + DayTo: -3, Frequency: Monthly, }, - //29,30,31,1,2,3,4 - targetTime: time.Date(2024, time.Month(2), 4, 9, 59, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 4, 10, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.Month(2), 26, 9, 1, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(2), 27, 10, 0, 0, 0, time.Local), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec and target time is for next month ", + description: "Target time before the time range with HourMinuteFrom > HourMinuteTo", timeRange: TimeRange{ HourMinuteFrom: "09:00", HourMinuteTo: "10:00", - DayFrom: -3, - DayTo: 4, + DayFrom: 13, + DayTo: -2, Frequency: Monthly, }, - //29,30,31,1,2,3,4 - targetTime: time.Date(2024, time.Month(2), 4, 9, 01, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 4, 10, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.Month(2), 14, 9, 30, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(2), 28, 10, 0, 0, 0, time.Local), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, + { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec and target time is for next month ", + description: "Target time with negative DayFrom and DayTo, time within range", timeRange: TimeRange{ HourMinuteFrom: "09:00", HourMinuteTo: "10:00", DayFrom: -3, - DayTo: 4, + DayTo: -1, Frequency: Monthly, }, - //29,30,31,1,2,3,4 - targetTime: time.Date(2024, time.Month(2), 3, 9, 01, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 4, 10, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.Month(1), 30, 10, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(1), 31, 10, 0, 0, 0, time.Local), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo for dec and target time is for next month ", + description: "Target time outside range with negative DayFrom and DayTo", timeRange: TimeRange{ HourMinuteFrom: "09:00", HourMinuteTo: "10:00", - DayFrom: -3, - DayTo: 4, + DayFrom: -2, + DayTo: -1, Frequency: Monthly, }, - //29,30,31,1,2,3,4 - targetTime: time.Date(2024, time.Month(2), 4, 6, 01, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 4, 10, 0, 0, 0, time.Local), + targetTime: time.Date(2025, time.Month(1), 30, 10, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2025, time.Month(1), 31, 10, 0, 0, 0, time.Local), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: 26, - DayTo: -3, - Frequency: Monthly, - }, - targetTime: time.Date(2024, time.Month(2), 26, 8, 59, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(2), 26, 9, 0, 0, 0, time.Local), - expectedIsBetween: false, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo and dayTo< -4", + description: "Target time after the time range with End Date", timeRange: TimeRange{ HourMinuteFrom: "09:00", HourMinuteTo: "08:00", - DayFrom: 26, - DayTo: -4, + DayFrom: 4, + DayTo: 28, Frequency: Monthly, + TimeTo: time.Date(2024, time.Month(4), 16, 8, 0, 0, 0, time.Local), }, - targetTime: time.Date(2024, time.Month(5), 26, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, + targetTime: time.Date(2024, time.Month(4), 27, 10, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(4), 16, 8, 0, 0, 0, time.Local), expectedIsBetween: false, + expectedIsExpired: true, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo and dayTo< -4", + description: "Target time between the time range with HourMinuteFrom > HourMinuteTo and DayFrom > DayTo (December)", timeRange: TimeRange{ HourMinuteFrom: "09:00", HourMinuteTo: "11:00", - DayFrom: 26, - DayTo: -4, + DayFrom: 3, + DayTo: 27, Frequency: Monthly, + TimeTo: time.Date(2024, time.Month(4), 26, 10, 0, 0, 0, time.Local), }, - targetTime: time.Date(2024, time.Month(5), 26, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, + targetTime: time.Date(2024, time.Month(3), 28, 10, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(4), 3, 9, 0, 0, 0, time.Local), expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, + { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: 26, - DayTo: -2, - Frequency: Monthly, - }, - targetTime: time.Date(2024, time.Month(5), 26, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(5), 30, 8, 0, 0, 0, time.Local), - expectedIsBetween: true, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: 26, - DayTo: -1, - Frequency: Monthly, - }, - targetTime: time.Date(2024, time.Month(5), 26, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(5), 31, 8, 0, 0, 0, time.Local), - expectedIsBetween: true, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo , both dayFrom and DayTo less than 0", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: -3, - DayTo: -1, - Frequency: Monthly, - }, - targetTime: time.Date(2024, time.Month(5), 29, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(5), 31, 8, 0, 0, 0, time.Local), - expectedIsBetween: true, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo , both dayFrom and DayTo less than 0", + description: "Target time within the time range with DayFrom < DayTo, target time for next month", timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: -3, - DayTo: -4, + HourMinuteFrom: "08:00", + HourMinuteTo: "10:00", + DayFrom: 4, + DayTo: 26, Frequency: Monthly, + //TimeFrom: time.Date(2024, time.Month(3), 1, 10, 0, 0, 0, time.Local), + TimeTo: time.Date(2024, time.Month(4), 28, 10, 0, 0, 0, time.Local), }, - targetTime: time.Date(2024, time.Month(5), 29, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, + targetTime: time.Date(2024, time.Month(4), 27, 8, 30, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(4), 26, 10, 0, 0, 0, time.Local), expectedIsBetween: false, + expectedIsExpired: true, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom ==DayTo , both dayFrom and DayTo less than 0", + description: "Target time within the time range with DayFrom < DayTo, target time for next month", timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: -3, - DayTo: -3, + HourMinuteFrom: "08:00", + HourMinuteTo: "10:00", + DayFrom: 4, + DayTo: 26, Frequency: Monthly, + TimeFrom: time.Date(2024, time.Month(3), 1, 10, 0, 0, 0, time.Local), + TimeTo: time.Date(2024, time.Month(4), 28, 10, 0, 0, 0, time.Local), }, - targetTime: time.Date(2024, time.Month(5), 29, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, + targetTime: time.Date(2024, time.Month(3), 2, 8, 30, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(3), 4, 8, 0, 0, 0, time.Local), expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, + { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom HourMinuteTo and DayFrom HourMinuteTo and DayFrom 0", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: -3, - DayTo: 24, - Frequency: Monthly, - }, - targetTime: time.Date(2024, time.Month(6), 20, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(6), 24, 8, 0, 0, 0, time.Local), + targetTime: time.Date(2025, time.Month(1), 30, 10, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2025, time.Month(1), 31, 8, 0, 0, 0, time.Local), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom 0", - timeRange: TimeRange{ - HourMinuteFrom: "09:00ab", - HourMinuteTo: "08:00", - DayFrom: -3, - DayTo: 24, - Frequency: Monthly, - }, - targetTime: time.Date(2024, time.Month(6), 20, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, - expectedIsBetween: false, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom 0", + description: "Target time at the edge of the time range", timeRange: TimeRange{ HourMinuteFrom: "09:00", - HourMinuteTo: "08:00ab", - DayFrom: -3, - DayTo: 24, + HourMinuteTo: "10:00", + DayFrom: 25, + DayTo: -3, Frequency: Monthly, }, - targetTime: time.Date(2024, time.Month(6), 20, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, - expectedIsBetween: false, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom 0", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00ab", - Frequency: Daily, - }, - targetTime: time.Date(2024, time.Month(6), 20, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, - expectedIsBetween: false, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom 0", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "08:00ab", - DayFrom: -3, - DayTo: 24, - Weekdays: []time.Weekday{time.Monday, time.Wednesday, time.Friday}, - Frequency: Weekly, - }, - targetTime: time.Date(2024, time.Month(6), 20, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, + targetTime: time.Date(2024, time.Month(2), 24, 4, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(2), 25, 9, 0, 0, 0, time.Local), expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom HourMinuteTo", timeRange: TimeRange{ HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: 26, - DayTo: 27, + HourMinuteTo: "10:00", + DayFrom: 3, + DayTo: -2, Frequency: Monthly, }, - targetTime: time.Date(2024, time.Month(5), 26, 10, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(5), 27, 8, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.Month(3), 4, 10, 1, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(3), 30, 10, 0, 0, 0, time.Local), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom HourMinuteTo and DayFrom HourMinuteTo", timeRange: TimeRange{ HourMinuteFrom: "09:00", - HourMinuteTo: "08:00", - DayFrom: 26, - DayTo: 27, + HourMinuteTo: "10:00", + DayFrom: 13, + DayTo: -2, Frequency: Monthly, }, - targetTime: time.Date(2024, time.Month(5), 26, 9, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(5), 27, 8, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.Month(2), 14, 9, 30, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(2), 28, 10, 0, 0, 0, time.Local), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom HourMinuteTo and DayFrom HourMinuteTo and DayFrom HourMinuteTo and DayFrom HourMinuteTo and DayFrom >DayTo", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "17:00", - DayFrom: 26, - DayTo: 29, - Frequency: Monthly, - TimeFrom: time.Date(2024, time.Month(5), 26, 10, 0, 0, 0, time.Local), - }, - targetTime: time.Date(2024, time.Month(5), 26, 11, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(5), 29, 17, 0, 0, 0, time.Local), - expectedIsBetween: true, - }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo", + description: "Target time with negative DayFrom and DayTo, time within range", timeRange: TimeRange{ HourMinuteFrom: "09:00", - HourMinuteTo: "17:00", - DayFrom: 26, - DayTo: 29, + HourMinuteTo: "10:00", + DayFrom: -3, + DayTo: -1, Frequency: Monthly, - TimeFrom: time.Date(2024, time.Month(5), 26, 10, 0, 0, 0, time.Local), - TimeTo: time.Date(2024, time.Month(5), 29, 13, 0, 0, 0, time.Local), }, - targetTime: time.Date(2024, time.Month(5), 26, 11, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(5), 29, 13, 0, 0, 0, time.Local), + targetTime: time.Date(2024, time.Month(1), 30, 10, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2024, time.Month(1), 31, 10, 0, 0, 0, time.Local), expectedIsBetween: true, + expectedIsExpired: false, + expectErr: false, }, { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo", + description: "Target time outside range with negative DayFrom and DayTo", timeRange: TimeRange{ HourMinuteFrom: "09:00", - HourMinuteTo: "17:00", - DayFrom: 26, - DayTo: 29, + HourMinuteTo: "10:00", + DayFrom: -2, + DayTo: -1, Frequency: Monthly, - TimeTo: time.Date(2024, time.Month(5), 29, 13, 0, 0, 0, time.Local), }, - targetTime: time.Date(2024, time.Month(5), 26, 11, 0, 0, 0, time.Local), - expectedWindowEdge: time.Date(2024, time.Month(5), 29, 13, 0, 0, 0, time.Local), + targetTime: time.Date(2025, time.Month(1), 30, 10, 0, 0, 0, time.Local), + expectedWindowEdge: time.Date(2025, time.Month(1), 31, 10, 0, 0, 0, time.Local), expectedIsBetween: true, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "17:00", - WeekdayFrom: 9, - WeekdayTo: 2, - Frequency: WeeklyRange, - TimeTo: time.Date(2024, time.Month(5), 29, 13, 0, 0, 0, time.Local), - }, - targetTime: time.Date(2024, time.Month(5), 26, 11, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, - expectedIsBetween: false, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "17:00", - WeekdayFrom: 5, - WeekdayTo: 11, - Frequency: WeeklyRange, - TimeTo: time.Date(2024, time.Month(5), 29, 13, 0, 0, 0, time.Local), - }, - targetTime: time.Date(2024, time.Month(5), 26, 11, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, - expectedIsBetween: false, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "17:00ac", - WeekdayFrom: 5, - WeekdayTo: 6, - Frequency: WeeklyRange, - TimeTo: time.Date(2024, time.Month(5), 29, 13, 0, 0, 0, time.Local), - }, - targetTime: time.Date(2024, time.Month(5), 26, 11, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, - expectedIsBetween: false, - }, - { - description: "Target time between the time range and HourMinuteFrom>HourMinuteTo and DayFrom >DayTo", - timeRange: TimeRange{ - HourMinuteFrom: "09:00", - HourMinuteTo: "17:00ac", - WeekdayFrom: 5, - WeekdayTo: 6, - Frequency: "hello", - TimeTo: time.Date(2024, time.Month(5), 29, 13, 0, 0, 0, time.Local), - }, - targetTime: time.Date(2024, time.Month(5), 26, 11, 0, 0, 0, time.Local), - expectedWindowEdge: time.Time{}, - expectedIsBetween: false, + expectedIsExpired: false, + expectErr: false, }, } - // Execute test cases + for _, tc := range testCases { t.Run(tc.description, func(t *testing.T) { - nextWindowEdge, isTimeBetween, _ := tc.timeRange.GetTimeRangeWindow(tc.targetTime) - if nextWindowEdge != tc.expectedWindowEdge || isTimeBetween != tc.expectedIsBetween { - t.Errorf("Test case failed: %s\nExpected nextWindowEdge: %v, got: %v\nExpected isTimeBetween: %t, got: %t", tc.description, tc.expectedWindowEdge, nextWindowEdge, tc.expectedIsBetween, isTimeBetween) + nextWindowEdge, isTimeBetween, isExpired, err := tc.timeRange.GetTimeRangeWindow(tc.targetTime) + + if (err != nil) != tc.expectErr { + t.Fatalf("Unexpected error: %v, expected error: %v", err, tc.expectErr) + } + + if nextWindowEdge != tc.expectedWindowEdge || isTimeBetween != tc.expectedIsBetween || isExpired != tc.expectedIsExpired { + t.Errorf("Test case failed: %s\nExpected nextWindowEdge: %v, got: %v\nExpected isTimeBetween: %t, got: %t\nExpected isExpired: %t, got: %t", + tc.description, tc.expectedWindowEdge, nextWindowEdge, tc.expectedIsBetween, isTimeBetween, tc.expectedIsExpired, isExpired) } }) } diff --git a/common-lib/timeRangeLib/validator.go b/common-lib/timeRangeLib/validator.go index 272e5e679..94bb1d3f0 100644 --- a/common-lib/timeRangeLib/validator.go +++ b/common-lib/timeRangeLib/validator.go @@ -37,14 +37,27 @@ func (tr TimeRange) ValidateTimeRange() error { return err } + // Ensure HourMinuteFrom < HourMinuteTo for Daily and Weekly frequencies + if tr.Frequency == Daily || tr.Frequency == Weekly { + if isToBeforeFrom(tr.HourMinuteFrom, tr.HourMinuteTo) { + return errors.New(string(InvalidHourMinuteForWeeklyAndDaily)) + } + } } if !tr.TimeFrom.IsZero() && !tr.TimeTo.IsZero() { - if tr.TimeFrom.After(tr.TimeTo) { - return errors.New(string(TimeFromLessThanTimeTo)) - } - if tr.TimeFrom.Equal(tr.TimeTo) { - return errors.New(string(TimeFromEqualToTimeTo)) + if tr.Frequency == Fixed { + if tr.TimeFrom.After(tr.TimeTo) { + return errors.New(string(TimeFromLessThanTimeTo)) + } + if tr.TimeFrom.Equal(tr.TimeTo) { + return errors.New(string(TimeFromEqualToTimeTo)) + } + } else { + // Validate that the date range is valid (same date safe for recurrence type windows) + if !isDateFromBeforeTo(tr.TimeFrom, tr.TimeTo) { + return errors.New(string(DayFromOrToNotValid)) + } } } @@ -80,6 +93,14 @@ func (tr TimeRange) ValidateTimeRange() error { if tr.DayFrom == tr.DayTo && isToBeforeFrom(tr.HourMinuteFrom, tr.HourMinuteTo) { return errors.New(string(ToBeforeFrom)) } + // DayFrom > DayTo => check for the correct value + if tr.DayFrom > 0 && tr.DayTo > 0 && tr.DayFrom > tr.DayTo { + return errors.New(string(DayFromOrToNotValid)) + } + if tr.DayFrom < 0 && tr.DayTo > 0 { + return errors.New(string(DayFromOrToNotValid)) + } + // this is to prevent overlapping windows crossing to next month for both negatives if tr.DayFrom < 0 && tr.DayTo < 0 && tr.DayFrom > tr.DayTo { return errors.New(string(BothLessThanZeroAndFromGreaterThanTo)) diff --git a/git-sensor/Makefile b/git-sensor/Makefile index 3761c38ed..f3f8589ce 100644 --- a/git-sensor/Makefile +++ b/git-sensor/Makefile @@ -38,8 +38,7 @@ run: build # docker push ${REGISTRY}/orchestrator:${TAG} dep-update-oss: - go mod edit -replace=github.com/devtron-labs/common-lib=github.com/devtron-labs/devtron-services/common-lib@$(TARGET_BRANCH) \ - -replace=github.com/devtron-labs/git-sensor=github.com/devtron-labs/devtron-services/git-sensor@$(TARGET_BRANCH) + go mod edit -replace=github.com/devtron-labs/common-lib=github.com/devtron-labs/devtron-services/common-lib@$(TARGET_BRANCH) go mod tidy go mod vendor diff --git a/git-sensor/go.mod b/git-sensor/go.mod index 239bf2cc2..cf9ce7ae9 100644 --- a/git-sensor/go.mod +++ b/git-sensor/go.mod @@ -4,7 +4,7 @@ go 1.21 toolchain go1.22.4 -replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece +replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 require ( github.com/caarlos0/env v3.5.0+incompatible @@ -89,4 +89,4 @@ require ( mellium.im/sasl v0.3.1 // indirect ) -replace github.com/devtron-labs/git-sensor => github.com/devtron-labs/devtron-services/git-sensor v0.0.0-20241024131256-7d3ba621dece +replace github.com/devtron-labs/git-sensor => github.com/devtron-labs/devtron-services/git-sensor v0.0.0-20241103151131-e0ee0068cae4 diff --git a/git-sensor/go.sum b/git-sensor/go.sum index 46b4a2330..dacebba08 100644 --- a/git-sensor/go.sum +++ b/git-sensor/go.sum @@ -29,8 +29,8 @@ github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxG github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece h1:TjQ0bGjUbwBoXUbjTDuAy+5TPfAh97ZMUDcjbMp3ovk= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece/go.mod h1:KpKnF4OSpQNDJmb4wVZq3Za88ePBw4xec2GOAGRm5UQ= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 h1:8fW1BLQ0YqIE5J8sQjKk+6pOG8JTVp/EGHYn3PM9WX4= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0/go.mod h1:KpKnF4OSpQNDJmb4wVZq3Za88ePBw4xec2GOAGRm5UQ= github.com/devtron-labs/protos v0.0.3-0.20240809072909-83171af34169 h1:9OMZv0/fOWKK9s9BLTofFL/BO79TdyvC1Sc1HsC4esQ= github.com/devtron-labs/protos v0.0.3-0.20240809072909-83171af34169/go.mod h1:1TqULGlTey+VNhAu/ag7NJuUvByJemkqodsc9L5PHJk= github.com/docker/cli v24.0.6+incompatible h1:fF+XCQCgJjjQNIMjzaSmiKJSCcfcXb3TWTcc7GAneOY= diff --git a/git-sensor/vendor/modules.txt b/git-sensor/vendor/modules.txt index 16abadd11..8e4f908cf 100644 --- a/git-sensor/vendor/modules.txt +++ b/git-sensor/vendor/modules.txt @@ -62,7 +62,7 @@ github.com/cyphar/filepath-securejoin # github.com/davecgh/go-spew v1.1.1 ## explicit github.com/davecgh/go-spew/spew -# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece +# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 ## explicit; go 1.21 github.com/devtron-labs/common-lib/constants github.com/devtron-labs/common-lib/git-manager @@ -487,4 +487,4 @@ gopkg.in/yaml.v3 # mellium.im/sasl v0.3.1 ## explicit; go 1.18 mellium.im/sasl -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 diff --git a/kubelink/Makefile b/kubelink/Makefile index e0af129e9..f4ca41fac 100644 --- a/kubelink/Makefile +++ b/kubelink/Makefile @@ -28,8 +28,7 @@ run: build ./kubelink dep-update-oss: - go mod edit -replace=github.com/devtron-labs/common-lib=github.com/devtron-labs/devtron-services/common-lib@$(TARGET_BRANCH) \ - -replace=github.com/devtron-labs/kubelink=github.com/devtron-labs/devtron-services/kubelink@$(TARGET_BRANCH) + go mod edit -replace=github.com/devtron-labs/common-lib=github.com/devtron-labs/devtron-services/common-lib@$(TARGET_BRANCH) go mod tidy go mod vendor diff --git a/kubelink/go.mod b/kubelink/go.mod index c7b4a0499..52039c4fa 100644 --- a/kubelink/go.mod +++ b/kubelink/go.mod @@ -177,7 +177,7 @@ require ( ) replace ( - github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece + github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 go.opentelemetry.io/otel/metric => go.opentelemetry.io/otel/metric v1.18.0 // https://github.com/kubernetes/kubernetes/issues/79384#issuecomment-505627280 k8s.io/api => k8s.io/api v0.29.0 @@ -209,4 +209,4 @@ replace ( k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.25.0 ) -replace github.com/devtron-labs/kubelink => github.com/devtron-labs/devtron-services/kubelink v0.0.0-20241024131256-7d3ba621dece +replace github.com/devtron-labs/kubelink => github.com/devtron-labs/devtron-services/kubelink v0.0.0-20241103151131-e0ee0068cae4 diff --git a/kubelink/go.sum b/kubelink/go.sum index 19f512155..fc88e80b2 100644 --- a/kubelink/go.sum +++ b/kubelink/go.sum @@ -79,8 +79,8 @@ github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxG github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece h1:TjQ0bGjUbwBoXUbjTDuAy+5TPfAh97ZMUDcjbMp3ovk= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece/go.mod h1:KpKnF4OSpQNDJmb4wVZq3Za88ePBw4xec2GOAGRm5UQ= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 h1:8fW1BLQ0YqIE5J8sQjKk+6pOG8JTVp/EGHYn3PM9WX4= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0/go.mod h1:KpKnF4OSpQNDJmb4wVZq3Za88ePBw4xec2GOAGRm5UQ= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/distribution/distribution/v3 v3.0.0-beta.1 h1:X+ELTxPuZ1Xe5MsD3kp2wfGUhc8I+MPfRis8dZ818Ic= diff --git a/kubelink/vendor/modules.txt b/kubelink/vendor/modules.txt index f4e161740..ff8f2a505 100644 --- a/kubelink/vendor/modules.txt +++ b/kubelink/vendor/modules.txt @@ -127,7 +127,7 @@ github.com/cyphar/filepath-securejoin # github.com/davecgh/go-spew v1.1.1 ## explicit github.com/davecgh/go-spew/spew -# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece +# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 ## explicit; go 1.21 github.com/devtron-labs/common-lib/async github.com/devtron-labs/common-lib/constants @@ -1353,7 +1353,7 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.3.0 ## explicit; go 1.12 sigs.k8s.io/yaml -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 # go.opentelemetry.io/otel/metric => go.opentelemetry.io/otel/metric v1.18.0 # k8s.io/api => k8s.io/api v0.29.0 # k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.29.0 diff --git a/kubewatch/go.mod b/kubewatch/go.mod index 28f538d6a..3d69f998f 100644 --- a/kubewatch/go.mod +++ b/kubewatch/go.mod @@ -245,4 +245,4 @@ replace ( k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.29.7 ) -replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96 +replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 diff --git a/kubewatch/go.sum b/kubewatch/go.sum index 964fcb876..041003bdf 100644 --- a/kubewatch/go.sum +++ b/kubewatch/go.sum @@ -719,8 +719,8 @@ github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxG github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96 h1:WVCAsCLoNNmPb+zUlf1aI2iSy1HHVpip4GxGGwBo0C0= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96/go.mod h1:t8dMjhJ1KFaGO2V9dR/cB/WIB3lQhP/wfFthEzgcW/4= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 h1:8fW1BLQ0YqIE5J8sQjKk+6pOG8JTVp/EGHYn3PM9WX4= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0/go.mod h1:KpKnF4OSpQNDJmb4wVZq3Za88ePBw4xec2GOAGRm5UQ= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= diff --git a/kubewatch/vendor/modules.txt b/kubewatch/vendor/modules.txt index 606532927..fbd0dafa3 100644 --- a/kubewatch/vendor/modules.txt +++ b/kubewatch/vendor/modules.txt @@ -211,7 +211,7 @@ github.com/cyphar/filepath-securejoin # github.com/davecgh/go-spew v1.1.1 ## explicit github.com/davecgh/go-spew/spew -# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96 +# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 ## explicit; go 1.21 github.com/devtron-labs/common-lib/constants github.com/devtron-labs/common-lib/git-manager/util @@ -1753,4 +1753,4 @@ upper.io/db.v3/postgresql # k8s.io/mount-utils => k8s.io/mount-utils v0.29.7 # k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.29.7 # k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.29.7 -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113074452-7bd23ef50c96 +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 diff --git a/lens/go.mod b/lens/go.mod index 2098a4c1f..01584dc94 100644 --- a/lens/go.mod +++ b/lens/go.mod @@ -59,4 +59,4 @@ require ( github.com/onsi/gomega v1.18.1 // indirect ) -replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece +replace github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 diff --git a/lens/go.sum b/lens/go.sum index cf257eae0..c741c6ac7 100644 --- a/lens/go.sum +++ b/lens/go.sum @@ -22,8 +22,8 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWH github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece h1:TjQ0bGjUbwBoXUbjTDuAy+5TPfAh97ZMUDcjbMp3ovk= -github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece/go.mod h1:KpKnF4OSpQNDJmb4wVZq3Za88ePBw4xec2GOAGRm5UQ= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 h1:8fW1BLQ0YqIE5J8sQjKk+6pOG8JTVp/EGHYn3PM9WX4= +github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0/go.mod h1:KpKnF4OSpQNDJmb4wVZq3Za88ePBw4xec2GOAGRm5UQ= github.com/devtron-labs/protos v0.0.3-0.20240130061723-7b2e12ab0abb h1:CkfQQgZc950/hTPqtQSiHV2RmZgkBLGCzwR02FZYjAU= github.com/devtron-labs/protos v0.0.3-0.20240130061723-7b2e12ab0abb/go.mod h1:pjLjgoa1GzbkOkvbMyP4SAKsaiK7eG6GoQCNauG03JA= github.com/docker/cli v24.0.6+incompatible h1:fF+XCQCgJjjQNIMjzaSmiKJSCcfcXb3TWTcc7GAneOY= diff --git a/lens/vendor/modules.txt b/lens/vendor/modules.txt index 59aa4899e..0c296dc62 100644 --- a/lens/vendor/modules.txt +++ b/lens/vendor/modules.txt @@ -7,7 +7,7 @@ github.com/caarlos0/env # github.com/cespare/xxhash/v2 v2.2.0 ## explicit; go 1.11 github.com/cespare/xxhash/v2 -# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece +# github.com/devtron-labs/common-lib v0.0.0 => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0 ## explicit; go 1.21 github.com/devtron-labs/common-lib/constants github.com/devtron-labs/common-lib/git-manager/util @@ -282,4 +282,4 @@ google.golang.org/protobuf/types/known/timestamppb # mellium.im/sasl v0.3.1 ## explicit; go 1.18 mellium.im/sasl -# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241024131256-7d3ba621dece +# github.com/devtron-labs/common-lib => github.com/devtron-labs/devtron-services/common-lib v0.0.0-20241113143019-dcdbe3a4ace0