Skip to content

Latest commit

 

History

History
409 lines (338 loc) · 18.2 KB

documentation.md

File metadata and controls

409 lines (338 loc) · 18.2 KB

Documentation

dev-tools


The scope of the library is to help a library consumer to manage its configuration values. DevTool represents the main, and the single library domain object, which wraps a configuration value and encapsulates different actions(i.e., persist, update...) that could be performed with it.

As the configuration values might be of different types, there is a set of different prebuilt DevTool implementations for each configuration value type in part.


Prebuilt dev tool types

The currently prebuilt list of dev tool types makes it possible to handle all configuration values of primitive types like String, Integer, and Floating-Point. Reference types are not supported yet.

Name Config value type Yaml Json Memory Description
Toggle Boolean Allows to store, update, and consume boolean config values. toggle-tool
Text String Integer Float Allows to store, update, and consume text and numeric config values. text-tool
Enum String Integer Float Allows to store, update, and consume text and numeric config values. You set a limited config value options. enum-tool
Time Long Allows to store, update, and consume time config values. The config value is stored as Long in ms. time-tool
Group DevTool Allows to group tools that belong to the same context. group-tool

👷 Custom dev tool types

In case the prebuilt dev tools are not sufficient, a library consumer might extend the library with its own dev tools.

Configuration sources

Currently, the library supports 3 dev tools sources Yaml, Json, and Memory. However, in case you need to use a custom one, you might add it very merely. Check how to do this here.

Prebuilt sources

🤖 Android 🍏 iOS
Yaml
val src = DevToolsSources.yaml(
   assetManager = assets,
   fileName = "dev-tools.yml"
)
Not ready yet.
Json
val src = DevToolsSources.json(
   assetManager = assets,
   fileName = "dev-tools.json"
)
Not ready yet.
Memory
val tools: Map<String, DevTool<*>> = mapOf(
   "toggle-tool" to ToggleTool(default = true),
   "text-tool" to TextTool(default = 3.0),
   "time-tool" to TimeTool(days = 1)
)
val src = DevToolsSources.memory(tools)
Not ready yet.

👷 Custom sources

To add a new custom source you just need to:

  1. Create a custom dev tools reader

    The reader is the place where you should gather the dev tools data from your own source and convert it to a collection of key-value pairs. Where the key is a unique dev tool key and the value is the actual dev tool.

    🤖 Android 🍏 iOS
    class MyCustomDevToolsReader : DevToolsReader {
         override fun getDevTools(): Map> {
             return mapOf(
                 "toggle-tool" to ToggleTool(default = true),
                 "text-tool" to TextTool(default = 3.0),
                 "time-tool" to TimeTool(days = 1)
             )
         }
     }
    Not ready yet.
  2. Create the actual source

    You can do this by implementing DevToolsSource

    🤖 Android 🍏 iOS
    class MyCustomSource : DevToolsSource {
         override fun getReader(): DevToolsReader {
             return MyCustomDevToolsReader()
         }
     }
    Not ready yet.

Public API

To access and manipulate your configuration values programmatically from your's app code you'll need too have access to a DevTools instance.

Create a dev tools instance

You'll need to provide at least 2 parameters to create a new DevTools instance which are:

  1. name: a unique for your app instance dev tools id;
  2. devToolsSources: a list of dev tools sources;
  3. onConfigUpdate (optional): a config values update listener.
🤖 Android 🍏 iOS
val source = DevToolsSources.yaml(assets, "dev-tools.yml")
val devtools = DevTools.create("TOOLS", source)
// or you can provide more sources
val memory = DevToolsSources.memory(tools)
val yml = DevToolsSources.yaml(assets, "dev-tools.yml")
val json = DevToolsSources.json(assets, "dev-tools.json")
val devtools = DevTools.create("TOOLS", memory, yml, json)
Not ready yet.

Access configuration

🤖 Android 🍏 iOS
val value: Boolean = devtools.getValue("toggle-tool")
Not ready yet.

React on configuration changes

The call back will be invoked whenever a new configuration value gets updated. isCriticalUpdate will be true just in case at least one dev tool that you marked as critical using the critical flag will be updated.

