Skip to content

Commit 543089c

Browse files
committed
Fix time comparison issues with buildscripts due to inconsistent time formatting
1 parent c20a2fb commit 543089c

9 files changed

Lines changed: 35 additions & 23 deletions

File tree

internal/runbits/buildscript/buildscript_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
)
1313

1414
const testProject = "https://platform.activestate.com/org/project?branch=main&commitID=00000000-0000-0000-0000-000000000000"
15-
const testTime = "2000-01-01T00:00:00.000Z"
15+
const testTime = "2000-01-01T00:00:00Z"
1616

1717
func checkoutInfo(project, time string) string {
1818
return "```\n" +

pkg/buildscript/buildscript.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/ActiveState/cli/internal/condition"
99
"github.com/ActiveState/cli/internal/errs"
10+
"github.com/ActiveState/cli/internal/logging"
1011
"github.com/ActiveState/cli/internal/rtutils/ptr"
1112
"github.com/ActiveState/cli/internal/sliceutils"
1213
"github.com/brunoga/deep"
@@ -65,7 +66,15 @@ func (b *BuildScript) SetAtTime(t time.Time, override bool) {
6566
if b.atTime != nil && !override {
6667
return
6768
}
68-
b.atTime = &t
69+
// Ensure time is RFC3339 formatted, even though it's not actually stored at that format, it does still
70+
// affect the specificity of the data stored and can ultimately lead to inconsistencies if not explicitly handled.
71+
t2, err := time.Parse(time.RFC3339, t.Format(time.RFC3339))
72+
if err != nil {
73+
// Pointless error check as this should never happen, but you know what they say about assumptions
74+
logging.Error("Error parsing time: %s", err)
75+
}
76+
b.atTime = ptr.To(t2)
77+
_ = b.atTime
6978
}
7079

7180
func (b *BuildScript) Equals(other *BuildScript) (bool, error) {
@@ -90,6 +99,7 @@ func (b *BuildScript) Equals(other *BuildScript) (bool, error) {
9099
if err != nil {
91100
return false, errs.Wrap(err, "Unable to marshal other buildscript")
92101
}
102+
93103
return string(myBytes) == string(otherBytes), nil
94104
}
95105

pkg/buildscript/buildscript_test.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88

99
"github.com/ActiveState/cli/internal/environment"
1010
"github.com/ActiveState/cli/internal/fileutils"
11-
"github.com/go-openapi/strfmt"
1211
"github.com/stretchr/testify/assert"
1312
"github.com/stretchr/testify/require"
1413
)
@@ -118,7 +117,7 @@ func TestRoundTripFromBuildExpressionWithLegacyAtTime(t *testing.T) {
118117
// Ensure that legacy at_time is preserved in the buildscript.
119118
atTime := script.AtTime()
120119
require.NotNil(t, atTime)
121-
require.Equal(t, initialTimeStamp, atTime.Format(strfmt.RFC3339Millis))
120+
require.Equal(t, initialTimeStamp, atTime.Format(time.RFC3339))
122121

123122
data, err = script.MarshalBuildExpression()
124123
require.NoError(t, err)
@@ -128,12 +127,12 @@ func TestRoundTripFromBuildExpressionWithLegacyAtTime(t *testing.T) {
128127
assert.NotContains(t, string(data), initialTimeStamp)
129128

130129
// Update the time in the build script but don't override the existing time
131-
updatedTime, err := time.Parse(strfmt.RFC3339Millis, updatedTimeStamp)
130+
updatedTime, err := time.Parse(time.RFC3339, updatedTimeStamp)
132131
require.NoError(t, err)
133132
script.SetAtTime(updatedTime, false)
134133

135134
// The updated time should be reflected in the build script
136-
require.Equal(t, initialTimeStamp, script.AtTime().Format(strfmt.RFC3339Millis))
135+
require.Equal(t, initialTimeStamp, script.AtTime().Format(time.RFC3339))
137136

138137
data, err = script.Marshal()
139138
require.NoError(t, err)
@@ -145,7 +144,7 @@ func TestRoundTripFromBuildExpressionWithLegacyAtTime(t *testing.T) {
145144

146145
// Now override the time in the build script
147146
script.SetAtTime(updatedTime, true)
148-
require.Equal(t, updatedTimeStamp, script.AtTime().Format(strfmt.RFC3339Millis))
147+
require.Equal(t, updatedTimeStamp, script.AtTime().Format(time.RFC3339))
149148

150149
data, err = script.Marshal()
151150
require.NoError(t, err)
@@ -165,7 +164,7 @@ func TestRoundTripFromBuildExpressionWithLegacyAtTime(t *testing.T) {
165164
// TestExpressionToScript tests that creating a build script from a given Platform build expression
166165
// and at time produces the expected result.
167166
func TestExpressionToScript(t *testing.T) {
168-
ts, err := time.Parse(strfmt.RFC3339Millis, testTime)
167+
ts, err := time.Parse(time.RFC3339, testTime)
169168
require.NoError(t, err)
170169

171170
script := New()
@@ -193,7 +192,7 @@ func TestScriptToExpression(t *testing.T) {
193192

194193
func TestOutdatedScript(t *testing.T) {
195194
_, err := Unmarshal([]byte(
196-
`at_time = "2000-01-01T00:00:00.000Z"
195+
`at_time = "2000-01-01T00:00:00Z"
197196
main = runtime
198197
`))
199198
assert.Error(t, err)

pkg/buildscript/marshal.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import (
55
"fmt"
66
"strconv"
77
"strings"
8+
"time"
89

9-
"github.com/go-openapi/strfmt"
1010
"github.com/thoas/go-funk"
1111
)
1212

@@ -31,7 +31,7 @@ func (b *BuildScript) Marshal() ([]byte, error) {
3131
buf.WriteString("```\n")
3232
buf.WriteString("Project: " + b.project + "\n")
3333
if b.atTime != nil {
34-
buf.WriteString("Time: " + b.atTime.Format(strfmt.RFC3339Millis) + "\n")
34+
buf.WriteString("Time: " + b.atTime.Format(time.RFC3339) + "\n")
3535
}
3636
buf.WriteString("```\n\n")
3737

pkg/buildscript/merge_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
"github.com/stretchr/testify/require"
99
)
1010

11-
const mergeATime = "2000-01-01T00:00:00.000Z"
12-
const mergeBTime = "2000-01-02T00:00:00.000Z"
11+
const mergeATime = "2000-01-01T00:00:00Z"
12+
const mergeBTime = "2000-01-02T00:00:00Z"
1313

1414
func TestMergeAdd(t *testing.T) {
1515
scriptA, err := Unmarshal([]byte(

pkg/buildscript/raw_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
)
1212

1313
const testProject = "https://platform.activestate.com/org/project?branch=main&commitID=00000000-0000-0000-0000-000000000000"
14-
const testTime = "2000-01-01T00:00:00.000Z"
14+
const testTime = "2000-01-01T00:00:00Z"
1515

1616
func checkoutInfoString(project, time string) string {
1717
return "```\n" +
@@ -43,7 +43,7 @@ main = runtime
4343
`))
4444
require.NoError(t, err)
4545

46-
atTimeStrfmt, err := strfmt.ParseDateTime("2000-01-01T00:00:00.000Z")
46+
atTimeStrfmt, err := strfmt.ParseDateTime("2000-01-01T00:00:00Z")
4747
require.NoError(t, err)
4848
atTime := time.Time(atTimeStrfmt)
4949

@@ -121,7 +121,7 @@ main = merge(
121121
`))
122122
require.NoError(t, err)
123123

124-
atTimeStrfmt, err := strfmt.ParseDateTime("2000-01-01T00:00:00.000Z")
124+
atTimeStrfmt, err := strfmt.ParseDateTime("2000-01-01T00:00:00Z")
125125
require.NoError(t, err)
126126
atTime := time.Time(atTimeStrfmt)
127127

pkg/buildscript/unmarshal.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"github.com/ActiveState/cli/internal/constants"
1313
"github.com/ActiveState/cli/internal/errs"
1414
"github.com/ActiveState/cli/internal/locale"
15-
"github.com/ActiveState/cli/internal/rtutils/ptr"
1615
)
1716

1817
const atTimeKey = "at_time"
@@ -72,11 +71,16 @@ func Unmarshal(data []byte) (*BuildScript, error) {
7271

7372
project = info.Project
7473

75-
atTimeStr, err := strfmt.ParseDateTime(info.Time)
74+
atTimeVal, err := time.Parse(time.RFC3339, info.Time)
7675
if err != nil {
77-
return nil, errs.Wrap(err, "Invalid timestamp: %s", info.Time)
76+
// Older buildscripts used microsecond specificity
77+
atDateTime, err := strfmt.ParseDateTime(info.Time)
78+
if err != nil {
79+
return nil, errs.Wrap(err, "Invalid timestamp: %s", info.Time)
80+
}
81+
atTimeVal = time.Time(atDateTime)
7882
}
79-
atTime = ptr.To(time.Time(atTimeStr))
83+
atTime = &atTimeVal
8084
}
8185

8286
return &BuildScript{raw, project, atTime}, nil

pkg/buildscript/unmarshal_buildexpression.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func (b *BuildScript) UnmarshalBuildExpression(data []byte) error {
7878
atTimeNode.Str = nil
7979
atTimeNode.Ident = ptr.To("TIME")
8080
// Preserve the original at_time found in the solve node.
81-
b.atTime = ptr.To(time.Time(atTime))
81+
b.SetAtTime(time.Time(atTime), true)
8282
} else if atTimeNode.Ident != nil && *atTimeNode.Ident == "at_time" {
8383
atTimeNode.Ident = ptr.To("TIME")
8484
}

scripts/to-buildscript/main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"github.com/ActiveState/cli/internal/errs"
1111
"github.com/ActiveState/cli/internal/fileutils"
1212
"github.com/ActiveState/cli/pkg/buildscript"
13-
"github.com/go-openapi/strfmt"
1413
)
1514

1615
func main() {
@@ -45,7 +44,7 @@ func main() {
4544
project := "https://platform.activestate.com/org/project?branch=main&commitID=00000000-0000-0000-0000-000000000000"
4645
var atTime *time.Time
4746
if len(os.Args) == (2 + argOffset) {
48-
t, err := time.Parse(strfmt.RFC3339Millis, os.Args[1+argOffset])
47+
t, err := time.Parse(time.RFC3339, os.Args[1+argOffset])
4948
if err != nil {
5049
panic(errs.JoinMessage(err))
5150
}

0 commit comments

Comments
 (0)