blob: 152729ba098cd6cdd79913c87d876d75a051ca65 [file] [log] [blame]
Colin Cross68f55102015-03-25 14:43:57 -07001// Copyright 2015 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
Lukacs T. Berki3243aa52021-02-25 14:44:14 +010015// Implements the environment JSON file handling for serializing the
16// environment variables that were used in soong_build so that soong_ui can
17// check whether they have changed
18package shared
Colin Cross68f55102015-03-25 14:43:57 -070019
20import (
21 "encoding/json"
22 "fmt"
23 "io/ioutil"
Colin Cross68f55102015-03-25 14:43:57 -070024 "sort"
25)
26
27type envFileEntry struct{ Key, Value string }
28type envFileData []envFileEntry
29
Jaewoong Jungf2200ad2020-11-16 16:01:27 -080030// Serializes the given environment variable name/value map into JSON formatted bytes by converting
31// to envFileEntry values and marshaling them.
32//
33// e.g. OUT_DIR = "out"
34// is converted to:
35// {
36// "Key": "OUT_DIR",
37// "Value": "out",
38// },
Colin Cross988414c2020-01-11 01:11:46 +000039func EnvFileContents(envDeps map[string]string) ([]byte, error) {
Colin Cross68f55102015-03-25 14:43:57 -070040 contents := make(envFileData, 0, len(envDeps))
41 for key, value := range envDeps {
42 contents = append(contents, envFileEntry{key, value})
43 }
44
45 sort.Sort(contents)
46
47 data, err := json.MarshalIndent(contents, "", " ")
48 if err != nil {
Colin Cross988414c2020-01-11 01:11:46 +000049 return nil, err
Colin Cross68f55102015-03-25 14:43:57 -070050 }
51
52 data = append(data, '\n')
53
Colin Cross988414c2020-01-11 01:11:46 +000054 return data, nil
Colin Cross68f55102015-03-25 14:43:57 -070055}
56
Jaewoong Jungf2200ad2020-11-16 16:01:27 -080057// Reads and deserializes a Soong environment file located at the given file path to determine its
58// staleness. If any environment variable values have changed, it prints them out and returns true.
59// Failing to read or parse the file also causes it to return true.
Lukacs T. Berki3243aa52021-02-25 14:44:14 +010060func StaleEnvFile(filepath string, getenv func(string) string) (bool, error) {
Jaewoong Jungf2200ad2020-11-16 16:01:27 -080061 data, err := ioutil.ReadFile(filepath)
Colin Cross68f55102015-03-25 14:43:57 -070062 if err != nil {
63 return true, err
64 }
65
66 var contents envFileData
67
68 err = json.Unmarshal(data, &contents)
69 if err != nil {
70 return true, err
71 }
72
73 var changed []string
74 for _, entry := range contents {
75 key := entry.Key
76 old := entry.Value
Lukacs T. Berki3243aa52021-02-25 14:44:14 +010077 cur := getenv(key)
Colin Cross68f55102015-03-25 14:43:57 -070078 if old != cur {
79 changed = append(changed, fmt.Sprintf("%s (%q -> %q)", key, old, cur))
80 }
81 }
82
83 if len(changed) > 0 {
84 fmt.Printf("environment variables changed value:\n")
85 for _, s := range changed {
86 fmt.Printf(" %s\n", s)
87 }
88 return true, nil
89 }
90
91 return false, nil
92}
93
Lukacs T. Berki7690c092021-02-26 14:27:36 +010094// Deserializes and environment serialized by EnvFileContents() and returns it
95// as a map[string]string.
96func EnvFromFile(envFile string) (map[string]string, error) {
97 result := make(map[string]string)
98 data, err := ioutil.ReadFile(envFile)
99 if err != nil {
100 return result, err
101 }
102
103 var contents envFileData
104 err = json.Unmarshal(data, &contents)
105 if err != nil {
106 return result, err
107 }
108
109 for _, entry := range contents {
110 result[entry.Key] = entry.Value
111 }
112
113 return result, nil
114}
115
Jaewoong Jungf2200ad2020-11-16 16:01:27 -0800116// Implements sort.Interface so that we can use sort.Sort on envFileData arrays.
Colin Cross68f55102015-03-25 14:43:57 -0700117func (e envFileData) Len() int {
118 return len(e)
119}
120
121func (e envFileData) Less(i, j int) bool {
122 return e[i].Key < e[j].Key
123}
124
125func (e envFileData) Swap(i, j int) {
126 e[i], e[j] = e[j], e[i]
127}
Jaewoong Jungf2200ad2020-11-16 16:01:27 -0800128
129var _ sort.Interface = envFileData{}