16
16
17
17
package com.google.firebase.gradle.plugins
18
18
19
+ import java.io.File
19
20
import org.w3c.dom.Element
20
21
import org.w3c.dom.NodeList
21
22
@@ -26,16 +27,14 @@ fun String.remove(regex: Regex) = replace(regex, "")
26
27
fun String.remove (str : String ) = replace(str, " " )
27
28
28
29
/* *
29
- * Returns a sequence containing all elements.
30
- *
31
- * The operation is _terminal_.
30
+ * Joins a variable amount of [strings][Any.toString] to a single [String] split by newlines (`\n`).
32
31
*
33
- * Syntax sugar for :
34
- * ```
35
- * take(count())
32
+ * For example :
33
+ * ```kotlin
34
+ * println(multiLine("Hello", "World", "!")) // "Hello\nWorld\n!"
36
35
* ```
37
36
*/
38
- public fun < T > Sequence<T>. takeAll (): Sequence < T > = take(count() )
37
+ fun multiLine ( vararg strings : Any? ) = strings.joinToString( " \n " )
39
38
40
39
/* *
41
40
* Converts an [Element] to an Artifact string.
@@ -77,19 +76,30 @@ fun Element.toArtifactString() =
77
76
* ```
78
77
*
79
78
* @throws NoSuchElementException if the [Element] does not have descendant [Element]s with tags
80
- * that match the components of an Artifact string; groupId, artifactId, version .
79
+ * that match the components of an Artifact string; groupId and artifactId .
81
80
*/
82
81
fun Element.toMavenName () = " ${textByTag(" groupId" )} :${textByTag(" artifactId" )} "
83
82
84
83
/* *
85
- * Finds a descendant [Element] by a given [tag], and returns the [textContent]
86
- * [Element.getTextContent] of it.
84
+ * Finds a descendant [Element] by a [tag], and returns the [textContent][Element.getTextContent] of
85
+ * it.
87
86
*
88
87
* @param tag the XML tag to filter for (the special value "*" matches all tags)
89
88
* @throws NoSuchElementException if an [Element] with the given [tag] does not exist
90
89
* @see findElementsByTag
90
+ * @see textByTagOrNull
91
+ */
92
+ fun Element.textByTag (tag : String ) =
93
+ textByTagOrNull(tag) ? : throw RuntimeException (" Element tag was missing: $tag " )
94
+
95
+ /* *
96
+ * Finds a descendant [Element] by a [tag], and returns the [textContent][Element.getTextContent] of
97
+ * it, or null if it couldn't be found.
98
+ *
99
+ * @param tag the XML tag to filter for (the special value "*" matches all tags)
100
+ * @see textByTag
91
101
*/
92
- fun Element.textByTag (tag : String ) = findElementsByTag(tag).first() .textContent
102
+ fun Element.textByTagOrNull (tag : String ) = findElementsByTag(tag).firstOrNull()? .textContent
93
103
94
104
/* *
95
105
* Finds a descendant [Element] by a given [tag], or creates a new one.
@@ -99,7 +109,7 @@ fun Element.textByTag(tag: String) = findElementsByTag(tag).first().textContent
99
109
* @param tag the XML tag to filter for (the special value "*" matches all tags)
100
110
* @see findElementsByTag
101
111
*/
102
- fun Element.findOrCreate (tag : String ) =
112
+ fun Element.findOrCreate (tag : String ): Element =
103
113
findElementsByTag(tag).firstOrNull() ? : ownerDocument.createElement(tag).also { appendChild(it) }
104
114
105
115
/* *
@@ -118,27 +128,21 @@ fun Element.findElementsByTag(tag: String) =
118
128
* Yields the items of this [NodeList] as a [Sequence].
119
129
*
120
130
* [NodeList] does not typically offer an iterator. This extension method offers a means to loop
121
- * through a NodeList's [item][NodeList.item] method, while also taking into account its [length]
122
- * [NodeList.getLength] property to avoid an [IndexOutOfBoundsException].
131
+ * through a NodeList's [item][NodeList.item] method, while also taking into account the element's
132
+ * [length][ NodeList.getLength] property to avoid an [IndexOutOfBoundsException].
123
133
*
124
134
* Additionally, this operation is _intermediate_ and _stateless_.
125
135
*/
126
- fun NodeList.children () = sequence {
127
- for (index in 0 .. length) {
128
- yield (item(index))
136
+ fun NodeList.children (removeDOMSections : Boolean = true) = sequence {
137
+ for (index in 0 until length) {
138
+ val child = item(index)
139
+
140
+ if (! removeDOMSections || ! child.nodeName.startsWith(" #" )) {
141
+ yield (child)
142
+ }
129
143
}
130
144
}
131
145
132
- /* *
133
- * Joins a variable amount of [strings][Any.toString] to a single [String] split by newlines (`\n`).
134
- *
135
- * For example:
136
- * ```kotlin
137
- * println(multiLine("Hello", "World", "!")) // "Hello\nWorld\n!"
138
- * ```
139
- */
140
- fun multiLine (vararg strings : Any? ) = strings.joinToString(" \n " )
141
-
142
146
/* *
143
147
* Returns the first match of a regular expression in the [input], beginning at the specified
144
148
* [startIndex].
@@ -152,6 +156,26 @@ fun Regex.findOrThrow(input: CharSequence, startIndex: Int = 0) =
152
156
find(input, startIndex)
153
157
? : throw RuntimeException (multiLine(" No match found for the given input:" , input.toString()))
154
158
159
+ /* *
160
+ * Returns the value of the first capture group.
161
+ *
162
+ * Intended to be used in [MatchResult] that are only supposed to capture a single entry.
163
+ */
164
+ val MatchResult .firstCapturedValue: String
165
+ get() = groupValues[1 ]
166
+
167
+ /* *
168
+ * Returns a sequence containing all elements.
169
+ *
170
+ * The operation is _terminal_.
171
+ *
172
+ * Syntax sugar for:
173
+ * ```
174
+ * take(count())
175
+ * ```
176
+ */
177
+ fun <T > Sequence<T>.takeAll (): Sequence <T > = take(count())
178
+
155
179
/* *
156
180
* Creates a [Pair] out of an [Iterable] with only two elements.
157
181
*
@@ -212,14 +236,6 @@ fun List<String>.replaceMatches(regex: Regex, transform: (MatchResult) -> String
212
236
}
213
237
}
214
238
215
- /* *
216
- * Returns the value of the first capture group.
217
- *
218
- * Intended to be used in [MatchResult] that are only supposed to capture a single entry.
219
- */
220
- val MatchResult .firstCapturedValue: String
221
- get() = groupValues[1 ]
222
-
223
239
/* *
224
240
* Creates a diff between two lists.
225
241
*
@@ -250,3 +266,23 @@ infix fun <T> List<T>.diff(other: List<T>): List<Pair<T?, T?>> {
250
266
* ```
251
267
*/
252
268
fun <T > List<T>.coerceToSize (targetSize : Int ) = List (targetSize) { getOrNull(it) }
269
+
270
+ /* *
271
+ * The [path][File.path] represented as a qualified unix path.
272
+ *
273
+ * Useful when a system expects a unix path, but you need to be able to run it on non unix systems.
274
+ *
275
+ * @see absoluteUnixPath
276
+ */
277
+ val File .unixPath: String
278
+ get() = path.replace(" \\ " , " /" )
279
+
280
+ /* *
281
+ * The [absolutePath][File.getAbsolutePath] represented as a qualified unix path.
282
+ *
283
+ * Useful when a system expects a unix path, but you need to be able to run it on non unix systems.
284
+ *
285
+ * @see unixPath
286
+ */
287
+ val File .absoluteUnixPath: String
288
+ get() = absolutePath.replace(" \\ " , " /" )
0 commit comments