🤖 Android 🍏 iOS
devtools.onConfigUpdated = { isCriticalUpdate -> 
    /* React on configuration changes*/ 
}
Not ready yet.

Access group child configuration value

🤖 Android 🍏 iOS
val value: Boolean = devtools.getGroup("toggle-tool")
             .getValue("toggle-tool")             
// or
val value: Boolean = devtools
             .getGroup("toggle-tool")
             .getGroup("toggle-inner-group")
             .getValue("toggle-tool")
Not ready yet.

Check if configuration is enabled

🤖 Android 🍏 iOS
val isEnabled = devtools.isEnabled("toggle-tool")
// or
val isEnabled = devtools
            .getGroup("toggle-tool")
            .getGroup("toggle-inner-group")
            .isEnabled("toggle-tool")
Not ready yet.

Get all configuration as JSON

Note that the lambda parameter is nothing else than a simple predicate(a filter). You can use it to filter out the configuration values that will reach the final JSON result.

For example, you can filter and get just the enabled config, as shown in the example.

🤖 Android 🍏 iOS
devtools.getAllConfigAsJson { tool -> tool.isEnabled }
Not ready yet.

Configuration screen

One of the easiest ways to update a configuration value is a good user interface. The library is able to generate a configuration screen dynamically based on your configuration file.

Startup arguments

Sometimes we might need to run the app preconfigured. The most common use case could be an automated test, for example. So the best way to run the app preconfigured is to run it from a terminal and pass some startup arguments. The library provides a similar feature, but to make use of it, you must integrate it first.

👷 For Developers

If you know how to fix an issue, consider opening a pull request for it. 🙏

You can read this repository’s contributing guidelines to learn how to open a good pull request.

Modules

modules-dependencies

The library is composed of 5 modules:

  1. Common: the actual multi-platform module which contains all business models and logic;

  2. Library Android: an Android module which contains just Android native view implementations;

  3. Library iOS: an iOS framework which contains just iOS native view implementations;

  4. Sample Android: an Android library consumer which serves as an Android library features demo.

  5. Sample iOS: an iOS library consumer which serves as an iOS library features demo.


Build process

Android iOS
You may use ./gradlew assemble to generate a new android library.

The Android library generation is straight forward.

First of all, an AAR is generated from the Common module, which is then used to generate another AAR for the Android Library itself.
The iOS framework generation is a bit more complex but not much harder than the Android one.

First of all, you need to build a Fat Framework(FF).
You can do this by running ./gradlew releaseFatFramework.

After this command succeeds, you'll notice the framework inside the iOS library package.

Now you can build the library itself.

Code Quality

Common Android iOS
- ktlint
- detekt
- ktlint
- detekt
- lint
- SwiftLint

Handy gradle tasks

  1. ./gradlew clean will remove all build directories together with the iOS Fat Framework
  2. ./gradlew assembe will generate release/debug aars and also the iOS Fat Framework
  3. ./gradlew releaseFatFramework will generate the iOS Fat Framework
  4. ./gradlew testDebugUnitTest runes all JVM modules unit tests
  5. ./gradlew detekt ktlint lint testDebugUnitTest assembleDebug will run all quality checks and will assemble the frameworks
  6. ./gradlew publishCommonPublicationToMavenRepository releases the common module to maven local
  7. ./gradlew publishAndroidPublicationToMavenRepository releases the Android library to maven local

In case you're working on the library you might find useful this alias:

alias checktools='./gradlew detekt ktlint lint testDebugUnitTest assembleDebug'

It will run all style checks, unit tests, and will assemble all artifacts.

Deployment

🍏 iOS

Not ready yet.

🤖 Android

Automated

  1. Just push the release-android-X.X.X
  2. Log in to
  3. Open
  4. Close the repository

Manual

  1. Checkout the latest master branch commit
  2. Release the project to Maven Central by running
    ./gradlew -Prelease publishReleasePublicationToMavenRepository
  3. Create and push a new tag for the new version
  4. Open a new PR to bump up to the library version and update the changelog file.

ℹ️ The deployment process will be automated after we hve the iOS library ready #56.