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