Skip to content

Commit 9b7be5b

Browse files
committed
feat: add Rust buildpack and smoke test
1 parent a08df38 commit 9b7be5b

9 files changed

Lines changed: 125 additions & 1 deletion

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
.bin/
2+
smoke/testdata/rust/target/
3+
smoke/testdata/rust/Cargo.lock

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
This builder uses the [Paketo Jammy Base
66
Stack](https://github.com/paketo-buildpacks/jammy-base-stack) (Ubuntu Jammy
77
Jellyfish build and run images) with buildpacks for Java,
8-
Java Native Image, Go, Python, .NET, Node.js, Apache HTTPD, NGINX and Procfile.
8+
Java Native Image, Go, Python, .NET, Node.js, Apache HTTPD, NGINX, Procfile and Rust.
99

1010
To see which versions of build and run images, buildpacks, and the lifecycle
1111
that are contained within a given builder version, see the

builder.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ description = "Ubuntu 22.04 Jammy Jellyfish base image with buildpacks for Java,
3636
uri = "docker://docker.io/paketobuildpacks/web-servers:4.0.3"
3737
version = "4.0.3"
3838

39+
[[buildpacks]]
40+
uri = "docker://ghcr.io/octopilot/rust:0.1.1"
41+
version = "0.1.1"
42+
3943
[lifecycle]
4044
version = "0.21.1"
4145

@@ -93,6 +97,12 @@ description = "Ubuntu 22.04 Jammy Jellyfish base image with buildpacks for Java,
9397
id = "paketo-buildpacks/procfile"
9498
version = "5.12.1"
9599

100+
[[order]]
101+
102+
[[order.group]]
103+
id = "octopilot/rust"
104+
version = "0.1.1"
105+
96106
[stack]
97107
build-image = "docker.io/paketobuildpacks/build-jammy-base:0.1.196"
98108
id = "io.buildpacks.stacks.jammy"

smoke/init_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func TestSmoke(t *testing.T) {
3737
suite("Procfile", testProcfile)
3838
suite("Python", testPython)
3939
suite("Ruby", testRuby)
40+
suite("Rust", testRust)
4041
suite("Web Servers", testWebServers)
4142
suite.Run(t)
4243
}

smoke/rust_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package smoke_test
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"path/filepath"
7+
"testing"
8+
9+
"github.com/paketo-buildpacks/occam"
10+
"github.com/sclevine/spec"
11+
12+
. "github.com/onsi/gomega"
13+
. "github.com/paketo-buildpacks/occam/matchers"
14+
)
15+
16+
func testRust(t *testing.T, context spec.G, it spec.S) {
17+
var (
18+
Expect = NewWithT(t).Expect
19+
Eventually = NewWithT(t).Eventually
20+
21+
pack occam.Pack
22+
docker occam.Docker
23+
)
24+
25+
it.Before(func() {
26+
pack = occam.NewPack().WithVerbose().WithNoColor()
27+
docker = occam.NewDocker()
28+
})
29+
30+
context("detects a Rust app", func() {
31+
var (
32+
image occam.Image
33+
container occam.Container
34+
35+
name string
36+
source string
37+
)
38+
39+
it.Before(func() {
40+
var err error
41+
name, err = occam.RandomName()
42+
Expect(err).NotTo(HaveOccurred())
43+
})
44+
45+
it.After(func() {
46+
if container.ID != "" {
47+
_ = docker.Container.Remove.Execute(container.ID)
48+
}
49+
_ = docker.Volume.Remove.Execute(occam.CacheVolumeNames(name))
50+
if image.ID != "" {
51+
_ = docker.Image.Remove.Execute(image.ID)
52+
}
53+
Expect(os.RemoveAll(source)).To(Succeed())
54+
})
55+
56+
it("builds successfully", func() {
57+
var err error
58+
source, err = occam.Source(filepath.Join("testdata", "rust"))
59+
Expect(err).NotTo(HaveOccurred())
60+
61+
var logs fmt.Stringer
62+
image, logs, err = pack.Build.
63+
WithPullPolicy("always").
64+
WithBuilder(Builder).
65+
Execute(name, source)
66+
Expect(err).ToNot(HaveOccurred(), logs.String)
67+
68+
container, err = docker.Container.Run.
69+
WithEnv(map[string]string{"PORT": "8080"}).
70+
WithPublish("8080").
71+
Execute(image.ID)
72+
Expect(err).NotTo(HaveOccurred())
73+
74+
Eventually(container).Should(BeAvailable())
75+
76+
Expect(logs).To(ContainLines(ContainSubstring("Octopilot Rust Buildpack")))
77+
})
78+
})
79+
}

smoke/testdata/rust/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

smoke/testdata/rust/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "rust-smoke"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
ctrlc = "3.4"

smoke/testdata/rust/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Minimal Rust app for builder smoke test. Single crate; no workspace.

smoke/testdata/rust/src/main.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Minimal Rust app for buildpack smoke test: listen on PORT and respond.
2+
use std::env;
3+
use std::io::Write;
4+
use std::net::TcpListener;
5+
use std::process;
6+
7+
fn main() {
8+
ctrlc::set_handler(|| process::exit(0)).expect("set signal handler");
9+
let port = env::var("PORT").unwrap_or_else(|_| "8080".to_string());
10+
let bind = format!("0.0.0.0:{}", port);
11+
let listener = TcpListener::bind(&bind).expect("bind");
12+
eprintln!("jammy rust test crate starting");
13+
eprintln!("port={}", port);
14+
for mut stream in listener.incoming().flatten() {
15+
let _ = stream.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nok");
16+
}
17+
}

0 commit comments

Comments
 (0)