aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2018-01-08 14:58:46 -0800
committerDan Willemsen <dwillemsen@google.com>2018-01-19 21:46:21 +0000
commited86952403dfc24ca270ff6d32ea4cdeeeff14f7 (patch)
treeb787271ebde12721f40ce877941fcc650bc8cc53 /ui
parentc1fecc2dfa3be12d532964d47463aa9eb20a059c (diff)
downloadbuild_soong-ed86952403dfc24ca270ff6d32ea4cdeeeff14f7.tar.gz
build_soong-ed86952403dfc24ca270ff6d32ea4cdeeeff14f7.tar.bz2
build_soong-ed86952403dfc24ca270ff6d32ea4cdeeeff14f7.zip
Normalize LANG / LC_* environment
This ensures that the current locale supports UTF-8, and that we're getting a consistent (but still supported by the system) locale for every configuration except user-facing messages. This should eliminate any reproducibility problems around sorting, formatting, etc for all built products, while still showing localized error messages where available. Bug: 71573630 Test: LANG=es_ES LANGUAGE=es: m (check env in soong.log) Change-Id: If33311899eaed8c44573113ee35c5a71cee503a0
Diffstat (limited to 'ui')
-rw-r--r--ui/build/config.go48
-rw-r--r--ui/build/environment.go12
2 files changed, 60 insertions, 0 deletions
diff --git a/ui/build/config.go b/ui/build/config.go
index 0c37724b..363121f9 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -168,6 +168,8 @@ func NewConfig(ctx Context, args ...string) Config {
}()
absJavaHome := absPath(ctx, javaHome)
+ ret.configureLocale(ctx)
+
newPath := []string{filepath.Join(absJavaHome, "bin")}
if path, ok := ret.environ.Get("PATH"); ok && path != "" {
newPath = append(newPath, path)
@@ -228,6 +230,52 @@ func (c *configImpl) parseArgs(ctx Context, args []string) {
}
}
+func (c *configImpl) configureLocale(ctx Context) {
+ cmd := Command(ctx, Config{c}, "locale", "locale", "-a")
+ output, err := cmd.Output()
+
+ var locales []string
+ if err == nil {
+ locales = strings.Split(string(output), "\n")
+ } else {
+ // If we're unable to list the locales, let's assume en_US.UTF-8
+ locales = []string{"en_US.UTF-8"}
+ ctx.Verbosef("Failed to list locales (%q), falling back to %q", err, locales)
+ }
+
+ // gettext uses LANGUAGE, which is passed directly through
+
+ // For LANG and LC_*, only preserve the evaluated version of
+ // LC_MESSAGES
+ user_lang := ""
+ if lc_all, ok := c.environ.Get("LC_ALL"); ok {
+ user_lang = lc_all
+ } else if lc_messages, ok := c.environ.Get("LC_MESSAGES"); ok {
+ user_lang = lc_messages
+ } else if lang, ok := c.environ.Get("LANG"); ok {
+ user_lang = lang
+ }
+
+ c.environ.UnsetWithPrefix("LC_")
+
+ if user_lang != "" {
+ c.environ.Set("LC_MESSAGES", user_lang)
+ }
+
+ // The for LANG, use C.UTF-8 if it exists (Debian currently, proposed
+ // for others)
+ if inList("C.UTF-8", locales) {
+ c.environ.Set("LANG", "C.UTF-8")
+ } else if inList("en_US.UTF-8", locales) {
+ c.environ.Set("LANG", "en_US.UTF-8")
+ } else if inList("en_US.utf8", locales) {
+ // These normalize to the same thing
+ c.environ.Set("LANG", "en_US.UTF-8")
+ } else {
+ ctx.Fatalln("System doesn't support either C.UTF-8 or en_US.UTF-8")
+ }
+}
+
// Lunch configures the environment for a specific product similarly to the
// `lunch` bash function.
func (c *configImpl) Lunch(ctx Context, product, variant string) {
diff --git a/ui/build/environment.go b/ui/build/environment.go
index baab101b..85899379 100644
--- a/ui/build/environment.go
+++ b/ui/build/environment.go
@@ -63,6 +63,18 @@ func (e *Environment) Unset(keys ...string) {
*e = out
}
+// UnsetWithPrefix removes all keys that start with prefix.
+func (e *Environment) UnsetWithPrefix(prefix string) {
+ out := (*e)[:0]
+ for _, env := range *e {
+ if key, _, ok := decodeKeyValue(env); ok && strings.HasPrefix(key, prefix) {
+ continue
+ }
+ out = append(out, env)
+ }
+ *e = out
+}
+
// Environ returns the []string required for exec.Cmd.Env
func (e *Environment) Environ() []string {
return []string(*e)