2015-07-09 22:57:48 +02:00
|
|
|
// Copyright 2015 Google Inc. All rights reserved.
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
|
2016-05-19 00:37:25 +02:00
|
|
|
package android
|
2015-07-09 22:57:48 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"reflect"
|
2015-11-25 02:53:15 +01:00
|
|
|
"runtime"
|
2015-07-09 22:57:48 +02:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/google/blueprint/proptools"
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2016-10-12 23:38:15 +02:00
|
|
|
PreDepsMutators(func(ctx RegisterMutatorsContext) {
|
|
|
|
ctx.BottomUp("variable", variableMutator).Parallel()
|
|
|
|
})
|
2015-07-09 22:57:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type variableProperties struct {
|
|
|
|
Product_variables struct {
|
2015-09-17 01:48:54 +02:00
|
|
|
Platform_sdk_version struct {
|
|
|
|
Asflags []string
|
2017-05-08 22:43:00 +02:00
|
|
|
Cflags []string
|
2015-09-17 01:48:54 +02:00
|
|
|
}
|
2015-12-02 01:31:16 +01:00
|
|
|
|
|
|
|
// unbundled_build is a catch-all property to annotate modules that don't build in one or
|
|
|
|
// more unbundled branches, usually due to dependencies missing from the manifest.
|
|
|
|
Unbundled_build struct {
|
|
|
|
Enabled *bool `android:"arch_variant"`
|
|
|
|
} `android:"arch_variant"`
|
2016-01-05 23:27:55 +01:00
|
|
|
|
|
|
|
Brillo struct {
|
2016-10-04 08:36:47 +02:00
|
|
|
Cflags []string
|
2016-01-05 23:27:55 +01:00
|
|
|
Version_script *string `android:"arch_variant"`
|
|
|
|
} `android:"arch_variant"`
|
2016-03-01 23:08:42 +01:00
|
|
|
|
|
|
|
Malloc_not_svelte struct {
|
|
|
|
Cflags []string
|
|
|
|
}
|
2016-05-13 03:04:18 +02:00
|
|
|
|
|
|
|
Safestack struct {
|
|
|
|
Cflags []string `android:"arch_variant"`
|
|
|
|
} `android:"arch_variant"`
|
2016-07-12 23:57:40 +02:00
|
|
|
|
2016-07-26 02:42:18 +02:00
|
|
|
Binder32bit struct {
|
|
|
|
Cflags []string
|
|
|
|
}
|
2016-09-22 23:49:10 +02:00
|
|
|
|
2017-05-02 19:58:50 +02:00
|
|
|
Device_uses_hwc2 struct {
|
|
|
|
Cflags []string
|
|
|
|
}
|
|
|
|
|
2017-05-04 22:57:05 +02:00
|
|
|
Override_rs_driver struct {
|
|
|
|
Cflags []string
|
|
|
|
}
|
|
|
|
|
2017-12-13 23:06:20 +01:00
|
|
|
// treble_linker_namespaces is true when the system/vendor linker namespace separation is
|
|
|
|
// enabled.
|
|
|
|
Treble_linker_namespaces struct {
|
|
|
|
Cflags []string
|
|
|
|
}
|
|
|
|
// enforce_vintf_manifest is true when a device is required to have a vintf manifest.
|
|
|
|
Enforce_vintf_manifest struct {
|
|
|
|
Cflags []string
|
|
|
|
}
|
|
|
|
|
2016-12-08 18:46:35 +01:00
|
|
|
// debuggable is true for eng and userdebug builds, and can be used to turn on additional
|
|
|
|
// debugging features that don't significantly impact runtime behavior. userdebug builds
|
|
|
|
// are used for dogfooding and performance testing, and should be as similar to user builds
|
|
|
|
// as possible.
|
2016-09-22 23:49:10 +02:00
|
|
|
Debuggable struct {
|
2016-10-04 08:36:47 +02:00
|
|
|
Cflags []string
|
|
|
|
Cppflags []string
|
2017-04-14 23:38:47 +02:00
|
|
|
Init_rc []string
|
2016-09-22 23:49:10 +02:00
|
|
|
}
|
2016-12-08 18:46:35 +01:00
|
|
|
|
|
|
|
// eng is true for -eng builds, and can be used to turn on additionaly heavyweight debugging
|
|
|
|
// features.
|
|
|
|
Eng struct {
|
|
|
|
Cflags []string
|
|
|
|
Cppflags []string
|
|
|
|
}
|
2017-05-05 22:37:11 +02:00
|
|
|
|
|
|
|
Pdk struct {
|
2017-10-17 22:55:02 +02:00
|
|
|
Enabled *bool `android:"arch_variant"`
|
|
|
|
} `android:"arch_variant"`
|
2017-08-23 23:58:37 +02:00
|
|
|
|
|
|
|
Uml struct {
|
|
|
|
Cppflags []string
|
|
|
|
}
|
2015-12-02 01:31:16 +01:00
|
|
|
} `android:"arch_variant"`
|
2015-07-09 22:57:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
var zeroProductVariables variableProperties
|
|
|
|
|
2015-08-27 22:28:01 +02:00
|
|
|
type productVariables struct {
|
2016-05-11 09:27:49 +02:00
|
|
|
// Suffix to add to generated Makefiles
|
|
|
|
Make_suffix *string `json:",omitempty"`
|
|
|
|
|
2018-01-11 01:06:12 +01:00
|
|
|
BuildId *string `json:",omitempty"`
|
|
|
|
BuildNumberFromFile *string `json:",omitempty"`
|
|
|
|
DateFromFile *string `json:",omitempty"`
|
|
|
|
|
2017-07-28 21:39:46 +02:00
|
|
|
Platform_sdk_version *int `json:",omitempty"`
|
2017-08-31 21:30:37 +02:00
|
|
|
Platform_sdk_final *bool `json:",omitempty"`
|
2017-07-28 21:39:46 +02:00
|
|
|
Platform_version_active_codenames []string `json:",omitempty"`
|
|
|
|
Platform_version_future_codenames []string `json:",omitempty"`
|
2017-12-07 09:18:15 +01:00
|
|
|
Platform_vndk_version *string `json:",omitempty"`
|
2018-01-15 07:05:10 +01:00
|
|
|
Platform_systemsdk_versions []string `json:",omitempty"`
|
|
|
|
|
|
|
|
DeviceName *string `json:",omitempty"`
|
|
|
|
DeviceArch *string `json:",omitempty"`
|
|
|
|
DeviceArchVariant *string `json:",omitempty"`
|
|
|
|
DeviceCpuVariant *string `json:",omitempty"`
|
|
|
|
DeviceAbi *[]string `json:",omitempty"`
|
|
|
|
DeviceVndkVersion *string `json:",omitempty"`
|
|
|
|
DeviceSystemSdkVersions *[]string `json:",omitempty"`
|
2015-09-17 23:33:42 +02:00
|
|
|
|
|
|
|
DeviceSecondaryArch *string `json:",omitempty"`
|
|
|
|
DeviceSecondaryArchVariant *string `json:",omitempty"`
|
|
|
|
DeviceSecondaryCpuVariant *string `json:",omitempty"`
|
|
|
|
DeviceSecondaryAbi *[]string `json:",omitempty"`
|
|
|
|
|
|
|
|
HostArch *string `json:",omitempty"`
|
|
|
|
HostSecondaryArch *string `json:",omitempty"`
|
2015-11-25 02:53:15 +01:00
|
|
|
|
|
|
|
CrossHost *string `json:",omitempty"`
|
|
|
|
CrossHostArch *string `json:",omitempty"`
|
|
|
|
CrossHostSecondaryArch *string `json:",omitempty"`
|
2015-12-02 01:31:16 +01:00
|
|
|
|
2017-10-31 01:32:15 +01:00
|
|
|
ResourceOverlays *[]string `json:",omitempty"`
|
|
|
|
EnforceRROTargets *[]string `json:",omitempty"`
|
|
|
|
EnforceRROExcludedOverlays *[]string `json:",omitempty"`
|
|
|
|
|
|
|
|
AAPTCharacteristics *string `json:",omitempty"`
|
|
|
|
AAPTConfig *[]string `json:",omitempty"`
|
|
|
|
AAPTPreferredConfig *string `json:",omitempty"`
|
|
|
|
AAPTPrebuiltDPI *[]string `json:",omitempty"`
|
|
|
|
|
2017-12-02 02:16:02 +01:00
|
|
|
DefaultAppCertificate *string `json:",omitempty"`
|
|
|
|
|
2017-10-31 01:32:15 +01:00
|
|
|
AppsDefaultVersionName *string `json:",omitempty"`
|
|
|
|
|
2016-03-16 20:35:33 +01:00
|
|
|
Allow_missing_dependencies *bool `json:",omitempty"`
|
|
|
|
Unbundled_build *bool `json:",omitempty"`
|
|
|
|
Brillo *bool `json:",omitempty"`
|
|
|
|
Malloc_not_svelte *bool `json:",omitempty"`
|
2016-05-13 03:04:18 +02:00
|
|
|
Safestack *bool `json:",omitempty"`
|
2016-05-18 01:35:02 +02:00
|
|
|
HostStaticBinaries *bool `json:",omitempty"`
|
2016-07-26 02:42:18 +02:00
|
|
|
Binder32bit *bool `json:",omitempty"`
|
2016-08-30 01:14:13 +02:00
|
|
|
UseGoma *bool `json:",omitempty"`
|
2016-09-22 23:49:10 +02:00
|
|
|
Debuggable *bool `json:",omitempty"`
|
2016-12-08 18:46:35 +01:00
|
|
|
Eng *bool `json:",omitempty"`
|
2017-05-02 19:58:50 +02:00
|
|
|
Device_uses_hwc2 *bool `json:",omitempty"`
|
2017-12-13 23:06:20 +01:00
|
|
|
Treble_linker_namespaces *bool `json:",omitempty"`
|
|
|
|
Sepolicy_split *bool `json:",omitempty"`
|
|
|
|
Enforce_vintf_manifest *bool `json:",omitempty"`
|
2017-05-25 19:18:24 +02:00
|
|
|
Pdk *bool `json:",omitempty"`
|
2017-08-23 23:58:37 +02:00
|
|
|
Uml *bool `json:",omitempty"`
|
2017-10-31 21:55:34 +01:00
|
|
|
MinimizeJavaDebugInfo *bool `json:",omitempty"`
|
2016-01-06 23:41:07 +01:00
|
|
|
|
2017-07-13 23:46:05 +02:00
|
|
|
IntegerOverflowExcludePaths *[]string `json:",omitempty"`
|
|
|
|
|
2017-10-31 10:26:14 +01:00
|
|
|
EnableCFI *bool `json:",omitempty"`
|
|
|
|
CFIExcludePaths *[]string `json:",omitempty"`
|
|
|
|
CFIIncludePaths *[]string `json:",omitempty"`
|
|
|
|
|
2018-01-10 11:00:15 +01:00
|
|
|
VendorPath *string `json:",omitempty"`
|
|
|
|
OdmPath *string `json:",omitempty"`
|
|
|
|
ProductPath *string `json:",omitempty"`
|
2016-12-06 02:16:02 +01:00
|
|
|
|
2016-09-27 00:45:04 +02:00
|
|
|
ClangTidy *bool `json:",omitempty"`
|
|
|
|
TidyChecks *string `json:",omitempty"`
|
|
|
|
|
2017-02-27 18:01:54 +01:00
|
|
|
NativeCoverage *bool `json:",omitempty"`
|
|
|
|
CoveragePaths *[]string `json:",omitempty"`
|
|
|
|
CoverageExcludePaths *[]string `json:",omitempty"`
|
2017-02-10 01:16:31 +01:00
|
|
|
|
2016-08-25 00:25:47 +02:00
|
|
|
DevicePrefer32BitExecutables *bool `json:",omitempty"`
|
|
|
|
HostPrefer32BitExecutables *bool `json:",omitempty"`
|
|
|
|
|
2016-11-02 22:34:39 +01:00
|
|
|
SanitizeHost []string `json:",omitempty"`
|
|
|
|
SanitizeDevice []string `json:",omitempty"`
|
2017-06-28 18:10:48 +02:00
|
|
|
SanitizeDeviceDiag []string `json:",omitempty"`
|
2016-11-02 22:34:39 +01:00
|
|
|
SanitizeDeviceArch []string `json:",omitempty"`
|
2016-12-19 22:44:41 +01:00
|
|
|
|
|
|
|
ArtUseReadBarrier *bool `json:",omitempty"`
|
2016-12-09 00:45:07 +01:00
|
|
|
|
|
|
|
BtConfigIncludeDir *string `json:",omitempty"`
|
2017-05-04 22:57:05 +02:00
|
|
|
|
|
|
|
Override_rs_driver *string `json:",omitempty"`
|
2017-07-03 06:18:12 +02:00
|
|
|
|
|
|
|
DeviceKernelHeaders []string `json:",omitempty"`
|
2017-11-27 23:52:21 +01:00
|
|
|
DistDir *string `json:",omitempty"`
|
Install VNDK snapshot libraries for system build
When BOARD_VNDK_VERSION := <VNDK version>, or
PRODUCT_EXTRA_VNDK_VERSIONS includes the needed <VNDK version> list,
the prebuilt VNDK libs in prebuilts/vndk/ directory will be
installed.
Each prebuilt VNDK module uses "vndk_prebuilt_shared" for shared
VNDK/VNDK-SP libs.
Following is the sample configuration of a vndk snapshot module:
vndk_prebuilt_shared {
name: "libfoo",
version: "27",
vendor_available: true,
vndk: {
enabled: true,
},
arch: {
arm64: {
srcs: ["arm/lib64/libfoo.so"],
},
arm: {
srcs: ["arm/lib/libfoo.so"],
},
},
}
The Android.bp for the snapshot modules will be auto-generated by a
script.
Bug: 38304393
Bug: 65377115
Bug: 68123344
Test: set BOARD_VNDK_VERSION := 27
copy a snapshot for v27
build with make command
Change-Id: Ib93107530dbabb4a24583f4d6e4f0c513c9adfec
2017-11-17 04:10:28 +01:00
|
|
|
|
|
|
|
ExtraVndkVersions []string `json:",omitempty"`
|
2017-11-30 01:47:17 +01:00
|
|
|
|
|
|
|
NamespacesToExport []string `json:",omitempty"`
|
2018-01-30 08:11:42 +01:00
|
|
|
|
|
|
|
PgoAdditionalProfileDirs []string `json:",omitempty"`
|
2015-09-16 22:53:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func boolPtr(v bool) *bool {
|
|
|
|
return &v
|
2015-08-27 22:28:01 +02:00
|
|
|
}
|
|
|
|
|
2015-09-17 01:48:54 +02:00
|
|
|
func intPtr(v int) *int {
|
|
|
|
return &v
|
|
|
|
}
|
|
|
|
|
2015-09-17 23:33:42 +02:00
|
|
|
func stringPtr(v string) *string {
|
|
|
|
return &v
|
|
|
|
}
|
|
|
|
|
2015-09-18 19:57:10 +02:00
|
|
|
func (v *productVariables) SetDefaultConfig() {
|
|
|
|
*v = productVariables{
|
2017-11-13 23:34:56 +01:00
|
|
|
Platform_sdk_version: intPtr(26),
|
|
|
|
Platform_version_active_codenames: []string{"P"},
|
|
|
|
Platform_version_future_codenames: []string{"P"},
|
|
|
|
|
2015-09-17 23:33:42 +02:00
|
|
|
HostArch: stringPtr("x86_64"),
|
|
|
|
HostSecondaryArch: stringPtr("x86"),
|
2017-11-13 23:34:56 +01:00
|
|
|
DeviceName: stringPtr("generic_arm64"),
|
2015-09-17 23:33:42 +02:00
|
|
|
DeviceArch: stringPtr("arm64"),
|
2016-03-30 07:06:05 +02:00
|
|
|
DeviceArchVariant: stringPtr("armv8-a"),
|
2017-11-13 23:34:56 +01:00
|
|
|
DeviceCpuVariant: stringPtr("generic"),
|
2015-09-17 23:33:42 +02:00
|
|
|
DeviceAbi: &[]string{"arm64-v8a"},
|
|
|
|
DeviceSecondaryArch: stringPtr("arm"),
|
2017-11-13 23:34:56 +01:00
|
|
|
DeviceSecondaryArchVariant: stringPtr("armv8-a"),
|
|
|
|
DeviceSecondaryCpuVariant: stringPtr("generic"),
|
|
|
|
DeviceSecondaryAbi: &[]string{"armeabi-v7a", "armeabi"},
|
2017-10-31 01:32:15 +01:00
|
|
|
|
|
|
|
AAPTConfig: &[]string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
|
|
|
|
AAPTPreferredConfig: stringPtr("xhdpi"),
|
|
|
|
AAPTCharacteristics: stringPtr("nosdcard"),
|
|
|
|
AAPTPrebuiltDPI: &[]string{"xhdpi", "xxhdpi"},
|
|
|
|
|
2017-11-13 23:34:56 +01:00
|
|
|
Malloc_not_svelte: boolPtr(true),
|
2017-10-31 01:32:15 +01:00
|
|
|
Safestack: boolPtr(false),
|
2015-08-27 22:28:01 +02:00
|
|
|
}
|
2015-11-25 02:53:15 +01:00
|
|
|
|
|
|
|
if runtime.GOOS == "linux" {
|
|
|
|
v.CrossHost = stringPtr("windows")
|
|
|
|
v.CrossHostArch = stringPtr("x86")
|
2016-02-04 08:16:33 +01:00
|
|
|
v.CrossHostSecondaryArch = stringPtr("x86_64")
|
2015-11-25 02:53:15 +01:00
|
|
|
}
|
2015-07-09 22:57:48 +02:00
|
|
|
}
|
|
|
|
|
2016-05-19 00:37:25 +02:00
|
|
|
func variableMutator(mctx BottomUpMutatorContext) {
|
|
|
|
var module Module
|
2015-07-09 22:57:48 +02:00
|
|
|
var ok bool
|
2016-05-19 00:37:25 +02:00
|
|
|
if module, ok = mctx.Module().(Module); !ok {
|
2015-07-09 22:57:48 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: depend on config variable, create variants, propagate variants up tree
|
|
|
|
a := module.base()
|
2015-10-29 01:23:31 +01:00
|
|
|
variableValues := reflect.ValueOf(&a.variableProperties.Product_variables).Elem()
|
2015-07-09 22:57:48 +02:00
|
|
|
zeroValues := reflect.ValueOf(zeroProductVariables.Product_variables)
|
|
|
|
|
|
|
|
for i := 0; i < variableValues.NumField(); i++ {
|
|
|
|
variableValue := variableValues.Field(i)
|
|
|
|
zeroValue := zeroValues.Field(i)
|
2015-08-27 22:28:01 +02:00
|
|
|
name := variableValues.Type().Field(i).Name
|
|
|
|
property := "product_variables." + proptools.PropertyNameForField(name)
|
|
|
|
|
2015-09-16 22:53:42 +02:00
|
|
|
// Check that the variable was set for the product
|
2017-11-29 09:27:14 +01:00
|
|
|
val := reflect.ValueOf(mctx.Config().ProductVariables).FieldByName(name)
|
2015-09-16 22:53:42 +02:00
|
|
|
if !val.IsValid() || val.Kind() != reflect.Ptr || val.IsNil() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
val = val.Elem()
|
|
|
|
|
|
|
|
// For bools, check that the value is true
|
|
|
|
if val.Kind() == reflect.Bool && val.Bool() == false {
|
|
|
|
continue
|
|
|
|
}
|
2015-07-09 22:57:48 +02:00
|
|
|
|
2015-09-16 22:53:42 +02:00
|
|
|
// Check if any properties were set for the module
|
|
|
|
if reflect.DeepEqual(variableValue.Interface(), zeroValue.Interface()) {
|
|
|
|
continue
|
2015-07-09 22:57:48 +02:00
|
|
|
}
|
2015-09-16 22:53:42 +02:00
|
|
|
|
|
|
|
a.setVariableProperties(mctx, property, variableValue, val.Interface())
|
2015-07-09 22:57:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-19 00:37:25 +02:00
|
|
|
func (a *ModuleBase) setVariableProperties(ctx BottomUpMutatorContext,
|
2015-07-09 22:57:48 +02:00
|
|
|
prefix string, productVariablePropertyValue reflect.Value, variableValue interface{}) {
|
|
|
|
|
2017-05-06 01:16:24 +02:00
|
|
|
printfIntoProperties(ctx, prefix, productVariablePropertyValue, variableValue)
|
2015-07-09 22:57:48 +02:00
|
|
|
|
2015-10-29 01:23:31 +01:00
|
|
|
err := proptools.AppendMatchingProperties(a.generalProperties,
|
|
|
|
productVariablePropertyValue.Addr().Interface(), nil)
|
|
|
|
if err != nil {
|
|
|
|
if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
|
|
|
|
ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
|
|
|
|
} else {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
2015-07-09 22:57:48 +02:00
|
|
|
}
|
|
|
|
|
2017-05-06 01:16:24 +02:00
|
|
|
func printfIntoPropertiesError(ctx BottomUpMutatorContext, prefix string,
|
|
|
|
productVariablePropertyValue reflect.Value, i int, err error) {
|
|
|
|
|
|
|
|
field := productVariablePropertyValue.Type().Field(i).Name
|
|
|
|
property := prefix + "." + proptools.PropertyNameForField(field)
|
|
|
|
ctx.PropertyErrorf(property, "%s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func printfIntoProperties(ctx BottomUpMutatorContext, prefix string,
|
|
|
|
productVariablePropertyValue reflect.Value, variableValue interface{}) {
|
|
|
|
|
2015-07-09 22:57:48 +02:00
|
|
|
for i := 0; i < productVariablePropertyValue.NumField(); i++ {
|
|
|
|
propertyValue := productVariablePropertyValue.Field(i)
|
2015-12-03 00:24:38 +01:00
|
|
|
kind := propertyValue.Kind()
|
|
|
|
if kind == reflect.Ptr {
|
|
|
|
if propertyValue.IsNil() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
propertyValue = propertyValue.Elem()
|
|
|
|
}
|
2015-07-09 22:57:48 +02:00
|
|
|
switch propertyValue.Kind() {
|
|
|
|
case reflect.String:
|
2017-05-06 01:16:24 +02:00
|
|
|
err := printfIntoProperty(propertyValue, variableValue)
|
|
|
|
if err != nil {
|
|
|
|
printfIntoPropertiesError(ctx, prefix, productVariablePropertyValue, i, err)
|
|
|
|
}
|
2015-07-09 22:57:48 +02:00
|
|
|
case reflect.Slice:
|
|
|
|
for j := 0; j < propertyValue.Len(); j++ {
|
2017-05-06 01:16:24 +02:00
|
|
|
err := printfIntoProperty(propertyValue.Index(j), variableValue)
|
|
|
|
if err != nil {
|
|
|
|
printfIntoPropertiesError(ctx, prefix, productVariablePropertyValue, i, err)
|
|
|
|
}
|
2015-07-09 22:57:48 +02:00
|
|
|
}
|
2015-12-03 00:24:38 +01:00
|
|
|
case reflect.Bool:
|
|
|
|
// Nothing
|
2015-07-09 22:57:48 +02:00
|
|
|
case reflect.Struct:
|
2017-05-06 01:16:24 +02:00
|
|
|
printfIntoProperties(ctx, prefix, propertyValue, variableValue)
|
2015-07-09 22:57:48 +02:00
|
|
|
default:
|
|
|
|
panic(fmt.Errorf("unsupported field kind %q", propertyValue.Kind()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-06 01:16:24 +02:00
|
|
|
func printfIntoProperty(propertyValue reflect.Value, variableValue interface{}) error {
|
2015-07-09 22:57:48 +02:00
|
|
|
s := propertyValue.String()
|
2017-05-06 01:16:24 +02:00
|
|
|
|
|
|
|
count := strings.Count(s, "%")
|
|
|
|
if count == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if count > 1 {
|
|
|
|
return fmt.Errorf("product variable properties only support a single '%%'")
|
|
|
|
}
|
|
|
|
|
2015-07-09 22:57:48 +02:00
|
|
|
if strings.Contains(s, "%d") {
|
|
|
|
switch v := variableValue.(type) {
|
|
|
|
case int:
|
2017-05-06 01:16:24 +02:00
|
|
|
// Nothing
|
2015-07-09 22:57:48 +02:00
|
|
|
case bool:
|
|
|
|
if v {
|
2017-05-06 01:16:24 +02:00
|
|
|
variableValue = 1
|
|
|
|
} else {
|
|
|
|
variableValue = 0
|
2015-07-09 22:57:48 +02:00
|
|
|
}
|
|
|
|
default:
|
2017-05-06 01:16:24 +02:00
|
|
|
return fmt.Errorf("unsupported type %T for %%d", variableValue)
|
|
|
|
}
|
|
|
|
} else if strings.Contains(s, "%s") {
|
|
|
|
switch variableValue.(type) {
|
|
|
|
case string:
|
|
|
|
// Nothing
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("unsupported type %T for %%s", variableValue)
|
2015-07-09 22:57:48 +02:00
|
|
|
}
|
2017-05-06 01:16:24 +02:00
|
|
|
} else {
|
|
|
|
return fmt.Errorf("unsupported %% in product variable property")
|
2015-07-09 22:57:48 +02:00
|
|
|
}
|
2017-05-06 01:16:24 +02:00
|
|
|
|
|
|
|
propertyValue.Set(reflect.ValueOf(fmt.Sprintf(s, variableValue)))
|
|
|
|
|
|
|
|
return nil
|
2015-07-09 22:57:48 +02:00
|
|
|
}
|