Skip to content

Commit

Permalink
Synchronize build script when changing checkout info like commitID.
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchell-as committed Sep 30, 2024
1 parent 5bfd1cd commit fb8182c
Show file tree
Hide file tree
Showing 13 changed files with 103 additions and 26 deletions.
2 changes: 1 addition & 1 deletion internal/migrator/migrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func NewMigrator(auth *authentication.Auth, cfg *config.Instance, svcm *model.Sv
case 0:
if cfg.GetBool(constants.OptinBuildscriptsConfig) {
logging.Debug("Creating buildscript")
info := checkoutinfo.New(project)
info := checkoutinfo.New(project, cfg)
if err := buildscript_runbit.Initialize(filepath.Dir(project.Path()), auth, svcm, info); err != nil {
return v, errs.Wrap(err, "Failed to initialize buildscript")
}
Expand Down
4 changes: 2 additions & 2 deletions internal/primer/primer.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ func New(values ...any) *Values {
}
}
}
result.checkoutinfo = checkoutinfo.New(result.projectfile)
result.checkoutinfo = checkoutinfo.New(result.projectfile, result.config)
return result
}

func (v *Values) SetProject(p *project.Project) {
v.project = p
v.projectfile = p.Source()
v.checkoutinfo = checkoutinfo.New(v.projectfile)
v.checkoutinfo = checkoutinfo.New(v.projectfile, v.config)
}

