Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHANGELOG parser by date #426

Merged
merged 20 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions skate-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ tasks {

publishPlugin { token.set(System.getenv("PUBLISH_TOKEN")) }
}

dependencies {
testImplementation(libs.junit)
testImplementation(libs.truth)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2023 Slack Technologies, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.slack.sgp.intellij

import java.time.LocalDate

/**
* Reads a CHANGELOG.md file and produces a subset of it, based on a specified previous entry date.
*
* If a previous entry date is supplied and is found within the changelog, this function will return
* a new changelog that contains entries only up to and including this date. If the previous entry
* date is not found, the entire changelog is returned.
*
* @param changeLogString The entire changelog, as a string, where each entry is expected to start
* with a date line.
* @param previousEntry The date of the previous entry. Can be null, in which case the entire
* changelog is returned.
* @return A ParseResult object containing the filtered changelog string and the date of the latest
* entry.
*/
private val LOCAL_DATE_REGEX = "^\\d{4}-\\d{2}-\\d{2}\$".toRegex()
kateliu20 marked this conversation as resolved.
Show resolved Hide resolved
private val String.isLocalDate: Boolean
get() {
return LOCAL_DATE_REGEX.matches(this)
}

object ChangelogParser {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a doc to this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc added: 37f1b00

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it landed in the wrong place? I don't see it on ChangelogParser

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a doc to ChangelogParser.kt

fun readFile(changeLogString: String, previousEntry: LocalDate? = null): ParseResult {
/*
date format: yyyy-mm-dd
*/

if (previousEntry != null && !changeLogString.contains(previousEntry.toString())) {
return ParseResult(
changeLogString,
LocalDate.parse(changeLogString.lines().firstOrNull { it.isLocalDate })
)
}

var previous: LocalDate? = null
var entryCount = 0
val changeLogSubstring =
buildString {
var currentBlock = StringBuilder()
for (line in changeLogString.lines()) {
kateliu20 marked this conversation as resolved.
Show resolved Hide resolved
if (line.isLocalDate) {
val localDate = LocalDate.parse(line)
if (localDate == previousEntry) {
break
}
if (previous != null) {
append(currentBlock.toString())
}
currentBlock = StringBuilder()
kateliu20 marked this conversation as resolved.
Show resolved Hide resolved
if (previous == null) {
previous = localDate
}
entryCount++
}
currentBlock.appendLine(line)
}
if (entryCount == 0) {
append(currentBlock.toString())
}
}
.trimEnd()
return ParseResult(changeLogSubstring.takeIf { it.isNotBlank() }, previous ?: LocalDate.now())
}

data class ParseResult(val changeLogString: String?, val latestEntry: LocalDate)
kateliu20 marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Copyright (C) 2023 Slack Technologies, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.slack.sgp.intellij

import com.google.common.truth.Truth.assertThat
import java.time.LocalDate
import org.junit.Test

class ChangeLogParserTest {
ZacSweers marked this conversation as resolved.
Show resolved Hide resolved
kateliu20 marked this conversation as resolved.
Show resolved Hide resolved
@Test
fun `no entries and null changelogstring`() {
val (changeLogString, latestEntry) = ChangelogParser.readFile("", null)
assertThat(changeLogString).isNull()
assertThat(latestEntry).isEqualTo(LocalDate.now())
}

@Test
fun `one entry, no previous entries`() {
val input =
"""
2023-06-28

* Bug fixes
* New features
"""
.trimIndent()

val expectedDate = LocalDate.of(2023, 6, 28)
val (changeLogString, latestEntry) = ChangelogParser.readFile(input, null)
assertThat(changeLogString).isNull()
assertThat(latestEntry).isEqualTo(expectedDate)
}

@Test
fun `mutliple entries, and no previous entries`() {
val input =
"""
2023-06-28

* Bug fixes
* New features

2023-06-27

* Other changes
"""
.trimIndent()
val expectedDate = LocalDate.of(2023, 6, 28)
val expectedString =
"""
2023-06-28

* Bug fixes
* New features
"""
.trimIndent()
val (changeLogString, latestEntry) = ChangelogParser.readFile(input, null)
assertThat(changeLogString).isEqualTo(expectedString)
assertThat(latestEntry).isEqualTo(expectedDate)
}

@Test
fun `multiple entries, where the previous is the same as the latest`() {
val input =
"""
2023-06-28

* Bug fixes
* New features

2023-06-27

* Other changes
"""
.trimIndent()
val expectedDate = LocalDate.of(2023, 6, 28)
val (changeLogString, latestEntry) = ChangelogParser.readFile(input, LocalDate.of(2023, 6, 28))
assertThat(changeLogString).isNull()
assertThat(latestEntry).isEqualTo(expectedDate)
}

@Test
fun `test with a previous entry not in the change log`() {
val input =
"""
2023-06-28

* Bug fixes
* New features

2023-06-27

* Other changes
"""
.trimIndent()
val expectedDate = LocalDate.of(2023, 6, 28)
val expectedString =
"""
2023-06-28

* Bug fixes
* New features

2023-06-27

* Other changes
"""
.trimIndent()
val (changeLogString, latestEntry) = ChangelogParser.readFile(input, LocalDate.of(2023, 6, 29))
assertThat(changeLogString).isEqualTo(expectedString)
assertThat(latestEntry).isEqualTo(expectedDate)
}
}