Skip to content

Commit 6e42e84

Browse files
author
Ryan Moran
committed
Refactors detector codepath
- renames detector pkg -> detection - splits up detector.Detector into 2 parts: - detection.GetNodeVersion which parses the node version number out of a package.json - detection.NewPlan which will return a buildplan.Plan [#166687251]
1 parent e19b9ed commit 6e42e84

14 files changed

Lines changed: 259 additions & 289 deletions

File tree

cmd/build/main.go

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,28 @@ func main() {
1717
os.Exit(100)
1818
}
1919

20-
code, err := runBuild(context)
21-
if err != nil {
22-
context.Logger.Info(err.Error())
23-
}
24-
25-
os.Exit(code)
26-
}
27-
28-
func runBuild(context build.Build) (int, error) {
2920
context.Logger.FirstLine(context.Logger.PrettyIdentity(context.Buildpack))
3021

31-
packageManager := npm.NPM{
22+
contributor, willContribute, err := modules.NewContributor(context, npm.NPM{
3223
Runner: utils.Command{},
3324
Logger: context.Logger,
34-
}
35-
36-
contributor, willContribute, err := modules.NewContributor(context, packageManager)
25+
})
3726
if err != nil {
38-
return context.Failure(102), err
27+
context.Logger.Info(err.Error())
28+
os.Exit(context.Failure(102))
3929
}
4030

4131
if willContribute {
4232
if err := contributor.Contribute(); err != nil {
43-
return context.Failure(103), err
33+
context.Logger.Info(err.Error())
34+
os.Exit(context.Failure(103))
4435
}
4536
}
4637

47-
return context.Success()
38+
code, err := context.Success()
39+
if err != nil {
40+
context.Logger.Info(err.Error())
41+
}
42+
43+
os.Exit(code)
4844
}

cmd/build/main_test.go

Lines changed: 0 additions & 29 deletions
This file was deleted.

cmd/detect/main.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,29 @@ package main
33
import (
44
"fmt"
55
"os"
6+
"path/filepath"
67

78
"github.com/cloudfoundry/libcfbuildpack/detect"
8-
"github.com/cloudfoundry/npm-cnb/detector"
9+
"github.com/cloudfoundry/npm-cnb/detection"
910
)
1011

1112
func main() {
1213
context, err := detect.DefaultDetect()
1314
if err != nil {
14-
_, _ = fmt.Fprintf(os.Stderr, "failed to create default detect context: %s", err)
15+
fmt.Fprintf(os.Stderr, "failed to create default detect context: %s", err)
1516
os.Exit(100)
1617
}
1718

18-
d := detector.Detector{}
19-
code, err := d.RunDetect(context)
19+
version, err := detection.GetNodeVersion(filepath.Join(context.Application.Root, "package.json"))
20+
if err != nil {
21+
if !os.IsNotExist(err) {
22+
context.Logger.Info(err.Error())
23+
}
24+
25+
os.Exit(detect.FailStatusCode)
26+
}
27+
28+
code, err := context.Pass(detection.NewPlan(version))
2029
if err != nil {
2130
context.Logger.Info(err.Error())
2231
}

detection/init_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package detection_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/sclevine/spec"
7+
"github.com/sclevine/spec/report"
8+
)
9+
10+
func TestUnitDetection(t *testing.T) {
11+
suite := spec.New("detection", spec.Report(report.Terminal{}))
12+
13+
suite("GetNodeVersion", testNodeVersion)
14+
suite("Plan", testPlan)
15+
16+
suite.Run(t)
17+
}

detection/node_version.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package detection
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"os"
7+
)
8+
9+
func GetNodeVersion(path string) (string, error) {
10+
file, err := os.Open(path)
11+
if err != nil {
12+
return "", err
13+
}
14+
defer file.Close()
15+
16+
var pkg struct {
17+
Engines struct {
18+
Node string `json:"node"`
19+
} `json:"engines"`
20+
}
21+
if err := json.NewDecoder(file).Decode(&pkg); err != nil {
22+
return "", fmt.Errorf("unable to parse package.json: %s", err)
23+
}
24+
25+
return pkg.Engines.Node, nil
26+
}

