MCPcopy Create free account
hub / github.com/coder/envbuilder / Compile

Method Compile

devcontainer/features/features.go:195–259  ·  view source on GitHub ↗

Extract unpacks the feature from the image and returns a set of lines that should be appended to a Dockerfile to install the feature.

(featureRef, featureName, featureDir, containerUser, remoteUser string, useBuildContexts bool, options map[string]any)

Source from the content-addressed store, hash-verified

193// Extract unpacks the feature from the image and returns a set of lines
194// that should be appended to a Dockerfile to install the feature.
195func (s *Spec) Compile(featureRef, featureName, featureDir, containerUser, remoteUser string, useBuildContexts bool, options map[string]any) (string, string, error) {
196 // TODO not sure how we figure out _(REMOTE|CONTAINER)_USER_HOME
197 // as per the feature spec.
198 // See https://containers.dev/implementors/features/#user-env-var
199 var fromDirective string
200 runDirective := []string{
201 "_CONTAINER_USER=" + strconv.Quote(containerUser),
202 "_REMOTE_USER=" + strconv.Quote(remoteUser),
203 }
204 for key, value := range s.Options {
205 strValue := fmt.Sprint(value.Default)
206 provided, ok := options[key]
207 if ok {
208 strValue = fmt.Sprint(provided)
209 // delete so we can check if there are any unknown options
210 delete(options, key)
211 }
212 runDirective = append(runDirective, fmt.Sprintf(`%s=%q`, convertOptionNameToEnv(key), strValue))
213 }
214 if len(options) > 0 {
215 return "", "", fmt.Errorf("unknown option: %v", options)
216 }
217 // It's critical that the Dockerfile produced is deterministic,
218 // regardless of map iteration order.
219 sort.Strings(runDirective)
220 // See https://containers.dev/implementors/features/#invoking-installsh
221 if useBuildContexts {
222 // Use a deterministic target directory to make the resulting Dockerfile cacheable
223 featureDir = "/.envbuilder/features/" + featureName
224 fromDirective = "FROM scratch AS envbuilder_feature_" + featureName + "\nCOPY --from=" + featureRef + " / /\n"
225 runDirective = append([]string{"RUN", "--mount=type=bind,from=envbuilder_feature_" + featureName + ",target=" + featureDir + ",rw"}, runDirective...)
226 } else {
227 runDirective = append([]string{"RUN"}, runDirective...)
228 }
229 runDirective = append(runDirective, "./install.sh")
230
231 comment := ""
232 if s.Name != "" {
233 comment += "# " + s.Name
234 }
235 if s.Version != "" {
236 comment += " " + s.Version
237 }
238 if s.Description != "" {
239 comment += " - " + s.Description
240 }
241 lines := []string{}
242 if comment != "" {
243 lines = append(lines, comment)
244 }
245 lines = append(lines, "WORKDIR "+featureDir)
246 envKeys := make([]string, 0, len(s.ContainerEnv))
247 for key := range s.ContainerEnv {
248 envKeys = append(envKeys, key)
249 }
250 // It's critical that the Dockerfile produced is deterministic,
251 // regardless of map iteration order.
252 sort.Strings(envKeys)

Callers 1

TestCompileFunction · 0.95

Calls 2

convertOptionNameToEnvFunction · 0.85
JoinMethod · 0.80

Tested by 1

TestCompileFunction · 0.76