Skip to content

Commit

Permalink
Add support for setting start script name
Browse files Browse the repository at this point in the history
Refs: paketo-buildpacks/npm-start#292

Signed-off-by: Michael Dawson <[email protected]>
  • Loading branch information
mhdawson committed May 2, 2023
1 parent 1055d49 commit 4c5dddf
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 6 deletions.
25 changes: 20 additions & 5 deletions package_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import (
// PackageJSON represents the contents of a package.json file.
type PackageJSON struct {
Scripts struct {
PostStart string `json:"poststart"`
PreStart string `json:"prestart"`
Start string `json:"start"`
} `json:"scripts"`
PostStart string
PreStart string
Start string
}

AllScripts map[string]string `json:"scripts"`
}

// ParsePackageJSON parses the contents of a package.json file.
Expand All @@ -30,11 +32,24 @@ func ParsePackageJSON(path string) (PackageJSON, error) {
return PackageJSON{}, fmt.Errorf("unable to decode package.json %w", err)
}

startScriptName := os.Getenv(StartScriptNameEnvName)
if startScriptName == "" {
startScriptName = "start"
} else {
if pkg.AllScripts[startScriptName] == "" {
return PackageJSON{}, fmt.Errorf("no script entry with name \"%s\" exists", startScriptName)
}
}

pkg.Scripts.Start = pkg.AllScripts[startScriptName]
pkg.Scripts.PreStart = pkg.AllScripts["prestart"]
pkg.Scripts.PostStart = pkg.AllScripts["poststart"]

return pkg, nil
}

// HasStartScript indicates the presence of a start script in the package.json
// file.
// file or as defined by .
func (pj PackageJSON) HasStartScript() bool {
return pj.Scripts.Start != ""
}
70 changes: 69 additions & 1 deletion package_json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ func testPackageJSON(t *testing.T, context spec.G, it spec.S) {
"scripts": {
"poststart": "echo \"poststart\"",
"prestart": "echo \"prestart\"",
"start": "echo \"start\" && node server.js"
"start": "echo \"start\" && node server.js",
"serve": "echo \"about to serve\" && node app.js"
}
}`), 0600)).To(Succeed())
})
Expand All @@ -45,6 +46,37 @@ func testPackageJSON(t *testing.T, context spec.G, it spec.S) {
})
})

context("when parsing a valid package.json poststart and prestart are optional", func() {
it.Before(func() {
Expect(os.WriteFile(filePath, []byte(`{
"scripts": {
"start": "echo \"start\" && node server.js"
}
}`), 0600)).To(Succeed())
})

it("successfully extracts the scripts information", func() {
pkg, err := libnodejs.ParsePackageJSON(path)
Expect(err).NotTo(HaveOccurred())

Expect(pkg.Scripts.Start).To(ContainSubstring(`echo "start" && node server.js`))
Expect(pkg.Scripts.PreStart).To(Equal(``))
Expect(pkg.Scripts.PostStart).To(Equal(``))
})
})

context("when parsing a valid package.json with BP_NPM_START_SCRIPT", func() {
it("successfully extracts the scripts information", func() {
t.Setenv("BP_NPM_START_SCRIPT", "serve")
pkg, err := libnodejs.ParsePackageJSON(path)
Expect(err).NotTo(HaveOccurred())

Expect(pkg.Scripts.Start).To(ContainSubstring(`echo "about to serve" && node app.js`))
Expect(pkg.Scripts.PreStart).To(Equal(`echo "prestart"`))
Expect(pkg.Scripts.PostStart).To(Equal(`echo "poststart"`))
})
})

context("failure cases", func() {
context("when the package.json is not a valid json file", func() {
it.Before(func() {
Expand All @@ -63,6 +95,24 @@ func testPackageJSON(t *testing.T, context spec.G, it spec.S) {
Expect(err).To(HaveOccurred())
})
})

context("when parsing a valid package.json with BP_NPM_START_SCRIPT and script does not exist", func() {
it.Before(func() {
Expect(os.WriteFile(filePath, []byte(`{
"scripts": {
"poststart": "echo \"poststart\"",
"prestart": "echo \"prestart\"",
"start": "echo \"start\" && node server.js"
}
}`), 0600)).To(Succeed())
})

it("fails to extracts the script information", func() {
t.Setenv("BP_NPM_START_SCRIPT", "serve")
_, err := libnodejs.ParsePackageJSON(path)
Expect(err).To(MatchError(ContainSubstring("no script entry with name \"serve\" exists")))
})
})
})

context("HasStartScript", func() {
Expand All @@ -75,6 +125,24 @@ func testPackageJSON(t *testing.T, context spec.G, it spec.S) {
})
})

context("when a start script is present and BP_NPM_START_SCRIPT is used", func() {
it.Before(func() {
Expect(os.WriteFile(filePath, []byte(`{
"scripts": {
"serve": "echo \"start\" && node server.js"
}
}`), 0600)).To(Succeed())
})

it("indicates that the package.json file has a start script", func() {
t.Setenv("BP_NPM_START_SCRIPT", "serve")
pkg, err := libnodejs.ParsePackageJSON(path)
Expect(err).NotTo(HaveOccurred())

Expect(pkg.HasStartScript()).To(BeTrue())
})
})

context("when a start script is NOT present", func() {
it.Before(func() {
Expect(os.WriteFile(filePath, []byte(`{}`), 0600)).To(Succeed())
Expand Down
1 change: 1 addition & 0 deletions spec_constants.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
package libnodejs

const ProjectPathEnvName = "BP_NODE_PROJECT_PATH"
const StartScriptNameEnvName = "BP_NPM_START_SCRIPT"

0 comments on commit 4c5dddf

Please sign in to comment.