1 /*
2  * Copyright (C) 2024 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.common
18 
19 import com.android.SdkConstants
20 import com.github.ajalt.clikt.parameters.groups.OptionGroup
21 import com.github.ajalt.clikt.parameters.options.option
22 import java.io.File
23 
24 const val ARG_COMMON_SOURCE_PATH = "--common-source-path"
25 const val ARG_SOURCE_PATH = "--source-path"
26 
27 /** The name of the group, can be used in help text to refer to the options in this group. */
28 const val SOURCE_OPTIONS_GROUP = "Sources"
29 
30 class SourceOptions :
31     OptionGroup(
32         name = SOURCE_OPTIONS_GROUP,
33         help =
34             """
35             Options that control which source files will be processed.
36         """
37                 .trimIndent()
38     ) {
39 
40     private val commonSourcePathString by
41         option(
42             ARG_COMMON_SOURCE_PATH,
43             metavar = "<path>",
44             help =
45                 """
46                     A ${File.pathSeparator} separated list of directories containing common source
47                     files (organized in a standard Java package hierarchy). Common source files
48                     are where platform-agnostic `expect` declarations for Kotlin multi-platform code
49                     as well as common business logic are defined.
50                 """
51                     .trimIndent(),
52         )
53 
54     private val sourcePathString by
55         option(
56             ARG_SOURCE_PATH,
57             metavar = "<path>",
58             help =
59                 """
60                     A ${File.pathSeparator} separated list of directories containing source
61                     files (organized in a standard Java package hierarchy).
62                 """
63                     .trimIndent(),
64         )
65 
66     internal val commonSourcePath by
<lambda>null67         lazy(LazyThreadSafetyMode.NONE) {
68             getSourcePath(ARG_COMMON_SOURCE_PATH, commonSourcePathString)
69         }
70 
71     internal val sourcePath by
<lambda>null72         lazy(LazyThreadSafetyMode.NONE) { getSourcePath(ARG_SOURCE_PATH, sourcePathString) }
73 
getSourcePathnull74     private fun getSourcePath(argName: String, path: String?) =
75         if (path == null) {
76             emptyList()
77         } else if (path.isBlank()) {
78             // Don't compute absolute path; we want to skip this file later on.
79             // For current directory one should use ".", not "".
80             listOf(File(""))
81         } else {
<lambda>null82             path.split(File.pathSeparator).map {
83                 if (it.endsWith(SdkConstants.DOT_JAVA)) {
84                     throw MetalavaCliException(
85                         "$argName should point to a source root directory, not a source file ($it)"
86                     )
87                 }
88 
89                 stringToExistingDir(it)
90             }
91         }
92 }
93