-
Notifications
You must be signed in to change notification settings - Fork 147
/
main.go
88 lines (77 loc) · 2.63 KB
/
main.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
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Implements ruby/rails buildpack.
// The rails buildpack precompiles assets using Rails.
package main
import (
"fmt"
gcp "github.com/GoogleCloudPlatform/buildpacks/pkg/gcpbuildpack"
"github.com/GoogleCloudPlatform/buildpacks/pkg/nodejs"
"github.com/GoogleCloudPlatform/buildpacks/pkg/ruby"
)
const (
yarnLayer = "yarn"
)
func main() {
gcp.Main(detectFn, buildFn)
}
func detectFn(ctx *gcp.Context) (gcp.DetectResult, error) {
railsExists, err := ctx.FileExists("bin", "rails")
if err != nil {
return nil, err
}
if !railsExists {
return gcp.OptOutFileNotFound("bin/rails"), nil
}
needsPrecompile, err := ruby.NeedsRailsAssetPrecompile(ctx)
if err != nil {
return nil, err
}
if !needsPrecompile {
return gcp.OptOut("Rails assets do not need precompilation"), nil
}
return gcp.OptIn("found Rails assets to precompile"), nil
}
func buildFn(ctx *gcp.Context) error {
ctx.Logf("Running Rails asset precompilation")
// Install Yarn as it is needed for asset precompilation.
if err := installYarn(ctx); err != nil {
return fmt.Errorf("installing Yarn: %w", err)
}
// It is common practise in Ruby asset precompilation to ignore non-zero exit codes.
result, err := ctx.Exec([]string{"bundle", "exec", "ruby", "bin/rails", "assets:precompile"},
gcp.WithEnv("RAILS_ENV=production", "MALLOC_ARENA_MAX=2", "RAILS_LOG_TO_STDOUT=true", "LANG=C.utf8"), gcp.WithUserAttribution)
if err != nil && result != nil && result.ExitCode != 0 {
ctx.Logf("WARNING: Asset precompilation returned non-zero exit code %d. Ignoring.", result.ExitCode)
return nil
}
if err != nil && result != nil {
return gcp.UserErrorf(result.Combined)
}
if err != nil {
return gcp.InternalErrorf("asset precompilation failed: %v", err)
}
return nil
}
func installYarn(ctx *gcp.Context) error {
pjs, err := nodejs.ReadPackageJSONIfExists(ctx.ApplicationRoot())
if err != nil {
return err
}
yrl, err := ctx.Layer(yarnLayer, gcp.BuildLayer, gcp.CacheLayer)
if err != nil {
return fmt.Errorf("creating %v layer: %w", yarnLayer, err)
}
return nodejs.InstallYarnLayer(ctx, yrl, pjs)
}