blob: 27e8198a8b446f24965e3b33fa905a2bbb22b5b4 [file] [log] [blame]
Sasha Smundakd7d07ad2021-09-10 15:42:34 -07001// Copyright 2021 Google LLC
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
15package mk2rbc
16
17import (
18 mkparser "android/soong/androidmk/parser"
19 "bytes"
20 "fmt"
21 "io/ioutil"
22 "os"
23 "sort"
24 "strconv"
25 "strings"
26)
27
28const codenamePrefix = "PLATFORM_VERSION_CODENAME."
29
30// ParseVersionDefaults extracts version settings from the given file
31// and returns the map.
32func ParseVersionDefaults(path string) (map[string]string, error) {
33 contents, err := ioutil.ReadFile(path)
34 if err != nil {
35 return nil, err
36 }
37 parser := mkparser.NewParser(path, bytes.NewBuffer(contents))
38 nodes, errs := parser.Parse()
39 if len(errs) > 0 {
40 for _, e := range errs {
41 fmt.Fprintln(os.Stderr, "ERROR:", e)
42 }
43 return nil, fmt.Errorf("cannot parse %s", path)
44 }
45
46 result := map[string]string{
47 "DEFAULT_PLATFORM_VERSION": "",
48 "MAX_PLATFORM_VERSION": "",
49 "MIN_PLATFORM_VERSION": "A",
50 "PLATFORM_BASE_SDK_EXTENSION_VERSION": "",
51 "PLATFORM_SDK_EXTENSION_VERSION": "",
52 "PLATFORM_SDK_VERSION": "",
53 "PLATFORM_SECURITY_PATCH": "",
54 "PLATFORM_VERSION_LAST_STABLE": "",
55 }
56 for _, node := range nodes {
57 asgn, ok := node.(*mkparser.Assignment)
58 if !(ok && asgn.Name.Const()) {
59 continue
60 }
61 s := asgn.Name.Strings[0]
62 _, ok = result[s]
63 if !ok {
64 ok = strings.HasPrefix(s, codenamePrefix)
65 }
66 if !ok {
67 continue
68 }
69 v := asgn.Value
70 if !v.Const() {
71 return nil, fmt.Errorf("the value of %s should be constant", s)
72 }
73 result[s] = strings.TrimSpace(v.Strings[0])
74 }
75 return result, nil
76}
77
78func genericValue(s string) interface{} {
79 if ival, err := strconv.ParseInt(s, 0, 0); err == nil {
80 return ival
81 }
82 return s
83}
84
85// VersionDefaults generates the contents of the version_defaults.rbc file
86func VersionDefaults(values map[string]string) string {
87 var sink bytes.Buffer
88 var lines []string
89 var codenames []string
90 for name, value := range values {
91 if strings.HasPrefix(name, codenamePrefix) {
92 codenames = append(codenames,
93 fmt.Sprintf("%q: %q", strings.TrimPrefix(name, codenamePrefix), value))
94 } else {
95 // Print numbers as such
96 lines = append(lines, fmt.Sprintf(" %s = %#v,\n",
97 strings.ToLower(name), genericValue(value)))
98 }
99 }
100 sort.Strings(lines)
101 sink.WriteString("version_defaults = struct(\n")
102 for _, l := range lines {
103 sink.WriteString(l)
104 }
105 sink.WriteString(" codenames = { ")
106 sink.WriteString(strings.Join(codenames, ", "))
107 sink.WriteString(" }\n)\n")
108 return sink.String()
109}