forked from paketo-buildpacks/packit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
doc.go
191 lines (191 loc) · 6.76 KB
/
doc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// Package packit provides primitives for implementing a Cloud Native Buildpack
// according to the specification:
// https://github.com/buildpacks/spec/blob/main/buildpack.md.
//
// Buildpack Interface
//
// According to the specification, the buildpack interface is composed of both
// a detect and build phase. Each of these phases has a corresponding set of
// packit primitives enable developers to easily implement a buildpack.
//
// Detect Phase
//
// The purpose of the detect phase is for buildpacks to declare dependencies
// that are provided or required for the buildpack to execute. Implementing the
// detect phase can be achieved by calling the Detect function and providing a
// DetectFunc callback to be invoked during that phase. Below is an example of
// a simple detect phase that provides the "yarn" dependency and requires the
// "node" dependency.
//
// package main
//
// import (
// "encoding/json"
// "os"
// "path/filepath"
//
// "github.com/paketo-buildpacks/packit"
// )
//
// func main() {
// // The detect phase provides yarn and requires node. When requiring node,
// // a version specified in the package.json file is included to indicate
// // what versions of node are acceptable to the buildpack.
//
// packit.Detect(func(context packit.DetectContext) (packit.DetectResult, error) {
//
// // The DetectContext includes a WorkingDir field that specifies the
// // location of the application source code. This field can be combined with
// // other paths to find and inspect files included in the application source
// // code that is provided to the buildpack.
// file, err := os.Open(filepath.Join(context.WorkingDir, "package.json"))
// if err != nil {
// return packit.DetectResult{}, err
// }
//
// // The package.json file includes a declaration of what versions of node
// // are acceptable. For example:
// // {
// // "engines": {
// // "node": ">=0.10.3 <0.12"
// // }
// // }
// var config struct {
// Engines struct {
// Node string `json:"node"`
// } `json:"engines"`
// }
//
// err = json.NewDecoder(file).Decode(&config)
// if err != nil {
// return packit.DetectResult{}, err
// }
//
// // Once the package.json file has been parsed, the detect phase can return
// // a result that indicates the provision of yarn and the requirement of
// // node. As can be seen below, the BuildPlanRequirement may also include
// // optional metadata information to such as the source of the version
// // information for a given requirement.
// return packit.DetectResult{
// Plan: packit.BuildPlan{
// Provides: []packit.BuildPlanProvision{
// {Name: "yarn"},
// },
// Requires: []packit.BuildPlanRequirement{
// {
// Name: "node",
// Version: config.Engines.Node,
// Metadata: map[string]string{
// "version-source": "package.json",
// },
// },
// },
// },
// }, nil
// })
// }
//
// Build Phase
//
// The purpose of the build phase is to perform the operation of providing
// whatever dependencies were declared in the detect phase for the given
// application code. Implementing the build phase can be achieved by calling
// the Build function and providing a BuildFunc callback to be invoked during
// that phase. Below is an example that adds "yarn" as a dependency to the
// application source code.
//
// package main
//
// import "github.com/paketo-buildpacks/packit"
//
// func main() {
// // The build phase includes the yarn cli in a new layer that is made
// // available for subsequent buildpacks during their build phase as well as to
// // the start command during launch.
//
// packit.Build(func(context packit.BuildContext) (packit.BuildResult, error) {
//
// // The BuildContext includes a BuildpackPlan with entries that specify a
// // requirement on a dependency provided by the buildpack. This example
// // simply chooses the first entry, but more intelligent resolution
// // processes can and likely shoud be used in real implementations.
// entry := context.Plan.Entries[0]
//
// // The BuildContext also provides a mechanism whereby a layer can be
// // created to store the results of a given portion of the build process.
// // This example creates a layer called "yarn" that will hold the yarn cli.
// layer, err := context.Layers.Get("yarn")
// if err != nil {
// return packit.BuildResult{}, err
// }
// layer.Build = true
// layer.Launch = true
//
// // At this point we are performing the process of installing the yarn cli.
// // As those details are not important to the explanation of the packit API,
// // they are omitted here.
// err = InstallYarn(entry.Version, layer.Path)
// if err != nil {
// return packit.BuildResult{}, err
// }
//
// // After the installation of the yarn cli, a BuildResult can be returned
// // that included details of the executed BuildpackPlan, the Layers to
// // provide back to the lifecycle, and the Processes to execute at launch.
// return packit.BuildResult{
// Layers: []packit.Layer{
// layer,
// },
// Processes: []packit.Process{
// {
// Type: "web",
// Command: "yarn start",
// },
// },
// }, nil
// })
// }
//
// // InstallYarn executes the process of installing the yarn cli.
// func InstallYarn(version, path string) error {
// // Implemention omitted.
// return nil
// }
//
// Run
//
// Buildpacks can be created with a single entrypoint executable using the
// packit.Run function. Here, you can combine both the Detect and Build phases
// and run will ensure that the correct phase is called when the matching
// executable is called by the Cloud Native Buildpack Lifecycle. Below is an
// example that combines a simple detect and build into a single main program.
//
// package main
//
// import "github.com/paketo-buildpacks/packit"
//
// func main() {
// detect := func(context packit.DetectContext) (packit.DetectResult, error) {
// return packit.DetectResult{}, nil
// }
//
// build := func(context packit.BuildContext) (packit.BuildResult, error) {
// return packit.BuildResult{
// Processes: []packit.Process{
// {
// Type: "web",
// Command: `while true; do nc -l -p $PORT -c 'echo -e "HTTP/1.1 200 OK\n\n Hello, world!\n"'; done`,
// },
// },
// }, nil
// }
//
// packit.Run(detect, build)
// }
//
// Summary
//
// These examples show the very basics of what a buildpack implementation using
// packit might entail. For more details, please consult the documentation of
// the types and functions declared herein.
package packit