-
Notifications
You must be signed in to change notification settings - Fork 508
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor 'CurrentBaseline' to 'Baseline' in public 'api' package (#1569)
KtLint does not distinct between old or new baseline. Hence, the term CurrentBaseline is meaningless. The class was located in the `internal` package but was exposed in the public API and is used by Diktat. Now the class is moved to the public API package and documented more properly.
- Loading branch information
1 parent
d64733b
commit 6ed2589
Showing
5 changed files
with
213 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
153 changes: 153 additions & 0 deletions
153
ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/api/Baseline.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
package com.pinterest.ktlint.core.api | ||
|
||
import com.pinterest.ktlint.core.LintError | ||
import com.pinterest.ktlint.core.api.Baseline.Status.INVALID | ||
import com.pinterest.ktlint.core.api.Baseline.Status.NOT_FOUND | ||
import com.pinterest.ktlint.core.api.Baseline.Status.VALID | ||
import com.pinterest.ktlint.core.initKtLintKLogger | ||
import java.io.File | ||
import java.io.IOException | ||
import java.io.InputStream | ||
import java.nio.file.Paths | ||
import javax.xml.parsers.DocumentBuilderFactory | ||
import javax.xml.parsers.ParserConfigurationException | ||
import mu.KotlinLogging | ||
import org.w3c.dom.Element | ||
import org.xml.sax.SAXException | ||
|
||
private val logger = KotlinLogging.logger {}.initKtLintKLogger() | ||
|
||
/** | ||
* Baseline of lint errors to be ignored in subsequent calls to ktlint. | ||
*/ | ||
public class Baseline( | ||
/** | ||
* Lint errors grouped by (relative) file path. | ||
*/ | ||
public val lintErrorsPerFile: Map<String, List<LintError>> = emptyMap(), | ||
|
||
/** | ||
* Status of the baseline file. | ||
*/ | ||
public val status: Status | ||
) { | ||
public enum class Status { | ||
/** | ||
* Baseline file is successfully parsed. | ||
*/ | ||
VALID, | ||
|
||
/** | ||
* Baseline file does not exist. File needs to be generated by the consumer first. | ||
*/ | ||
NOT_FOUND, | ||
|
||
/** | ||
* Baseline file is not successfully parsed. File needs to be regenerated by the consumer. | ||
*/ | ||
INVALID | ||
} | ||
} | ||
|
||
/** | ||
* Loads the [Baseline] from the file located on [path]. | ||
*/ | ||
public fun loadBaseline(path: String): Baseline { | ||
Paths | ||
.get(path) | ||
.toFile() | ||
.takeIf { it.exists() } | ||
?.let { baselineFile -> | ||
try { | ||
return Baseline( | ||
lintErrorsPerFile = parseBaseline(baselineFile.inputStream()), | ||
status = VALID | ||
) | ||
} catch (e: IOException) { | ||
logger.error { "Unable to parse baseline file: $path" } | ||
} catch (e: ParserConfigurationException) { | ||
logger.error { "Unable to parse baseline file: $path" } | ||
} catch (e: SAXException) { | ||
logger.error { "Unable to parse baseline file: $path" } | ||
} | ||
|
||
// Baseline can not be parsed. | ||
try { | ||
baselineFile.delete() | ||
} catch (e: IOException) { | ||
logger.error { "Unable to delete baseline file: $path" } | ||
} | ||
return Baseline(status = INVALID) | ||
} | ||
|
||
return Baseline(status = NOT_FOUND) | ||
} | ||
|
||
/** | ||
* Parses the [inputStream] of a baseline file and return the lint errors grouped by the relative file names. | ||
*/ | ||
internal fun parseBaseline(inputStream: InputStream): Map<String, List<LintError>> { | ||
val lintErrorsPerFile = HashMap<String, List<LintError>>() | ||
val fileNodeList = | ||
DocumentBuilderFactory | ||
.newInstance() | ||
.newDocumentBuilder() | ||
.parse(inputStream) | ||
.getElementsByTagName("file") | ||
for (i in 0 until fileNodeList.length) { | ||
with(fileNodeList.item(i) as Element) { | ||
lintErrorsPerFile[getAttribute("name")] = parseBaselineErrorsByFile() | ||
} | ||
} | ||
return lintErrorsPerFile | ||
} | ||
|
||
/** | ||
* Parses the [LintError]s inside a file element in the xml | ||
*/ | ||
private fun Element.parseBaselineErrorsByFile(): List<LintError> { | ||
val errors = mutableListOf<LintError>() | ||
val errorsList = getElementsByTagName("error") | ||
for (i in 0 until errorsList.length) { | ||
errors.add( | ||
with(errorsList.item(i) as Element) { | ||
LintError( | ||
line = getAttribute("line").toInt(), | ||
col = getAttribute("column").toInt(), | ||
ruleId = getAttribute("source"), | ||
detail = "" // Not available in the baseline file | ||
) | ||
} | ||
) | ||
} | ||
return errors | ||
} | ||
|
||
/** | ||
* Checks if the list contains the given [LintError]. The [List.contains] function can not be used as [LintError.detail] | ||
* is not available in the baseline file and a normal equality check on the [LintErrpr] fails. | ||
*/ | ||
public fun List<LintError>.containsLintError(lintError: LintError): Boolean = | ||
any { it.isSameAs(lintError) } | ||
|
||
private fun LintError.isSameAs(lintError: LintError) = | ||
col == lintError.col && | ||
line == lintError.line && | ||
ruleId == lintError.ruleId | ||
|
||
/** | ||
* Checks if the list does not contain the given [LintError]. The [List.contains] function can not be used as | ||
* [LintError.detail] is not available in the baseline file and a normal equality check on the [LintErrpr] fails. | ||
*/ | ||
public fun List<LintError>.doesNotContain(lintError: LintError): Boolean = | ||
none { it.isSameAs(lintError) } | ||
|
||
/** | ||
* Gets the relative route of the file for baselines. Also adjusts the slashes for uniformity between file systems | ||
*/ | ||
public val File.relativeRoute: String | ||
get() { | ||
val rootPath = Paths.get("").toAbsolutePath() | ||
val filePath = this.toPath() | ||
return rootPath.relativize(filePath).toString().replace(File.separatorChar, '/') | ||
} |
133 changes: 0 additions & 133 deletions
133
ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/internal/CurrentBaseline.kt
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.