-
Notifications
You must be signed in to change notification settings - Fork 16
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
Proof of concept: MastodonMinServerVersion annotation #335
Draft
PattaFeuFeu
wants to merge
5
commits into
master
Choose a base branch
from
feature/annotation-mastodonMinServerVersion
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
8bdc1b4
Add MastodonMinServerVersion annotation class
PattaFeuFeu b481ea4
Add BigBoneVersionException
PattaFeuFeu 717823c
Check annotated version through reflection and throw exception
PattaFeuFeu 2a4dcca
Prepare MockClient for instance version testing
PattaFeuFeu 29e379b
Proof of concept: Add annotation to InstanceMethods#getInstance
PattaFeuFeu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
81 changes: 81 additions & 0 deletions
81
bigbone/src/main/kotlin/social/bigbone/MastodonMinServerVersion.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,81 @@ | ||
package social.bigbone | ||
|
||
import social.bigbone.api.exception.BigBoneVersionException | ||
import kotlin.annotation.AnnotationTarget.FUNCTION | ||
import kotlin.math.max | ||
import kotlin.reflect.KFunction | ||
import kotlin.reflect.full.findAnnotation | ||
|
||
/** | ||
* Specifies the first version of a Mastodon server where a declaration has appeared. | ||
* In essence, this defines the minimum server version that is required in order to make a call successful. | ||
* | ||
* @property version the version in the following formats: `<major>.<minor>` or `<major>.<minor>.<patch>`, where major, minor and patch | ||
* are non-negative integer numbers without leading zeros. | ||
*/ | ||
@Target(FUNCTION) | ||
@Retention(AnnotationRetention.RUNTIME) | ||
@MustBeDocumented | ||
internal annotation class MastodonMinServerVersion(val version: String) | ||
|
||
/** | ||
* Tries to get the version defined in the [MastodonMinServerVersion] of this [KFunction], if any. | ||
* | ||
* @return [String] version of the [MastodonMinServerVersion] if this function is annotated, `null` otherwise | ||
*/ | ||
internal fun <T> KFunction<T>.minMastodonVersion(): String? = findAnnotation<MastodonMinServerVersion>()?.version | ||
|
||
/** | ||
* Helper function to ensure that the annotated [MastodonMinServerVersion] of this [KFunction] is lower than that of the | ||
* instance the [client] is connected to. | ||
*/ | ||
@Throws(BigBoneVersionException::class) | ||
fun <T> KFunction<T>.requireMinVersion(client: MastodonClient) { | ||
val minMastodonVersion = minMastodonVersion() ?: return | ||
val instanceVersion = client.getInstanceVersion() ?: return | ||
if (SemanticVersion(instanceVersion) >= SemanticVersion(minMastodonVersion)) return | ||
|
||
throw BigBoneVersionException( | ||
methodName = name, | ||
minVersion = minMastodonVersion, | ||
actualVersion = instanceVersion | ||
) | ||
} | ||
|
||
/** | ||
* Wrapper to allow comparison of version [String]s that follow semantic versioning. | ||
* @see <a href="https://semver.org">SemVer.org</a> | ||
*/ | ||
private class SemanticVersion(val version: String) { | ||
|
||
init { | ||
require(version.matches(versionRegex)) { "String $version doesn't appear to contain a semantic version" } | ||
} | ||
|
||
operator fun compareTo(other: SemanticVersion): Int { | ||
val thisParts = parts() | ||
val otherParts = other.parts() | ||
for (i in 0 until max(thisParts.size, otherParts.size)) { | ||
val thisPart = if (i < thisParts.size) thisParts[i].toInt() else 0 | ||
val thatPart = if (i < otherParts.size) otherParts[i].toInt() else 0 | ||
if (thisPart < thatPart) return -1 | ||
if (thisPart > thatPart) return 1 | ||
} | ||
return 0 | ||
} | ||
|
||
private fun parts() = version.split(".") | ||
|
||
companion object { | ||
/** | ||
* Suggested regular expression to parse all valid SemVer strings. | ||
* @see <a href="https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string">SemVer RegEx</a> | ||
*/ | ||
private val versionRegex = ( | ||
"""^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)""" + | ||
"""(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)""" + | ||
"""(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?""" + | ||
"""(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?${'$'}""" | ||
).toRegex() | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
bigbone/src/main/kotlin/social/bigbone/api/exception/BigBoneVersionException.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,11 @@ | ||
package social.bigbone.api.exception | ||
|
||
import social.bigbone.MastodonMinServerVersion | ||
|
||
/** | ||
* Exception which is thrown if a method annotated with a [MastodonMinServerVersion] requires a higher version of the | ||
* Mastodon software to be running on a server than is actually running on it. | ||
*/ | ||
class BigBoneVersionException(methodName: String, minVersion: String, actualVersion: String) : Exception( | ||
"$methodName requires the server to run at least Mastodon $minVersion but it runs $actualVersion" | ||
) |
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
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
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
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
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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might need to be a bit more lenient, seeing as Mastodon doesn’t follow semantic versioning to the letter at least when it comes to release candidates, as can be seen in this example JSON:
bigbone/bigbone/src/test/assets/instance_extended.json
Line 4 in b42c060
They only switched to a more SemVer-friendly variant starting with 4.2.0-beta3 in mastodon/mastodon#26653:
https://github.com/mastodon/mastodon/blob/v4.2.0-beta3/lib/mastodon/version.rb#L36-L38