-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move function to find applications into libnodejs
Move function from to find applications from node-start into libnodejs so that it can be used across buildpacks and extensions. API has been refined from what was in node-start to make it better as a shared function. Signed-off-by: Michael Dawson <[email protected]>
- Loading branch information
Showing
4 changed files
with
235 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package libnodejs | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
func FindNodeApplication(workingDir string) (string, error) { | ||
|
||
projectPath, err := FindProjectPath(workingDir) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
launchpoint := os.Getenv(LaunchPointEnvName) | ||
if launchpoint != "" { | ||
if _, err := os.Stat(filepath.Join(workingDir, launchpoint)); err != nil { | ||
if errors.Is(err, os.ErrNotExist) { | ||
return "", fmt.Errorf("expected value derived from BP_LAUNCHPOINT [%s] to be an existing file", launchpoint) | ||
} | ||
|
||
return "", err | ||
} | ||
|
||
return filepath.Clean(launchpoint), nil | ||
} | ||
|
||
files := []string{"server.js", "app.js", "main.js", "index.js"} | ||
for _, file := range files { | ||
_, err := os.Stat(filepath.Join(projectPath, file)) | ||
if err != nil { | ||
if errors.Is(err, os.ErrNotExist) { | ||
continue | ||
} | ||
|
||
return "", err | ||
} | ||
|
||
return filepath.Join(os.Getenv(ProjectPathEnvName), file), nil | ||
} | ||
|
||
return "", fmt.Errorf("could not find app in %s: expected one of %s", filepath.Clean(projectPath), strings.Join(files, " | ")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
package libnodejs_test | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/paketo-buildpacks/libnodejs" | ||
"github.com/sclevine/spec" | ||
|
||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func testFindNodeApplication(t *testing.T, context spec.G, it spec.S) { | ||
var ( | ||
Expect = NewWithT(t).Expect | ||
|
||
workingDir string | ||
) | ||
|
||
it.Before(func() { | ||
workingDir = t.TempDir() | ||
}) | ||
|
||
it.After(func() { | ||
Expect(os.RemoveAll(workingDir)).To(Succeed()) | ||
}) | ||
|
||
context("finds the server.js application entrypoint", func() { | ||
it.Before(func() { | ||
Expect(os.WriteFile(filepath.Join(workingDir, "server.js"), nil, 0600)).To(Succeed()) | ||
Expect(os.WriteFile(filepath.Join(workingDir, "app.js"), nil, 0600)).To(Succeed()) | ||
Expect(os.WriteFile(filepath.Join(workingDir, "main.js"), nil, 0600)).To(Succeed()) | ||
Expect(os.WriteFile(filepath.Join(workingDir, "index.js"), nil, 0600)).To(Succeed()) | ||
}) | ||
|
||
it("finds the server.js application entrypoint successfully", func() { | ||
file, err := libnodejs.FindNodeApplication(workingDir) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(file).To(Equal(filepath.Join("server.js"))) | ||
}) | ||
}) | ||
|
||
context("finds the app.js application entrypoint", func() { | ||
it.Before(func() { | ||
Expect(os.WriteFile(filepath.Join(workingDir, "app.js"), nil, 0600)).To(Succeed()) | ||
Expect(os.WriteFile(filepath.Join(workingDir, "main.js"), nil, 0600)).To(Succeed()) | ||
Expect(os.WriteFile(filepath.Join(workingDir, "index.js"), nil, 0600)).To(Succeed()) | ||
}) | ||
|
||
it("finds the app.js application entrypoint successfully", func() { | ||
file, err := libnodejs.FindNodeApplication(workingDir) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(file).To(Equal(filepath.Join("app.js"))) | ||
}) | ||
}) | ||
|
||
context("finds the main.js application entrypoint", func() { | ||
it.Before(func() { | ||
Expect(os.WriteFile(filepath.Join(workingDir, "main.js"), nil, 0600)).To(Succeed()) | ||
Expect(os.WriteFile(filepath.Join(workingDir, "index.js"), nil, 0600)).To(Succeed()) | ||
}) | ||
|
||
it("finds the main.js application entrypoint successfully", func() { | ||
file, err := libnodejs.FindNodeApplication(workingDir) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(file).To(Equal(filepath.Join("main.js"))) | ||
}) | ||
}) | ||
|
||
context("finds the index.js application entrypoint", func() { | ||
it.Before(func() { | ||
Expect(os.WriteFile(filepath.Join(workingDir, "index.js"), nil, 0600)).To(Succeed()) | ||
}) | ||
|
||
it("finds the index.js application entrypoint", func() { | ||
file, err := libnodejs.FindNodeApplication(workingDir) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(file).To(Equal(filepath.Join("index.js"))) | ||
}) | ||
}) | ||
|
||
context("when there is a launchpoint", func() { | ||
it.Before(func() { | ||
Expect(os.Mkdir(filepath.Join(workingDir, "src"), os.ModePerm)).To(Succeed()) | ||
Expect(os.WriteFile(filepath.Join(workingDir, "src", "launchpoint.js"), nil, 0600)).To(Succeed()) | ||
}) | ||
|
||
context("when the launchpoint file exists", func() { | ||
it("returns the highest priority file", func() { | ||
t.Setenv("BP_LAUNCHPOINT", "./src/launchpoint.js") | ||
file, err := libnodejs.FindNodeApplication(workingDir) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(file).To(Equal(filepath.Join("src", "launchpoint.js"))) | ||
}) | ||
}) | ||
|
||
context("when the launchpoint file does not exist", func() { | ||
it("returns the empty string and no error", func() { | ||
t.Setenv("BP_LAUNCHPOINT", "./no-such-file.js") | ||
file, err := libnodejs.FindNodeApplication(workingDir) | ||
Expect(err).To(MatchError(ContainSubstring("expected value derived from BP_LAUNCHPOINT [./no-such-file.js] to be an existing file"))) | ||
Expect(file).To(Equal("")) | ||
}) | ||
}) | ||
}) | ||
|
||
context("when there is a project path", func() { | ||
it.Before(func() { | ||
Expect(os.Mkdir(filepath.Join(workingDir, "frontend"), os.ModePerm)).To(Succeed()) | ||
Expect(os.WriteFile(filepath.Join(workingDir, "frontend", "server.js"), nil, 0600)).To(Succeed()) | ||
Expect(os.WriteFile(filepath.Join(workingDir, "frontend", "app.js"), nil, 0600)).To(Succeed()) | ||
}) | ||
|
||
it("returns the highest priority file", func() { | ||
t.Setenv("BP_NODE_PROJECT_PATH", "frontend") | ||
file, err := libnodejs.FindNodeApplication(workingDir) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(file).To(Equal(filepath.Join("frontend", "server.js"))) | ||
}) | ||
}) | ||
|
||
context("when there is a project path but value specified does not exist", func() { | ||
it("returns a failure", func() { | ||
t.Setenv("BP_NODE_PROJECT_PATH", "frontend") | ||
_, err := libnodejs.FindNodeApplication(workingDir) | ||
Expect(err).To(MatchError(ContainSubstring("no such file or directory"))) | ||
}) | ||
}) | ||
|
||
context("when no application can be found", func() { | ||
it("returns that application could not be found", func() { | ||
_, err := libnodejs.FindNodeApplication(workingDir) | ||
Expect(err).To(MatchError(fmt.Errorf("could not find app in %s: expected one of server.js | app.js | main.js | index.js", workingDir))) | ||
}) | ||
}) | ||
|
||
context("failure cases", func() { | ||
context("when the launchpoint cannot be stat'd", func() { | ||
it.Before(func() { | ||
Expect(os.Chmod(workingDir, 0000)).To(Succeed()) | ||
}) | ||
|
||
it.After(func() { | ||
Expect(os.Chmod(workingDir, os.ModePerm)).To(Succeed()) | ||
}) | ||
|
||
it("fails with helpful error", func() { | ||
t.Setenv("BP_LAUNCHPOINT", "something.js") | ||
_, err := libnodejs.FindNodeApplication(workingDir) | ||
Expect(err).To(MatchError(ContainSubstring("permission denied"))) | ||
}) | ||
}) | ||
|
||
context("when the working dir cannot be stat'd", func() { | ||
it.Before(func() { | ||
Expect(os.Chmod(workingDir, 0000)).To(Succeed()) | ||
}) | ||
|
||
it.After(func() { | ||
Expect(os.Chmod(workingDir, os.ModePerm)).To(Succeed()) | ||
}) | ||
|
||
it("fails with helpful error", func() { | ||
_, err := libnodejs.FindNodeApplication(workingDir) | ||
Expect(err).To(MatchError(ContainSubstring("permission denied"))) | ||
}) | ||
}) | ||
|
||
context("when the project path cannot be stat'd", func() { | ||
it.Before(func() { | ||
Expect(os.Chmod(workingDir, 0000)).To(Succeed()) | ||
}) | ||
|
||
it.After(func() { | ||
Expect(os.Chmod(workingDir, os.ModePerm)).To(Succeed()) | ||
}) | ||
|
||
it("fails with helpful error", func() { | ||
t.Setenv("BP_NODE_PROJECT_PATH", "frontend") | ||
_, err := libnodejs.FindNodeApplication(workingDir) | ||
Expect(err).To(MatchError(ContainSubstring("permission denied"))) | ||
}) | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
package libnodejs | ||
|
||
const ProjectPathEnvName = "BP_NODE_PROJECT_PATH" | ||
const LaunchPointEnvName = "BP_LAUNCHPOINT" |