1// Copyright 2020 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 15package main 16 17import ( 18 "io/fs" 19 "io/ioutil" 20 "os" 21 "path/filepath" 22 23 "android/soong/android" 24 "android/soong/bp2build" 25) 26 27// A helper function to generate a Read-only Bazel workspace in outDir 28func createBazelWorkspace(ctx *bp2build.CodegenContext, outDir string, generateFilegroups bool) error { 29 os.RemoveAll(outDir) 30 ruleShims := bp2build.CreateRuleShims(android.ModuleTypeFactories()) 31 32 res, err := bp2build.GenerateBazelTargets(ctx, generateFilegroups) 33 if err != nil { 34 panic(err) 35 } 36 37 filesToWrite := bp2build.CreateBazelFiles(ruleShims, res.BuildDirToTargets(), ctx.Mode()) 38 bazelRcFiles, err2 := CopyBazelRcFiles() 39 if err2 != nil { 40 return err2 41 } 42 filesToWrite = append(filesToWrite, bazelRcFiles...) 43 for _, f := range filesToWrite { 44 if err := writeReadOnlyFile(outDir, f); err != nil { 45 return err 46 } 47 } 48 49 return nil 50} 51 52// CopyBazelRcFiles creates BazelFiles for all the bazelrc files under 53// build/bazel. They're needed because the rc files are still read when running 54// queryview, so they have to be in the queryview workspace. 55func CopyBazelRcFiles() ([]bp2build.BazelFile, error) { 56 result := make([]bp2build.BazelFile, 0) 57 err := filepath.WalkDir(filepath.Join(topDir, "build/bazel"), func(path string, info fs.DirEntry, err error) error { 58 if filepath.Ext(path) == ".bazelrc" { 59 contents, err := os.ReadFile(path) 60 if err != nil { 61 return err 62 } 63 path, err = filepath.Rel(topDir, path) 64 if err != nil { 65 return err 66 } 67 result = append(result, bp2build.BazelFile{ 68 Dir: filepath.Dir(path), 69 Basename: filepath.Base(path), 70 Contents: string(contents), 71 }) 72 } 73 return nil 74 }) 75 return result, err 76} 77 78// The auto-conversion directory should be read-only, sufficient for bazel query. The files 79// are not intended to be edited by end users. 80func writeReadOnlyFile(dir string, f bp2build.BazelFile) error { 81 dir = filepath.Join(dir, f.Dir) 82 if err := createDirectoryIfNonexistent(dir); err != nil { 83 return err 84 } 85 pathToFile := filepath.Join(dir, f.Basename) 86 87 // 0444 is read-only 88 err := ioutil.WriteFile(pathToFile, []byte(f.Contents), 0444) 89 90 return err 91} 92 93func writeReadWriteFile(dir string, f bp2build.BazelFile) error { 94 dir = filepath.Join(dir, f.Dir) 95 if err := createDirectoryIfNonexistent(dir); err != nil { 96 return err 97 } 98 pathToFile := filepath.Join(dir, f.Basename) 99 100 // 0644 is read-write 101 err := ioutil.WriteFile(pathToFile, []byte(f.Contents), 0644) 102 103 return err 104} 105 106func createDirectoryIfNonexistent(dir string) error { 107 if _, err := os.Stat(dir); os.IsNotExist(err) { 108 return os.MkdirAll(dir, os.ModePerm) 109 } else { 110 return err 111 } 112} 113