Skip to content

Commit

Permalink
Fix values being at root and local level
Browse files Browse the repository at this point in the history
Resolves #278
  • Loading branch information
russellbanks committed Aug 17, 2023
1 parent b3bf17f commit 7006f58
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 72 deletions.
54 changes: 27 additions & 27 deletions src/main/kotlin/data/InstallerManifestData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import schemas.manifest.DefaultLocaleManifest
import schemas.manifest.InstallerManifest
import utils.ManifestUtils.updateVersionInString
import utils.Zip
import utils.getDistinctOrNull
import utils.filterSingleDistinctOrElse
import utils.mapDistinctSingleOrNull
import utils.msi.Msi
import utils.msix.Msix
import utils.msix.MsixBundle
import utils.takeIfNotDistinct

object InstallerManifestData {
suspend fun addInstaller(
Expand Down Expand Up @@ -163,40 +163,40 @@ object InstallerManifestData {
return InstallerManifest.getBase(previousInstallerManifest, packageIdentifier, packageVersion).copy(
packageIdentifier = packageIdentifier,
packageVersion = packageVersion,
installerLocale = installers.getDistinctOrNull(InstallerManifest.Installer::installerLocale)
installerLocale = installers.mapDistinctSingleOrNull(InstallerManifest.Installer::installerLocale)
?.ifBlank { null }
?: previousInstallerManifest?.installerLocale,
platform = installers.getDistinctOrNull(InstallerManifest.Installer::platform)
platform = installers.mapDistinctSingleOrNull(InstallerManifest.Installer::platform)
?: previousInstallerManifest?.platform,
minimumOSVersion = installers.getDistinctOrNull(InstallerManifest.Installer::minimumOSVersion)
minimumOSVersion = installers.mapDistinctSingleOrNull(InstallerManifest.Installer::minimumOSVersion)
?.ifBlank { null },
installerType = installers.getDistinctOrNull(InstallerManifest.Installer::installerType)
installerType = installers.mapDistinctSingleOrNull(InstallerManifest.Installer::installerType)
?: previousInstallerManifest?.installerType,
nestedInstallerType = installers.getDistinctOrNull(InstallerManifest.Installer::nestedInstallerType)
nestedInstallerType = installers.mapDistinctSingleOrNull(InstallerManifest.Installer::nestedInstallerType)
?: previousInstallerManifest?.nestedInstallerType,
nestedInstallerFiles = (
installers.getDistinctOrNull(InstallerManifest.Installer::nestedInstallerFiles)
installers.mapDistinctSingleOrNull(InstallerManifest.Installer::nestedInstallerFiles)
?: previousInstallerManifest?.nestedInstallerFiles
)?.map {
it.copy(relativeFilePath = it.relativeFilePath.updateVersionInString(allVersions, packageVersion))
},
scope = installers.getDistinctOrNull(InstallerManifest.Installer::scope)
scope = installers.mapDistinctSingleOrNull(InstallerManifest.Installer::scope)
?: previousInstallerManifest?.scope,
packageFamilyName = installers.getDistinctOrNull(InstallerManifest.Installer::packageFamilyName)
packageFamilyName = installers.mapDistinctSingleOrNull(InstallerManifest.Installer::packageFamilyName)
?: previousInstallerManifest?.packageFamilyName,
productCode = installers.getDistinctOrNull(InstallerManifest.Installer::productCode),
productCode = installers.mapDistinctSingleOrNull(InstallerManifest.Installer::productCode),
installModes = installModes?.ifEmpty { null }
?: previousInstallerManifest?.installModes,
installerSwitches = installers.getDistinctOrNull(InstallerManifest.Installer::installerSwitches)
installerSwitches = installers.mapDistinctSingleOrNull(InstallerManifest.Installer::installerSwitches)
?: previousInstallerManifest?.installerSwitches,
installerSuccessCodes = installerSuccessCodes?.ifEmpty { null }
?: previousInstallerManifest?.installerSuccessCodes,
upgradeBehavior = installers.getDistinctOrNull(InstallerManifest.Installer::upgradeBehavior)
upgradeBehavior = installers.mapDistinctSingleOrNull(InstallerManifest.Installer::upgradeBehavior)
?: previousInstallerManifest?.upgradeBehavior,
commands = commands?.ifEmpty { null } ?: previousInstallerManifest?.commands,
protocols = protocols?.ifEmpty { null } ?: previousInstallerManifest?.protocols,
fileExtensions = fileExtensions?.ifEmpty { null } ?: previousInstallerManifest?.fileExtensions,
releaseDate = installers.getDistinctOrNull { it.releaseDate },
releaseDate = installers.mapDistinctSingleOrNull { it.releaseDate },
appsAndFeaturesEntries = when (installers.distinctBy { it.appsAndFeaturesEntries }.size) {
0 -> previousInstallerManifest?.appsAndFeaturesEntries
1 -> installers.first().appsAndFeaturesEntries
Expand All @@ -212,22 +212,22 @@ object InstallerManifestData {
List<InstallerManifest.Installer> {
return map { installer ->
installer.copy(
installerLocale = installers.takeIfNotDistinct(installer.installerLocale) { it.installerLocale },
platform = installers.takeIfNotDistinct(installer.platform) { it.platform },
minimumOSVersion = installers.takeIfNotDistinct(installer.minimumOSVersion) { it.minimumOSVersion },
installerType = installers.takeIfNotDistinct(installer.installerType) { it.installerType },
installerLocale = installers.filterSingleDistinctOrElse(installer.installerLocale) { it.installerLocale },
platform = installers.filterSingleDistinctOrElse(installer.platform) { it.platform },
minimumOSVersion = installers.filterSingleDistinctOrElse(installer.minimumOSVersion) { it.minimumOSVersion },
installerType = installers.filterSingleDistinctOrElse(installer.installerType) { it.installerType },
nestedInstallerType = installers
.takeIfNotDistinct(installer.nestedInstallerType) { it.nestedInstallerType },
.filterSingleDistinctOrElse(installer.nestedInstallerType) { it.nestedInstallerType },
nestedInstallerFiles = installers
.takeIfNotDistinct(installer.nestedInstallerFiles) { it.nestedInstallerFiles },
scope = installers.takeIfNotDistinct(installer.scope) { it.scope },
packageFamilyName = installers.takeIfNotDistinct(installer.packageFamilyName) { it.packageFamilyName },
productCode = installers.takeIfNotDistinct(installer.productCode) { it.productCode },
releaseDate = installers.takeIfNotDistinct(installer.releaseDate) { it.releaseDate },
upgradeBehavior = installers.takeIfNotDistinct(installer.upgradeBehavior) { it.upgradeBehavior },
installerSwitches = installers.takeIfNotDistinct(installer.installerSwitches) { it.installerSwitches },
.filterSingleDistinctOrElse(installer.nestedInstallerFiles) { it.nestedInstallerFiles },
scope = installers.filterSingleDistinctOrElse(installer.scope) { it.scope },
packageFamilyName = installers.filterSingleDistinctOrElse(installer.packageFamilyName) { it.packageFamilyName },
productCode = installers.filterSingleDistinctOrElse(installer.productCode) { it.productCode },
releaseDate = installers.filterSingleDistinctOrElse(installer.releaseDate) { it.releaseDate },
upgradeBehavior = installers.filterSingleDistinctOrElse(installer.upgradeBehavior) { it.upgradeBehavior },
installerSwitches = installers.filterSingleDistinctOrElse(installer.installerSwitches) { it.installerSwitches },
appsAndFeaturesEntries = installers
.takeIfNotDistinct(installer.appsAndFeaturesEntries) { it.appsAndFeaturesEntries }
.filterSingleDistinctOrElse(installer.appsAndFeaturesEntries) { it.appsAndFeaturesEntries }
)
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/main/kotlin/data/shared/PackageName.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@ class PackageName(private val msi: Msi?, private val defaultLocaleManifest: Defa
)

override val extraText: String = buildString {
append("Example: Microsoft Teams")
msi?.productName?.let { appendLine("Detected from MSI: $it") }
msi?.productName?.let {
appendLine(EXAMPLE)
append("Detected from MSI: $it")
} ?: append(EXAMPLE)
}

override val default: String? get() = defaultLocaleManifest?.packageName

companion object {
private const val EXAMPLE = "Example: Microsoft Teams"
}
}
1 change: 0 additions & 1 deletion src/main/kotlin/github/GitHubImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ object GitHubImpl {
info("Would you like to proceed?")
if (!yesNoMenu(default = false).prompt()) throw ProgramResult(0)
}
println()
}

fun createBranchFromUpstreamDefaultBranch(
Expand Down
35 changes: 16 additions & 19 deletions src/main/kotlin/utils/IterableExtensions.kt
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
package utils

/**
* Returns the default value if the values returned by the [selector] function on each element
* in this iterable are all the same. Otherwise, returns `null`.
* Transforms each element of the iterable using the provided [selector] function, collects the transformed elements
* into a set, and then evaluates whether there is a single distinct element in the set. If there's only one distinct
* element, returns `null`; otherwise, returns the specified [default] value.
*
* @param default the value to return if the elements are not distinct
* @param selector a function that maps elements to a value to be compared for distinctness
* @return the default value if the elements are not distinct, `null` otherwise
* @param default the default value to return if there is more than one distinct element.
* @param selector the function to transform elements.
* @return `null` if there is a single distinct element; otherwise, the [default] value.
*/
inline fun <T, R> Iterable<T>.takeIfNotDistinct(default: R, selector: (T) -> R): R? {
return if (any()) {
if (distinctBy(selector).size == 1) null else default
} else {
null
}
inline fun <T, R> Iterable<T>.filterSingleDistinctOrElse(default: R, selector: (T) -> R): R? {
return if (mapTo(HashSet(), selector).size == 1) null else default
}

/**
* Returns a distinct value of type [R] obtained by applying the given [selector] function to each element of the
* iterable, or null if there are multiple distinct values or if there are no values after applying the [selector].
* Maps each element of the iterable using the provided [selector] function, collects the transformed elements into a
* set, and then returns a single distinct element from the set, or null if the set is empty or contains more than one
* element.
*
* @param selector a function that maps an element of the iterable to a value of type [R] or returns null if the
* element should be skipped.
* @return a distinct value of type [R] or null if there are multiple distinct values or if there are no values
* after applying the [selector].
* @param selector the function to transform elements.
* @return a single distinct element from the transformed set, or null if the set is empty or contains more than one
* element.
*/
inline fun <T, R> Iterable<T>.getDistinctOrNull(selector: (T) -> R?): R? {
return mapNotNull(selector).toSet().singleOrNull()
inline fun <T, R> Iterable<T>.mapDistinctSingleOrNull(selector: (T) -> R): R? {
return mapTo(HashSet(), selector).singleOrNull()
}
64 changes: 41 additions & 23 deletions src/test/kotlin/extensions/IterableExtensionsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,52 @@ package extensions

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import io.ktor.http.URLBuilder
import io.ktor.http.Url
import schemas.manifest.InstallerManifest
import utils.takeIfNotDistinct
import utils.filterSingleDistinctOrElse
import utils.mapDistinctSingleOrNull

class IterableExtensionsTest : FunSpec({
context("takeIfNotDistinct") {
val baseInstaller = InstallerManifest.Installer(
architecture = InstallerManifest.Installer.Architecture.NEUTRAL,
installerUrl = Url(URLBuilder()),
installerSha256 = ""
)
val userScopeInstaller = baseInstaller.copy(scope = InstallerManifest.Scope.User)
val machineScopeInstaller = baseInstaller.copy(scope = InstallerManifest.Scope.Machine)
val baseInstaller = InstallerManifest.Installer(
architecture = InstallerManifest.Installer.Architecture.NEUTRAL,
installerUrl = Url(""),
installerSha256 = ""
)
val userScopeInstaller = baseInstaller.copy(scope = InstallerManifest.Scope.User)
val machineScopeInstaller = baseInstaller.copy(scope = InstallerManifest.Scope.Machine)

test("returns default value if iterable is not distinct") {
listOf(
userScopeInstaller,
machineScopeInstaller
).takeIfNotDistinct(default = machineScopeInstaller.scope) { it.scope } shouldBe machineScopeInstaller.scope
}
test("filterSingleDistinctOrElse returns the default value if the iterable is not distinct by the mapper") {
listOf(
userScopeInstaller,
machineScopeInstaller
).filterSingleDistinctOrElse(
default = machineScopeInstaller.scope,
selector = InstallerManifest.Installer::scope
) shouldBe machineScopeInstaller.scope
}

test("filterSingleDistinctOrElse returns null if the iterable is distinct by the mapper") {
listOf(
userScopeInstaller,
userScopeInstaller,
userScopeInstaller
).filterSingleDistinctOrElse(
default = userScopeInstaller.scope,
selector = InstallerManifest.Installer::scope
) shouldBe null
}

test("mapDistinctSingleOrNull returns null if the iterable is not distinct by the mapper") {
listOf(
userScopeInstaller,
baseInstaller
).mapDistinctSingleOrNull(InstallerManifest.Installer::scope) shouldBe null
}

test("returns null if iterable is distinct") {
listOf(
userScopeInstaller,
userScopeInstaller,
userScopeInstaller
).takeIfNotDistinct(default = userScopeInstaller.scope) { it.scope } shouldBe null
}
test("mapDistinctSingleOrNull returns the value if the iterable is distinct by the mapper") {
listOf(
userScopeInstaller,
userScopeInstaller
).mapDistinctSingleOrNull(InstallerManifest.Installer::scope) shouldBe userScopeInstaller.scope
}
})

0 comments on commit 7006f58

Please sign in to comment.