diff --git a/build.go b/build.go index a3d4752..f3e0224 100644 --- a/build.go +++ b/build.go @@ -27,7 +27,7 @@ func Build(pathParser PathParser, logger scribe.Logger) packit.BuildFunc { return packit.BuildResult{}, err } - file, err := os.Open(filepath.Join(projectPath, "package.json")) + file, err := os.Open(filepath.Join(context.WorkingDir, projectPath, "package.json")) if err != nil { return packit.BuildResult{}, fmt.Errorf("Unable to open package.json: %w", err) } @@ -53,7 +53,9 @@ func Build(pathParser PathParser, logger scribe.Logger) packit.BuildFunc { // Ideally we would like the lifecycle to support setting a custom working // directory to run the launch process. Until that happens we will cd in. - command = fmt.Sprintf("cd %s && %s", projectPath, command) + if projectPath != "" { + command = fmt.Sprintf("cd %s && %s", projectPath, command) + } logger.Process("Assigning launch processes") logger.Subprocess("web: %s", command) diff --git a/build_test.go b/build_test.go index 7a0afc2..8484d41 100644 --- a/build_test.go +++ b/build_test.go @@ -57,7 +57,7 @@ func testBuild(t *testing.T, context spec.G, it spec.S) { pathParser = &fakes.PathParser{} - pathParser.GetCall.Returns.ProjectPath = filepath.Join(workingDir, "some-project-dir") + pathParser.GetCall.Returns.ProjectPath = "some-project-dir" build = yarnstart.Build(pathParser, logger) }) @@ -91,7 +91,7 @@ func testBuild(t *testing.T, context spec.G, it spec.S) { Processes: []packit.Process{ { Type: "web", - Command: fmt.Sprintf("cd %s && some-prestart-command && some-start-command && some-poststart-command", filepath.Join(workingDir, "some-project-dir")), + Command: "cd some-project-dir && some-prestart-command && some-start-command && some-poststart-command", }, }, }, @@ -134,7 +134,7 @@ func testBuild(t *testing.T, context spec.G, it spec.S) { Processes: []packit.Process{ { Type: "web", - Command: fmt.Sprintf("cd %s && some-start-command && some-poststart-command", filepath.Join(workingDir, "some-project-dir")), + Command: "cd some-project-dir && some-start-command && some-poststart-command", }, }}, })) @@ -176,7 +176,7 @@ func testBuild(t *testing.T, context spec.G, it spec.S) { Processes: []packit.Process{ { Type: "web", - Command: fmt.Sprintf("cd %s && some-prestart-command && some-start-command", filepath.Join(workingDir, "some-project-dir")), + Command: "cd some-project-dir && some-prestart-command && some-start-command", }, }, }, @@ -219,7 +219,56 @@ func testBuild(t *testing.T, context spec.G, it spec.S) { Processes: []packit.Process{ { Type: "web", - Command: fmt.Sprintf("cd %s && some-prestart-command && node server.js && some-poststart-command", filepath.Join(workingDir, "some-project-dir")), + Command: "cd some-project-dir && some-prestart-command && node server.js && some-poststart-command", + }, + }, + }, + })) + }) + }) + + context("when the project-path env var is not set", func() { + it.Before(func() { + pathParser.GetCall.Returns.ProjectPath = "" + err := ioutil.WriteFile(filepath.Join(workingDir, "package.json"), []byte(`{ + "scripts": { + "prestart": "some-prestart-command", + "start": "some-start-command", + "poststart": "some-poststart-command" + } + }`), 0644) + Expect(err).NotTo(HaveOccurred()) + }) + + it.After(func() { + Expect(os.Remove(filepath.Join(workingDir, "package.json"))).To(Succeed()) + }) + + it("returns a result with a valid start command", func() { + result, err := build(packit.BuildContext{ + WorkingDir: workingDir, + CNBPath: cnbDir, + Stack: "some-stack", + BuildpackInfo: packit.BuildpackInfo{ + Name: "Some Buildpack", + Version: "some-version", + }, + Plan: packit.BuildpackPlan{ + Entries: []packit.BuildpackPlanEntry{}, + }, + Layers: packit.Layers{Path: layersDir}, + }) + Expect(err).NotTo(HaveOccurred()) + + Expect(result).To(Equal(packit.BuildResult{ + Plan: packit.BuildpackPlan{ + Entries: []packit.BuildpackPlanEntry{}, + }, + Launch: packit.LaunchMetadata{ + Processes: []packit.Process{ + { + Type: "web", + Command: "some-prestart-command && some-start-command && some-poststart-command", }, }, }, diff --git a/detect.go b/detect.go index dbf3a2a..fe58c51 100644 --- a/detect.go +++ b/detect.go @@ -20,7 +20,7 @@ func Detect(projectPathParser PathParser) packit.DetectFunc { return packit.DetectResult{}, err } - _, err = os.Stat(filepath.Join(projectPath, "yarn.lock")) + _, err = os.Stat(filepath.Join(context.WorkingDir, projectPath, "yarn.lock")) if err != nil { if os.IsNotExist(err) { return packit.DetectResult{}, packit.Fail diff --git a/detect_test.go b/detect_test.go index d5f3b5d..d21c807 100644 --- a/detect_test.go +++ b/detect_test.go @@ -31,7 +31,7 @@ func testDetect(t *testing.T, context spec.G, it spec.S) { Expect(os.Mkdir(filepath.Join(workingDir, "custom"), os.ModePerm)).To(Succeed()) projectPathParser = &fakes.PathParser{} - projectPathParser.GetCall.Returns.ProjectPath = filepath.Join(workingDir, "custom") + projectPathParser.GetCall.Returns.ProjectPath = "custom" detect = yarnstart.Detect(projectPathParser) }) diff --git a/integration/custom_start_cmd_test.go b/integration/custom_start_cmd_test.go index 8004fa8..e83f595 100644 --- a/integration/custom_start_cmd_test.go +++ b/integration/custom_start_cmd_test.go @@ -68,6 +68,13 @@ func testCustomStartCmd(t *testing.T, context spec.G, it spec.S) { Execute(name, source) Expect(err).NotTo(HaveOccurred(), logs.String()) + Expect(logs).To(ContainLines( + MatchRegexp(fmt.Sprintf(`%s \d+\.\d+\.\d+`, settings.Buildpack.Name)), + " Assigning launch processes", + ` web: echo "prestart" && echo "start" && node server.js && echo "poststart"`, + "", + )) + container, err = docker.Container.Run. WithEnv(map[string]string{"PORT": "8080"}). WithPublish("8080"). @@ -77,13 +84,6 @@ func testCustomStartCmd(t *testing.T, context spec.G, it spec.S) { Eventually(container).Should(BeAvailable()) - Expect(logs).To(ContainLines( - MatchRegexp(fmt.Sprintf(`%s \d+\.\d+\.\d+`, settings.Buildpack.Name)), - " Assigning launch processes", - ` web: cd /workspace && echo "prestart" && echo "start" && node server.js && echo "poststart"`, - "", - )) - response, err := http.Get(fmt.Sprintf("http://localhost:%s", container.HostPort("8080"))) Expect(err).NotTo(HaveOccurred()) defer response.Body.Close() diff --git a/integration/default_test.go b/integration/default_test.go index f5037aa..09d4974 100644 --- a/integration/default_test.go +++ b/integration/default_test.go @@ -66,6 +66,13 @@ func testDefault(t *testing.T, context spec.G, it spec.S) { Execute(name, source) Expect(err).NotTo(HaveOccurred(), logs.String()) + Expect(logs).To(ContainLines( + MatchRegexp(fmt.Sprintf(`%s \d+\.\d+\.\d+`, settings.Buildpack.Name)), + " Assigning launch processes", + " web: node server.js", + "", + )) + container, err = docker.Container.Run. WithEnv(map[string]string{"PORT": "8080"}). WithPublish("8080"). @@ -75,13 +82,6 @@ func testDefault(t *testing.T, context spec.G, it spec.S) { Eventually(container).Should(BeAvailable()) - Expect(logs).To(ContainLines( - MatchRegexp(fmt.Sprintf(`%s \d+\.\d+\.\d+`, settings.Buildpack.Name)), - " Assigning launch processes", - " web: cd /workspace && node server.js", - "", - )) - response, err := http.Get(fmt.Sprintf("http://localhost:%s", container.HostPort("8080"))) Expect(err).NotTo(HaveOccurred()) defer response.Body.Close() diff --git a/integration/graceful_shutdown_test.go b/integration/graceful_shutdown_test.go index 3171368..4e5b6a2 100644 --- a/integration/graceful_shutdown_test.go +++ b/integration/graceful_shutdown_test.go @@ -81,7 +81,7 @@ func testGracefulShutdown(t *testing.T, context spec.G, it spec.S) { Expect(logs).To(ContainLines( MatchRegexp(fmt.Sprintf(`%s \d+\.\d+\.\d+`, settings.Buildpack.Name)), " Assigning launch processes", - " web: cd /workspace && node server.js", + " web: node server.js", "", )) diff --git a/integration/project_path_test.go b/integration/project_path_test.go index b3d3989..a2ddeb3 100644 --- a/integration/project_path_test.go +++ b/integration/project_path_test.go @@ -69,6 +69,13 @@ func testProjectPath(t *testing.T, context spec.G, it spec.S) { Execute(name, source) Expect(err).NotTo(HaveOccurred(), logs.String()) + Expect(logs).To(ContainLines( + MatchRegexp(fmt.Sprintf(`%s \d+\.\d+\.\d+`, settings.Buildpack.Name)), + " Assigning launch processes", + ` web: cd hello_world_server && echo "prehello" && echo "starthello" && node server.js && echo "posthello"`, + "", + )) + container, err = docker.Container.Run. WithEnv(map[string]string{"PORT": "8080"}). WithPublish("8080"). @@ -78,13 +85,6 @@ func testProjectPath(t *testing.T, context spec.G, it spec.S) { Eventually(container).Should(BeAvailable()) - Expect(logs).To(ContainLines( - MatchRegexp(fmt.Sprintf(`%s \d+\.\d+\.\d+`, settings.Buildpack.Name)), - " Assigning launch processes", - ` web: cd /workspace/hello_world_server && echo "prehello" && echo "starthello" && node server.js && echo "posthello"`, - "", - )) - response, err := http.Get(fmt.Sprintf("http://localhost:%s", container.HostPort("8080"))) Expect(err).NotTo(HaveOccurred()) defer response.Body.Close() diff --git a/project_path_parser.go b/project_path_parser.go index 59e284d..5534cdd 100644 --- a/project_path_parser.go +++ b/project_path_parser.go @@ -22,17 +22,15 @@ func NewProjectPathParser() ProjectPathParser { func (p ProjectPathParser) Get(path string) (string, error) { customProjPath := os.Getenv("BP_NODE_PROJECT_PATH") if customProjPath == "" { - return path, nil + return "", nil } - customProjPath = filepath.Clean(customProjPath) - path = filepath.Join(path, customProjPath) - _, err := os.Stat(path) + _, err := os.Stat(filepath.Join(path, customProjPath)) if err != nil { if errors.Is(err, os.ErrNotExist) { - return "", fmt.Errorf("expected value derived from BP_NODE_PROJECT_PATH [%s] to be an existing directory", path) + return "", fmt.Errorf("expected value derived from BP_NODE_PROJECT_PATH [%s] to be an existing directory", customProjPath) } return "", err } - return path, nil + return customProjPath, nil } diff --git a/project_path_parser_test.go b/project_path_parser_test.go index c7aa5be..fde7dd4 100644 --- a/project_path_parser_test.go +++ b/project_path_parser_test.go @@ -43,7 +43,7 @@ func testProjectPathParser(t *testing.T, context spec.G, it spec.S) { it("returns the set project path", func() { result, err := projectPathParser.Get(workingDir) Expect(err).NotTo(HaveOccurred()) - Expect(result).To(Equal(projectDir)) + Expect(result).To(Equal(filepath.Join("custom", "path"))) }) }) @@ -74,7 +74,7 @@ func testProjectPathParser(t *testing.T, context spec.G, it spec.S) { it("returns an error", func() { _, err := projectPathParser.Get(workingDir) - Expect(err).To(MatchError(ContainSubstring(fmt.Sprintf("expected value derived from BP_NODE_PROJECT_PATH [%s] to be an existing directory", filepath.Join(workingDir, "some-garbage"))))) + Expect(err).To(MatchError(ContainSubstring(fmt.Sprintf("expected value derived from BP_NODE_PROJECT_PATH [%s] to be an existing directory", "some-garbage")))) }) })