Liz Kammer | ea6666f | 2021-02-17 10:17:28 -0500 | [diff] [blame] | 1 | // Copyright 2021 Google Inc. All rights reserved. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | package android |
| 16 | |
Liz Kammer | ba3ea16 | 2021-02-17 13:22:03 -0500 | [diff] [blame] | 17 | import ( |
| 18 | "fmt" |
| 19 | "io/ioutil" |
| 20 | "path/filepath" |
| 21 | "strings" |
| 22 | |
Liz Kammer | bdc6099 | 2021-02-24 16:55:11 -0500 | [diff] [blame] | 23 | "github.com/google/blueprint" |
Liz Kammer | ba3ea16 | 2021-02-17 13:22:03 -0500 | [diff] [blame] | 24 | "github.com/google/blueprint/proptools" |
| 25 | ) |
| 26 | |
| 27 | type bazelModuleProperties struct { |
| 28 | // The label of the Bazel target replacing this Soong module. When run in conversion mode, this |
| 29 | // will import the handcrafted build target into the autogenerated file. Note: this may result in |
| 30 | // a conflict due to duplicate targets if bp2build_available is also set. |
| 31 | Label *string |
| 32 | |
| 33 | // If true, bp2build will generate the converted Bazel target for this module. Note: this may |
| 34 | // cause a conflict due to the duplicate targets if label is also set. |
| 35 | Bp2build_available bool |
| 36 | } |
| 37 | |
| 38 | // Properties contains common module properties for Bazel migration purposes. |
| 39 | type properties struct { |
| 40 | // In USE_BAZEL_ANALYSIS=1 mode, this represents the Bazel target replacing |
| 41 | // this Soong module. |
| 42 | Bazel_module bazelModuleProperties |
| 43 | } |
Liz Kammer | ea6666f | 2021-02-17 10:17:28 -0500 | [diff] [blame] | 44 | |
| 45 | // BazelModuleBase contains the property structs with metadata for modules which can be converted to |
| 46 | // Bazel. |
| 47 | type BazelModuleBase struct { |
Liz Kammer | ba3ea16 | 2021-02-17 13:22:03 -0500 | [diff] [blame] | 48 | bazelProperties properties |
Liz Kammer | ea6666f | 2021-02-17 10:17:28 -0500 | [diff] [blame] | 49 | } |
| 50 | |
| 51 | // Bazelable is specifies the interface for modules that can be converted to Bazel. |
| 52 | type Bazelable interface { |
Liz Kammer | ba3ea16 | 2021-02-17 13:22:03 -0500 | [diff] [blame] | 53 | bazelProps() *properties |
| 54 | HasHandcraftedLabel() bool |
Liz Kammer | bdc6099 | 2021-02-24 16:55:11 -0500 | [diff] [blame] | 55 | HandcraftedLabel() string |
| 56 | GetBazelLabel(ctx BazelConversionPathContext, module blueprint.Module) string |
Liz Kammer | ea6666f | 2021-02-17 10:17:28 -0500 | [diff] [blame] | 57 | ConvertWithBp2build() bool |
Liz Kammer | ba3ea16 | 2021-02-17 13:22:03 -0500 | [diff] [blame] | 58 | GetBazelBuildFileContents(c Config, path, name string) (string, error) |
Liz Kammer | bdc6099 | 2021-02-24 16:55:11 -0500 | [diff] [blame] | 59 | ConvertedToBazel() bool |
Liz Kammer | ea6666f | 2021-02-17 10:17:28 -0500 | [diff] [blame] | 60 | } |
| 61 | |
| 62 | // BazelModule is a lightweight wrapper interface around Module for Bazel-convertible modules. |
| 63 | type BazelModule interface { |
| 64 | Module |
| 65 | Bazelable |
| 66 | } |
| 67 | |
| 68 | // InitBazelModule is a wrapper function that decorates a BazelModule with Bazel-conversion |
| 69 | // properties. |
| 70 | func InitBazelModule(module BazelModule) { |
| 71 | module.AddProperties(module.bazelProps()) |
| 72 | } |
| 73 | |
| 74 | // bazelProps returns the Bazel properties for the given BazelModuleBase. |
Liz Kammer | ba3ea16 | 2021-02-17 13:22:03 -0500 | [diff] [blame] | 75 | func (b *BazelModuleBase) bazelProps() *properties { |
Liz Kammer | ea6666f | 2021-02-17 10:17:28 -0500 | [diff] [blame] | 76 | return &b.bazelProperties |
| 77 | } |
| 78 | |
Liz Kammer | ba3ea16 | 2021-02-17 13:22:03 -0500 | [diff] [blame] | 79 | // HasHandcraftedLabel returns whether this module has a handcrafted Bazel label. |
| 80 | func (b *BazelModuleBase) HasHandcraftedLabel() bool { |
| 81 | return b.bazelProperties.Bazel_module.Label != nil |
| 82 | } |
| 83 | |
| 84 | // HandcraftedLabel returns the handcrafted label for this module, or empty string if there is none |
| 85 | func (b *BazelModuleBase) HandcraftedLabel() string { |
| 86 | return proptools.String(b.bazelProperties.Bazel_module.Label) |
| 87 | } |
| 88 | |
Liz Kammer | ea6666f | 2021-02-17 10:17:28 -0500 | [diff] [blame] | 89 | // GetBazelLabel returns the Bazel label for the given BazelModuleBase. |
Liz Kammer | bdc6099 | 2021-02-24 16:55:11 -0500 | [diff] [blame] | 90 | func (b *BazelModuleBase) GetBazelLabel(ctx BazelConversionPathContext, module blueprint.Module) string { |
| 91 | if b.HasHandcraftedLabel() { |
| 92 | return b.HandcraftedLabel() |
| 93 | } |
| 94 | if b.ConvertWithBp2build() { |
| 95 | return bp2buildModuleLabel(ctx, module) |
| 96 | } |
| 97 | return "" // no label for unconverted module |
Liz Kammer | ea6666f | 2021-02-17 10:17:28 -0500 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | // ConvertWithBp2build returns whether the given BazelModuleBase should be converted with bp2build. |
| 101 | func (b *BazelModuleBase) ConvertWithBp2build() bool { |
| 102 | return b.bazelProperties.Bazel_module.Bp2build_available |
| 103 | } |
Liz Kammer | ba3ea16 | 2021-02-17 13:22:03 -0500 | [diff] [blame] | 104 | |
| 105 | // GetBazelBuildFileContents returns the file contents of a hand-crafted BUILD file if available or |
| 106 | // an error if there are errors reading the file. |
| 107 | // TODO(b/181575318): currently we append the whole BUILD file, let's change that to do |
| 108 | // something more targeted based on the rule type and target. |
| 109 | func (b *BazelModuleBase) GetBazelBuildFileContents(c Config, path, name string) (string, error) { |
Liz Kammer | bdc6099 | 2021-02-24 16:55:11 -0500 | [diff] [blame] | 110 | if !strings.Contains(b.HandcraftedLabel(), path) { |
| 111 | return "", fmt.Errorf("%q not found in bazel_module.label %q", path, b.HandcraftedLabel()) |
Liz Kammer | ba3ea16 | 2021-02-17 13:22:03 -0500 | [diff] [blame] | 112 | } |
| 113 | name = filepath.Join(path, name) |
| 114 | f, err := c.fs.Open(name) |
| 115 | if err != nil { |
| 116 | return "", err |
| 117 | } |
| 118 | defer f.Close() |
| 119 | |
| 120 | data, err := ioutil.ReadAll(f) |
| 121 | if err != nil { |
| 122 | return "", err |
| 123 | } |
| 124 | return string(data[:]), nil |
| 125 | } |
Liz Kammer | bdc6099 | 2021-02-24 16:55:11 -0500 | [diff] [blame] | 126 | |
| 127 | // ConvertedToBazel returns whether this module has been converted to Bazel, whether automatically |
| 128 | // or manually |
| 129 | func (b *BazelModuleBase) ConvertedToBazel() bool { |
| 130 | return b.ConvertWithBp2build() || b.HasHandcraftedLabel() |
| 131 | } |