Skip to content

Commit

Permalink
All test cases passing
Browse files Browse the repository at this point in the history
  • Loading branch information
Katherine Liu committed Jun 30, 2023
1 parent af7b9b5 commit b04e14b
Showing 1 changed file with 39 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -1,84 +1,90 @@
/*
* 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.
*/
// Define a regular expression that matches a date in "yyyy-mm-dd" format
private val LOCAL_DATE_REGEX = "^\\d{4}-\\d{2}-\\d{2}\$".toRegex()

// Define an extension function for the String class to check if a string can be parsed as a date
private val String.isLocalDate: Boolean
get() {
return LOCAL_DATE_REGEX.matches(this)
}

object ChangelogParser {

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

// If previousEntry is not null and it is not contained in changeLogString
// the function will return the changeLogString and the first date found
if (previousEntry != null && !changeLogString.contains(previousEntry.toString())) {
return ParseResult(
changeLogString,
LocalDate.parse(changeLogString.lines().firstOrNull { it.isLocalDate })
)
}

// previous is used to store the last date encountered
var previous: LocalDate? = null

// entryCount is used to track the number of date entries encountered
var entryCount = 0

// changeLogSubstring is the filtered changeLogString
// buildString is used to append entries and dates to a string
val changeLogSubstring =
buildString {
var currentBlock = StringBuilder()
for (line in changeLogString.lines()) {

// If the line is a date
if (line.isLocalDate) {

// Parse the date
val localDate = LocalDate.parse(line)

// If the parsed date equals the previous entry, stop the loop
if (localDate == previousEntry) {
break
}

// If a date was previously encountered, append the block to the final string
if (previous != null) {
append(currentBlock.toString())
}

// Reset the current block
currentBlock = StringBuilder()

// If this is the first date encountered, set it as previous
if (previous == null) {
previous = localDate
}

// Increment the entry count
entryCount++
}

// Append the line to the current block
currentBlock.appendLine(line)
}

// If no date entries were encountered, append the block to the final string
if (entryCount == 0) {
append(currentBlock.toString())
}
}
.trimEnd()
return ParseResult(changeLogSubstring.takeIf { it.isNotBlank() }, previous ?: LocalDate.now())

// If the changelog substring is blank, set it as null
// If the previous entry equals to the latest entry, or if no date is found,
// use the previous entry date as the latest date instead of the current date.
return ParseResult(
changeLogSubstring.takeIf { it.isNotBlank() },
previous ?: previousEntry ?: LocalDate.now()
)
}

// Define the class ParseResult to return the filtered changelog and the latest date entry
data class ParseResult(val changeLogString: String?, val latestEntry: LocalDate)
}

0 comments on commit b04e14b

Please sign in to comment.