diff --git a/.fastly/config.toml b/.fastly/config.toml index 097f79b38..2e2a6ac36 100644 --- a/.fastly/config.toml +++ b/.fastly/config.toml @@ -18,7 +18,7 @@ toolchain_constraint = ">= 1.21" # Go toolchain constraint for use wit toolchain_constraint_tinygo = ">= 1.18" # Go toolchain constraint for use with TinyGo. [language.rust] -toolchain_constraint = ">= 1.56.1" +toolchain_constraint = ">= 1.56.1, <1.84.0" wasm_wasi_target = "wasm32-wasi" [wasm-tools] diff --git a/pkg/commands/compute/language_go.go b/pkg/commands/compute/language_go.go index aeadc66ab..161863d84 100644 --- a/pkg/commands/compute/language_go.go +++ b/pkg/commands/compute/language_go.go @@ -2,6 +2,7 @@ package compute import ( "bufio" + "errors" "fmt" "io" "os" @@ -315,7 +316,8 @@ func (g *Go) toolchainConstraint(toolchain, pattern, constraint string) { return } - if !c.Check(v) { - text.Warning(g.output, "The %s version '%s' didn't meet the constraint '%s'\n\n", toolchain, version, constraint) + valid, errs := c.Validate(v) + if !valid { + text.Warning(g.output, "The %s version requirement was not satisfied: %s", toolchain, errors.Join(errs...)) } } diff --git a/pkg/commands/compute/language_rust.go b/pkg/commands/compute/language_rust.go index 2ae33deca..c57bddba3 100644 --- a/pkg/commands/compute/language_rust.go +++ b/pkg/commands/compute/language_rust.go @@ -3,6 +3,7 @@ package compute import ( "bytes" "encoding/json" + "errors" "fmt" "io" "os" @@ -157,7 +158,10 @@ func (r *Rust) Build() error { text.Info(r.output, "No [scripts.build] found in %s. The following default build command for Rust will be used: `%s`\n\n", r.manifestFilename, r.build) } - version := r.toolchainConstraint() + version, err := r.toolchainConstraint() + if err != nil { + return err + } if version != nil { err := r.checkCargoConfigFileName(version) @@ -296,12 +300,8 @@ func (r *Rust) modifyCargoPackageName(noBuildScript bool) error { return nil } -// toolchainConstraint warns the user if the required constraint is not met. -// -// NOTE: We don't stop the build as their toolchain may compile successfully. -// The warning is to help a user know something isn't quite right and gives them -// the opportunity to do something about it if they choose. -func (r *Rust) toolchainConstraint() *semver.Version { +// toolchainConstraint generates an error if the toolchain constraint is not met. +func (r *Rust) toolchainConstraint() (*semver.Version, error) { if r.verbose { text.Info(r.output, "The Fastly CLI requires a Rust version '%s'.\n\n", r.config.ToolchainConstraint) } @@ -318,31 +318,40 @@ func (r *Rust) toolchainConstraint() *semver.Version { stdout, err := cmd.Output() output := string(stdout) if err != nil { - return nil + return nil, err } versionPattern := regexp.MustCompile(`cargo (?P\d[^\s]+)`) match := versionPattern.FindStringSubmatch(output) if len(match) < 2 { // We expect a pattern with one capture group. - return nil + return nil, fmt.Errorf("unable to obtain a version number from the 'cargo' command") } version := match[1] v, err := semver.NewVersion(version) if err != nil { - return nil + return nil, fmt.Errorf("the version string '%s' reported by the 'cargo' command is not a valid version number", version) } c, err := semver.NewConstraint(r.config.ToolchainConstraint) if err != nil { - return nil + return nil, fmt.Errorf("the 'toolchain_constraint' value '%s' (from the config.toml file) is not a valid version constraint", r.config.ToolchainConstraint) } - if !c.Check(v) { - text.Warning(r.output, "The Rust version '%s' didn't meet the constraint '%s'\n\n", version, r.config.ToolchainConstraint) + valid, errs := c.Validate(v) + if !valid { + for _, err = range errs { + // if an 'upper bound' constraint was + // violated, generate an error message + // specific to that situation + if strings.Contains(err.Error(), "is greater than") { + return nil, fmt.Errorf("version '%s' of Rust has not been validated for use with Fastly Compute", v) + } + } + return nil, fmt.Errorf("the Rust version requirement was not satisfied: '%w'", errors.Join(errs...)) } - return v + return v, nil } func (r *Rust) checkCargoConfigFileName(rustVersion *semver.Version) error {