detection/node_version_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package detection_test
2+
3+
import (
4+
"io/ioutil"
5+
"os"
6+
"testing"
7+
8+
"github.com/cloudfoundry/npm-cnb/detection"
9+
"github.com/sclevine/spec"
10+
11+
. "github.com/onsi/gomega"
12+
)
13+
14+
func testNodeVersion(t *testing.T, when spec.G, it spec.S) {
15+
when("GetNodeVersion", func() {
16+
var path string
17+
18+
it.Before(func() {
19+
RegisterTestingT(t)
20+
21+
file, err := ioutil.TempFile("", "package.json")
22+
Expect(err).NotTo(HaveOccurred())
23+
defer file.Close()
24+
25+
path = file.Name()
26+
27+
_, err = file.WriteString(`{
28+
"engines": {
29+
"node": "1.2.3"
30+
}
31+
}`)
32+
Expect(err).NotTo(HaveOccurred())
33+
})
34+
35+
it.After(func() {
36+
Expect(os.Remove(path)).To(Succeed())
37+
})
38+
39+
it("parses the node engine version out of a package.json file", func() {
40+
version, err := detection.GetNodeVersion(path)
41+
Expect(err).NotTo(HaveOccurred())
42+
Expect(version).To(Equal("1.2.3"))
43+
})
44+
45+
when("the package.json file does not exist", func() {
46+
it("returns an error", func() {
47+
_, err := detection.GetNodeVersion("/no/such/path/package.json")
48+
Expect(err).To(MatchError(ContainSubstring("no such file or directory")))
49+
})
50+
})
51+
52+
when("the package.json is malformed", func() {
53+
it.Before(func() {
54+
err := ioutil.WriteFile(path, []byte("%%%"), 0644)
55+
Expect(err).NotTo(HaveOccurred())
56+
})
57+
58+
it("returns an error", func() {
59+
_, err := detection.GetNodeVersion(path)
60+
Expect(err).To(MatchError(ContainSubstring("unable to parse package.json")))
61+
Expect(err).To(MatchError(ContainSubstring("invalid character '%'")))
62+
})
63+
})
64+
})
65+
}

detection/plan.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package detection
2+
3+
import (
4+
"github.com/buildpack/libbuildpack/buildplan"
5+
"github.com/cloudfoundry/npm-cnb/modules"
6+
)
7+
8+
func NewPlan(version string) buildplan.Plan {
9+
var source string
10+
if version != "" {
11+
source = "package.json"
12+
}
13+
14+
return buildplan.Plan{
15+
Provides: []buildplan.Provided{
16+
{Name: modules.Dependency},
17+
},
18+
Requires: []buildplan.Required{
19+
{
20+
Name: modules.NodeDependency,
21+
Version: version,
22+
Metadata: buildplan.Metadata{
23+
"build": true,
24+
"launch": true,
25+
"version-source": source,
26+
},
27+
},
28+
{
29+
Name: modules.Dependency,
30+
Metadata: buildplan.Metadata{
31+
"launch": true,
32+
},
33+
},
34+
},
35+
}
36+
}

detection/plan_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package detection_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/buildpack/libbuildpack/buildplan"
7+
"github.com/cloudfoundry/npm-cnb/detection"
8+
"github.com/cloudfoundry/npm-cnb/modules"
9+
"github.com/sclevine/spec"
10+
11+
. "github.com/onsi/gomega"
12+
)
13+
14+
func testPlan(t *testing.T, when spec.G, it spec.S) {
15+
when("Plan", func() {
16+
it.Before(func() {
17+
RegisterTestingT(t)
18+
})
19+
20+
it("returns a plan for the node modules dependency", func() {
21+
plan := detection.NewPlan("1.2.3")
22+
Expect(plan).To(Equal(buildplan.Plan{
23+
Provides: []buildplan.Provided{
24+
{Name: modules.Dependency},
25+
},
26+
Requires: []buildplan.Required{
27+
{
28+
Name: modules.NodeDependency,
29+
Version: "1.2.3",
30+
Metadata: buildplan.Metadata{
31+
"build": true,
32+
"launch": true,
33+
"version-source": "package.json",
34+
},
35+
},
36+
{
37+
Name: modules.Dependency,
38+
Metadata: buildplan.Metadata{
39+
"launch": true,
40+
},
41+
},
42+
},
43+
}))
44+
})
45+
46+
when("the version number is empty", func() {
47+
it("returns a plan with an empty version-source", func() {
48+
plan := detection.NewPlan("")
49+
Expect(plan).To(Equal(buildplan.Plan{
50+
Provides: []buildplan.Provided{
51+
{Name: modules.Dependency},
52+
},
53+
Requires: []buildplan.Required{
54+
{
55+
Name: modules.NodeDependency,
56+
Metadata: buildplan.Metadata{
57+
"build": true,
58+
"launch": true,
59+
"version-source": "",
60+
},
61+
},
62+
{
63+
Name: modules.Dependency,
64+
Metadata: buildplan.Metadata{
65+
"launch": true,
66+
},
67+
},
68+
},
69+
}))
70+
})
71+
})
72+
})
73+
}

0 commit comments

Comments
 (0)