Skip to content

Commit

Permalink
Initial support for commit info in buildscript.
Browse files Browse the repository at this point in the history
Of the form:

```
Project: URL
Time: time
```
  • Loading branch information
mitchell-as committed Sep 6, 2024
1 parent 2081db6 commit 5033503
Show file tree
Hide file tree
Showing 15 changed files with 137 additions and 89 deletions.
3 changes: 1 addition & 2 deletions internal/runbits/runtime/requirements/requirements.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,7 @@ func (r *RequirementOperation) prepareBuildScript(bp *bpModel.BuildPlanner, pare
if err != nil {
return nil, errs.Wrap(err, "Unable to fetch latest Platform timestamp")
}
atTime := script.AtTime()
if atTime == nil || latest.After(*atTime) {
if latest.After(script.AtTime()) {
script.SetAtTime(latest)
}
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/buildscript/buildscript.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ func New() (*BuildScript, error) {
return UnmarshalBuildExpression([]byte(emptyBuildExpression), nil)
}

func (b *BuildScript) AtTime() *time.Time {
return b.raw.AtTime
func (b *BuildScript) AtTime() time.Time {
return b.raw.CommitInfo.AtTime
}

func (b *BuildScript) SetAtTime(t time.Time) {
b.raw.AtTime = &t
b.raw.CommitInfo.AtTime = t
}

func (b *BuildScript) Equals(other *BuildScript) (bool, error) {
Expand Down
22 changes: 14 additions & 8 deletions pkg/buildscript/buildscript_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package buildscript

import (
"fmt"
"testing"
"time"

Expand All @@ -10,10 +9,8 @@ import (
"github.com/stretchr/testify/require"
)

var atTime = "2000-01-01T00:00:00.000Z"

var basicBuildScript = []byte(fmt.Sprintf(
`at_time = "%s"
var basicBuildScript = []byte(
commitInfo(testProject, testTime) + `
runtime = state_tool_artifacts(
src = sources
)
Expand All @@ -29,7 +26,7 @@ sources = solve(
solver_version = null
)
main = runtime`, atTime))
main = runtime`)

var basicBuildExpression = []byte(`{
"let": {
Expand Down Expand Up @@ -99,10 +96,10 @@ func TestRoundTripFromBuildExpression(t *testing.T) {
// TestExpressionToScript tests that creating a build script from a given Platform build expression
// and at time produces the expected result.
func TestExpressionToScript(t *testing.T) {
ts, err := time.Parse(strfmt.RFC3339Millis, atTime)
ts, err := time.Parse(strfmt.RFC3339Millis, testTime)
require.NoError(t, err)

script, err := UnmarshalBuildExpression(basicBuildExpression, &ts)
script, err := UnmarshalBuildExpression(basicBuildExpression, &CommitInfo{testProject, ts})
require.NoError(t, err)

data, err := script.Marshal()
Expand All @@ -122,3 +119,12 @@ func TestScriptToExpression(t *testing.T) {

require.Equal(t, string(basicBuildExpression), string(data))
}

func TestOutdatedScript(t *testing.T) {
_, err := Unmarshal([]byte(
`at_time = "2000-01-01T00:00:00.000Z"
main = runtime
`))
assert.Error(t, err)
assert.ErrorIs(t, err, ErrOutdatedAtTime)
}
11 changes: 4 additions & 7 deletions pkg/buildscript/marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (

"github.com/go-openapi/strfmt"
"github.com/thoas/go-funk"

"github.com/ActiveState/cli/internal/rtutils/ptr"
)

const (
Expand All @@ -30,11 +28,10 @@ const (
func (b *BuildScript) Marshal() ([]byte, error) {
buf := strings.Builder{}

if b.raw.AtTime != nil {
buf.WriteString(assignmentString(
&Assignment{atTimeKey, &Value{Str: ptr.To(b.raw.AtTime.Format(strfmt.RFC3339Millis))}}))
buf.WriteString("\n")
}
buf.WriteString("```\n")
buf.WriteString("Project: " + b.raw.CommitInfo.Project + "\n")
buf.WriteString("Time: " + b.raw.CommitInfo.AtTime.Format(strfmt.RFC3339Millis) + "\n")
buf.WriteString("```\n\n")

var main *Assignment
for _, assignment := range b.raw.Assignments {
Expand Down
14 changes: 0 additions & 14 deletions pkg/buildscript/marshal_buildexpression.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@ package buildscript
import (
"encoding/json"
"strings"
"time"

"github.com/go-openapi/strfmt"

"github.com/ActiveState/cli/internal/errs"
"github.com/ActiveState/cli/internal/logging"
"github.com/ActiveState/cli/internal/rtutils/ptr"
)

const (
Expand Down Expand Up @@ -39,16 +35,6 @@ func (b *BuildScript) MarshalJSON() ([]byte, error) {
key := assignment.Key
value := assignment.Value
switch key {
case atTimeKey:
if value.Str == nil {
return nil, errs.New("String timestamp expected for '%s'", key)
}
atTime, err := strfmt.ParseDateTime(*value.Str)
if err != nil {
return nil, errs.Wrap(err, "Invalid timestamp: %s", *value.Str)
}
b.raw.AtTime = ptr.To(time.Time(atTime))
continue // do not include this custom assignment in the let block
case mainKey:
key = inKey // rename
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/buildscript/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ func (b *BuildScript) Merge(other *BuildScript, strategies *mono_models.MergeStr

// When merging build scripts we want to use the most recent timestamp
atTime := other.AtTime()
if atTime != nil && atTime.After(*b.AtTime()) {
b.SetAtTime(*atTime)
if atTime.After(b.AtTime()) {
b.SetAtTime(atTime)
}

return nil
Expand Down
31 changes: 17 additions & 14 deletions pkg/buildscript/merge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ import (
"github.com/stretchr/testify/require"
)

const mergeATime = "2000-01-01T00:00:00.000Z"
const mergeBTime = "2000-01-02T00:00:00.000Z"

func TestMergeAdd(t *testing.T) {
scriptA, err := Unmarshal([]byte(`
at_time = "2000-01-01T00:00:00.000Z"
scriptA, err := Unmarshal([]byte(
commitInfo(testProject, mergeATime) + `
runtime = solve(
at_time = at_time,
platforms = [
Expand All @@ -27,8 +30,8 @@ main = runtime
`))
require.NoError(t, err)

scriptB, err := Unmarshal([]byte(`
at_time = "2000-01-02T00:00:00.000Z"
scriptB, err := Unmarshal([]byte(
commitInfo(testProject, mergeBTime) + `
runtime = solve(
at_time = at_time,
platforms = [
Expand Down Expand Up @@ -60,7 +63,7 @@ main = runtime
require.NoError(t, err)

assert.Equal(t,
`at_time = "2000-01-02T00:00:00.000Z"
commitInfo(testProject, mergeBTime)+`
runtime = solve(
at_time = at_time,
platforms = [
Expand All @@ -78,8 +81,8 @@ main = runtime`, string(v))
}

func TestMergeRemove(t *testing.T) {
scriptA, err := Unmarshal([]byte(`
at_time = "2000-01-02T00:00:00.000Z"
scriptA, err := Unmarshal([]byte(
commitInfo(testProject, mergeBTime) + `
runtime = solve(
at_time = at_time,
platforms = [
Expand All @@ -97,8 +100,8 @@ main = runtime
`))
require.NoError(t, err)

scriptB, err := Unmarshal([]byte(`
at_time = "2000-01-01T00:00:00.000Z"
scriptB, err := Unmarshal([]byte(
commitInfo(testProject, mergeATime) + `
runtime = solve(
at_time = at_time,
platforms = [
Expand Down Expand Up @@ -129,7 +132,7 @@ main = runtime
require.NoError(t, err)

assert.Equal(t,
`at_time = "2000-01-02T00:00:00.000Z"
commitInfo(testProject, mergeBTime)+`
runtime = solve(
at_time = at_time,
platforms = [
Expand All @@ -146,8 +149,8 @@ main = runtime`, string(v))
}

func TestMergeConflict(t *testing.T) {
scriptA, err := Unmarshal([]byte(`
at_time = "2000-01-01T00:00:00.000Z"
scriptA, err := Unmarshal([]byte(
commitInfo(testProject, mergeATime) + `
runtime = solve(
at_time = at_time,
platforms = [
Expand All @@ -163,8 +166,8 @@ main = runtime
`))
require.NoError(t, err)

scriptB, err := Unmarshal([]byte(`
at_time = "2000-01-01T00:00:00.000Z"
scriptB, err := Unmarshal([]byte(
commitInfo(testProject, mergeATime) + `
runtime = solve(
at_time = at_time,
platforms = [
Expand Down
8 changes: 7 additions & 1 deletion pkg/buildscript/raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import (

// Tagged fields will be filled in by Participle.
type rawBuildScript struct {
Info *string `parser:"(RawString @RawString RawString)?"`
Assignments []*Assignment `parser:"@@+"`

AtTime *time.Time // set after initial read
CommitInfo CommitInfo // set after initial read
}

type Assignment struct {
Expand Down Expand Up @@ -36,3 +37,8 @@ type FuncCall struct {
Name string `parser:"@Ident"`
Arguments []*Value `parser:"'(' @@ (',' @@)* ','? ')'"`
}

type CommitInfo struct {
Project string
AtTime time.Time
}
40 changes: 30 additions & 10 deletions pkg/buildscript/raw_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,25 @@ import (
"github.com/stretchr/testify/require"
)

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

func commitInfo(project, time string) string {
return "```\n" +
"Project: " + project + "\n" +
"Time: " + time + "\n" +
"```\n"
}

var testCommitInfo string

func init() {
testCommitInfo = commitInfo(testProject, testTime)
}

func TestRawRepresentation(t *testing.T) {
script, err := Unmarshal([]byte(
`at_time = "2000-01-01T00:00:00.000Z"
testCommitInfo + `
runtime = solve(
at_time = at_time,
platforms = ["linux", "windows"],
Expand All @@ -32,6 +48,7 @@ main = runtime
atTime := time.Time(atTimeStrfmt)

assert.Equal(t, &rawBuildScript{
Info: ptr.To(testCommitInfo[2 : len(testCommitInfo)-3]),
Assignments: []*Assignment{
{"runtime", &Value{
FuncCall: &FuncCall{"solve", []*Value{
Expand Down Expand Up @@ -72,13 +89,13 @@ main = runtime
}},
{"main", &Value{Ident: ptr.To("runtime")}},
},
AtTime: &atTime,
CommitInfo: CommitInfo{testProject, atTime},
}, script.raw)
}

func TestComplex(t *testing.T) {
script, err := Unmarshal([]byte(
`at_time = "2000-01-01T00:00:00.000Z"
testCommitInfo + `
linux_runtime = solve(
at_time = at_time,
requirements=[
Expand Down Expand Up @@ -107,6 +124,7 @@ main = merge(
atTime := time.Time(atTimeStrfmt)

assert.Equal(t, &rawBuildScript{
Info: ptr.To(testCommitInfo[2 : len(testCommitInfo)-3]),
Assignments: []*Assignment{
{"linux_runtime", &Value{
FuncCall: &FuncCall{"solve", []*Value{
Expand Down Expand Up @@ -152,11 +170,14 @@ main = merge(
{FuncCall: &FuncCall{"tar_installer", []*Value{{Ident: ptr.To("linux_runtime")}}}},
}}}},
},
AtTime: &atTime,
CommitInfo: CommitInfo{testProject, atTime},
}, script.raw)
}

const buildscriptWithComplexVersions = `at_time = "2023-04-27T17:30:05.999Z"
func TestComplexVersions(t *testing.T) {
commitInfo := commitInfo(testProject, "2023-04-27T17:30:05.999Z")
script, err := Unmarshal([]byte(
commitInfo + `
runtime = solve(
at_time = at_time,
platforms = ["96b7e6f2-bebf-564c-bc1c-f04482398f38", "96b7e6f2-bebf-564c-bc1c-f04482398f38"],
Expand All @@ -168,17 +189,16 @@ runtime = solve(
solver_version = 0
)
main = runtime`

func TestComplexVersions(t *testing.T) {
script, err := Unmarshal([]byte(buildscriptWithComplexVersions))
main = runtime
`))
require.NoError(t, err)

atTimeStrfmt, err := strfmt.ParseDateTime("2023-04-27T17:30:05.999Z")
require.NoError(t, err)
atTime := time.Time(atTimeStrfmt)

assert.Equal(t, &rawBuildScript{
Info: ptr.To(commitInfo[2 : len(commitInfo)-3]),
Assignments: []*Assignment{
{"runtime", &Value{
FuncCall: &FuncCall{"solve", []*Value{
Expand Down Expand Up @@ -246,6 +266,6 @@ func TestComplexVersions(t *testing.T) {
}},
{"main", &Value{Ident: ptr.To("runtime")}},
},
AtTime: &atTime,
CommitInfo: CommitInfo{testProject, atTime},
}, script.raw)
}
Loading

0 comments on commit 5033503

Please sign in to comment.