1 /* 2 * Copyright (C) 2023 The Android Open Source Project 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 com.android.tools.metalava.cli.signature 18 19 import com.android.tools.metalava.OptionsDelegate 20 import com.android.tools.metalava.SignatureWriter 21 import com.android.tools.metalava.cli.common.MetalavaCliException 22 import com.android.tools.metalava.cli.common.MetalavaSubCommand 23 import com.android.tools.metalava.cli.common.existingFile 24 import com.android.tools.metalava.cli.common.newFile 25 import com.android.tools.metalava.cli.common.progressTracker 26 import com.android.tools.metalava.createReportFile 27 import com.android.tools.metalava.model.text.ApiFile 28 import com.android.tools.metalava.model.text.ApiParseException 29 import com.android.tools.metalava.model.text.SignatureFile 30 import com.android.tools.metalava.model.visitors.ApiVisitor 31 import com.github.ajalt.clikt.parameters.arguments.argument 32 import com.github.ajalt.clikt.parameters.arguments.multiple 33 import com.github.ajalt.clikt.parameters.groups.provideDelegate 34 import com.github.ajalt.clikt.parameters.options.option 35 import com.github.ajalt.clikt.parameters.options.required 36 37 class MergeSignaturesCommand : 38 MetalavaSubCommand( 39 help = 40 """ 41 Merge multiple signature files together into a single file. 42 43 The files must all be from the same API surface. The input files may overlap at the 44 package and class level but if two files do include the same class they must be 45 identical. Note: It is the user's responsibility to ensure that these constraints 46 are met as metalava does not have the information available to enforce it. Failure 47 to do so will result in undefined behavior. 48 """ 49 .trimIndent(), 50 ) { 51 /** Add options for controlling the format of the generated files. */ 52 private val signatureFormat by SignatureFormatOptions() 53 54 private val files by 55 argument( 56 name = "<files>", 57 help = 58 """ 59 Multiple signature files that will be merged together. 60 """ 61 .trimIndent() 62 ) 63 .existingFile() 64 .multiple(required = true) 65 66 private val out by 67 option( 68 "--out", 69 help = 70 """ 71 The output file into which the result will be written. The format of the 72 file will be determined by the options in `$SIGNATURE_FORMAT_OUTPUT_GROUP`. 73 """ 74 .trimIndent() 75 ) 76 .newFile() 77 .required() 78 runnull79 override fun run() { 80 // Make sure that none of the code called by this command accesses the global `options` 81 // property. 82 OptionsDelegate.disallowAccess() 83 84 try { 85 val codebase = ApiFile.parseApi(SignatureFile.fromFiles(files)) 86 createReportFile(progressTracker, codebase, out, description = "Merged file") { 87 SignatureWriter( 88 writer = it, 89 filterEmit = { true }, 90 filterReference = { true }, 91 preFiltered = true, 92 fileFormat = signatureFormat.fileFormat, 93 showUnannotated = false, 94 apiVisitorConfig = ApiVisitor.Config(), 95 ) 96 } 97 } catch (e: ApiParseException) { 98 throw MetalavaCliException(stderr = e.message) 99 } 100 } 101 } 102