Skip to content

Commit

Permalink
feat: expand package.json files in npm.dependencies (#914)
Browse files Browse the repository at this point in the history
* refactor: remove always-true checks

* feat: expand package.json files in npm.dependencies

* feat: introduce human readable byte units

* feat: dislay human readable units
  • Loading branch information
alexplischke authored May 29, 2024
1 parent 77a9777 commit a493cce
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 4 deletions.
14 changes: 14 additions & 0 deletions internal/human/bytes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package human

import (
"fmt"
"math"
)

func Bytes(b int64) string {
sizes := []string{"B", "kB", "MB", "GB"}
e := math.Floor(math.Log(float64(b)) / math.Log(1000))
suffix := sizes[int(math.Min(e, float64(len(sizes)-1)))]
val := float64(b) / math.Pow(1000, e)
return fmt.Sprintf("%.0f %s", val, suffix)
}
18 changes: 18 additions & 0 deletions internal/human/bytes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package human

import "fmt"

func ExampleBytes_gigaByte() {
fmt.Println(Bytes(3000000000))
// Output: 3 GB
}

func ExampleBytes_megaByte() {
fmt.Println(Bytes(82854982))
// Output: 83 MB
}

func ExampleBytes_kiloByte() {
fmt.Println(Bytes(828549))
// Output: 829 kB
}
40 changes: 36 additions & 4 deletions internal/saucecloud/zip/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/rs/zerolog/log"
"github.com/saucelabs/saucectl/internal/archive/zip"
"github.com/saucelabs/saucectl/internal/human"
"github.com/saucelabs/saucectl/internal/jsonio"
"github.com/saucelabs/saucectl/internal/msg"
"github.com/saucelabs/saucectl/internal/node"
Expand Down Expand Up @@ -92,8 +93,8 @@ func ArchiveFiles(targetFileName string, targetDir string, sourceDir string, fil
}

log.Info().
Dur("durationMs", time.Since(start)).
Int64("size", f.Size()).
Str("duration", time.Since(start).Round(time.Second).String()).
Str("size", human.Bytes(f.Size())).
Int("fileCount", totalFileCount).
Int("longestPathLength", longestPathLength).
Msg("Archive created.")
Expand Down Expand Up @@ -130,10 +131,15 @@ func ArchiveNodeModules(targetDir string, sourceDir string, matcher sauceignore.
return "", nil
}

dependencies, err = ExpandDependencies(sourceDir, dependencies)
if err != nil {
return "", err
}

var files []string

// does the user only want a subset of dependencies?
if hasMods && wantMods {
if wantMods {
reqs := node.Requirements(filepath.Join(sourceDir, "node_modules"), dependencies...)
if len(reqs) == 0 {
return "", fmt.Errorf("unable to find required dependencies; please check 'node_modules' folder and make sure the dependencies exist")
Expand All @@ -146,7 +152,7 @@ func ArchiveNodeModules(targetDir string, sourceDir string, matcher sauceignore.

// node_modules exists, has not been ignored and a subset has not been specified, so include the entire folder.
// This is the legacy behavior (backwards compatible) of saucectl.
if hasMods && !ignored && !wantMods {
if !wantMods {
log.Warn().Msg("Adding the entire node_modules folder to the payload. " +
"This behavior is deprecated, not recommended and will be removed in the future. " +
"Please address your dependency needs via https://docs.saucelabs.com/dev/cli/saucectl/usage/use-cases/#set-npm-packages-in-configyml")
Expand All @@ -155,3 +161,29 @@ func ArchiveNodeModules(targetDir string, sourceDir string, matcher sauceignore.

return ArchiveFiles("node_modules", targetDir, sourceDir, files, matcher)
}

// ExpandDependencies looks for "package.json" files inside dependencies and
// expands them into a list of dependencies.
func ExpandDependencies(sourceDir string, dependencies []string) ([]string, error) {
var expanded []string
for _, dep := range dependencies {
if strings.HasSuffix(dep, "package.json") {
p, err := node.PackageFromFile(filepath.Join(sourceDir, dep))
if err != nil {
return nil, fmt.Errorf("failed to read dependencies from %s: %w", dep, err)
}

for k := range p.Dependencies {
expanded = append(expanded, k)
}
for k := range p.DevDependencies {
expanded = append(expanded, k)
}
continue
}

expanded = append(expanded, dep)
}

return expanded, nil
}
33 changes: 33 additions & 0 deletions internal/saucecloud/zip/archive_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package zip

import (
"testing"

"github.com/google/go-cmp/cmp"
"gotest.tools/v3/fs"
)

func TestExpandDependencies(t *testing.T) {
dir := fs.NewDir(t, "test-project",
fs.WithFile("package.json", `{
"dependencies": {
"i-am-regular": "0.1.2"
},
"devDependencies": {
"i-am-dev": "0.1.2"
}
}
`))
defer dir.Remove()

deps := []string{"i-am-extra", "package.json"}
expanded, err := ExpandDependencies(dir.Path(), deps)
if err != nil {
t.Error(err)
}

expected := []string{"i-am-extra", "i-am-regular", "i-am-dev"}
if !cmp.Equal(expected, expanded) {
t.Errorf("unexpected expanded dependencies: %s", cmp.Diff(expected, expanded))
}
}

0 comments on commit a493cce

Please sign in to comment.