Skip to content

Commit

Permalink
Implement dynamic package name (#686)
Browse files Browse the repository at this point in the history
  • Loading branch information
Integralist authored Oct 19, 2022
1 parent 202880a commit 8bbc210
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 21 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ require (
)

require (
github.com/kennygrant/sanitize v1.2.4
github.com/mholt/archiver v3.1.1+incompatible
github.com/otiai10/copy v1.7.0
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
Expand All @@ -54,5 +55,6 @@ require (
github.com/ulikunitz/xz v0.5.10 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYb
github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE=
github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro=
github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8=
github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o=
github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
Expand Down
2 changes: 1 addition & 1 deletion pkg/app/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func defineCommands(
computePublish := compute.NewPublishCommand(computeCmdRoot.CmdClause, globals, computeBuild, computeDeploy, data)
computeServe := compute.NewServeCommand(computeCmdRoot.CmdClause, globals, computeBuild, opts.Versioners.Viceroy, data)
computeUpdate := compute.NewUpdateCommand(computeCmdRoot.CmdClause, globals, data)
computeValidate := compute.NewValidateCommand(computeCmdRoot.CmdClause, globals)
computeValidate := compute.NewValidateCommand(computeCmdRoot.CmdClause, globals, data)
configCmdRoot := config.NewRootCommand(app, globals)
dictionaryCmdRoot := dictionary.NewRootCommand(app, globals)
dictionaryCreate := dictionary.NewCreateCommand(dictionaryCmdRoot.CmdClause, globals, data)
Expand Down
21 changes: 20 additions & 1 deletion pkg/commands/compute/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/fastly/cli/pkg/filesystem"
"github.com/fastly/cli/pkg/manifest"
"github.com/fastly/cli/pkg/text"
"github.com/kennygrant/sanitize"
"github.com/mholt/archiver/v3"
)

Expand All @@ -30,6 +31,7 @@ const CustomPostBuildScriptMessage = "This project has a custom post build scrip
type Flags struct {
IncludeSrc bool
Lang string
PackageName string
SkipVerification bool
Timeout int
}
Expand All @@ -55,6 +57,7 @@ func NewBuildCommand(parent cmd.Registerer, globals *config.Data, data manifest.
// `compute publish` and `compute serve`.
c.CmdClause.Flag("include-source", "Include source code in built package").BoolVar(&c.Flags.IncludeSrc)
c.CmdClause.Flag("language", "Language type").StringVar(&c.Flags.Lang)
c.CmdClause.Flag("package-name", "Package name").StringVar(&c.Flags.PackageName)
c.CmdClause.Flag("skip-verification", "Skip verification steps and force build").BoolVar(&c.Flags.SkipVerification)
c.CmdClause.Flag("timeout", "Timeout, in seconds, for the build compilation step").IntVar(&c.Flags.Timeout)

Expand Down Expand Up @@ -83,6 +86,22 @@ func (c *BuildCommand) Exec(in io.Reader, out io.Writer) (err error) {
return err
}

var packageName string

switch {
case c.Flags.PackageName != "":
packageName = c.Flags.PackageName
case c.Manifest.File.Name != "":
packageName = c.Manifest.File.Name // use the project name as a fallback
default:
return fsterr.RemediationError{
Inner: fmt.Errorf("package name is missing"),
Remediation: "Add a name to the fastly.toml 'name' field. Reference: https://developer.fastly.com/reference/compute/fastly-toml/",
}
}

packageName = sanitize.BaseName(packageName)

// Language from flag takes priority, otherwise infer from manifest and
// error if neither are provided. Sanitize by trim and lowercase.
var toolchain string
Expand Down Expand Up @@ -230,7 +249,7 @@ func (c *BuildCommand) Exec(in io.Reader, out io.Writer) (err error) {
progress = text.ResetProgress(out, c.Globals.Verbose())
progress.Step("Creating package archive...")

dest := filepath.Join("pkg", "package.tar.gz")
dest := filepath.Join("pkg", fmt.Sprintf("%s.tar.gz", packageName))

files := []string{
manifest.Filename,
Expand Down
19 changes: 13 additions & 6 deletions pkg/commands/compute/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/fastly/cli/pkg/text"
"github.com/fastly/cli/pkg/undo"
"github.com/fastly/go-fastly/v6/fastly"
"github.com/kennygrant/sanitize"
"github.com/mholt/archiver/v3"
)

Expand Down Expand Up @@ -400,7 +401,8 @@ func validatePackage(
}
}

pkgPath, err = packagePath(packageFlag)
projectName, source := data.Name()
pkgPath, err = packagePath(packageFlag, projectName, source)
if err != nil {
errLog.AddWithContext(err, map[string]any{
"Package path": packageFlag,
Expand All @@ -413,7 +415,10 @@ func validatePackage(
errLog.AddWithContext(err, map[string]any{
"Package path": pkgPath,
})
return pkgPath, hashSum, err
return pkgPath, hashSum, fsterr.RemediationError{
Inner: fmt.Errorf("error reading package size: %w", err),
Remediation: "Run `fastly compute build` to produce a Compute@Edge package, alternatively use the --package flag to reference a package outside of the current project.",
}
}

if pkgSize > PackageSizeLimit {
Expand Down Expand Up @@ -522,11 +527,13 @@ func locateManifest(path string) (string, error) {
}

// packagePath generates a path that points to a package tar inside the pkg
// directory if the `path` flag was not set by the user.
func packagePath(path string) (string, error) {
// directory if the package path flag was not set by the user.
func packagePath(path, projectName string, source manifest.Source) (string, error) {
if path == "" {
path = filepath.Join("pkg", "package.tar.gz")
return path, nil
if source == manifest.SourceUndefined {
return "", fsterr.ErrReadingManifest
}
path = filepath.Join("pkg", fmt.Sprintf("%s.tar.gz", sanitize.BaseName(projectName)))
}
return path, nil
}
Expand Down
6 changes: 5 additions & 1 deletion pkg/commands/compute/hashsum.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@ func (c *HashsumCommand) Exec(in io.Reader, out io.Writer) (err error) {

_, hashSum, err := validatePackage(c.Manifest, c.Package, c.Globals.Verbose(), c.Globals.ErrLog, out)
if err != nil {
var skipBuildMsg string
if c.SkipBuild {
skipBuildMsg = " avoid using --skip-build, or"
}
return fsterr.RemediationError{
Inner: fmt.Errorf("failed to validate package: %w", err),
Remediation: "Run `fastly compute build` to produce a Compute@Edge package, alternatively use the --package flag to reference a package outside of the current project.",
Remediation: fmt.Sprintf("Run `fastly compute build` to produce a Compute@Edge package, alternatively%s use the --package flag to reference a package outside of the current project.", skipBuildMsg),
}
}

Expand Down
8 changes: 7 additions & 1 deletion pkg/commands/compute/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,13 @@ func verifyDestination(path string, progress text.Progress) (dst string, err err
// promptOrReturn will prompt the user for information missing from the
// fastly.toml manifest file, otherwise if it already exists then the value is
// returned as is.
func promptOrReturn(flags config.Flag, m manifest.Data, path, email string, in io.Reader, out io.Writer) (name, description string, authors []string, err error) {
func promptOrReturn(
flags config.Flag,
m manifest.Data,
path, email string,
in io.Reader,
out io.Writer,
) (name, description string, authors []string, err error) {
name, _ = m.Name()
name, err = packageName(flags, name, path, in, out)
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions pkg/commands/compute/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type PublishCommand struct {
// Build fields
includeSrc cmd.OptionalBool
lang cmd.OptionalString
packageName cmd.OptionalString
skipVerification cmd.OptionalBool
timeout cmd.OptionalInt

Expand All @@ -44,6 +45,7 @@ func NewPublishCommand(parent cmd.Registerer, globals *config.Data, build *Build
c.CmdClause.Flag("include-source", "Include source code in built package").Action(c.includeSrc.Set).BoolVar(&c.includeSrc.Value)
c.CmdClause.Flag("language", "Language type").Action(c.lang.Set).StringVar(&c.lang.Value)
c.CmdClause.Flag("package", "Path to a package tar.gz").Short('p').Action(c.pkg.Set).StringVar(&c.pkg.Value)
c.CmdClause.Flag("package-name", "Package name").Action(c.packageName.Set).StringVar(&c.packageName.Value)
c.RegisterFlag(cmd.StringFlagOpts{
Name: cmd.FlagServiceIDName,
Description: cmd.FlagServiceIDDesc,
Expand Down Expand Up @@ -83,6 +85,9 @@ func (c *PublishCommand) Exec(in io.Reader, out io.Writer) (err error) {
if c.lang.WasSet {
c.build.Flags.Lang = c.lang.Value
}
if c.packageName.WasSet {
c.build.Flags.PackageName = c.packageName.Value
}
if c.skipVerification.WasSet {
c.build.Flags.SkipVerification = c.skipVerification.Value
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/commands/compute/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type ServeCommand struct {
// Build fields
includeSrc cmd.OptionalBool
lang cmd.OptionalString
packageName cmd.OptionalString
skipVerification cmd.OptionalBool
timeout cmd.OptionalInt

Expand Down Expand Up @@ -70,6 +71,7 @@ func NewServeCommand(parent cmd.Registerer, globals *config.Data, build *BuildCo
c.CmdClause.Flag("file", "The Wasm file to run").Default("bin/main.wasm").StringVar(&c.file)
c.CmdClause.Flag("include-source", "Include source code in built package").Action(c.includeSrc.Set).BoolVar(&c.includeSrc.Value)
c.CmdClause.Flag("language", "Language type").Action(c.lang.Set).StringVar(&c.lang.Value)
c.CmdClause.Flag("package-name", "Package name").Action(c.packageName.Set).StringVar(&c.packageName.Value)
c.CmdClause.Flag("skip-build", "Skip the build step").BoolVar(&c.skipBuild)
c.CmdClause.Flag("skip-verification", "Skip verification steps and force build").Action(c.skipVerification.Set).BoolVar(&c.skipVerification.Value)
c.CmdClause.Flag("timeout", "Timeout, in seconds, for the build compilation step").Action(c.timeout.Set).IntVar(&c.timeout.Value)
Expand Down Expand Up @@ -133,6 +135,9 @@ func (c *ServeCommand) Build(in io.Reader, out io.Writer) error {
if c.lang.WasSet {
c.build.Flags.Lang = c.lang.Value
}
if c.packageName.WasSet {
c.build.Flags.PackageName = c.packageName.Value
}
if c.skipVerification.WasSet {
c.build.Flags.SkipVerification = c.skipVerification.Value
}
Expand Down
29 changes: 23 additions & 6 deletions pkg/commands/compute/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package compute
import (
"fmt"
"io"
"path/filepath"

"github.com/fastly/cli/pkg/cmd"
"github.com/fastly/cli/pkg/config"
"github.com/fastly/cli/pkg/errors"
fsterr "github.com/fastly/cli/pkg/errors"
"github.com/fastly/cli/pkg/manifest"
"github.com/fastly/cli/pkg/text"
"github.com/fastly/go-fastly/v6/fastly"
"github.com/kennygrant/sanitize"
)

// UpdateCommand calls the Fastly API to update packages.
Expand Down Expand Up @@ -50,15 +52,15 @@ func NewUpdateCommand(parent cmd.Registerer, globals *config.Data, data manifest
Action: c.autoClone.Set,
Dst: &c.autoClone.Value,
})
c.CmdClause.Flag("package", "Path to a package tar.gz").Required().Short('p').StringVar(&c.path)
c.CmdClause.Flag("package", "Path to a package tar.gz").Short('p').StringVar(&c.path)
return &c
}

// Exec invokes the application logic for the command.
func (c *UpdateCommand) Exec(_ io.Reader, out io.Writer) (err error) {
_, s := c.Globals.Token()
if s == config.SourceUndefined {
return errors.ErrNoToken
return fsterr.ErrNoToken
}

serviceID, serviceVersion, err := cmd.ServiceDetails(cmd.ServiceDetailsOpts{
Expand All @@ -73,11 +75,23 @@ func (c *UpdateCommand) Exec(_ io.Reader, out io.Writer) (err error) {
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]any{
"Service ID": serviceID,
"Service Version": errors.ServiceVersion(serviceVersion),
"Service Version": fsterr.ServiceVersion(serviceVersion),
})
return err
}

packagePath := c.path
if packagePath == "" {
projectName, source := c.manifest.Name()
if source == manifest.SourceUndefined {
return fsterr.RemediationError{
Inner: fmt.Errorf("failed to read project name: %w", fsterr.ErrReadingManifest),
Remediation: "Run `fastly compute build` to produce a Compute@Edge package, alternatively use the --package flag to reference a package outside of the current project.",
}
}
packagePath = filepath.Join("pkg", fmt.Sprintf("%s.tar.gz", sanitize.BaseName(projectName)))
}

progress := text.NewProgress(out, c.Globals.Verbose())
defer func() {
if err != nil {
Expand All @@ -93,14 +107,17 @@ func (c *UpdateCommand) Exec(_ io.Reader, out io.Writer) (err error) {
_, err = c.Globals.APIClient.UpdatePackage(&fastly.UpdatePackageInput{
ServiceID: serviceID,
ServiceVersion: serviceVersion.Number,
PackagePath: c.path,
PackagePath: packagePath,
})
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]any{
"Service ID": serviceID,
"Service Version": serviceVersion.Number,
})
return fmt.Errorf("error uploading package: %w", err)
return fsterr.RemediationError{
Inner: fmt.Errorf("error uploading package: %w", err),
Remediation: "Run `fastly compute build` to produce a Compute@Edge package, alternatively use the --package flag to reference a package outside of the current project.",
}
}
progress.Done()

Expand Down
30 changes: 25 additions & 5 deletions pkg/commands/compute/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,38 @@ import (

"github.com/fastly/cli/pkg/cmd"
"github.com/fastly/cli/pkg/config"
fsterr "github.com/fastly/cli/pkg/errors"
"github.com/fastly/cli/pkg/manifest"
"github.com/fastly/cli/pkg/text"
"github.com/kennygrant/sanitize"
"github.com/mholt/archiver/v3"
)

// NewValidateCommand returns a usable command registered under the parent.
func NewValidateCommand(parent cmd.Registerer, globals *config.Data) *ValidateCommand {
func NewValidateCommand(parent cmd.Registerer, globals *config.Data, data manifest.Data) *ValidateCommand {
var c ValidateCommand
c.Globals = globals
c.manifest = data
c.CmdClause = parent.Command("validate", "Validate a Compute@Edge package")
c.CmdClause.Flag("package", "Path to a package tar.gz").Required().Short('p').StringVar(&c.path)
c.CmdClause.Flag("package", "Path to a package tar.gz").Short('p').StringVar(&c.path)
return &c
}

// Exec implements the command interface.
func (c *ValidateCommand) Exec(_ io.Reader, out io.Writer) error {
p, err := filepath.Abs(c.path)
packagePath := c.path
if packagePath == "" {
projectName, source := c.manifest.Name()
if source == manifest.SourceUndefined {
return fsterr.RemediationError{
Inner: fmt.Errorf("failed to read project name: %w", fsterr.ErrReadingManifest),
Remediation: "Run `fastly compute build` to produce a Compute@Edge package, alternatively use the --package flag to reference a package outside of the current project.",
}
}
packagePath = filepath.Join("pkg", fmt.Sprintf("%s.tar.gz", sanitize.BaseName(projectName)))
}

p, err := filepath.Abs(packagePath)
if err != nil {
c.Globals.ErrLog.AddWithContext(err, map[string]any{
"Path": c.path,
Expand All @@ -35,7 +51,10 @@ func (c *ValidateCommand) Exec(_ io.Reader, out io.Writer) error {
c.Globals.ErrLog.AddWithContext(err, map[string]any{
"Path": c.path,
})
return err
return fsterr.RemediationError{
Inner: fmt.Errorf("failed to validate package: %w", err),
Remediation: "Run `fastly compute build` to produce a Compute@Edge package, alternatively use the --package flag to reference a package outside of the current project.",
}
}

text.Success(out, "Validated package %s", p)
Expand All @@ -45,7 +64,8 @@ func (c *ValidateCommand) Exec(_ io.Reader, out io.Writer) error {
// ValidateCommand validates a package archive.
type ValidateCommand struct {
cmd.Base
path string
manifest manifest.Data
path string
}

// FileValidator validates a file.
Expand Down

0 comments on commit 8bbc210

Please sign in to comment.