Working with android flavors, I'm trying to inherit a flavor from another and to override a class in the parent one. Everything looks and works perfectly except that the target class shows up as duplicated. My guess is there's a way to exclude the class on the parent flavor from sourceSets like:
sourceSets {
benchmark {
java {
srcDirs = ['src/main/java', 'src/offline/java', 'src/benchmark/java']
exclude { '**/Facade.java' in sourceSets.offline.files }
}
}
}
Can someone help me with this. Thanks!
Instead of inheriting from another flavor, use flavor dimensions
android {
...
flavorDimensions "version", "online"
productFlavors {
benchmark {
dimension "version"
...
}
standard {
dimension "version"
...
}
online {
dimension "online"
...
}
offline {
dimension "online"
...
}
}
//optionally filter combinations you don't want
variantFilter { variant ->
if (variant.flavors*.name.contains("online") && variant.flavors*.name.contains("benchmark")) {
variant.ignore = true
}
}
}
Put one version of facade.java in src\benchmark\java\com\yourcompany\namespace\facade.java
Put the alternate version in src\standard\java\com\yourcompany\namespace\facade.java
Files that are always the same no matter which build flavor are left in the standard directory, src\main\java\com\yourcompany\namespace\
Related
I want to tinker with Kotlin Compose for Web a bit.
In some of my past web projects, I made use of some web components of the Clarity Design System (CDS).
In a JavaScript or TypeScript project,
you first need to install both npm packages#cds/core and #cds/city.
Secondly, you have to include some global stylesheets, e.g. via HTML or sass-import.
For each component you want to use, you need to import the corresponding register.js.
Lastly, you can include the component in your HTML like any other tag:
<cds-button>Click me!</cds-button>
I tried to replicate the steps with Kotlin Compose for Web, but wasn't able to get it to work.
Any help appreciated!
Okay, I've got it to work now, which included several steps.
Install npm dependencies
kotlin {
...
sourceSets {
val jsMain by getting {
dependencies {
// dependencies for Compose for Web
implementation(compose.web.core)
implementation(compose.runtime)
// dependencies for Clarity Design System
implementation(npm("#cds/core", "5.6.0"))
implementation(npm("#cds/city", "1.1.0"))
// dependency for webpack - see step 3
implementation(npm("file-loader", "6.2.0"))
}
}
...
}
}
Enable css support
This seems to be required, in order to include the global stylesheets.
kotlin {
js(IR) {
browser {
...
commonWebpackConfig {
cssSupport.enabled = true
}
}
...
}
...
}
Add support for .woff2 files included in stylesheet of Clarity
The stylesheet of CDS include font files of type .woff2, whose support in webpack must be configured.
This can be achieved by creating the file webpack.config.d/support-fonts.js
at the project root with the following content:
config.module.rules.push({
test: /\.(woff(2)?|ttf|eot|svg|gif|png|jpe?g)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}]
});
Include global stylesheets
external fun require(module: String): dynamic
fun main() {
require("modern-normalize/modern-normalize.css")
require("#cds/core/global.min.css")
require("#cds/core/styles/module.shims.min.css")
require("#cds/city/css/bundles/default.min.css")
...
}
Import register.js for desired web component
external fun require(module: String): dynamic
fun main() {
...
require("#cds/core/button/register.js")
...
}
Create #Composable for the web component
Sadly this solution makes use of APIs marked as #OptIn(ComposeWebInternalApi::class),
which stands for "This API is internal and is likely to change in the future".
Any hints on how this may be implemented without relying on internal APIs are appreciated.
#Composable
fun CdsButton(
status: CdsButtonStatus = CdsButtonStatus.Primary,
attrs: AttrBuilderContext<HTMLElement>? = null,
content: ContentBuilder<HTMLElement>? = null
) = TagElement(
elementBuilder = CdsElementBuilder("cds-button"),
applyAttrs = {
if (attrs != null) apply(attrs)
attr("status", status.attributeValue)
},
content = content
)
/**
* This is a copy of the private class org.jetbrains.compose.web.dom.ElementBuilderImplementation
*/
internal class CdsElementBuilder<TElement : Element>(private val tagName: String) : ElementBuilder<TElement> {
private val element: Element by lazy {
document.createElement(tagName)
}
override fun create(): TElement = element.cloneNode() as TElement
}
sealed interface CdsButtonStatus {
object Primary : CdsButtonStatus
...
}
internal val CdsButtonStatus.attributeValue
get() = when (this) {
CdsButtonStatus.Primary -> "primary"
...
}
Make us of your #Composable!
fun main() {
...
renderComposable(rootElementId = "root") {
CdsButton(
status = CdsButtonStatus.Success
) {
Text("It works! :-)")
}
}
}
I trying to create API with ktor.
Test for ktor api using JUnit5 and I need use the custom properties for database information in 'Application.conf' like below:
ktor {
deployment {
.....
}
application {
.....
}
database {
host = ${?DB_HOST}
user = ${?DB_USER}
pass = ${?DB_PASS}
}
}
I following official guidline for useing custom properties:
HoconApplicationConfig
private val testEnv = createTestEnvironment {
config = HoconApplicationConfig(ConfigFactory.load("application.conf"))
}
class MyTest {
#Test
fun Testing() {
withApplication(testEnv) {
handleRequest(HttpMethod.Get, "/foo").apply {
...
}
}
}
}
Succeed test when only one function in class, but defined second test function then test failed with Exception.
I want define multiple function to simplify the definition and checking in case of failure.
class MyTest {
#Test
fun Testing() {
withApplication(testEnv) {
handleRequest(HttpMethod.Get, "/foo").apply {
....
}
}
}
#Test
fun Testing2() {
withApplication(testEnv) {
handleRequest(HttpMethod.Get, "/foo/bar").apply {
...
}
}
}
}
io.ktor.server.engine.BaseApplicationResponse$ResponseAlreadySentException: Response has already been sent
I know all test will success using 'withTestApplication' but can't use the custom properties.
How can I use the custom properties, and define multiple test funcitons?
Environment:
macOS Big Sur 11.5
IntelliJ Ultimate 2021.1.3
kotlin 1.5.21
ktor 1.6.1
junit-jupiter 5.7.0
Sorry for bad English.
Best Regards.
I am trying to make a universal framework for iOS in KMP.
Here is my module build.gradle file
import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask
buildscript {
ext.serialization_version = "0.20.0"
repositories {
mavenCentral()
jcenter()
maven { url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies" }
}
}
repositories {
mavenCentral()
maven { url "https://kotlin.bintray.com/kotlinx" }
}
apply plugin: 'kotlin-multiplatform'
apply plugin: 'kotlinx-serialization'
def serialization_version = "0.20.0"
kotlin{
targets {
fromPreset(presets.jvm, 'android')
iosArm32("ios32")
iosArm64("ios64")
iosX64("simulator")
configure([ios32, ios64, simulator]) {
binaries.framework('Shared')
}
}
//we have 3 different sourceSets for common, android and iOS.
//each sourceSet can have their own set of dependencies and configurations
sourceSets {
commonMain.dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib-common'
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"
}
androidMain.dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib'
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
}
iosMain {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version")
}
}
ios32.dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version")
}
ios64.dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version")
}
simulator.dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version")
}
}
task fatFramework(type: FatFrameworkTask) {
// the fat framework must have the same base name as the initial frameworks
baseName = "Shared"
final File frameworkDir = new File(buildDir, "xcode-frameworks")
destinationDir = frameworkDir
// specify the frameworks to be merged
from(
targets.ios32.binaries.getFramework('Shared', 'RELEASE'),
targets.ios64.binaries.getFramework('Shared', 'RELEASE'),
targets.simulator.binaries.getFramework('Shared', 'RELEASE')
)
doLast {
new File(frameworkDir, 'gradlew').with {
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$#\n"
setExecutable(true)
}
}
}
}
configurations {
compileClasspath
}
tasks.build.dependsOn fatFramework
When I try to build my Module it gives me this error
Execution failed for task ':Shared:linkSharedReleaseFrameworkIos32'.
> Resolving configuration 'ios32Api' directly is not allowed
Am I missing something in my configuration?
I was unable to reproduce the error as the question features only part of the project. So, while modifying it to make things work as a separate project rather than a module, I accidentally lost the original problem. But here are my thoughts on the possible cause.
This snippet seems to be missing the difference between source sets and targets. I mean, as there are three named targets ios32, ios64, simulator, the kotlin-multiplatform plugin creates six default source sets: ios32Main, ios64Main, simulatorMain, ios32Test, ios64Test, simulatorTest. But in this code, I see new source sets named ios32 etc. being created instead of setting defaults' dependencies. This can be a problem, as there are no explicit connections between those source sets and declared targets.
When I do this:
class KotlinTestNestingWithAndTests8 : BehaviorSpec() {
override fun isolationMode() = IsolationMode.InstancePerLeaf
init {
given(" Some given") {
and("Some and") {
`when`("Some when") {
then("First then") {
(1).shouldBe(1)
}
then("Second then") {
(2).shouldBe(2)
}
then("Third then") {
(3).shouldBe(3)
}
}
}
}
}
}
IntelliJ shows this:
Why are the last two leaf tests not nested as siblings of the first leaf test?
Am I not understanding the use case for the InstancePerLeaf setting and tests are not supposed to be nested in this way when using it?
UPDATE:
I created a bug ticket.
This is my way to display an array of data:
private val data = observableArrayList(
arrayOf("AAA", "111"),
arrayOf("BBB", "222"),
arrayOf("CCC", "333")
)
class HelloWorld : View() {
override val root = tableview<Array<String>>(data) {
column("name") { cellDataFeatures: TableColumn.CellDataFeatures<Array<String>, String> ->
SimpleStringProperty(cellDataFeatures.value[0])
}
column("value") { cellDataFeatures: TableColumn.CellDataFeatures<Array<String>, String> ->
SimpleStringProperty(cellDataFeatures.value[1])
}
}
}
It works but the code is quite complex. Is there any better way to do it?
(Maybe define a class to hold the data will make it much simpler, but I just want to test some uncommon cases)
Update:
A complete demo project for this: https://github.com/javafx-demos/tornadofx-tableview-array-data-demo
Here is a simpler way of defining your columns:
class HelloWorld : View() {
override val root = tableview(data) {
column<Array<String>, String>("name", { it.value[0].toProperty() })
column<Array<String>, String>("value", { it.value[1].toProperty() })
}
}
That said, using a specialized data structure would yield less headache :)
An alternative approach would be to configure just the cell item type and then a value factory:
column("name", String::class) {
value { it.value[0] }
}
column("value", String::class) {
value { it.value[1] }
}