kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/extractors/config/preprocessor/modifier/build_gradle_modifier.go (about) 1 /* 2 * Copyright 2018 The Kythe Authors. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // Package modifier provides a library for adding a forked javac executable 18 // into a build.gradle file or pom.xml file. 19 package modifier // import "kythe.io/kythe/go/extractors/config/preprocessor/modifier" 20 21 import ( 22 "fmt" 23 "io/ioutil" 24 "os" 25 "regexp" 26 ) 27 28 // These are the lines necessary for gradle build to use a different javac. 29 const kytheJavacWrapper = ` 30 allprojects { 31 gradle.projectsEvaluated { 32 tasks.withType(JavaCompile) { 33 options.fork = true 34 options.forkOptions.executable = '%s' 35 } 36 } 37 } 38 ` 39 40 // This matches a line which sets the javac to use Kythe's javac-wrapper.sh 41 func kytheMatcher(javacWrapper string) *regexp.Regexp { 42 return regexp.MustCompile(fmt.Sprintf(`\n\s*options\.forkOptions\.executable\ =\ '%s'`, javacWrapper)) 43 } 44 45 // This matches any line which sets a new javac executable, useful for detecting 46 // edge cases which already modify javac. 47 var javacMatcher = regexp.MustCompile(`\n\s*options\.forkOptions\.executable\ =`) 48 49 // PreProcessBuildGradle takes a build.gradle file and either verifies that it 50 // already has the bits necessary to run kythe's javac wrapper, or adds that 51 // functionality. 52 // 53 // Note this potentially modifies the input file, so make a copy beforehand if 54 // you need to keep the original. 55 func PreProcessBuildGradle(buildGradleFile, javacWrapper string) error { 56 k, err := hasKytheWrapper(buildGradleFile, javacWrapper) 57 if err != nil { 58 return err 59 } 60 if k { 61 // Already has the kythe javac-wrapper. 62 return nil 63 } 64 return appendKytheWrapper(buildGradleFile, javacWrapper) 65 } 66 67 func hasKytheWrapper(buildGradleFile, javacWrapper string) (bool, error) { 68 bits, err := ioutil.ReadFile(buildGradleFile) 69 if err != nil { 70 return false, fmt.Errorf("reading file %s: %v", buildGradleFile, err) 71 } 72 if kytheMatcher(javacWrapper).Match(bits) { 73 return true, nil 74 } 75 if javacMatcher.Match(bits) { 76 return false, fmt.Errorf("found existing non-kythe javac override for file %s, which we can't handle yet", buildGradleFile) 77 } 78 return false, nil 79 } 80 81 func appendKytheWrapper(buildGradleFile, javacWrapper string) error { 82 f, err := os.OpenFile(buildGradleFile, os.O_APPEND|os.O_WRONLY, os.ModeAppend) 83 if err != nil { 84 return fmt.Errorf("opening file %s for append: %v", buildGradleFile, err) 85 } 86 if _, err := fmt.Fprintf(f, kytheJavacWrapper, javacWrapper); err != nil { 87 return fmt.Errorf("appending javac-wrapper to %s: %v", buildGradleFile, err) 88 } 89 return f.Close() 90 }