Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pkg/commands/compute/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ func TestBuildRust(t *testing.T) {
language = "rust"`,
cargoManifest: `
[package]
name = "test"`,
wantError: "failed to find SDK 'fastly' in the 'Cargo.toml' manifest",
name = "test"
version = "1.0.0"`,
wantError: "required dependency missing",
applicationConfig: config.File{
Language: config.Language{
Rust: config.Rust{
Expand Down
1 change: 1 addition & 0 deletions pkg/commands/compute/language_assemblyscript.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func NewAssemblyScript(
FastlyManifestFile: fastlyManifest,
Installer: JsInstaller,
Manifest: JsManifest,
ManifestCommand: JsManifestCommand,
ManifestRemediation: JsManifestRemediation,
Output: out,
PatchedManifestNotifier: ch,
Expand Down
53 changes: 52 additions & 1 deletion pkg/commands/compute/language_go.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package compute

import (
"encoding/json"
"errors"
"fmt"
"io"
"regexp"

Expand Down Expand Up @@ -42,12 +45,16 @@ const GoInstaller = "go mod download"
// GoManifest is the manifest file for defining project configuration.
const GoManifest = "go.mod"

// GoManifestCommand is the toolchain command to validate the manifest exists,
// and also enables parsing of the project's dependencies.
const GoManifestCommand = "go mod edit -json"

// GoManifestRemediation is a error remediation message for a missing manifest.
const GoManifestRemediation = "go mod init"

// GoSDK is the required Compute@Edge SDK.
// https://pkg.go.dev/github.com/fastly/compute-sdk-go
const GoSDK = "fastly/compute-sdk-go"
const GoSDK = "github.com/fastly/compute-sdk-go"

// GoSourceDirectory represents the source code directory. │ │
const GoSourceDirectory = "."
Expand Down Expand Up @@ -89,10 +96,12 @@ func NewGo(
FastlyManifestFile: fastlyManifest,
Installer: GoInstaller,
Manifest: GoManifest,
ManifestCommand: GoManifestCommand,
ManifestRemediation: GoManifestRemediation,
Output: out,
PatchedManifestNotifier: ch,
SDK: GoSDK,
SDKCustomValidator: validateGoSDK,
Toolchain: GoToolchain,
ToolchainLanguage: "Go",
ToolchainVersionCommand: GoToolchainVersionCommand,
Expand Down Expand Up @@ -147,3 +156,45 @@ func (g *Go) Build(out io.Writer, progress text.Progress, verbose bool, callback
timeout: g.timeout,
}, out, progress, verbose, nil, callback)
}

// GoDependency represents the project's SDK and version.
type GoDependency struct {
Path string
Version string
}

// GoMod represents the project's go.mod manifest.
type GoMod struct {
Require []GoDependency
}

// validateGoSDK uses the Go toolchain to identify if the required SDK
// dependency is installed.
func validateGoSDK(sdk string, manifestCommandOutput []byte, _ chan string) error {
var gm GoMod

err := json.Unmarshal(manifestCommandOutput, &gm)
if err != nil {
return fmt.Errorf("failed to unmarshal manifest metadata: %w", err)
}

remediation := fmt.Sprintf("Ensure your %s is valid and contains the '%s' dependency.", GoManifest, sdk)

if len(gm.Require) < 1 {
return fsterr.RemediationError{
Inner: errors.New("no dependencies declared"),
Remediation: remediation,
}
}

for _, gd := range gm.Require {
if gd.Path == sdk {
return nil
}
}

return fsterr.RemediationError{
Inner: errors.New("required dependency missing"),
Remediation: remediation,
}
}
75 changes: 41 additions & 34 deletions pkg/commands/compute/language_javascript.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"
"io"
"strings"

fsterr "github.com/fastly/cli/pkg/errors"
"github.com/fastly/cli/pkg/manifest"
Expand Down Expand Up @@ -47,6 +46,10 @@ const JsInstaller = "npm install"
// JsManifest is the manifest file for defining project configuration.
const JsManifest = "package.json"

// JsManifestCommand is the toolchain command to validate the manifest exists,
// and also enables parsing of the project's dependencies.
const JsManifestCommand = "npm list --json --depth 0"

// JsManifestRemediation is a error remediation message for a missing manifest.
const JsManifestRemediation = "npm init"

Expand Down Expand Up @@ -77,24 +80,26 @@ func NewJavaScript(
postBuild: fastlyManifest.Scripts.PostBuild,
timeout: timeout,
validator: ToolchainValidator{
Compilation: JsCompilation,
CompilationIntegrated: true,
CompilationSkipVersion: true,
CompilationURL: JsCompilationURL,
DefaultBuildCommand: JsDefaultBuildCommand,
ErrLog: errlog,
FastlyManifestFile: fastlyManifest,
Installer: JsInstaller,
Manifest: JsManifest,
ManifestRemediation: JsManifestRemediation,
Output: out,
PatchedManifestNotifier: ch,
SDK: JsSDK,
SDKCustomValidator: validateJsSDK,
Toolchain: JsToolchain,
ToolchainLanguage: "JavaScript",
ToolchainSkipVersion: true,
ToolchainURL: JsToolchainURL,
Compilation: JsCompilation,
CompilationIntegrated: true,
CompilationSkipVersion: true,
CompilationURL: JsCompilationURL,
DefaultBuildCommand: JsDefaultBuildCommand,
ErrLog: errlog,
FastlyManifestFile: fastlyManifest,
Installer: JsInstaller,
Manifest: JsManifest,
ManifestCommand: JsManifestCommand,
ManifestCommandSkipError: true,
ManifestRemediation: JsManifestRemediation,
Output: out,
PatchedManifestNotifier: ch,
SDK: JsSDK,
SDKCustomValidator: validateJsSDK,
Toolchain: JsToolchain,
ToolchainLanguage: "JavaScript",
ToolchainSkipVersion: true,
ToolchainURL: JsToolchainURL,
},
}
}
Expand Down Expand Up @@ -140,34 +145,41 @@ func (j JavaScript) Build(out io.Writer, progress text.Progress, verbose bool, c
}, out, progress, verbose, nil, callback)
}

// JsDependency represents the project's SDK and version.
type JsDependency struct {
Version string `json:"version"`
Resolved string `json:"resolved"`
}

// JsPackage represents a package.json manifest.
//
// NOTE: npm returns JSON that has an `invalid` field.
// This means we know when searching for the manifest has failed.
type JsPackage struct {
Dependencies map[string]string `json:"dependencies"`
DevDependencies map[string]string `json:"devDependencies"`
Scripts map[string]string `json:"scripts"`
Dependencies map[string]JsDependency `json:"dependencies"`
}

// validateJsSDK marshals the JS manifest into JSON to check if the dependency
// has been defined in the package.json manifest.
//
// NOTE: This function also causes a side-effect of modifying the default build
// script based on the user's project context (e.g does it require webpack).
func validateJsSDK(name string, bs []byte, notifier chan string) error {
e := fmt.Errorf(SDKErrMessageFormat, name, JsManifest)
func validateJsSDK(sdk string, manifestCommandOutput []byte, notifier chan string) error {
e := fmt.Errorf(SDKErrMessageFormat, sdk, JsManifest)

var p JsPackage

err := json.Unmarshal(bs, &p)
err := json.Unmarshal(manifestCommandOutput, &p)
if err != nil {
return fsterr.RemediationError{
Inner: fmt.Errorf("failed to unmarshal package.json: %w", err),
Remediation: fmt.Sprintf("Ensure your package.json is valid and contains the '%s' dependency.", name),
Remediation: fmt.Sprintf("Ensure your package.json is valid and contains the '%s' dependency.", sdk),
}
}

var needsWebpack bool
for k, v := range p.Scripts {
if k == "prebuild" && strings.Contains(v, "webpack") {
for k := range p.Dependencies {
if k == "webpack" {
needsWebpack = true
break
}
Expand All @@ -182,12 +194,7 @@ func validateJsSDK(name string, bs []byte, notifier chan string) error {
}()

for k := range p.Dependencies {
if k == name {
return nil
}
}
for k := range p.DevDependencies {
if k == name {
if k == sdk {
return nil
}
}
Expand Down
Loading