type Projecter interface {
Expand Down
6 changes: 3 additions & 3 deletions internal/runbits/buildscript/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type projecter interface {
Name() string
}

var ErrBuildscriptNotExist = errors.New("Build script does not exist")
var ErrBuildscriptNotExist = checkoutinfo.ErrBuildscriptNotExist

func ScriptFromProject(proj projecter) (*buildscript.BuildScript, error) {
path := filepath.Join(proj.ProjectDir(), constants.BuildScriptFileName)
Expand All @@ -47,11 +47,11 @@ func Initialize(path string, auth *authentication.Auth, svcm *model.SvcModel, in
if err == nil {
return nil // nothing to do, buildscript already exists
}
if !errors.Is(err, os.ErrNotExist) {
if !errors.Is(err, os.ErrNotExist) && !errors.Is(err, buildscript.ErrOutdatedAtTime) {
return errs.Wrap(err, "Could not read build script from file")
}

logging.Debug("Build script does not exist. Creating one.")
logging.Debug("Build script does not exist or is outdated. Creating one.")
commitId, err := info.CommitID()
if err != nil {
return errs.Wrap(err, "Unable to get the local commit ID")
Expand Down
2 changes: 1 addition & 1 deletion internal/runbits/checkout/checkout.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (r *Checkout) Run(ns *project.Namespaced, branchName, cachePath, targetPath

// Clone the related repo, if it is defined
if !noClone && repoURL != nil && *repoURL != "" {
err := r.repo.CloneProject(ns.Owner, ns.Project, path, r.prime.Output(), r.prime.Analytics())
err := r.repo.CloneProject(ns.Owner, ns.Project, path, r.prime.Output(), r.prime.Analytics(), r.prime.Config())
if err != nil {
return "", locale.WrapError(err, "err_clone_project", "Could not clone associated git repository")
}
Expand Down
11 changes: 6 additions & 5 deletions internal/runbits/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/ActiveState/cli/internal/analytics"
anaConsts "github.com/ActiveState/cli/internal/analytics/constants"
"github.com/ActiveState/cli/internal/config"
"github.com/ActiveState/cli/internal/constants"
"github.com/ActiveState/cli/internal/errs"
"github.com/ActiveState/cli/internal/fileutils"
Expand All @@ -22,7 +23,7 @@ import (

// Repository is the interface used to represent a version control system repository
type Repository interface {
CloneProject(owner, name, path string, out output.Outputer, an analytics.Dispatcher) error
CloneProject(owner, name, path string, out output.Outputer, an analytics.Dispatcher, cfg *config.Instance) error
}

// NewRepo returns a new repository
Expand All @@ -36,7 +37,7 @@ type Repo struct {

// CloneProject will attempt to clone the associalted public git repository
// for the project identified by <owner>/<name> to the given directory
func (r *Repo) CloneProject(owner, name, path string, out output.Outputer, an analytics.Dispatcher) error {
func (r *Repo) CloneProject(owner, name, path string, out output.Outputer, an analytics.Dispatcher, cfg *config.Instance) error {
project, err := model.LegacyFetchProjectByName(owner, name)
if err != nil {
return locale.WrapError(err, "err_git_fetch_project", "Could not fetch project details")
Expand Down Expand Up @@ -67,7 +68,7 @@ func (r *Repo) CloneProject(owner, name, path string, out output.Outputer, an an
return errs.AddTips(err, tipMsg)
}

err = EnsureCorrectProject(owner, name, filepath.Join(tempDir, constants.ConfigFileName), *project.RepoURL, out, an)
err = EnsureCorrectProject(owner, name, filepath.Join(tempDir, constants.ConfigFileName), *project.RepoURL, out, an, cfg)
if err != nil {
return locale.WrapError(err, "err_git_ensure_project", "Could not ensure that the activestate.yaml in the cloned repository matches the project you are activating.")
}
Expand All @@ -80,7 +81,7 @@ func (r *Repo) CloneProject(owner, name, path string, out output.Outputer, an an
return nil
}

func EnsureCorrectProject(owner, name, projectFilePath, repoURL string, out output.Outputer, an analytics.Dispatcher) error {
func EnsureCorrectProject(owner, name, projectFilePath, repoURL string, out output.Outputer, an analytics.Dispatcher, cfg *config.Instance) error {
if !fileutils.FileExists(projectFilePath) {
return nil
}
Expand All @@ -97,7 +98,7 @@ func EnsureCorrectProject(owner, name, projectFilePath, repoURL string, out outp

if !(strings.EqualFold(proj.Owner(), owner)) || !(strings.EqualFold(proj.Name(), name)) {
out.Notice(locale.Tr("warning_git_project_mismatch", repoURL, project.NewNamespace(owner, name, "").String(), constants.DocumentationURLMismatch))
info := checkoutinfo.New(projectFile)
info := checkoutinfo.New(projectFile, cfg)
err = info.SetNamespace(owner, name)
if err != nil {
return locale.WrapError(err, "err_git_update_mismatch", "Could not update projectfile namespace")
Expand Down
2 changes: 1 addition & 1 deletion internal/runners/deploy/uninstall/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (u *Uninstall) Run(params *Params) error {
return locale.WrapError(err, "err_deploy_uninstall_cannot_read_project", "Cannot read project at '{{.V0}}'", path)
}

commitID, err := checkoutinfo.New(proj.Source()).CommitID()
commitID, err := checkoutinfo.New(proj.Source(), u.cfg).CommitID()
if err != nil {
return locale.WrapError(err, "err_deploy_uninstall_cannot_read_commit", "Cannot read commit ID from project at '{{.V0}}'", path)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/runners/initialize/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func inferLanguage(config projectfile.ConfigGetter, auth *authentication.Auth) (
if err != nil {
return "", "", false
}
commitID, err := checkoutinfo.New(defaultProj.Source()).CommitID()
commitID, err := checkoutinfo.New(defaultProj.Source(), config).CommitID()
if err != nil {
multilog.Error("Unable to get commit ID: %v", errs.JoinMessage(err))
return "", "", false
Expand Down
2 changes: 1 addition & 1 deletion internal/runners/projects/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (e *Edit) editLocalCheckout(owner, checkout string, params *EditParams) err
return errs.Wrap(err, "Could not get projectfile at %s", checkout)
}

info := checkoutinfo.New(pjFile)
info := checkoutinfo.New(pjFile, e.config)
err = info.SetNamespace(owner, params.ProjectName)
if err != nil {
return errs.Wrap(err, "Could not set project namespace at %s", checkout)
Expand Down
2 changes: 1 addition & 1 deletion internal/runners/projects/move.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (m *Move) updateLocalCheckout(checkout string, params *MoveParams) error {
return errs.Wrap(err, "Could not get projectfile at %s", checkout)
}

info := checkoutinfo.New(pjFile)
info := checkoutinfo.New(pjFile, m.config)
err = info.SetNamespace(params.NewOwner, params.Namespace.Project)
if err != nil {
return errs.Wrap(err, "Could not set project namespace at %s", checkout)
Expand Down
10 changes: 5 additions & 5 deletions internal/runners/reset/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,6 @@ func (r *Reset) Run(params *Params) error {
}
}

err = r.prime.CheckoutInfo().SetCommitID(commitID)
if err != nil {
return errs.Wrap(err, "Unable to set local commit")
}

// Ensure the buildscript exists. Normally we should never do this, but reset is used for resetting from a corrupted
// state, so it is appropriate.
if r.cfg.GetBool(constants.OptinBuildscriptsConfig) {
Expand All @@ -140,6 +135,11 @@ func (r *Reset) Run(params *Params) error {
}
}

err = r.prime.CheckoutInfo().SetCommitID(commitID)
if err != nil {
return errs.Wrap(err, "Unable to set local commit")
}

_, err = runtime_runbit.Update(r.prime, trigger.TriggerReset, runtime_runbit.WithoutBuildscriptValidation())
if err != nil {
return locale.WrapError(err, "err_refresh_runtime")
Expand Down
8 changes: 8 additions & 0 deletions pkg/buildscript/buildscript.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ func New() (*BuildScript, error) {
return UnmarshalBuildExpression([]byte(emptyBuildExpression), nil)
}

func (b *BuildScript) Project() string {
return b.raw.CheckoutInfo.Project
}

func (b *BuildScript) SetProject(url string) {
b.raw.CheckoutInfo.Project = url
}

func (b *BuildScript) AtTime() time.Time {
return b.raw.CheckoutInfo.AtTime
}
Expand Down
77 changes: 72 additions & 5 deletions pkg/checkoutinfo/checkoutinfo.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
package checkoutinfo

import (
"errors"
"os"
"path/filepath"

"github.com/go-openapi/strfmt"

"github.com/ActiveState/cli/internal/constants"
"github.com/ActiveState/cli/internal/errs"
"github.com/ActiveState/cli/internal/fileutils"
"github.com/ActiveState/cli/pkg/buildscript"
)

type ErrInvalidCommitID struct {
Expand All @@ -20,14 +29,23 @@ type projectfiler interface {
SetNamespace(string, string) error
SetBranch(string) error
SetLegacyCommit(string) error
Dir() string
URL() string
}

type configurer interface {
GetBool(string) bool
}

type CheckoutInfo struct {
project projectfiler
config configurer
}

func New(project projectfiler) *CheckoutInfo {
return &CheckoutInfo{project}
var ErrBuildscriptNotExist = errors.New("Build script does not exist")

func New(project projectfiler, config configurer) *CheckoutInfo {
return &CheckoutInfo{project, config}
}

// Owner returns the project owner from activestate.yaml.
Expand Down Expand Up @@ -57,13 +75,62 @@ func (c *CheckoutInfo) CommitID() (strfmt.UUID, error) {
}

func (c *CheckoutInfo) SetNamespace(owner, project string) error {
return c.project.SetNamespace(owner, project)
err := c.project.SetNamespace(owner, project)
if err != nil {
return errs.Wrap(err, "Unable to update project")
}
return c.updateBuildScriptProject()
}

func (c *CheckoutInfo) SetBranch(branch string) error {
return c.project.SetBranch(branch)
err := c.project.SetBranch(branch)
if err != nil {
return errs.Wrap(err, "Unable to update project")
}
return c.updateBuildScriptProject()
}

func (c *CheckoutInfo) SetCommitID(commitID strfmt.UUID) error {
return c.project.SetLegacyCommit(commitID.String())
err := c.project.SetLegacyCommit(commitID.String())
if err != nil {
return errs.Wrap(err, "Unable to update project")
}
return c.updateBuildScriptProject()
}

func (c *CheckoutInfo) updateBuildScriptProject() error {
if !c.config.GetBool(constants.OptinBuildscriptsConfig) {
return nil
}

// Note: cannot use functions from buildscript_runbit due to import cycle.
scriptPath := filepath.Join(c.project.Dir(), constants.BuildScriptFileName)
data, err := fileutils.ReadFile(scriptPath)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return errs.Pack(err, ErrBuildscriptNotExist)
}
return errs.Wrap(err, "Could not read build script from file")
}

script, err := buildscript.Unmarshal(data)
if err != nil {
return errs.Wrap(err, "Could not unmarshal build script")
}

if c.project.URL() == script.Project() {
return nil //nothing to update
}
script.SetProject(c.project.URL())

data, err = script.Marshal()
if err != nil {
return errs.Wrap(err, "Could not marshal build script")
}

if err := fileutils.WriteFile(scriptPath, data); err != nil {
return errs.Wrap(err, "Could not write build script to file")
}

return nil
}
1 change: 1 addition & 0 deletions pkg/projectfile/projectfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,7 @@ type ConfigGetter interface {
AllKeys() []string
GetStringSlice(string) []string
GetString(string) string
GetBool(string) bool
Set(string, interface{}) error
GetThenSet(string, func(interface{}) (interface{}, error)) error
Close() error
Expand Down

0 comments on commit fb8182c

Please sign in to comment.